diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index f722366..1bee990 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -922,7 +922,7 @@ void Human::DecHP(float dec_hp, int killer_id, const std::string& killer_name, i health = MetaMgr::Instance()->GetSysParamAsInt("downed_recover_hp"); downed = true; downed_timer = room->xtimer.AddRepeatTimerAndAttach( - SERVER_FRAME_RATE, + SERVER_FRAME_RATE * MetaMgr::Instance()->tank_damage_interval, a8::XParams() .SetSender(this) .SetParam1(killer_id) @@ -1997,13 +1997,46 @@ int Human::SkinLv() void Human::CheckSkinTank() { + auto dechp_func = + [] (const a8::XParams& param) + { + Human* hum = (Human*)param.sender.GetUserData(); + if (hum->dead || + !hum->last_tank_attacker || + hum->last_tank_attacker->dead || + hum->last_tank_attacker->skin_tank.skin_id == 0 || + hum->last_tank_attack_idx != param.param1.GetInt64() + ) { + hum->last_tank_attacker = nullptr; + hum->last_tank_attack_idx = 0; + hum->room->xtimer.DeleteTimer(hum->room->xtimer.GetRunningTimer()); + return; + } + float old_rad = hum->last_tank_attacker->self_collider_->rad; + if (!hum->TestCollision(hum->last_tank_attacker)) { + hum->last_tank_attacker->self_collider_->rad = old_rad; + hum->last_tank_attacker = nullptr; + hum->last_tank_attack_idx = 0; + hum->room->xtimer.DeleteTimer(hum->room->xtimer.GetRunningTimer()); + return; + } + hum->last_tank_attacker->self_collider_->rad = old_rad; + hum->DecHP(MetaMgr::Instance()->tank_damage2, + hum->last_tank_attacker->entity_uniid, + hum->last_tank_attacker->name, + VW_Tank); + }; + if (tank_weapon.meta) { float old_rad = self_collider_->rad; self_collider_->rad = tank_weapon.meta->i->rad2(); std::set objects; for (auto& grid : grid_list) { for (Human* hum: grid->human_list) { - if (hum != this && !hum->dead && !hum->tank_weapon.meta && + if (hum != this && + !hum->dead && + !hum->tank_weapon.meta && + hum->last_tank_attacker != this && (hum->team_id == 0 || team_id != hum->team_id)) { if (TestCollision(hum)) { objects.insert(hum); @@ -2012,7 +2045,20 @@ void Human::CheckSkinTank() } }//end for for (Human* hum : objects) { - hum->BeKill(entity_uniid, name, VW_Tank); + hum->last_tank_attacker = this; + hum->last_tank_attack_idx = App::Instance()->NewUuid(); + hum->DecHP(MetaMgr::Instance()->tank_damage1, + entity_uniid, + name, + VW_Tank); + room->xtimer.AddRepeatTimerAndAttach( + SERVER_FRAME_RATE, + a8::XParams() + .SetSender(hum) + .SetParam1(hum->last_tank_attack_idx), + dechp_func, + &hum->xtimer_attacher.timer_list_ + ); } self_collider_->rad = old_rad; } diff --git a/server/gameserver/human.h b/server/gameserver/human.h index 63181a6..9f7e8e2 100644 --- a/server/gameserver/human.h +++ b/server/gameserver/human.h @@ -114,6 +114,8 @@ class Human : public Entity std::set* team_members = nullptr; std::set kill_humans; + Human* last_tank_attacker = nullptr; + long long last_tank_attack_idx = 0; bool shot_start = false; bool shot_hold = false; diff --git a/server/gameserver/metamgr.cc b/server/gameserver/metamgr.cc index 2f1c441..db7a749 100755 --- a/server/gameserver/metamgr.cc +++ b/server/gameserver/metamgr.cc @@ -119,6 +119,7 @@ public: MetaMgr::Instance()->fighting_mode = MetaMgr::Instance()->GetSysParamAsInt("fighting_mode", 1); MetaMgr::Instance()->tank_damage1 = MetaMgr::Instance()->GetSysParamAsInt("tank_damage1"); MetaMgr::Instance()->tank_damage2 = MetaMgr::Instance()->GetSysParamAsInt("tank_damage2"); + MetaMgr::Instance()->tank_damage_interval = MetaMgr::Instance()->GetSysParamAsInt("tank_damage_interval", 1); MetaMgr::Instance()->average_oil = MetaMgr::Instance()->GetSysParamAsInt("average_oil"); MetaMgr::Instance()->max_oil = MetaMgr::Instance()->GetSysParamAsInt("max_oil"); if (MetaMgr::Instance()->K < 0.01f) { diff --git a/server/gameserver/metamgr.h b/server/gameserver/metamgr.h index b4b765f..7f1fd48 100755 --- a/server/gameserver/metamgr.h +++ b/server/gameserver/metamgr.h @@ -50,6 +50,7 @@ class MetaMgr : public a8::Singleton int fighting_mode = 0; float tank_damage1 = 0.0f; float tank_damage2 = 0.0f; + float tank_damage_interval = 0.0f; float average_oil = 0.0f; float max_oil = 0.0f;