diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index 703bc27..d2ee979 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -381,6 +381,9 @@ void Human::Shot(a8::Vec2& target_dir, bool& shot_ok) if (!curr_weapon->meta) { return; } + if (downed) { + return; + } if (curr_weapon->weapon_idx != 0 && curr_weapon->ammo <= 0) { @@ -1066,25 +1069,26 @@ void Human::DecHP(float dec_hp, int killer_id, const std::string& killer_name, i } #endif #endif - auto downed_func = [] (const a8::XParams& param) - { - Human* hum = (Human*)param.sender.GetUserData(); - if (!hum->downed) { - hum->FreeDownedTimer(); - return; - } - if (hum->dead) { - hum->FreeDownedTimer(); - return; - } - if (!hum->HasLiveTeammate()) { - hum->FreeDownedTimer(); - hum->BeKill(param.param1, param.param2, param.param3); - return; - } - int dec_hp = MetaMgr::Instance()->GetSysParamAsInt("downed_dec_hp"); - hum->DecHP(dec_hp, param.param1, param.param2, param.param3); - }; + auto downed_func = + [] (const a8::XParams& param) + { + Human* hum = (Human*)param.sender.GetUserData(); + if (!hum->downed) { + hum->FreeDownedTimer(); + return; + } + if (hum->dead) { + hum->FreeDownedTimer(); + return; + } + if (!hum->HasLiveTeammate()) { + hum->FreeDownedTimer(); + hum->BeKill(param.param1, param.param2, param.param3); + return; + } + int dec_hp = MetaMgr::Instance()->GetSysParamAsInt("downed_dec_hp"); + hum->DecHP(dec_hp, param.param1, param.param2, param.param3); + }; if (energy_shield > 0.001f) { energy_shield = std::max(0.0f, energy_shield - dec_hp); SyncAroundPlayers(__FILE__, __LINE__, __func__); @@ -1114,16 +1118,17 @@ void Human::DecHP(float dec_hp, int killer_id, const std::string& killer_name, i } CancelAction(); DoGetDown(); - downed_timer = room->xtimer.AddRepeatTimerAndAttach( - SERVER_FRAME_RATE, - a8::XParams() - .SetSender(this) - .SetParam1(killer_id) - .SetParam2(killer_name) - .SetParam3(weapon_id), - downed_func, - &xtimer_attacher.timer_list_ - ); + downed_timer = room->xtimer.AddRepeatTimerAndAttach + ( + SERVER_FRAME_RATE, + a8::XParams() + .SetSender(this) + .SetParam1(killer_id) + .SetParam2(killer_name) + .SetParam3(weapon_id), + downed_func, + &xtimer_attacher.timer_list_ + ); SyncAroundPlayers(__FILE__, __LINE__, __func__); } else { BeKill(killer_id, killer_name, weapon_id); @@ -1181,6 +1186,9 @@ void Human::RemoveOutObjects(Entity* entity) bool Human::HasLiveTeammate() { + if (room->GetRoomMode() == kZombieMode) { + return true; + } if (team_members) { for (auto& hum : *team_members) { if (hum != this && !hum->dead) { @@ -1193,6 +1201,10 @@ bool Human::HasLiveTeammate() bool Human::HasNoDownedTeammate() { + if (room->GetRoomMode() == kZombieMode && + GetRace() == kHumanRace) { + return true; + } if (team_members) { for (auto& hum : *team_members) { if (hum != this && !hum->dead && !hum->downed) { diff --git a/server/gameserver/room.cc b/server/gameserver/room.cc index f2b8c1a..4389ce4 100644 --- a/server/gameserver/room.cc +++ b/server/gameserver/room.cc @@ -568,7 +568,7 @@ void Room::OnHumanDie(Human* hum) { if (GetRoomMode() == kZombieMode) { if (hum->GetRace() == kHumanRace) { - + RemoveRescue(hum); } else if (hum->GetRace() == kZombieRace) { } else { abort(); @@ -3110,6 +3110,16 @@ void Room::FillObjectPositions(Human* hum, cs::SMUpdate& msg) } } +void Room::RemoveRescue(Human* hum) +{ + for (auto& pair : human_hash_) { + if (pair.second != hum && pair.second->action_type == AT_Relive && + pair.second->action_target_id == hum->GetEntityUniId()) { + pair.second->CancelAction(); + } + } +} + size_t Room::GetRoomMaxPlayerNum() { if (room_mode_ == kZombieMode) { diff --git a/server/gameserver/room.h b/server/gameserver/room.h index f778585..3267cc4 100644 --- a/server/gameserver/room.h +++ b/server/gameserver/room.h @@ -134,6 +134,7 @@ public: void AdjustPosInnerMap(a8::Vec2& pos, float radius); bool IsMiniRoom(); void FillObjectPositions(Human* hum, cs::SMUpdate& msg); + void RemoveRescue(Human* hum); private: int AllocUniid();