diff --git a/server/gameserver/frameevent.cc b/server/gameserver/frameevent.cc index d577b14..9602a22 100644 --- a/server/gameserver/frameevent.cc +++ b/server/gameserver/frameevent.cc @@ -148,6 +148,21 @@ void FrameEvent::AddSmoke(Bullet* bullet, int item_id, a8::Vec2 pos) } } +void FrameEvent::AddDead(Human* sender) +{ + dead_objs_.push_back( + std::make_tuple( + sender->entity_uniid, + MetaMgr::Instance()->revive_time * 1000 + ) + ); +} + +void FrameEvent::AddRevive(Human* sender) +{ + revive_objids_.push_back(sender->entity_uniid); +} + void FrameEvent::Clear() { if (!explosions_.empty()) { @@ -168,4 +183,10 @@ void FrameEvent::Clear() if (airdrops_.size() > 0) { airdrops_.Clear(); } + if (!revive_objids_.empty()) { + revive_objids_.clear(); + } + if (!dead_objs_.empty()) { + dead_objs_.clear(); + } } diff --git a/server/gameserver/frameevent.h b/server/gameserver/frameevent.h index a44564c..b47f009 100644 --- a/server/gameserver/frameevent.h +++ b/server/gameserver/frameevent.h @@ -14,6 +14,8 @@ public: void AddExplosion(Bullet* bullet, int item_id, a8::Vec2 bomb_pos); void AddSmoke(Bullet* bullet, int item_id, a8::Vec2 pos); void AddExplosionEx(Human* sender, int item_id, a8::Vec2 bomb_pos, int effect); + void AddDead(Human* sender); + void AddRevive(Human* sender); void Clear(); private: @@ -23,6 +25,8 @@ private: std::vector> explosions_; std::vector> smokes_; std::vector> emotes_; + std::vector revive_objids_; + std::vector> dead_objs_; friend class FrameMaker; }; diff --git a/server/gameserver/framemaker.cc b/server/gameserver/framemaker.cc index 1c1659d..1079d32 100644 --- a/server/gameserver/framemaker.cc +++ b/server/gameserver/framemaker.cc @@ -62,6 +62,14 @@ cs::SMUpdate* FrameMaker::MakeUpdateMsg(const Human* hum) } } } + for (int objid : room->frame_event.revive_objids_) { + msg->add_revive_objids(objid); + } + for (auto& tuple : room->frame_event.dead_objs_) { + auto p = msg->add_dead_objs(); + p->add_values(std::get<0>(tuple)); + p->add_values(std::get<1>(tuple)); + } if (room->frame_event.airdrops_.size() > 0) { *msg->mutable_airdrop() = room->frame_event.airdrops_.Get(0); } diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index 17f1e15..e0f7eae 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -543,124 +543,24 @@ void Human::BeKill(int killer_id, const std::string& killer_name, int weapon_id) { if (!dead && !room->game_over) { lethal_weapon = weapon_id; - Entity* hum = room->GetEntityByUniId(killer_id); - if (hum && hum->entity_type == ET_Player) { - if (killer_id == entity_uniid) { - std::string msg = a8::Format("%s 自杀", - { - killer_name, - }); - SendRollMsg(msg); - } else { - ((Human*)hum)->stats.kills++; - ((Human*)hum)->kill_humans.insert(this); - MetaData::Equip* equip_meta = MetaMgr::Instance()->GetEquip(weapon_id); - if (equip_meta) { - std::string msg = a8::Format("%s 使用 %s 干掉了 %s", - { - killer_name, - equip_meta->i->name(), - name - }); - SendRollMsg(msg); - } - } - } else { - switch (weapon_id) { - case VW_SafeArea: - { - std::string msg = a8::Format("%s 被毒圈干掉", - { - name - }); - SendRollMsg(msg); - } - break; - case VW_Spectate: - { - std::string msg = a8::Format("%s 自杀", - { - name - }); - SendRollMsg(msg); - } - break; - case VW_SelfDetonate: - { - std::string msg = a8::Format("%s 被炸死", - { - name - }); - SendRollMsg(msg); - } - break; - case VW_Mine: - { - std::string msg = a8::Format("%s 被地雷炸死", - { - name - }); - SendRollMsg(msg); - } - break; - } - } stats.killer_id = killer_id; stats.killer_name = killer_name; stats.weapon_id = weapon_id; dead = true; health = 0.0f; dead_frameno = room->frame_no; - room->OnHumanDie(this); + room->xtimer.AddDeadLineTimerAndAttach(MetaMgr::Instance()->revive_time * SERVER_FRAME_RATE, + a8::XParams() + .SetSender(this), + [] (const a8::XParams& param) + { + Human* hum = (Human*)param.sender.GetUserData(); + hum->Relive(); + }, + &xtimer_attacher.timer_list_ + ); + room->frame_event.AddDead(this); SyncAroundPlayers(); - if (team_members) { - for (auto& hum : *team_members) { - if (hum != this && hum->action_type == AT_Relive && - hum->action_target_id == entity_uniid) { - hum->CancelAction(); - } - } - } - if (!HasNoDownedTeammate() && !leave_) { - if (team_members) { - for (auto& member : *team_members) { - if (member == this) { - member->SendGameOver(); - } else { - if (member->dead) { - member->SendGameOver(); - } else if (member->downed) { - a8::XParams& timer_param = room->xtimer.GetTimerXParams(member->downed_timer); - member->stats.killer_id = timer_param.param1; - member->stats.killer_name = timer_param.param2.GetString(); - member->stats.weapon_id = timer_param.param2; - member->dead = true; - member->health = 0.0f; - member->dead_frameno = room->frame_no; - member->room->OnHumanDie(this); - member->SyncAroundPlayers(); - member->SendGameOver(); - room->xtimer.DeleteTimer(member->downed_timer); - member->downed_timer = nullptr; - } - } - } - } else { - SendGameOver(); - } - } - if (room->GetAliveTeamNum() == 1) { - std::set* alive_team = room->GetAliveTeam(); - if (team_members != alive_team) { - SendGameOver(); - } - if (alive_team) { - for (Human* member : *alive_team) { - member->SendGameOver(); - } - } - } - DeadDrop(); } } @@ -1941,3 +1841,11 @@ void Human::DeadDrop() } } } + +void Human::Relive() +{ + dead = false; + health = GetMaxHP(); + room->frame_event.AddRevive(this); + SyncAroundPlayers(); +} diff --git a/server/gameserver/human.h b/server/gameserver/human.h index 67cf92f..7e757d8 100644 --- a/server/gameserver/human.h +++ b/server/gameserver/human.h @@ -200,6 +200,7 @@ private: void InternalSendGameOver(); void DeadDrop(); void FillSMGameOver(cs::SMGameOver& msg); + void Relive(); protected: long long last_shot_frameno_ = 0; diff --git a/server/gameserver/metamgr.cc b/server/gameserver/metamgr.cc index 2e5b609..68f0b92 100755 --- a/server/gameserver/metamgr.cc +++ b/server/gameserver/metamgr.cc @@ -105,6 +105,7 @@ public: MetaMgr::Instance()->kill_param = MetaMgr::Instance()->GetSysParamAsFloat("kill_parameter"); MetaMgr::Instance()->rank_param = MetaMgr::Instance()->GetSysParamAsFloat("rank_parameter"); MetaMgr::Instance()->fighting_mode = MetaMgr::Instance()->GetSysParamAsInt("fighting_mode", 1); + MetaMgr::Instance()->revive_time = MetaMgr::Instance()->GetSysParamAsInt("revive_time", 5); if (MetaMgr::Instance()->K < 0.01f) { abort(); } diff --git a/server/gameserver/metamgr.h b/server/gameserver/metamgr.h index 0a0ad53..d8e3bb7 100755 --- a/server/gameserver/metamgr.h +++ b/server/gameserver/metamgr.h @@ -42,6 +42,7 @@ class MetaMgr : public a8::Singleton float kill_param = 0.0f; float rank_param = 0.0f; int fighting_mode = 0; + int revive_time = 5; private: MetaDataLoader* loader_ = nullptr; diff --git a/server/tools/protobuild/cs_proto.proto b/server/tools/protobuild/cs_proto.proto index 0c65d5f..e2e2788 100755 --- a/server/tools/protobuild/cs_proto.proto +++ b/server/tools/protobuild/cs_proto.proto @@ -81,6 +81,12 @@ message MFPair64 optional int64 value = 2; //val } +//int32元组 +message MFTuple +{ + repeated int32 values = 1; //values +} + //向量 message MFVector2D { @@ -368,7 +374,7 @@ message MFObjectFull //活跃玩家数据(当前) message MFActivePlayerData { - optional int32 action_type = 3; //0: none 1:reload 2:useitem 3:relive 4: rescue + optional int32 action_type = 3; //0: none 1:reload 2:useitem 3:revive 4: rescue optional int32 action_duration = 5; //持续时间毫秒 optional int32 action_item_id = 6; optional int32 action_target_id = 7; @@ -718,6 +724,8 @@ message SMUpdate repeated MFSmoke smokes = 25; //烟雾 repeated MFEmote emotes = 23; //表情 optional MFAirDrop airdrop = 26; //空投 + repeated int32 revive_objids = 27; //复活的玩家 + repeated MFTuple dead_objs = 28; //死亡的玩家values[0]:objid values[1]:多少毫秒后复活 } //滚动消息