From 9a460eecbad93557c76f5ec12a164c43f32b7305 Mon Sep 17 00:00:00 2001 From: aozhiwei Date: Wed, 8 Nov 2023 15:56:22 +0800 Subject: [PATCH] 1 --- server/gameserver/buff/callfunc.cc | 298 ++++++++++++++++------------- server/gameserver/buff/callfunc.h | 4 + 2 files changed, 164 insertions(+), 138 deletions(-) diff --git a/server/gameserver/buff/callfunc.cc b/server/gameserver/buff/callfunc.cc index b745a4ad..43d565ae 100644 --- a/server/gameserver/buff/callfunc.cc +++ b/server/gameserver/buff/callfunc.cc @@ -1,5 +1,7 @@ #include "precompile.h" +#include + #include "buff/callfunc.h" #include "creature.h" @@ -183,6 +185,11 @@ void CallFuncBuff::Activate() PlayFlyEffect(); } break; + case BuffCallFunc_e::kSpecCenterRangeHoldBuff: + { + SpecCenterRangeHoldBuff(); + } + break; default: { } @@ -992,145 +999,7 @@ void CallFuncBuff::SummonCarSpecPoint() void CallFuncBuff::RangeHoldBuff() { - if (owner->dead) { - return; - } - struct InnerObject - { - CreatureWeakPtr c; - std::vector buff_uniids; - void OnEnter() - { - - } - - void OnLeave() - { - } - - }; - - auto context = A8_MAKE_ANON_STRUCT_SHARED - ( - std::map in_human_infos; - ); - - auto on_enter = - [this, context] (Creature* hum) - { - if (context->in_human_infos.find(hum->GetUniId()) != context->in_human_infos.end()) { - abort(); - } - InnerObject o; - o.c = hum->GetWeakPtrRef(); - - if (owner->team_id == hum->team_id) { - for (int buff_id : meta->_buff_param3_int_list) { - o.buff_uniids.push_back(hum->TryAddBuff(GetCaster().Get(), buff_id, skill_meta)); - } - } else { - for (int buff_id : meta->_buff_param4_int_list) { - o.buff_uniids.push_back(hum->TryAddBuff(GetCaster().Get(), buff_id, skill_meta)); - } - } - - context->in_human_infos[hum->GetUniId()] = o; - context->in_human_infos[hum->GetUniId()].OnEnter(); - }; - auto on_stay = - [this, context] (Creature* hum) - { - }; - auto on_leave = - [this, context] (Creature* hum) - { - auto itr = context->in_human_infos.find(hum->GetUniId()); - if (itr == context->in_human_infos.end()) { - abort(); - } - for (int buff_uniid : itr->second.buff_uniids) { - hum->RemoveBuffByUniId(buff_uniid); - } - itr->second.OnLeave(); - }; - auto check_cb = - [this, context, on_enter, on_stay, on_leave] - () - { - float range = meta->GetBuffParam2(this); - std::set hit_humans; - owner->room->TraverseAliveHumanList - ( - [this, range, &hit_humans] (Human* hum) mutable - { - if (Collision::CheckCC(owner, owner->GetRadius(), - hum, range)) { - hit_humans.insert(hum); - } - return true; - }); - std::vector leave_humans; - for (auto& pair : context->in_human_infos) { - if (hit_humans.find(pair.second.c.Get()) == hit_humans.end()) { - on_leave(pair.second.c.Get()->AsHuman()); - leave_humans.push_back(pair.second.c.Get()->AsHuman()); - } - } - for (Human* hum : leave_humans) { - context->in_human_infos.erase(hum->GetUniId()); - } - for (Creature* hum : hit_humans) { - if (context->in_human_infos.find(hum->GetUniId()) == - context->in_human_infos.end()) { - on_enter(hum); - on_stay(hum); - } else { - on_stay(hum); - } - } - }; - auto check_timer = owner->room->xtimer.SetIntervalWpEx - ( - SERVER_FRAME_RATE, - [this, context, on_enter, on_stay, on_leave, check_cb] - (int event, const a8::Args* args) mutable - { - if (a8::TIMER_EXEC_EVENT == event) { - check_cb(); - } - }, - &owner->xtimer_attacher); - auto clear_func = - [this, context, check_timer] () mutable - { - if (!check_timer.expired()) { - owner->room->xtimer.Delete(check_timer); - } - for (auto& pair : context->in_human_infos) { - for (int buff_uniid : pair.second.buff_uniids) { - if (pair.second.c.Get()) { - pair.second.c.Get()->RemoveBuffByUniId(buff_uniid); - } - } - } - context->in_human_infos.clear(); - }; - { - event_handlers_.push_back(owner->GetTrigger()->AddListener - ( - kDieEvent, - [this, clear_func] (const a8::Args& args) mutable - { - clear_func(); - } - )); - deactivate_cb_ = - [this, clear_func] () mutable - { - clear_func(); - }; - } } void CallFuncBuff::PlayFlyEffect() @@ -1215,3 +1084,156 @@ void CallFuncBuff::LispEval() } } } + +void CallFuncBuff::SpecCenterRangeHoldBuff() +{ +} + +void CallFuncBuff::InternalRangeHoldBuff(std::function get_center_func) +{ + if (owner->dead) { + return; + } + struct InnerObject + { + CreatureWeakPtr c; + std::vector buff_uniids; + + void OnEnter() + { + + } + + void OnLeave() + { + } + + }; + + auto context = A8_MAKE_ANON_STRUCT_SHARED + ( + std::map in_human_infos; + ); + + auto on_enter = + [this, context] (Creature* hum) + { + if (context->in_human_infos.find(hum->GetUniId()) != context->in_human_infos.end()) { + abort(); + } + InnerObject o; + o.c = hum->GetWeakPtrRef(); + + if (owner->team_id == hum->team_id) { + for (int buff_id : meta->_buff_param3_int_list) { + o.buff_uniids.push_back(hum->TryAddBuff(GetCaster().Get(), buff_id, skill_meta)); + } + } else { + for (int buff_id : meta->_buff_param4_int_list) { + o.buff_uniids.push_back(hum->TryAddBuff(GetCaster().Get(), buff_id, skill_meta)); + } + } + + context->in_human_infos[hum->GetUniId()] = o; + context->in_human_infos[hum->GetUniId()].OnEnter(); + }; + auto on_stay = + [this, context] (Creature* hum) + { + }; + auto on_leave = + [this, context] (Creature* hum) + { + auto itr = context->in_human_infos.find(hum->GetUniId()); + if (itr == context->in_human_infos.end()) { + abort(); + } + for (int buff_uniid : itr->second.buff_uniids) { + hum->RemoveBuffByUniId(buff_uniid); + } + itr->second.OnLeave(); + }; + auto check_cb = + [this, context, on_enter, on_stay, on_leave, get_center_func] + () + { + float range = meta->GetBuffParam2(this); + std::set hit_humans; + owner->room->TraverseAliveHumanList + ( + [this, range, &hit_humans, &get_center_func] (Human* hum) mutable + { + glm::vec3 center; + if (get_center_func(center)) { + if (a8::IntersectCylinderCylinder + ( + center, owner->GetRadius(), 10, + hum->GetPos().ToGlmVec3(), range, 10 + )) { + hit_humans.insert(hum); + } + } + return true; + }); + std::vector leave_humans; + for (auto& pair : context->in_human_infos) { + if (hit_humans.find(pair.second.c.Get()) == hit_humans.end()) { + on_leave(pair.second.c.Get()->AsHuman()); + leave_humans.push_back(pair.second.c.Get()->AsHuman()); + } + } + for (Human* hum : leave_humans) { + context->in_human_infos.erase(hum->GetUniId()); + } + for (Creature* hum : hit_humans) { + if (context->in_human_infos.find(hum->GetUniId()) == + context->in_human_infos.end()) { + on_enter(hum); + on_stay(hum); + } else { + on_stay(hum); + } + } + }; + auto check_timer = owner->room->xtimer.SetIntervalWpEx + ( + SERVER_FRAME_RATE, + [this, context, on_enter, on_stay, on_leave, check_cb] + (int event, const a8::Args* args) mutable + { + if (a8::TIMER_EXEC_EVENT == event) { + check_cb(); + } + }, + &owner->xtimer_attacher); + auto clear_func = + [this, context, check_timer] () mutable + { + if (!check_timer.expired()) { + owner->room->xtimer.Delete(check_timer); + } + for (auto& pair : context->in_human_infos) { + for (int buff_uniid : pair.second.buff_uniids) { + if (pair.second.c.Get()) { + pair.second.c.Get()->RemoveBuffByUniId(buff_uniid); + } + } + } + context->in_human_infos.clear(); + }; + { + event_handlers_.push_back(owner->GetTrigger()->AddListener + ( + kDieEvent, + [this, clear_func] (const a8::Args& args) mutable + { + clear_func(); + } + )); + deactivate_cb_ = + [this, clear_func] () mutable + { + clear_func(); + }; + } +} diff --git a/server/gameserver/buff/callfunc.h b/server/gameserver/buff/callfunc.h index 1275723b..ee671b07 100644 --- a/server/gameserver/buff/callfunc.h +++ b/server/gameserver/buff/callfunc.h @@ -34,6 +34,7 @@ A8_DECLARE_CLASS_ENUM(BuffCallFunc_e, int, kRangeHoldBuff = 34, kPlayFlyEffect = 35, kLispEval = 36, + kSpecCenterRangeHoldBuff = 37, ); @@ -67,6 +68,9 @@ class CallFuncBuff : public Buff void RangeHoldBuff(); void PlayFlyEffect(); void LispEval(); + void SpecCenterRangeHoldBuff(); + + void InternalRangeHoldBuff(std::function get_center_func); float hold_param2_ = 0.0; Weapon* hold_weapon_ = nullptr;