1
This commit is contained in:
parent
6dfeb77c1e
commit
1656f6000c
@ -118,8 +118,10 @@ void AndroidAI::DoAttack()
|
|||||||
Human* enemy = owner->room->FindEnemy((Human*)owner);
|
Human* enemy = owner->room->FindEnemy((Human*)owner);
|
||||||
if (enemy) {
|
if (enemy) {
|
||||||
Human* sender = (Human*)owner;
|
Human* sender = (Human*)owner;
|
||||||
Vector2D shot_dir = enemy->pos;
|
Vector2D shot_dir = enemy->pos - sender->pos;
|
||||||
shot_dir.Normalize();
|
shot_dir.Normalize();
|
||||||
|
shot_dir.Rotate((rand() % 10) / 180.0f);
|
||||||
|
sender->attack_dir = shot_dir;
|
||||||
sender->Shot(shot_dir);
|
sender->Shot(shot_dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,15 @@ void Android::Initialize()
|
|||||||
health = meta->i->health();
|
health = meta->i->health();
|
||||||
skin = 14001;
|
skin = 14001;
|
||||||
RecalcSelfCollider();
|
RecalcSelfCollider();
|
||||||
|
MetaData::Equip* weapon_meta = MetaMgr::Instance()->GetEquip(a8::RandEx(12103, 12122));
|
||||||
|
if (weapon_meta) {
|
||||||
|
weapons[GUN_SLOT1].weapon_idx = GUN_SLOT1;
|
||||||
|
weapons[GUN_SLOT1].weapon_id = weapon_meta->i->id();
|
||||||
|
weapons[GUN_SLOT1].weapon_lv = 1;
|
||||||
|
weapons[GUN_SLOT1].ammo = 0;
|
||||||
|
weapons[GUN_SLOT1].meta = weapon_meta;
|
||||||
|
curr_weapon = &weapons[GUN_SLOT1];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Android::Update(int delta_time)
|
void Android::Update(int delta_time)
|
||||||
@ -32,5 +41,8 @@ void Android::Update(int delta_time)
|
|||||||
pos = room->plane.curr_pos;
|
pos = room->plane.curr_pos;
|
||||||
room->grid_service.MoveHuman(this);
|
room->grid_service.MoveHuman(this);
|
||||||
}
|
}
|
||||||
|
if (action_type != AT_None) {
|
||||||
|
UpdateAction();
|
||||||
|
}
|
||||||
ai->Update(delta_time);
|
ai->Update(delta_time);
|
||||||
}
|
}
|
||||||
|
@ -192,6 +192,12 @@ void Human::Shot(Vector2D& target_dir)
|
|||||||
Vector2D bullet_born_offset = Vector2D(std::get<0>(tuple), std::get<1>(tuple));
|
Vector2D bullet_born_offset = Vector2D(std::get<0>(tuple), std::get<1>(tuple));
|
||||||
bullet_born_offset.Rotate(attack_dir.CalcAngle(Vector2D::UP));
|
bullet_born_offset.Rotate(attack_dir.CalcAngle(Vector2D::UP));
|
||||||
Vector2D bullet_born_pos = pos + bullet_born_offset;
|
Vector2D bullet_born_pos = pos + bullet_born_offset;
|
||||||
|
Vector2D bullet_dir = attack_dir;
|
||||||
|
float bullet_angle = std::get<2>(tuple);
|
||||||
|
if (curr_weapon->meta->i->bullet_angle() >= 1.0f) {
|
||||||
|
bullet_angle += (rand() % (int)curr_weapon->meta->i->bullet_angle()) * (rand() % 2 == 0 ? 1 : -1);
|
||||||
|
}
|
||||||
|
bullet_dir.Rotate(bullet_angle / 180.0f);
|
||||||
room->frame_event.AddBullet(this, bullet_born_pos, attack_dir, fly_distance);
|
room->frame_event.AddBullet(this, bullet_born_pos, attack_dir, fly_distance);
|
||||||
room->CreateBullet(this, curr_weapon->meta, bullet_born_pos, attack_dir, fly_distance);
|
room->CreateBullet(this, curr_weapon->meta, bullet_born_pos, attack_dir, fly_distance);
|
||||||
}
|
}
|
||||||
@ -1472,6 +1478,140 @@ void Human::SendRollMsg(const std::string& roll_msg)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Human::UpdateAction()
|
||||||
|
{
|
||||||
|
int duration = std::max(0,
|
||||||
|
action_duration -
|
||||||
|
(int)((room->frame_no - action_frameno) * 1.0f / SERVER_FRAME_RATE) * 1000
|
||||||
|
);
|
||||||
|
if (duration <= 0) {
|
||||||
|
switch (action_type) {
|
||||||
|
case AT_Reload:
|
||||||
|
{
|
||||||
|
if (curr_weapon->weapon_idx == action_target_id &&
|
||||||
|
curr_weapon->weapon_id == action_item_id &&
|
||||||
|
curr_weapon->weapon_idx != 0) {
|
||||||
|
MetaData::Equip* bullet_meta = MetaMgr::Instance()->GetEquip(curr_weapon->meta->i->use_bullet());
|
||||||
|
if (bullet_meta) {
|
||||||
|
int ammo = curr_weapon->ammo;
|
||||||
|
if (ammo < curr_weapon->meta->i->clip_volume()) {
|
||||||
|
if (bullet_meta->i->_inventory_slot() >= 0 &&
|
||||||
|
bullet_meta->i->_inventory_slot() < IS_END) {
|
||||||
|
if (GetInventory(bullet_meta->i->_inventory_slot()) > 0) {
|
||||||
|
int add_num = 0;
|
||||||
|
if (GetInventory(bullet_meta->i->_inventory_slot()) <=
|
||||||
|
curr_weapon->meta->i->clip_volume() - ammo) {
|
||||||
|
add_num = GetInventory(bullet_meta->i->_inventory_slot());
|
||||||
|
DecInventory(bullet_meta->i->_inventory_slot(), add_num);
|
||||||
|
} else {
|
||||||
|
add_num = curr_weapon->meta->i->clip_volume() - ammo;
|
||||||
|
DecInventory(bullet_meta->i->_inventory_slot(), add_num);
|
||||||
|
}
|
||||||
|
curr_weapon->ammo += add_num;
|
||||||
|
need_sync_active_player = true;;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case AT_UseItem:
|
||||||
|
{
|
||||||
|
switch (action_item_id) {
|
||||||
|
case IS_HEALTHKIT:
|
||||||
|
{
|
||||||
|
MetaData::Equip* item_meta = MetaMgr::Instance()->GetEquipBySlotId(action_item_id);
|
||||||
|
if (item_meta){
|
||||||
|
if (GetInventory(item_meta->i->_inventory_slot()) > 0) {
|
||||||
|
float old_health = health;
|
||||||
|
health += item_meta->i->heal();
|
||||||
|
health = std::min(health, GetMaxHP());
|
||||||
|
stats.heal_amount += health - old_health;
|
||||||
|
DecInventory(item_meta->i->_inventory_slot(), 1);
|
||||||
|
need_sync_active_player = true;
|
||||||
|
SyncAroundPlayers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IS_PAIN_KILLER:
|
||||||
|
{
|
||||||
|
MetaData::Equip* item_meta = MetaMgr::Instance()->GetEquipBySlotId(action_item_id);
|
||||||
|
if (item_meta){
|
||||||
|
if (GetInventory(item_meta->i->_inventory_slot()) > 0) {
|
||||||
|
if (pain_killer_timer) {
|
||||||
|
int passed_time = (room->frame_no - pain_killer_frameno) * FRAME_RATE_MS;
|
||||||
|
int left_time = std::max(0, pain_killer_lastingtime * 1000 - passed_time);
|
||||||
|
int anodyne_max_time = MetaMgr::Instance()->GetSysParamAsInt("anodyne_max_time");
|
||||||
|
left_time = std::min(left_time, anodyne_max_time * 1000);
|
||||||
|
pain_killer_lastingtime += std::min(item_meta->i->time() * 1000, anodyne_max_time * 1000 - left_time) / 1000;
|
||||||
|
need_sync_active_player = true;
|
||||||
|
} else {
|
||||||
|
pain_killer_frameno = room->frame_no;
|
||||||
|
pain_killer_lastingtime = item_meta->i->time();
|
||||||
|
pain_killer_timer = room->xtimer.AddRepeatTimerAndAttach(
|
||||||
|
SERVER_FRAME_RATE,
|
||||||
|
a8::XParams()
|
||||||
|
.SetSender(this)
|
||||||
|
.SetParam1(item_meta->i->heal()),
|
||||||
|
[] (const a8::XParams& param)
|
||||||
|
{
|
||||||
|
Human* hum = (Human*)param.sender.GetUserData();
|
||||||
|
float old_health = hum->health;
|
||||||
|
hum->health += param.param1.GetDouble();
|
||||||
|
hum->health = std::min(hum->health, hum->GetMaxHP());
|
||||||
|
hum->stats.heal_amount += hum->health - old_health;
|
||||||
|
hum->SyncAroundPlayers();
|
||||||
|
if (hum->room->frame_no - hum->pain_killer_frameno > hum->pain_killer_lastingtime * SERVER_FRAME_RATE) {
|
||||||
|
hum->room->xtimer.DeleteTimer(hum->pain_killer_timer);
|
||||||
|
hum->pain_killer_timer = nullptr;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
&xtimer_attacher.timer_list_
|
||||||
|
);
|
||||||
|
}
|
||||||
|
DecInventory(item_meta->i->_inventory_slot(), 1);
|
||||||
|
need_sync_active_player = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case AT_Relive:
|
||||||
|
{
|
||||||
|
Entity* entity = room->GetEntityByUniId(action_target_id);
|
||||||
|
if (entity->entity_type != ET_Player) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Human* hum = (Human*)entity;
|
||||||
|
if (hum->action_type == AT_Rescue) {
|
||||||
|
hum->CancelAction();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!hum->dead && hum->downed) {
|
||||||
|
hum->health = MetaMgr::Instance()->GetSysParamAsInt("downed_relive_recover_hp");
|
||||||
|
hum->downed = false;
|
||||||
|
if (hum->downed_timer) {
|
||||||
|
room->xtimer.DeleteTimer(hum->downed_timer);
|
||||||
|
hum->downed_timer = nullptr;
|
||||||
|
}
|
||||||
|
++hum->stats.rescue_member;
|
||||||
|
}
|
||||||
|
hum->SyncAroundPlayers();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ResetAction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Human::ClearFrameData()
|
void Human::ClearFrameData()
|
||||||
{
|
{
|
||||||
if (!new_objects.empty()) {
|
if (!new_objects.empty()) {
|
||||||
|
@ -171,6 +171,7 @@ class Human : public Entity
|
|||||||
void FollowTarget(Human* target);
|
void FollowTarget(Human* target);
|
||||||
void SendDebugMsg(const std::string& debug_msg);
|
void SendDebugMsg(const std::string& debug_msg);
|
||||||
void SendRollMsg(const std::string& roll_msg);
|
void SendRollMsg(const std::string& roll_msg);
|
||||||
|
void UpdateAction();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ClearFrameData();
|
void ClearFrameData();
|
||||||
|
@ -191,140 +191,6 @@ void Player::UpdateSelectWeapon()
|
|||||||
selected_weapon_idx = 0;
|
selected_weapon_idx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::UpdateAction()
|
|
||||||
{
|
|
||||||
int duration = std::max(0,
|
|
||||||
action_duration -
|
|
||||||
(int)((room->frame_no - action_frameno) * 1.0f / SERVER_FRAME_RATE) * 1000
|
|
||||||
);
|
|
||||||
if (duration <= 0) {
|
|
||||||
switch (action_type) {
|
|
||||||
case AT_Reload:
|
|
||||||
{
|
|
||||||
if (curr_weapon->weapon_idx == action_target_id &&
|
|
||||||
curr_weapon->weapon_id == action_item_id &&
|
|
||||||
curr_weapon->weapon_idx != 0) {
|
|
||||||
MetaData::Equip* bullet_meta = MetaMgr::Instance()->GetEquip(curr_weapon->meta->i->use_bullet());
|
|
||||||
if (bullet_meta) {
|
|
||||||
int ammo = curr_weapon->ammo;
|
|
||||||
if (ammo < curr_weapon->meta->i->clip_volume()) {
|
|
||||||
if (bullet_meta->i->_inventory_slot() >= 0 &&
|
|
||||||
bullet_meta->i->_inventory_slot() < IS_END) {
|
|
||||||
if (GetInventory(bullet_meta->i->_inventory_slot()) > 0) {
|
|
||||||
int add_num = 0;
|
|
||||||
if (GetInventory(bullet_meta->i->_inventory_slot()) <=
|
|
||||||
curr_weapon->meta->i->clip_volume() - ammo) {
|
|
||||||
add_num = GetInventory(bullet_meta->i->_inventory_slot());
|
|
||||||
DecInventory(bullet_meta->i->_inventory_slot(), add_num);
|
|
||||||
} else {
|
|
||||||
add_num = curr_weapon->meta->i->clip_volume() - ammo;
|
|
||||||
DecInventory(bullet_meta->i->_inventory_slot(), add_num);
|
|
||||||
}
|
|
||||||
curr_weapon->ammo += add_num;
|
|
||||||
need_sync_active_player = true;;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AT_UseItem:
|
|
||||||
{
|
|
||||||
switch (action_item_id) {
|
|
||||||
case IS_HEALTHKIT:
|
|
||||||
{
|
|
||||||
MetaData::Equip* item_meta = MetaMgr::Instance()->GetEquipBySlotId(action_item_id);
|
|
||||||
if (item_meta){
|
|
||||||
if (GetInventory(item_meta->i->_inventory_slot()) > 0) {
|
|
||||||
float old_health = health;
|
|
||||||
health += item_meta->i->heal();
|
|
||||||
health = std::min(health, GetMaxHP());
|
|
||||||
stats.heal_amount += health - old_health;
|
|
||||||
DecInventory(item_meta->i->_inventory_slot(), 1);
|
|
||||||
need_sync_active_player = true;
|
|
||||||
SyncAroundPlayers();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case IS_PAIN_KILLER:
|
|
||||||
{
|
|
||||||
MetaData::Equip* item_meta = MetaMgr::Instance()->GetEquipBySlotId(action_item_id);
|
|
||||||
if (item_meta){
|
|
||||||
if (GetInventory(item_meta->i->_inventory_slot()) > 0) {
|
|
||||||
if (pain_killer_timer) {
|
|
||||||
int passed_time = (room->frame_no - pain_killer_frameno) * FRAME_RATE_MS;
|
|
||||||
int left_time = std::max(0, pain_killer_lastingtime * 1000 - passed_time);
|
|
||||||
int anodyne_max_time = MetaMgr::Instance()->GetSysParamAsInt("anodyne_max_time");
|
|
||||||
left_time = std::min(left_time, anodyne_max_time * 1000);
|
|
||||||
pain_killer_lastingtime += std::min(item_meta->i->time() * 1000, anodyne_max_time * 1000 - left_time) / 1000;
|
|
||||||
need_sync_active_player = true;
|
|
||||||
} else {
|
|
||||||
pain_killer_frameno = room->frame_no;
|
|
||||||
pain_killer_lastingtime = item_meta->i->time();
|
|
||||||
pain_killer_timer = room->xtimer.AddRepeatTimerAndAttach(
|
|
||||||
SERVER_FRAME_RATE,
|
|
||||||
a8::XParams()
|
|
||||||
.SetSender(this)
|
|
||||||
.SetParam1(item_meta->i->heal()),
|
|
||||||
[] (const a8::XParams& param)
|
|
||||||
{
|
|
||||||
Human* hum = (Human*)param.sender.GetUserData();
|
|
||||||
float old_health = hum->health;
|
|
||||||
hum->health += param.param1.GetDouble();
|
|
||||||
hum->health = std::min(hum->health, hum->GetMaxHP());
|
|
||||||
hum->stats.heal_amount += hum->health - old_health;
|
|
||||||
hum->SyncAroundPlayers();
|
|
||||||
if (hum->room->frame_no - hum->pain_killer_frameno > hum->pain_killer_lastingtime * SERVER_FRAME_RATE) {
|
|
||||||
hum->room->xtimer.DeleteTimer(hum->pain_killer_timer);
|
|
||||||
hum->pain_killer_timer = nullptr;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
&xtimer_attacher.timer_list_
|
|
||||||
);
|
|
||||||
}
|
|
||||||
DecInventory(item_meta->i->_inventory_slot(), 1);
|
|
||||||
need_sync_active_player = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AT_Relive:
|
|
||||||
{
|
|
||||||
Entity* entity = room->GetEntityByUniId(action_target_id);
|
|
||||||
if (entity->entity_type != ET_Player) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Human* hum = (Human*)entity;
|
|
||||||
if (hum->action_type == AT_Rescue) {
|
|
||||||
hum->CancelAction();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!hum->dead && hum->downed) {
|
|
||||||
hum->health = MetaMgr::Instance()->GetSysParamAsInt("downed_relive_recover_hp");
|
|
||||||
hum->downed = false;
|
|
||||||
if (hum->downed_timer) {
|
|
||||||
room->xtimer.DeleteTimer(hum->downed_timer);
|
|
||||||
hum->downed_timer = nullptr;
|
|
||||||
}
|
|
||||||
++hum->stats.rescue_member;
|
|
||||||
}
|
|
||||||
hum->SyncAroundPlayers();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ResetAction();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Player::UpdateReload()
|
void Player::UpdateReload()
|
||||||
{
|
{
|
||||||
AutoLoadingBullet(true);
|
AutoLoadingBullet(true);
|
||||||
|
@ -71,7 +71,6 @@ class Player : public Human
|
|||||||
void UpdateSelectWeapon();
|
void UpdateSelectWeapon();
|
||||||
void UpdateDropWeapon();
|
void UpdateDropWeapon();
|
||||||
void UpdateUseScope();
|
void UpdateUseScope();
|
||||||
void UpdateAction();
|
|
||||||
void UpdateReload();
|
void UpdateReload();
|
||||||
void UpdateCancelAction();
|
void UpdateCancelAction();
|
||||||
void UpdateUseItemIdx();
|
void UpdateUseItemIdx();
|
||||||
|
@ -199,8 +199,8 @@ void Room::ShuaAndroid()
|
|||||||
hum->meta = hum_meta;
|
hum->meta = hum_meta;
|
||||||
hum->entity_uniid = AllocUniid();
|
hum->entity_uniid = AllocUniid();
|
||||||
{
|
{
|
||||||
hum->pos.x = 3000 + rand() % 400;
|
hum->pos.x = 3000 + rand() % 1400;
|
||||||
hum->pos.y = 3000 + rand() % 500;
|
hum->pos.y = 3000 + rand() % 1500;
|
||||||
hum->attack_dir = hum->pos;
|
hum->attack_dir = hum->pos;
|
||||||
hum->attack_dir.Normalize();
|
hum->attack_dir.Normalize();
|
||||||
hum->attack_dir.Rotate(a8::RandAngle());
|
hum->attack_dir.Rotate(a8::RandAngle());
|
||||||
@ -227,11 +227,17 @@ Human* Room::FindEnemy(Human* hum)
|
|||||||
{
|
{
|
||||||
std::vector<Human*> enemys;
|
std::vector<Human*> enemys;
|
||||||
enemys.reserve(50);
|
enemys.reserve(50);
|
||||||
for (auto& pair : accountid_hash_) {
|
for (auto& cell : hum->grid_list) {
|
||||||
if (pair.second->team_id == 0 ||
|
for (Human* target : cell->human_list) {
|
||||||
pair.second->team_id != hum->team_id
|
if (target->entity_subtype == EST_Player) {
|
||||||
|
if (hum->pos.Distance(target->pos) < 300.0f) {
|
||||||
|
if (target->team_id == 0 ||
|
||||||
|
target->team_id != hum->team_id
|
||||||
) {
|
) {
|
||||||
enemys.push_back(pair.second);
|
enemys.push_back(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::sort(enemys.begin(), enemys.end(),
|
std::sort(enemys.begin(), enemys.end(),
|
||||||
|
@ -135,6 +135,12 @@ Vector2D Vector2D::FromAngle(float angle)
|
|||||||
return vec2;
|
return vec2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float Vector2D::Distance(const Vector2D& b)
|
||||||
|
{
|
||||||
|
Vector2D v = b - *this;
|
||||||
|
return v.Norm();
|
||||||
|
}
|
||||||
|
|
||||||
Vector2D Vector2D::Perp()
|
Vector2D Vector2D::Perp()
|
||||||
{
|
{
|
||||||
return Vector2D(y, -x);
|
return Vector2D(y, -x);
|
||||||
|
@ -19,6 +19,7 @@ struct Vector2D
|
|||||||
void Rotate(float angle);
|
void Rotate(float angle);
|
||||||
float CalcAngle(const Vector2D& b);
|
float CalcAngle(const Vector2D& b);
|
||||||
static Vector2D FromAngle(float angle);
|
static Vector2D FromAngle(float angle);
|
||||||
|
float Distance(const Vector2D& b);
|
||||||
|
|
||||||
bool operator == (const Vector2D& b) const;
|
bool operator == (const Vector2D& b) const;
|
||||||
Vector2D operator + (const Vector2D& b) const;
|
Vector2D operator + (const Vector2D& b) const;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user