diff --git a/server/gameserver/creature.cc b/server/gameserver/creature.cc index 20434ed..5dc862e 100644 --- a/server/gameserver/creature.cc +++ b/server/gameserver/creature.cc @@ -478,7 +478,7 @@ bool Creature::CanUseSkill(int skill_id) if (!skill) { return false; } - return skill->GetLeftTime() <= 0; + return skill->GetCurrTimes() > 0; } void Creature::DoSkill(int skill_id, @@ -1452,3 +1452,10 @@ void Creature::RecoverSkillCasterState(SkillCasterState* caster_state) skill_distance_ = caster_state->caster_skill_distance; skill_param1 = caster_state->caster_skill_param1; } + +CreatureWeakPtr Creature::AllocWeakPtr() +{ + CreatureWeakPtr ptr; + ptr.Attach(this); + return ptr; +} diff --git a/server/gameserver/creature.h b/server/gameserver/creature.h index 5c5e111..c229839 100644 --- a/server/gameserver/creature.h +++ b/server/gameserver/creature.h @@ -134,6 +134,7 @@ class Creature : public MoveableEntity bool CollisonDetection(); void FillSkillCasterState(SkillCasterState* caster_state); void RecoverSkillCasterState(SkillCasterState* caster_state); + CreatureWeakPtr AllocWeakPtr(); private: diff --git a/server/gameserver/frameevent.cc b/server/gameserver/frameevent.cc index ac33f3f..f9c03fc 100644 --- a/server/gameserver/frameevent.cc +++ b/server/gameserver/frameevent.cc @@ -250,16 +250,22 @@ void FrameEvent::RemoveBuff(Human* sender, int buff_id) } } -void FrameEvent::AddSkillCdChg(Human* sender, int skill_id, int left_time) +void FrameEvent::AddSkillCdChg(CreatureWeakPtr sender, int skill_id, int left_time) { - chged_skillcds_.push_back(std::make_tuple(sender, skill_id, left_time)); - int idx = chged_skillcds_.size() - 1; - sender->TouchAllLayerHumanList - ( - [idx] (Human* hum, bool& stop) - { - hum->chged_skillcds_.push_back(idx); - }); + if (sender.Get() && sender.Get()->IsHuman()) { + chged_skillcds_.push_back(std::make_tuple(sender, skill_id, left_time)); + int idx = chged_skillcds_.size() - 1; + ((Human*)sender.Get())->chged_skillcds_.push_back(idx); + } +} + +void FrameEvent::AddSkillCurrTimesChg(CreatureWeakPtr sender, int skill_id, int curr_times) +{ + if (sender.Get() && sender.Get()->IsHuman()) { + chged_skill_curr_times_.push_back(std::make_tuple(sender, skill_id, curr_times)); + int idx = chged_skill_curr_times_.size() - 1; + ((Human*)sender.Get())->chged_skill_curr_times_.push_back(idx); + } } void FrameEvent::AddItemChg(Human* hum, int item_id, int item_num) @@ -375,6 +381,9 @@ void FrameEvent::Clear() if (!chged_skillcds_.empty()) { chged_skillcds_.clear(); } + if (!chged_skill_curr_times_.empty()) { + chged_skill_curr_times_.clear(); + } if (!chged_items_.empty()) { chged_items_.clear(); } diff --git a/server/gameserver/frameevent.h b/server/gameserver/frameevent.h index 2fe8849..dc5e146 100644 --- a/server/gameserver/frameevent.h +++ b/server/gameserver/frameevent.h @@ -29,7 +29,8 @@ public: void AddWeaponAmmoChg(Human* hum); void AddBuff(Human* hum, Buff* buff); void RemoveBuff(Human* hum, int buff_id); - void AddSkillCdChg(Human* hum, int skill_id, int left_time); + void AddSkillCdChg(CreatureWeakPtr sender, int skill_id, int left_time); + void AddSkillCurrTimesChg(CreatureWeakPtr sender, int skill_id, int curr_times); void AddItemChg(Human* hum, int item_id, int item_num); void AddZombieIdChg(Human* hum); void AddDead(Human* sender, int revive_time); @@ -50,7 +51,8 @@ private: std::vector chged_bullet_nums_; std::vector> chged_weapon_ammo_; std::vector chged_hps_; - std::vector> chged_skillcds_; + std::vector> chged_skillcds_; + std::vector> chged_skill_curr_times_; std::vector chged_zombieids_; std::vector chged_cars_; std::vector> dead_alive_objs_; diff --git a/server/gameserver/framemaker.cc b/server/gameserver/framemaker.cc index 823846f..3198cc0 100644 --- a/server/gameserver/framemaker.cc +++ b/server/gameserver/framemaker.cc @@ -165,18 +165,33 @@ cs::SMUpdate* FrameMaker::MakeUpdateMsg(Human* hum) for (size_t idx : hum->chged_skillcds_) { if (idx < room->frame_event.chged_skillcds_.size()) { auto tuple = room->frame_event.chged_skillcds_[idx]; - Human* target = std::get<0>(tuple); + CreatureWeakPtr target = std::get<0>(tuple); int skill_id = std::get<1>(tuple); int left_time = std::get<2>(tuple); - { + if (target.Get()) { auto p = msg->add_chged_property_list(); - p->set_obj_id(target->GetEntityUniId()); + p->set_obj_id(target.Get()->GetEntityUniId()); p->set_property_type(kPropSkillLeftTime); p->set_property_subtype(skill_id); p->set_value(left_time); } } } + for (size_t idx : hum->chged_skill_curr_times_) { + if (idx < room->frame_event.chged_skill_curr_times_.size()) { + auto tuple = room->frame_event.chged_skill_curr_times_[idx]; + CreatureWeakPtr& target = std::get<0>(tuple); + int skill_id = std::get<1>(tuple); + int curr_times = std::get<2>(tuple); + if (target.Get()) { + auto p = msg->add_chged_property_list(); + p->set_obj_id(target.Get()->GetEntityUniId()); + p->set_property_type(kPropSkillCurrTimes); + p->set_property_subtype(skill_id); + p->set_value(curr_times); + } + } + } for (size_t idx : hum->chged_hps_) { if (idx < room->frame_event.chged_hps_.size()) { Human* target = room->frame_event.chged_hps_[idx]; diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index 5bf1954..c463466 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -1998,6 +1998,9 @@ void Human::ClearFrameData() if (!chged_skillcds_.empty()) { chged_skillcds_.clear(); } + if (!chged_skill_curr_times_.empty()) { + chged_skill_curr_times_.clear(); + } if (!chged_items_.empty()) { chged_items_.clear(); } @@ -3359,7 +3362,9 @@ void Human::DoSkillPostProc(bool used, int skill_id, int target_id, const a8::Ve ++stats.skill_times; Skill* skill = GetSkill(skill_id); if (skill) { - room->frame_event.AddSkillCdChg(this, skill_id, skill->GetLeftTime()); + skill->DecTimes(); + room->frame_event.AddSkillCdChg(AllocWeakPtr(), skill_id, skill->GetLeftTime()); + room->frame_event.AddSkillCurrTimesChg(AllocWeakPtr(), skill_id, skill->GetCurrTimes()); } OnAttack(); } diff --git a/server/gameserver/human.h b/server/gameserver/human.h index 2d712ab..0e2c8f5 100644 --- a/server/gameserver/human.h +++ b/server/gameserver/human.h @@ -316,6 +316,7 @@ protected: std::vector chged_bullet_nums_; std::vector chged_hps_; std::vector chged_skillcds_; + std::vector chged_skill_curr_times_; std::vector chged_items_; std::vector chged_weapon_ammo_; std::vector chged_level_; diff --git a/server/gameserver/metadata.cc b/server/gameserver/metadata.cc index a11898f..09a6233 100644 --- a/server/gameserver/metadata.cc +++ b/server/gameserver/metadata.cc @@ -448,6 +448,7 @@ namespace MetaData void Skill::Init() { + { std::vector strings; a8::Split(i->buff_list(), strings, '|'); diff --git a/server/gameserver/skill.cc b/server/gameserver/skill.cc index cec93c8..89a49d1 100644 --- a/server/gameserver/skill.cc +++ b/server/gameserver/skill.cc @@ -28,6 +28,8 @@ void Skill::FillMFSkill(cs::MFSkill* skill_pb) skill_pb->set_skill_id(meta->i->skill_id()); skill_pb->set_left_time(GetLeftTime()); skill_pb->set_cd_time(GetCd()); + skill_pb->set_curr_times(GetCurrTimes()); + skill_pb->set_max_times(meta->i->max_times()); } void Skill::ClearPassiveSkillBuff() @@ -57,3 +59,16 @@ void Skill::AddPassiveSkillBuff() owner->skill_target_id_ = old_skill_target_id_; owner->skill_target_pos_ = old_skill_target_pos_; } + +void Skill::DecTimes() +{ + --curr_times_; + if (curr_times_ < 0) { + curr_times_ = 0; + } +} + +int Skill::GetCurrTimes() +{ + return curr_times_; +} diff --git a/server/gameserver/skill.h b/server/gameserver/skill.h index 3d5ab87..bccc60d 100644 --- a/server/gameserver/skill.h +++ b/server/gameserver/skill.h @@ -22,9 +22,13 @@ class Skill int GetCd(); int GetLeftTime(); int GetPassedTime(); + int GetCurrTimes(); + void DecTimes(); void FillMFSkill(cs::MFSkill* skill_pb); void ClearPassiveSkillBuff(); void AddPassiveSkillBuff(); +private: + int curr_times_ = 0; };