diff --git a/server/gameserver/buff.cc b/server/gameserver/buff.cc index 9c7886d5..b78d15dd 100644 --- a/server/gameserver/buff.cc +++ b/server/gameserver/buff.cc @@ -43,6 +43,7 @@ void Buff::UnInit() *cb->next = (*cb->next)->next; list_del_init(&cb->entry); } + ClearEventHandlers(); } int Buff::GetLeftTime() @@ -1022,7 +1023,65 @@ void Buff::ProcMachineGun() owner->room->xtimer.ModifyTimer (remover_timer, skill_meta->number_meta->float_time * 1000 / FRAME_RATE_MS); - + event_handlers_.push_back + ( + owner->GetTrigger()->AddListener + ( + kSkillBulletPreCreateEvent, + [this] (const std::vector& params) + { + int delay_time = std::any_cast(params.at(0)); + MetaData::Skill* bullet_skill_meta = std::any_cast(params.at(1)); + int passed_frames = (owner->room->GetFrameNo() - add_frameno); + int raw_frames = skill_meta->number_meta->float_time * 1000 / FRAME_RATE_MS; + if (skill_meta == bullet_skill_meta && + delay_time >= (passed_frames - raw_frames - 2) * FRAME_RATE_MS) { + int remain_time = owner->room->xtimer.GetRemainTime(remover_timer); + owner->room->xtimer.ModifyTimer + (remover_timer, delay_time / FRAME_RATE_MS + 2); + } +#ifdef DEBUG + a8::XPrintf("event1 %d %d %d\n", {passed_frames, raw_frames, delay_time}); +#endif + } + ) + ); + event_handlers_.push_back + ( + owner->GetTrigger()->AddListener + ( + kFlyHookCreateEvent, + [this] (const std::vector& params) + { + Bullet* bullet = std::any_cast(params.at(0)); + int passed_frames = (owner->room->GetFrameNo() - add_frameno); + int raw_frames = skill_meta->number_meta->float_time * 1000 / FRAME_RATE_MS; + owner->room->xtimer.ModifyTimer + (remover_timer, + skill_meta->number_meta->float_time * 1000 / FRAME_RATE_MS); +#ifdef DEBUG + a8::XPrintf("event2 %d %d\n", {passed_frames, raw_frames}); +#endif + }) + ); + event_handlers_.push_back + ( + owner->GetTrigger()->AddListener + ( + kFlyHookDestoryEvent, + [this] (const std::vector& params) + { + int passed_frames = (owner->room->GetFrameNo() - add_frameno); + int raw_frames = skill_meta->number_meta->float_time * 1000 / FRAME_RATE_MS; + if (passed_frames >= raw_frames) { + owner->RemoveBuffByUniId(buff_uniid); + } +#ifdef DEBUG + a8::XPrintf("event3 %d %d\n", {passed_frames, raw_frames}); +#endif + } + ) + ); } break; default: @@ -1112,3 +1171,13 @@ void Buff::ProcRemoveHide() } } } + +void Buff::ClearEventHandlers() +{ + for (auto& handler : event_handlers_) { + if (!handler.expired()) { + owner->GetTrigger()->RemoveEventHandler(handler); + } + } + event_handlers_.clear(); +} diff --git a/server/gameserver/buff.h b/server/gameserver/buff.h index ba795571..10eeaf5f 100644 --- a/server/gameserver/buff.h +++ b/server/gameserver/buff.h @@ -26,6 +26,7 @@ struct RemoveBuffCbConext class Human; class Creature; +struct EventHandlerPtr; struct xtimer_list; class Buff { @@ -90,9 +91,11 @@ class Buff private: void InternalTimerAddBuff(); void RecoverHoldWeapons(); + void ClearEventHandlers(); private: int hold_curr_weapon_idx_ = 0; std::list hold_weapons_; + std::list> event_handlers_; CreatureWeakPtr caster_; }; diff --git a/server/gameserver/bullet.cc b/server/gameserver/bullet.cc index 90dd1a81..608f4adc 100644 --- a/server/gameserver/bullet.cc +++ b/server/gameserver/bullet.cc @@ -46,6 +46,9 @@ void Bullet::Initialize() sender.Get()->room->xtimer.ModifyTimer(buff->remover_timer, SERVER_FRAME_RATE * 10); } } + if (sender.Get()) { + sender.Get()->GetTrigger()->FlyHookCreate(this); + } } } @@ -653,6 +656,7 @@ void Bullet::Check(float distance) Creature* c = (Creature*)param.sender.GetUserData(); c->DecDisableMoveTimes(); c->DecDisableAttackDirTimes(); + c->GetTrigger()->FlyHookDestory(); }, &sender.Get()->xtimer_attacher.timer_list_ ); @@ -883,6 +887,7 @@ void Bullet::ProcFlyHook(Entity* target) { Creature* c = (Creature*)param.sender.GetUserData(); c->DecDisableMoveTimes(); + c->GetTrigger()->FlyHookDestory(); }, &sender.Get()->xtimer_attacher.timer_list_ ); diff --git a/server/gameserver/shot.cc b/server/gameserver/shot.cc index 3ce3c675..7c589d13 100644 --- a/server/gameserver/shot.cc +++ b/server/gameserver/shot.cc @@ -404,10 +404,10 @@ void InternalShot(Creature* c, a8::XPrintf("bullet trace_target_uniid:%d\n", {bullet_info.trace_target_uniid}); } #endif - InternalCreateBullet(bullet_info); if (bullet_info.skill_meta && bullet_info.skill_meta->number_meta) { - + c->GetTrigger()->SkillBulletPreCreate(bullet_info.delay_time, bullet_info.skill_meta); } + InternalCreateBullet(bullet_info); } } c->GetTrigger()->Shot(weapon_meta); diff --git a/server/gameserver/trigger.cc b/server/gameserver/trigger.cc index 8aba7a0b..e4ae8c0d 100644 --- a/server/gameserver/trigger.cc +++ b/server/gameserver/trigger.cc @@ -387,7 +387,7 @@ void Trigger::RemoveBuffs(int cond, std::vector& buffids) std::weak_ptr Trigger::AddListener(int event_id, CommonCbProc cb) { auto itr = listeners_hash_.find(event_id); - if (itr != listeners_hash_.end()) { + if (itr == listeners_hash_.end()) { listeners_hash_[event_id] = list_head(); itr = listeners_hash_.find(event_id); INIT_LIST_HEAD(&itr->second); @@ -448,3 +448,18 @@ void Trigger::YsBuffRemove(Buff* buff) { DispatchEvent(kYsRemoveEvent, {buff}); } + +void Trigger::SkillBulletPreCreate(int delay_time, MetaData::Skill* skill_meta) +{ + DispatchEvent(kSkillBulletPreCreateEvent, {delay_time, skill_meta}); +} + +void Trigger::FlyHookCreate(Bullet* bullet) +{ + DispatchEvent(kFlyHookCreateEvent, {bullet}); +} + +void Trigger::FlyHookDestory() +{ + DispatchEvent(kFlyHookDestoryEvent, {}); +} diff --git a/server/gameserver/trigger.h b/server/gameserver/trigger.h index d620934e..5b1ef8e8 100644 --- a/server/gameserver/trigger.h +++ b/server/gameserver/trigger.h @@ -4,6 +4,7 @@ namespace MetaData { struct Buff; struct Equip; + struct Skill; }; struct EventHandlerPtr @@ -67,6 +68,9 @@ public: void StartRescue(Human* target); void EndRescue(Human* target); void YsBuffRemove(Buff* buff); + void SkillBulletPreCreate(int delay_time, MetaData::Skill* skill_meta); + void FlyHookCreate(Bullet* bullet); + void FlyHookDestory(); std::weak_ptr AddListener(int event_id, CommonCbProc cb); void RemoveEventHandler(std::weak_ptr handler_ptr);