diff --git a/server/gameserver/buff.cc b/server/gameserver/buff.cc index 6ebce80..e18d367 100644 --- a/server/gameserver/buff.cc +++ b/server/gameserver/buff.cc @@ -18,9 +18,28 @@ Buff::Buff() } -void Buff::Initialize() +void Buff::Init() { + INIT_LIST_HEAD(&effect_entry); + INIT_LIST_HEAD(&depend_entry); + INIT_LIST_HEAD(&cond_entry); + INIT_LIST_HEAD(&on_remove_contexts); +} +void Buff::UnInit() +{ + list_del_init(&effect_entry); + if (!list_empty(&depend_entry)) { + list_del_init(&depend_entry); + } + if (!list_empty(&cond_entry)) { + list_del_init(&cond_entry); + } + while (!list_empty(&on_remove_contexts)) { + RemoveBuffCbConext* cb = list_last_entry(&on_remove_contexts, RemoveBuffCbConext, entry); + *cb->next = (*cb->next)->next; + list_del_init(&cb->entry); + } } int Buff::GetLeftTime() diff --git a/server/gameserver/buff.h b/server/gameserver/buff.h index 58ed6dd..bba2d62 100644 --- a/server/gameserver/buff.h +++ b/server/gameserver/buff.h @@ -17,6 +17,12 @@ namespace cs class MFBuff; } +struct RemoveBuffCbConext +{ + list_head** next; + list_head entry; +}; + class Human; class Creature; class Buff @@ -31,9 +37,11 @@ class Buff list_head effect_entry; list_head depend_entry; list_head cond_entry; + list_head on_remove_contexts; Buff(); - void Initialize(); + void Init(); + void UnInit(); int GetLeftTime(); int GetLastingTime(); bool NeedSync(Human* hum); diff --git a/server/gameserver/creature.cc b/server/gameserver/creature.cc index 430f6d9..0158e81 100644 --- a/server/gameserver/creature.cc +++ b/server/gameserver/creature.cc @@ -205,15 +205,12 @@ void Creature::AddBuff(Creature* caster, buff->skill_meta = buff_skill_meta; buff->add_frameno = room->GetFrameNo(); buff->xtimer_attacher.xtimer = &room->xtimer; + buff->Init(); list_add_tail(&buff->effect_entry, &buff_effect_[buff->meta->i->buff_effect()]); if (buff->meta->i->depend_effect() != 0 && IsValidBuffEffect(buff->meta->i->depend_effect())) { list_add_tail(&buff->depend_entry, &depend_effect_[buff->meta->i->depend_effect()]); - } else { - INIT_LIST_HEAD(&buff->depend_entry); } - INIT_LIST_HEAD(&buff->cond_entry); - buff->Initialize(); { room->xtimer.AddDeadLineTimerAndAttach ( @@ -284,15 +281,9 @@ void Creature::RemoveBuffById(int buff_id) for (auto itr = buff_list_.begin(); itr != buff_list_.end(); ++itr) { Buff& buff = *itr; if (buff.meta->i->buff_id() == buff_id) { - list_del_init(&buff.effect_entry); - if (!list_empty(&buff.depend_entry)) { - list_del_init(&buff.depend_entry); - } - if (!list_empty(&buff.cond_entry)) { - list_del_init(&buff.cond_entry); - } removed_buffs.push_back(std::make_tuple(buff.meta, buff.GetCaster().Get())); OnBuffRemove(buff); + buff.UnInit(); buff_list_.erase(itr); break; } diff --git a/server/gameserver/creature.h b/server/gameserver/creature.h index 9d03fef..0af24df 100644 --- a/server/gameserver/creature.h +++ b/server/gameserver/creature.h @@ -258,6 +258,7 @@ private: std::map passive_skill_hash_; std::array inventory_ = {}; friend class Skill; + friend class Trigger; }; void InternalShot(Creature* sender, diff --git a/server/gameserver/trigger.cc b/server/gameserver/trigger.cc index 2904603..9d43f40 100644 --- a/server/gameserver/trigger.cc +++ b/server/gameserver/trigger.cc @@ -1,6 +1,9 @@ #include "precompile.h" +#include + #include "trigger.h" +#include "creature.h" void Trigger::Init() { @@ -44,3 +47,32 @@ void Trigger::Die() { } + +void Trigger::TraverseCondBuffs(int cond, std::function func) +{ + if (!IsValidCondBuff(cond)) { + abort(); + } + + list_head* pos = nullptr; + list_head* next = nullptr; + list_head* head = &owner_->cond_buffs_[cond]; + RemoveBuffCbConext cb; + cb.next = &next; + INIT_LIST_HEAD(&cb.entry); + list_for_each_safe(pos, next, head) { + if (list_empty(next)) { + Buff *next_buff = list_entry(next, Buff, cond_entry); + list_add_tail(&cb.entry, &next_buff->on_remove_contexts); + } + Buff *curr_buff = list_entry(pos, Buff, cond_entry); + bool stop = false; + func(curr_buff, stop); + if (!list_empty(&cb.entry)) { + list_del_init(&cb.entry); + } + if (stop) { + return; + } + } +} diff --git a/server/gameserver/trigger.h b/server/gameserver/trigger.h index 3894304..86e3f0c 100644 --- a/server/gameserver/trigger.h +++ b/server/gameserver/trigger.h @@ -3,6 +3,7 @@ class Weapon; class Creature; class Skill; +class Buff; class Trigger { public: @@ -19,6 +20,9 @@ public: void HpChg(float old_hp, float new_hp); void Die(); + private: + void TraverseCondBuffs(int cond, std::function func); + private: Creature* owner_ = nullptr; };