From 3514c58477421e310fc68e9fec9ef9ab03591265 Mon Sep 17 00:00:00 2001 From: aozhiwei Date: Tue, 28 Apr 2020 14:21:15 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=AA=E8=A3=85ok?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/gameserver/constant.h | 4 ++- server/gameserver/frameevent.cc | 10 ++++++ server/gameserver/frameevent.h | 2 ++ server/gameserver/framemaker.cc | 12 +++++++ server/gameserver/human.cc | 57 +++++++++++++++++++++++++++++++++ server/gameserver/human.h | 6 ++++ server/gameserver/player.cc | 39 ++++++++++++++++++++++ server/gameserver/player.h | 5 +++ server/gameserver/roommgr.cc | 5 +++ 9 files changed, 139 insertions(+), 1 deletion(-) diff --git a/server/gameserver/constant.h b/server/gameserver/constant.h index 999ee06..519aa6b 100755 --- a/server/gameserver/constant.h +++ b/server/gameserver/constant.h @@ -197,6 +197,7 @@ enum EquipType_e EQUIP_TYPE_OLDSKIN = 8, EQUIP_TYPE_CAR = 9, EQUIP_TYPE_SKIN = 10, + EQUIP_TYPE_CAMOUFLAGE = 11, EQUIP_TYPE_End }; @@ -235,7 +236,8 @@ enum PropertyType_e kPropSkillCd = 5, kPropTankBulletNum = 6, kPropTankOil = 7, - kPropBulletNum = 8 + kPropBulletNum = 8, + kPropItem = 9 }; enum MapObjectType_e diff --git a/server/gameserver/frameevent.cc b/server/gameserver/frameevent.cc index 4bc1c46..0189d6f 100644 --- a/server/gameserver/frameevent.cc +++ b/server/gameserver/frameevent.cc @@ -245,6 +245,13 @@ void FrameEvent::AddSkillCdChg(Human* hum) hum->chged_skillcds_.push_back(idx); } +void FrameEvent::AddItemChg(Human* hum, int item_id, int item_num) +{ + chged_items_.push_back(std::make_tuple(hum, item_id, item_num)); + int idx = chged_items_.size() - 1; + hum->chged_items_.push_back(idx); +} + void FrameEvent::Clear() { if (!explosions_.empty()) { @@ -286,4 +293,7 @@ void FrameEvent::Clear() if (!chged_skillcds_.empty()) { chged_skillcds_.clear(); } + if (!chged_items_.empty()) { + chged_items_.clear(); + } } diff --git a/server/gameserver/frameevent.h b/server/gameserver/frameevent.h index c33aa1b..83870f4 100644 --- a/server/gameserver/frameevent.h +++ b/server/gameserver/frameevent.h @@ -24,6 +24,7 @@ public: void AddBuff(Human* hum, Buff* buff); void RemoveBuff(Human* hum, int buff_id); void AddSkillCdChg(Human* hum); + void AddItemChg(Human* hum, int item_id, int item_num); void Clear(); private: @@ -34,6 +35,7 @@ private: std::vector> smokes_; std::vector> emotes_; std::vector> chged_buffs_; + std::vector> chged_items_; std::vector chged_bullet_nums_; std::vector chged_tank_bullet_nums_; std::vector chged_tank_oil_value_; diff --git a/server/gameserver/framemaker.cc b/server/gameserver/framemaker.cc index 2b39eb8..7086d47 100644 --- a/server/gameserver/framemaker.cc +++ b/server/gameserver/framemaker.cc @@ -167,6 +167,18 @@ cs::SMUpdate* FrameMaker::MakeUpdateMsg(const Human* hum) } } } + for (size_t idx : hum->chged_items_) { + if (idx < room->frame_event.chged_items_.size()) { + auto& tuple = room->frame_event.chged_items_[idx]; + { + auto p = msg->add_chged_property_list(); + p->set_obj_id((std::get<0>(tuple))->entity_uniid); + p->set_property_type(kPropItem); + p->set_property_subtype(std::get<1>(tuple)); + p->set_value(std::get<2>(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 6c0646e..345c39f 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -686,6 +686,9 @@ void Human::StartAction(ActionType_e action_type, this->action_item_id = item_id; this->action_target_id = target_id; need_sync_active_player = true; + if (HasBuffEffect(kBET_Camouflage)) { + RemoveBuffByEffectId(kBET_Camouflage); + } } void Human::CancelAction() @@ -857,6 +860,9 @@ void Human::BeKill(int killer_id, const std::string& killer_name, int weapon_id) ability.hp = 0.0f; dead_frameno = room->frame_no; ++dead_times; + if (HasBuffEffect(kBET_Camouflage)) { + RemoveBuffByEffectId(kBET_Camouflage); + } int max_revive_times = MetaMgr::Instance()->GetSysParamAsInt("max_revive_times", 1); if (weapon_id != VW_Spectate && dead_times <= max_revive_times && @@ -914,6 +920,9 @@ void Human::DecHP(float dec_hp, int killer_id, const std::string& killer_name, i if (HasNoDownedTeammate()) { ability.hp = MetaMgr::Instance()->GetSysParamAsInt("downed_recover_hp"); downed = true; + if (HasBuffEffect(kBET_Camouflage)) { + RemoveBuffByEffectId(kBET_Camouflage); + } CancelAction(); DoGetDown(); downed_timer = room->xtimer.AddRepeatTimerAndAttach( @@ -1080,6 +1089,9 @@ void Human::DoSkill() #else need_sync_active_player = true; #endif + if (HasBuffEffect(kBET_Camouflage)) { + RemoveBuffByEffectId(kBET_Camouflage); + } } use_skill = false; } @@ -1290,6 +1302,7 @@ void Human::FillMFActivePlayerData(cs::MFActivePlayerData* player_data) } #endif FillBodyState(player_data->mutable_states()); + FillItemList(player_data->mutable_items()); } void Human::FillMFGasData(cs::MFGasData* gas_data) @@ -1488,6 +1501,15 @@ void Human::FillBuffList(::google::protobuf::RepeatedPtrField<::cs::MFBuff>* pb_ } } +void Human::FillItemList(::google::protobuf::RepeatedPtrField<::cs::MFPair>* pb_item_list) +{ + for (auto& pair : items_) { + auto p = pb_item_list->Add(); + p->set_key(pair.first); + p->set_value(pair.second); + } +} + void Human::SummonHero() { #if 0 @@ -2001,6 +2023,9 @@ void Human::ClearFrameData() if (!chged_skillcds_.empty()) { chged_skillcds_.clear(); } + if (!chged_items_.empty()) { + chged_items_.clear(); + } } void Human::GenBattleReportData(a8::MutableXObject* params) @@ -2764,6 +2789,38 @@ void Human::ProcBuffEffect(Buff* buff) } } +int Human::GetItemNum(int item_id) +{ + auto itr = items_.find(item_id); + return itr != items_.end() ? itr->second : 0; +} + +void Human::AddItem(int item_id, int item_num) +{ + auto itr = items_.find(item_id); + if (itr != items_.end()) { + itr->second += item_num; + } else { + items_[item_id] = item_num; + } + + if (room->frame_no > join_frameno) { + room->frame_event.AddItemChg(this, item_id, items_[item_id]); + } +} + +void Human::DecItem(int item_id, int item_num) +{ + auto itr = items_.find(item_id); + if (itr != items_.end()) { + itr->second -= item_num; + room->frame_event.AddItemChg(this, item_id, std::max(0, itr->second)); + if (itr->second <= 0) { + items_.erase(itr); + } + } +} + void Human::RecalcBuffAttr() { buff_attr_abs_ = {}; diff --git a/server/gameserver/human.h b/server/gameserver/human.h index 238aca6..86a7357 100644 --- a/server/gameserver/human.h +++ b/server/gameserver/human.h @@ -196,6 +196,7 @@ class Human : public Entity void RecoverHp(int inc_hp); void FillBodyState(::google::protobuf::RepeatedPtrField<::cs::MFBodyState>* states); void FillBuffList(::google::protobuf::RepeatedPtrField<::cs::MFBuff>* pb_buff_list); + void FillItemList(::google::protobuf::RepeatedPtrField<::cs::MFPair>* pb_item_list); void SummonHero(); void AddObserver(Human* observer); void RemoveObserver(Human* observer); @@ -239,6 +240,9 @@ class Human : public Entity int GetLevel() {return 1;}; void OnAttack() {}; void OnHit() {}; + int GetItemNum(int item_id); + void AddItem(int item_id, int item_num); + void DecItem(int item_id, int item_num); protected: void _UpdateMove(int speed); @@ -295,6 +299,7 @@ protected: std::vector chged_tank_oil_max_; std::vector chged_hps_; std::vector chged_skillcds_; + std::vector chged_items_; Human* follow_target_ = nullptr; bool follow_synced_active_player = false; HumanCar car_; @@ -305,6 +310,7 @@ private: CircleCollider* self_collider_ = nullptr; long long last_sync_gas_frameno = 0; std::list buff_list_; + std::map items_; std::array buff_effect_ = {}; std::array buff_attr_abs_ = {}; diff --git a/server/gameserver/player.cc b/server/gameserver/player.cc index 66939cf..a9764fb 100644 --- a/server/gameserver/player.cc +++ b/server/gameserver/player.cc @@ -74,6 +74,9 @@ void Player::Update(int delta_time) if (use_item) { UpdateUseItemIdx(); } + if (has_use_item_id) { + UpdateUseItemId(); + } if (action_type != AT_None) { UpdateAction(); } @@ -111,6 +114,9 @@ void Player::UpdateMove() last_collision_door = nullptr; return; } + if (HasBuffEffect(kBET_Camouflage)) { + RemoveBuffByEffectId(kBET_Camouflage); + } ++moved_frames; if (moved_frames > 4) { moving = false; @@ -167,6 +173,9 @@ void Player::UpdateShot() series_shot_frames = 0; } } + if (HasBuffEffect(kBET_Camouflage)) { + RemoveBuffByEffectId(kBET_Camouflage); + } } void Player::UpdateSelectWeapon() @@ -191,6 +200,9 @@ void Player::UpdateSelectWeapon() } select_weapon = false; selected_weapon_idx = 0; + if (HasBuffEffect(kBET_Camouflage)) { + RemoveBuffByEffectId(kBET_Camouflage); + } } void Player::UpdateReload() @@ -249,6 +261,29 @@ void Player::UpdateUseItemIdx() use_item = false; } +void Player::UpdateUseItemId() +{ + if (downed) { + return; + } + MetaData::Equip* item_meta = MetaMgr::Instance()->GetEquip(use_item_id); + if (item_meta && item_meta->i->equip_type() == EQUIP_TYPE_CAMOUFLAGE) { + int item_num = GetItemNum(use_item_id); + if (item_num > 0) { + MetaData::Buff* buff_meta = MetaMgr::Instance()->GetBuff(item_meta->i->buffid()); + if (buff_meta && !GetBuffById(item_meta->i->buffid())) { + if (HasBuffEffect(kBET_Camouflage)) { + RemoveBuffByEffectId(kBET_Camouflage); + } + AddBuff(buff_meta, 1); + DecItem(use_item_id, 1); + } + } + } + use_item_id = 0; + has_use_item_id = false; +} + void Player::UpdateSpectate() { if (room->gas_data.gas_mode == GasInactive || @@ -941,6 +976,10 @@ void Player::_CMMove(f8::MsgHdr& hdr, const cs::CMMove& msg) use_item = true; use_item_idx = msg.use_item_idx(); } + if (msg.has_use_item_id()) { + has_use_item_id = true; + use_item_id = msg.use_item_id(); + } if (msg.has_spectate()) { spectate = true; } diff --git a/server/gameserver/player.h b/server/gameserver/player.h index bcca0fa..e2bd5b8 100644 --- a/server/gameserver/player.h +++ b/server/gameserver/player.h @@ -10,6 +10,7 @@ namespace cs class CMVoice; class MFActivePlayerData; class MFGasData; + class MFPair; } class Room; @@ -40,6 +41,9 @@ class Player : public Human bool use_item = false; int use_item_idx = 0; + bool has_use_item_id = false; + int use_item_id = 0; + bool use_scope = false; int use_scope_idx = 0; @@ -70,6 +74,7 @@ class Player : public Human void UpdateReload(); void UpdateCancelAction(); void UpdateUseItemIdx(); + void UpdateUseItemId(); void UpdateSpectate(); void UpdateEmote(); void UpdateJump(); diff --git a/server/gameserver/roommgr.cc b/server/gameserver/roommgr.cc index fde611d..f0e0fb4 100644 --- a/server/gameserver/roommgr.cc +++ b/server/gameserver/roommgr.cc @@ -107,6 +107,11 @@ void RoomMgr::_CMJoin(f8::MsgHdr& hdr, const cs::CMJoin& msg) hum->meta = hum_meta; room->AddPlayer(hum); hum->ProcPrepareItems(msg.prepare_items()); + { + for (auto& pair : msg.prepare_items2()) { + hum->AddItem(pair.key(), pair.value()); + } + } { cs::SMJoinedNotify notifymsg;