diff --git a/server/gameserver/buff.cc b/server/gameserver/buff.cc index e69de29..540d94d 100644 --- a/server/gameserver/buff.cc +++ b/server/gameserver/buff.cc @@ -0,0 +1,24 @@ +#include "precompile.h" + +#include "buff.h" +#include "metamgr.h" +#include "human.h" +#include "room.h" + +int Buff::GetLeftTime() +{ + int passed_ms = (owner->room->frame_no - add_frameno) * FRAME_RATE_MS; + return std::max(GetLastingTime() - passed_ms, 0); +} + +int Buff::GetLastingTime() +{ + return meta->i->duration_time() * 1000; +} + +void Buff::FillMFBuff(cs::MFBuff* buff_pb) +{ + buff_pb->set_buff_id(meta->i->buff_id()); + buff_pb->set_left_time(GetLeftTime()); + buff_pb->set_lasting_time(GetLastingTime()); +} diff --git a/server/gameserver/buff.h b/server/gameserver/buff.h index e9b7919..a7f2d7a 100644 --- a/server/gameserver/buff.h +++ b/server/gameserver/buff.h @@ -10,6 +10,11 @@ namespace MetaData struct Buff; } +namespace cs +{ + class MFBuff; +} + class Human; class Buff { @@ -20,4 +25,7 @@ class Buff a8::XTimerAttacher xtimer_attacher; long long add_frameno = 0; + int GetLeftTime(); + int GetLastingTime(); + void FillMFBuff(cs::MFBuff* buff_pb); }; diff --git a/server/gameserver/frameevent.cc b/server/gameserver/frameevent.cc index 3de5bda..42d6554 100644 --- a/server/gameserver/frameevent.cc +++ b/server/gameserver/frameevent.cc @@ -183,6 +183,39 @@ void FrameEvent::AddRevive(Human* hum) } } +void FrameEvent::AddBuff(Human* hum, Buff* buff) +{ + { + cs::MFAddBuff add_buff_pb; + add_buff_pb.set_obj_id(hum->entity_uniid); + buff->FillMFBuff(add_buff_pb.mutable_buff()); + add_buffs_.push_back(std::make_tuple(hum, add_buff_pb)); + } + { + int idx = add_buffs_.size() - 1; + for (auto& cell : hum->grid_list) { + for (auto& hum : cell->human_list) { + hum->add_buffs_.push_back(idx); + } + } + } +} + +void FrameEvent::RemoveBuff(Human* hum, int buff_id) +{ + { + remove_buffs_.push_back(std::make_tuple(hum->entity_uniid, buff_id)); + } + { + int idx = remove_buffs_.size() - 1; + for (auto& cell : hum->grid_list) { + for (auto& hum : cell->human_list) { + hum->remove_buffs_.push_back(idx); + } + } + } +} + void FrameEvent::Clear() { if (!explosions_.empty()) { diff --git a/server/gameserver/frameevent.h b/server/gameserver/frameevent.h index 5e274c0..551e712 100644 --- a/server/gameserver/frameevent.h +++ b/server/gameserver/frameevent.h @@ -4,6 +4,7 @@ class Bullet; class Human; +class Buff; struct FrameEvent { public: @@ -16,6 +17,8 @@ public: void AddExplosionEx(Human* sender, int item_id, a8::Vec2 bomb_pos, int effect); void AddDead(Human* hum); void AddRevive(Human* hum); + void AddBuff(Human* hum, Buff* buff); + void RemoveBuff(Human* hum, int buff_id); void Clear(); private: @@ -25,8 +28,8 @@ private: std::vector> explosions_; std::vector> smokes_; std::vector> emotes_; - std::vector> add_buffs_; - std::vector remove_buffs_; + std::vector> add_buffs_; + std::vector> remove_buffs_; std::vector revive_objs_; std::vector> dead_objs_; diff --git a/server/gameserver/framemaker.cc b/server/gameserver/framemaker.cc index d6d973e..be0feb4 100644 --- a/server/gameserver/framemaker.cc +++ b/server/gameserver/framemaker.cc @@ -75,6 +75,19 @@ cs::SMUpdate* FrameMaker::MakeUpdateMsg(const Human* hum) p->add_values(std::get<1>(room->frame_event.dead_objs_[idx])); } } + for (int idx : hum->add_buffs_) { + if (idx < room->frame_event.add_buffs_.size()) { + auto p = msg->add_add_buff_list(); + *p = std::get<1>(room->frame_event.add_buffs_[idx]); + } + } + for (int idx : hum->remove_buffs_) { + if (idx < room->frame_event.remove_buffs_.size()) { + auto p = msg->add_remove_buff_list(); + p->set_key(std::get<0>(room->frame_event.remove_buffs_[idx])); + p->set_value(std::get<1>(room->frame_event.remove_buffs_[idx])); + } + } 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 bfceb45..c9cd137 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -1337,15 +1337,48 @@ void Human::TriggerBuff(std::set& target_list, BuffTriggerType_e trigge void Human::AddBuff(MetaData::Buff* buff_meta) { + if (GetBuffById(buff_meta->i->buff_id())) { + return; + } if (!buff_meta->EffectCanStack()) { Buff* buff = GetBuffByEffectId(buff_meta->i->buff_effect()); if (buff) { - return; + RemoveBuff(buff->meta->i->buff_id()); } } Buff* buff = &a8::FastAppend(buff_list_); + buff->owner = this; buff->meta = buff_meta; + //buff->skill_meta + buff->add_frameno = room->frame_no; buff_effect_hash_[buff->meta->i->buff_id()] = buff; + room->frame_event.AddBuff(this, buff); + { + room->xtimer.AddDeadLineTimerAndAttach( + buff_meta->i->duration_time() / FRAME_RATE_MS, + a8::XParams() + .SetSender(this) + .SetParam1(buff_meta->i->buff_id()), + [] (const a8::XParams& param) + { + Human* hum = (Human*)param.sender.GetUserData(); + hum->RemoveBuff(param.param1); + }, + &buff->xtimer_attacher.timer_list_ + ); + } +} + +void Human::RemoveBuff(int buff_id) +{ + for (auto itr = buff_list_.begin(); itr != buff_list_.end(); ++itr) { + if (itr->meta->i->buff_id() == buff_id) { + buff_effect_hash_.erase(itr->meta->i->buff_effect()); + buff_list_.erase(itr); + room->frame_event.RemoveBuff(this, buff_id); + break; + } + } } void Human::_UpdateMove(int speed) @@ -1450,7 +1483,48 @@ void Human::Revive() void Human::SelectSkillTargets(const a8::Vec2& target_pos, std::set& target_list) { + switch (skill_meta->i->skill_target()) { + case ST_All: + { + } + break; + case ST_Self: + { + + } + break; + case ST_FriendlyIncludeSelf: + { + + } + break; + case ST_FriendlyExcludeSelf: + { + + } + break; + case ST_EnemySingle: + { + + } + break; + case ST_EnemyGroup: + { + + } + break; + case ST_EnemyAndObject: + { + + } + break; + case ST_EnemyAndSelf: + { + + } + break; + } } Buff* Human::GetBuffById(int buff_id) diff --git a/server/gameserver/human.h b/server/gameserver/human.h index a49e6bc..c8a3852 100644 --- a/server/gameserver/human.h +++ b/server/gameserver/human.h @@ -200,6 +200,7 @@ class Human : public Entity int GetSkillCd(); void TriggerBuff(std::set& target_list, BuffTriggerType_e trigger_type); void AddBuff(MetaData::Buff* buff_meta); + void RemoveBuff(int buff_id); protected: void _UpdateMove(int speed); diff --git a/server/tools/protobuild/cs_proto.proto b/server/tools/protobuild/cs_proto.proto index 9877440..d03601d 100755 --- a/server/tools/protobuild/cs_proto.proto +++ b/server/tools/protobuild/cs_proto.proto @@ -133,8 +133,6 @@ message MFPlayerPart optional float max_health = 5; //血量上限(只有变化时才发,没变化时为undefined) optional float health = 6; //血量(只有变化时才发,没变化时为undefined) - repeated MFBuff add_buff_list = 7; //新增buff列表 - repeated int32 remove_buff_list = 8; //移除的buff列表 } //玩家信息-全量 @@ -534,6 +532,13 @@ message MFBuff optional float lasting_time = 3; //持续时间(总时间毫秒) } +//add buff +message MFAddBuff +{ + optional int32 obj_id = 1; //对象id + optional MFBuff buff = 2; //buff +} + //end mfmsg //加入 @@ -678,19 +683,21 @@ message SMUpdate repeated MFObjectPart part_objects = 4; //对象-部分(用于插值更新) optional int32 active_player_id = 5; //当前活跃玩家id(如果玩家死亡后是观战对象的id) optional MFActivePlayerData active_player_data = 6; //活跃玩家数据(如果玩家死亡后是观战对象的数据) - optional int32 game_left_time = 15; //游戏剩余时间(毫秒, 战斗开始后字段才有意义) - optional int32 gas_progress = 16; //毒圈进度,表示缩进的像素数(只有当gas_data.mode == moving时才会发进度) - optional MFVec2 gas_pos_old = 30; //毒圈当前圆心坐标 - optional MFGasData gas_data = 17; //毒圈数据 - repeated MFTeamData team_data = 18; //队伍数据 - repeated MFBullet bullets = 20; //子弹 - repeated MFShot shots = 21; //射击 - repeated MFExplosion explosions = 22; //爆炸 - 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]:多少毫秒后复活 + optional int32 game_left_time = 7; //游戏剩余时间(毫秒, 战斗开始后字段才有意义) + optional int32 gas_progress = 8; //毒圈进度,表示缩进的像素数(只有当gas_data.mode == moving时才会发进度) + optional MFVec2 gas_pos_old = 9; //毒圈当前圆心坐标 + optional MFGasData gas_data = 10; //毒圈数据 + repeated MFTeamData team_data = 11; //队伍数据 + repeated MFBullet bullets = 12; //子弹 + repeated MFShot shots = 13; //射击 + repeated MFExplosion explosions = 14; //爆炸 + repeated MFSmoke smokes = 15; //烟雾 + repeated MFEmote emotes = 16; //表情 + optional MFAirDrop airdrop = 17; //空投 + repeated int32 revive_objids = 18; //复活的玩家 + repeated MFTuple dead_objs = 19; //死亡的玩家values[0]:objid values[1]:多少毫秒后复活 + repeated MFAddBuff add_buff_list = 20; //新增的buff列表 + repeated MFPair remove_buff_list = 21; //移除的buff列表 key:objid value:buff_id } //滚动消息