diff --git a/server/gameserver/btcoroutine.h b/server/gameserver/btcoroutine.h index ce66f969..3f546c68 100644 --- a/server/gameserver/btcoroutine.h +++ b/server/gameserver/btcoroutine.h @@ -12,18 +12,24 @@ class BtCoroutine std::function runing_cb; long long sleep_end_frameno = 0; int sleep_time = 0; + list_head entry; + behaviac::EBTStatus status = behaviac::BT_INVALID; - BtCoroutine(std::shared_ptr context, const char* name) + BtCoroutine(std::shared_ptr context, int id, const char* name) { - this->context_ = context; - this->name_ = name; + context_ = context; + id_ = id; + name_ = name; + INIT_LIST_HEAD(&entry); } const char* GetName() const { return name_; } auto GetContext() { return context_; } + int GetId() { return id_; } private: std::shared_ptr context_; const char* name_ = nullptr; + int id_ = 0; }; diff --git a/server/gameserver/hero_agent.cc b/server/gameserver/hero_agent.cc index e79f1adc..98895b85 100644 --- a/server/gameserver/hero_agent.cc +++ b/server/gameserver/hero_agent.cc @@ -25,11 +25,21 @@ #include "mt/Equip.h" #include "mt/Skill.h" +#define PRE_ENTER_COROUTINE() \ + const int co_id = __LINE__; \ + { \ + behaviac::EBTStatus status; \ + if (PreEnterCoroutine(co_id, status)) { \ + return status; \ + } \ + } + HeroAgent::HeroAgent():BaseAgent() { current_target_agent = behaviac::Agent::Create(); master_agent = behaviac::Agent::Create(); team_agent = behaviac::Agent::Create(); + INIT_LIST_HEAD(&coroutines_list_); } HeroAgent::~HeroAgent() @@ -51,6 +61,7 @@ HeroAgent::~HeroAgent() void HeroAgent::Exec() { behaviac::EBTStatus status = f8::BtMgr::Instance()->BtExec(this); + #if 0 if (status == behaviac::BT_RUNNING && coroutine_ && coroutine_->GetContext()->HasEvent()) { @@ -61,6 +72,7 @@ void HeroAgent::Exec() old_coroutine->GetContext()->FireEvent(this); old_coroutine = nullptr; } + #endif } void HeroAgent::SetOwner(Creature* owner) @@ -261,13 +273,11 @@ glm::vec3 HeroAgent::RandomPoint(const glm::vec3& center, float range) behaviac::EBTStatus HeroAgent::RandomSafeZonePoint(int try_count, int step_len) { - if (status_ == behaviac::BT_RUNNING) { - return DoRunningCb(); - } + PRE_ENTER_COROUTINE(); auto context = MAKE_BTCONTEXT ( ); - auto co = std::make_shared(context, "RandomSafeZonePoint"); + auto co = std::make_shared(context, co_id, "RandomSafeZonePoint"); co->runing_cb = [this, context, try_count, step_len] () { @@ -409,15 +419,13 @@ behaviac::EBTStatus HeroAgent::SearchEnemy(float range) behaviac::EBTStatus HeroAgent::CoIdle(int min_val, int max_val) { - if (status_ == behaviac::BT_RUNNING) { - return DoRunningCb(); - } + PRE_ENTER_COROUTINE(); auto context = MAKE_BTCONTEXT ( int time = 0; ); context->time = a8::RandEx(min_val, max_val); - auto co = std::make_shared(context, "CoIdle"); + auto co = std::make_shared(context, co_id, "CoIdle"); co->runing_cb = [this, context] () { @@ -433,13 +441,11 @@ behaviac::EBTStatus HeroAgent::CoIdle(int min_val, int max_val) behaviac::EBTStatus HeroAgent::CoMoveCurrentTargetRaycast() { - if (status_ == behaviac::BT_RUNNING) { - return DoRunningCb(); - } + PRE_ENTER_COROUTINE(); auto context = MAKE_BTCONTEXT ( ); - auto co = std::make_shared(context, "CoMoveCurrentTargetRaycast"); + auto co = std::make_shared(context, co_id, "CoMoveCurrentTargetRaycast"); co->runing_cb = [this, context] () { @@ -459,13 +465,11 @@ behaviac::EBTStatus HeroAgent::CoMoveCurrentTargetRaycast() behaviac::EBTStatus HeroAgent::CoShotCurrentTargetRaycast() { - if (status_ == behaviac::BT_RUNNING) { - return DoRunningCb(); - } + PRE_ENTER_COROUTINE(); auto context = MAKE_BTCONTEXT ( ); - auto co = std::make_shared(context, "CoShotCurrentTargetRaycast"); + auto co = std::make_shared(context, co_id, "CoShotCurrentTargetRaycast"); co->runing_cb = [this, context] () { @@ -485,9 +489,7 @@ behaviac::EBTStatus HeroAgent::CoShotCurrentTargetRaycast() behaviac::EBTStatus HeroAgent::CoMoveMasterRaycast() { - if (status_ == behaviac::BT_RUNNING) { - return DoRunningCb(); - } + PRE_ENTER_COROUTINE(); auto context = MAKE_BTCONTEXT ( a8::XTimerWp timer_ptr; @@ -499,7 +501,7 @@ behaviac::EBTStatus HeroAgent::CoMoveMasterRaycast() { }, &owner_->xtimer_attacher); - auto co = std::make_shared(context, "CoMoveMasterRaycast"); + auto co = std::make_shared(context, co_id, "CoMoveMasterRaycast"); co->runing_cb = [this, context] () { @@ -514,16 +516,14 @@ behaviac::EBTStatus HeroAgent::CoMoveMasterRaycast() behaviac::EBTStatus HeroAgent::CoFindPath(const glm::vec3& pos) { - if (status_ == behaviac::BT_RUNNING) { - return DoRunningCb(); - } + PRE_ENTER_COROUTINE(); auto context = MAKE_BTCONTEXT ( bool find_ok = false; glm::vec3 target_pos; ); context->target_pos = pos; - auto co = std::make_shared(context, "CoFindPath"); + auto co = std::make_shared(context, co_id, "CoFindPath"); co->runing_cb = [this, context, pos] () { @@ -550,16 +550,14 @@ behaviac::EBTStatus HeroAgent::CoFindPath(const glm::vec3& pos) behaviac::EBTStatus HeroAgent::CoFindPathEx(const glm::vec3& pos, float distance) { - if (status_ == behaviac::BT_RUNNING) { - return DoRunningCb(); - } + PRE_ENTER_COROUTINE(); auto context = MAKE_BTCONTEXT ( bool find_ok = false; glm::vec3 target_pos; ); context->target_pos = pos; - auto co = std::make_shared(context, "CoFindPathEx"); + auto co = std::make_shared(context, co_id, "CoFindPathEx"); co->runing_cb = [this, context, distance] () { @@ -586,14 +584,12 @@ behaviac::EBTStatus HeroAgent::CoFindPathEx(const glm::vec3& pos, float distance behaviac::EBTStatus HeroAgent::CoStartMove(int min_val, int max_val) { - if (status_ == behaviac::BT_RUNNING) { - return DoRunningCb(); - } + PRE_ENTER_COROUTINE(); float distance = a8::RandEx(min_val, max_val); auto context = MAKE_BTCONTEXT ( ); - auto co = std::make_shared(context, "CoStartMove"); + auto co = std::make_shared(context, co_id, "CoStartMove"); co->runing_cb = [this, context, distance] () { @@ -607,9 +603,7 @@ behaviac::EBTStatus HeroAgent::CoStartMove(int min_val, int max_val) behaviac::EBTStatus HeroAgent::CoSleep(int time) { - if (status_ == behaviac::BT_RUNNING) { - return DoRunningCb(); - } + PRE_ENTER_COROUTINE(); auto context = MAKE_BTCONTEXT ( a8::XTimerWp timer_ptr; @@ -621,7 +615,7 @@ behaviac::EBTStatus HeroAgent::CoSleep(int time) { }, &owner_->xtimer_attacher); - auto co = std::make_shared(context, "CoSleep"); + auto co = std::make_shared(context, co_id, "CoSleep"); co->runing_cb = [this, context] () { @@ -663,39 +657,9 @@ void HeroAgent::UnSetFlag(int tag) a8::UnSetBitFlag(flags_, tag); } -behaviac::EBTStatus HeroAgent::DoRunningCb() -{ - if (status_ != behaviac::BT_RUNNING) { - abort(); - } - if (owner_->room->GetFrameNo() < coroutine_->sleep_end_frameno) { - return behaviac::BT_RUNNING; - } - status_ = coroutine_->runing_cb(); -#ifdef DEBUG1 - if ((owner_->room->GetFrameNo() - status_frameno_) % SERVER_FRAME_RATE == 0 || - last_status_ != status_) { - last_status_ = status_; - a8::XPrintf("Running Status:%s %d\n", {status_name_, status_}); - } -#endif - if (status_ != behaviac::BT_RUNNING) { - coroutine_ = nullptr; - } - return status_; -} - behaviac::EBTStatus HeroAgent::StartCoroutine(std::shared_ptr coroutine) { -#ifdef DEBUG1 - a8::XPrintf("StartCoroutine:%d %s\n", {owner_->GetUniId(), coroutine->GetName()}); -#endif coroutine_ = coroutine; -#ifdef DEBUG - last_status_ = behaviac::BT_INVALID; - status_frameno_ = owner_->room->GetFrameNo(); - status_name_ = coroutine_->GetName(); -#endif status_ = behaviac::BT_RUNNING; return status_; } @@ -707,15 +671,13 @@ behaviac::EBTStatus HeroAgent::RegisterEvents(behaviac::vector events behaviac::EBTStatus HeroAgent::CoMoveForward(int min_val, int max_val) { - if (status_ == behaviac::BT_RUNNING) { - return DoRunningCb(); - } + PRE_ENTER_COROUTINE(); float distance = a8::RandEx(min_val, max_val); auto context = MAKE_BTCONTEXT ( ); owner_->GetMovement()->CalcTargetPos(distance); - auto co = std::make_shared(context, "CoMoveForward"); + auto co = std::make_shared(context, co_id, "CoMoveForward"); co->runing_cb = [this, context] () { @@ -961,3 +923,28 @@ bool HeroAgent::InternalUseSkill(int skill_id, int& wait_time) } return false; } + +bool HeroAgent::PreEnterCoroutine(int co_id, behaviac::EBTStatus& status) +{ + status = behaviac::BT_FAILURE; + if (coroutines_hash_.empty()) { + return false; + } + auto itr = coroutines_hash_.find(co_id); + if (itr == coroutines_hash_.end()) { + return false; + } + auto& co = itr->second; + if (co->status != behaviac::BT_RUNNING) { + abort(); + } + if (owner_->room->GetFrameNo() < co->sleep_end_frameno) { + status = behaviac::BT_RUNNING; + return true; + } + co->status = co->runing_cb(); + if (co->status != behaviac::BT_RUNNING) { + } + status = co->status; + return true; +} diff --git a/server/gameserver/hero_agent.h b/server/gameserver/hero_agent.h index 04dcc1ca..c8b1050f 100644 --- a/server/gameserver/hero_agent.h +++ b/server/gameserver/hero_agent.h @@ -140,7 +140,7 @@ public: glm::vec3 out_point2 = glm::vec3(0.0f, 0.0f, 0.0f); protected: - behaviac::EBTStatus DoRunningCb(); + bool PreEnterCoroutine(int co_id, behaviac::EBTStatus& status); behaviac::EBTStatus StartCoroutine(std::shared_ptr coroutine); bool InternalUseSkill(int skill_id, int& wait_time); @@ -150,12 +150,8 @@ private: long long flags_ = 0; std::map dyn_hash_; -#ifdef DEBUG - behaviac::EBTStatus last_status_ = behaviac::BT_INVALID; - long long status_frameno_ = 0; - const char* status_name_ = nullptr; -#endif behaviac::EBTStatus status_= behaviac::BT_SUCCESS; std::shared_ptr coroutine_; - + std::map> coroutines_hash_; + list_head coroutines_list_; };