This commit is contained in:
aozhiwei 2023-10-21 11:48:22 +08:00
parent 46e3e8a92d
commit a75eabe884
3 changed files with 69 additions and 80 deletions

View File

@ -12,18 +12,24 @@ class BtCoroutine
std::function<behaviac::EBTStatus()> runing_cb; std::function<behaviac::EBTStatus()> runing_cb;
long long sleep_end_frameno = 0; long long sleep_end_frameno = 0;
int sleep_time = 0; int sleep_time = 0;
list_head entry;
behaviac::EBTStatus status = behaviac::BT_INVALID;
BtCoroutine(std::shared_ptr<BtContext> context, const char* name) BtCoroutine(std::shared_ptr<BtContext> context, int id, const char* name)
{ {
this->context_ = context; context_ = context;
this->name_ = name; id_ = id;
name_ = name;
INIT_LIST_HEAD(&entry);
} }
const char* GetName() const { return name_; } const char* GetName() const { return name_; }
auto GetContext() { return context_; } auto GetContext() { return context_; }
int GetId() { return id_; }
private: private:
std::shared_ptr<BtContext> context_; std::shared_ptr<BtContext> context_;
const char* name_ = nullptr; const char* name_ = nullptr;
int id_ = 0;
}; };

View File

@ -25,11 +25,21 @@
#include "mt/Equip.h" #include "mt/Equip.h"
#include "mt/Skill.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() HeroAgent::HeroAgent():BaseAgent()
{ {
current_target_agent = behaviac::Agent::Create<TargetAgent>(); current_target_agent = behaviac::Agent::Create<TargetAgent>();
master_agent = behaviac::Agent::Create<MasterAgent>(); master_agent = behaviac::Agent::Create<MasterAgent>();
team_agent = behaviac::Agent::Create<TeamAgent>(); team_agent = behaviac::Agent::Create<TeamAgent>();
INIT_LIST_HEAD(&coroutines_list_);
} }
HeroAgent::~HeroAgent() HeroAgent::~HeroAgent()
@ -51,6 +61,7 @@ HeroAgent::~HeroAgent()
void HeroAgent::Exec() void HeroAgent::Exec()
{ {
behaviac::EBTStatus status = f8::BtMgr::Instance()->BtExec(this); behaviac::EBTStatus status = f8::BtMgr::Instance()->BtExec(this);
#if 0
if (status == behaviac::BT_RUNNING && if (status == behaviac::BT_RUNNING &&
coroutine_ && coroutine_ &&
coroutine_->GetContext()->HasEvent()) { coroutine_->GetContext()->HasEvent()) {
@ -61,6 +72,7 @@ void HeroAgent::Exec()
old_coroutine->GetContext()->FireEvent(this); old_coroutine->GetContext()->FireEvent(this);
old_coroutine = nullptr; old_coroutine = nullptr;
} }
#endif
} }
void HeroAgent::SetOwner(Creature* owner) 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) behaviac::EBTStatus HeroAgent::RandomSafeZonePoint(int try_count, int step_len)
{ {
if (status_ == behaviac::BT_RUNNING) { PRE_ENTER_COROUTINE();
return DoRunningCb();
}
auto context = MAKE_BTCONTEXT auto context = MAKE_BTCONTEXT
( (
); );
auto co = std::make_shared<BtCoroutine>(context, "RandomSafeZonePoint"); auto co = std::make_shared<BtCoroutine>(context, co_id, "RandomSafeZonePoint");
co->runing_cb = co->runing_cb =
[this, context, try_count, step_len] () [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) behaviac::EBTStatus HeroAgent::CoIdle(int min_val, int max_val)
{ {
if (status_ == behaviac::BT_RUNNING) { PRE_ENTER_COROUTINE();
return DoRunningCb();
}
auto context = MAKE_BTCONTEXT auto context = MAKE_BTCONTEXT
( (
int time = 0; int time = 0;
); );
context->time = a8::RandEx(min_val, max_val); context->time = a8::RandEx(min_val, max_val);
auto co = std::make_shared<BtCoroutine>(context, "CoIdle"); auto co = std::make_shared<BtCoroutine>(context, co_id, "CoIdle");
co->runing_cb = co->runing_cb =
[this, context] () [this, context] ()
{ {
@ -433,13 +441,11 @@ behaviac::EBTStatus HeroAgent::CoIdle(int min_val, int max_val)
behaviac::EBTStatus HeroAgent::CoMoveCurrentTargetRaycast() behaviac::EBTStatus HeroAgent::CoMoveCurrentTargetRaycast()
{ {
if (status_ == behaviac::BT_RUNNING) { PRE_ENTER_COROUTINE();
return DoRunningCb();
}
auto context = MAKE_BTCONTEXT auto context = MAKE_BTCONTEXT
( (
); );
auto co = std::make_shared<BtCoroutine>(context, "CoMoveCurrentTargetRaycast"); auto co = std::make_shared<BtCoroutine>(context, co_id, "CoMoveCurrentTargetRaycast");
co->runing_cb = co->runing_cb =
[this, context] () [this, context] ()
{ {
@ -459,13 +465,11 @@ behaviac::EBTStatus HeroAgent::CoMoveCurrentTargetRaycast()
behaviac::EBTStatus HeroAgent::CoShotCurrentTargetRaycast() behaviac::EBTStatus HeroAgent::CoShotCurrentTargetRaycast()
{ {
if (status_ == behaviac::BT_RUNNING) { PRE_ENTER_COROUTINE();
return DoRunningCb();
}
auto context = MAKE_BTCONTEXT auto context = MAKE_BTCONTEXT
( (
); );
auto co = std::make_shared<BtCoroutine>(context, "CoShotCurrentTargetRaycast"); auto co = std::make_shared<BtCoroutine>(context, co_id, "CoShotCurrentTargetRaycast");
co->runing_cb = co->runing_cb =
[this, context] () [this, context] ()
{ {
@ -485,9 +489,7 @@ behaviac::EBTStatus HeroAgent::CoShotCurrentTargetRaycast()
behaviac::EBTStatus HeroAgent::CoMoveMasterRaycast() behaviac::EBTStatus HeroAgent::CoMoveMasterRaycast()
{ {
if (status_ == behaviac::BT_RUNNING) { PRE_ENTER_COROUTINE();
return DoRunningCb();
}
auto context = MAKE_BTCONTEXT auto context = MAKE_BTCONTEXT
( (
a8::XTimerWp timer_ptr; a8::XTimerWp timer_ptr;
@ -499,7 +501,7 @@ behaviac::EBTStatus HeroAgent::CoMoveMasterRaycast()
{ {
}, },
&owner_->xtimer_attacher); &owner_->xtimer_attacher);
auto co = std::make_shared<BtCoroutine>(context, "CoMoveMasterRaycast"); auto co = std::make_shared<BtCoroutine>(context, co_id, "CoMoveMasterRaycast");
co->runing_cb = co->runing_cb =
[this, context] () [this, context] ()
{ {
@ -514,16 +516,14 @@ behaviac::EBTStatus HeroAgent::CoMoveMasterRaycast()
behaviac::EBTStatus HeroAgent::CoFindPath(const glm::vec3& pos) behaviac::EBTStatus HeroAgent::CoFindPath(const glm::vec3& pos)
{ {
if (status_ == behaviac::BT_RUNNING) { PRE_ENTER_COROUTINE();
return DoRunningCb();
}
auto context = MAKE_BTCONTEXT auto context = MAKE_BTCONTEXT
( (
bool find_ok = false; bool find_ok = false;
glm::vec3 target_pos; glm::vec3 target_pos;
); );
context->target_pos = pos; context->target_pos = pos;
auto co = std::make_shared<BtCoroutine>(context, "CoFindPath"); auto co = std::make_shared<BtCoroutine>(context, co_id, "CoFindPath");
co->runing_cb = co->runing_cb =
[this, context, pos] () [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) behaviac::EBTStatus HeroAgent::CoFindPathEx(const glm::vec3& pos, float distance)
{ {
if (status_ == behaviac::BT_RUNNING) { PRE_ENTER_COROUTINE();
return DoRunningCb();
}
auto context = MAKE_BTCONTEXT auto context = MAKE_BTCONTEXT
( (
bool find_ok = false; bool find_ok = false;
glm::vec3 target_pos; glm::vec3 target_pos;
); );
context->target_pos = pos; context->target_pos = pos;
auto co = std::make_shared<BtCoroutine>(context, "CoFindPathEx"); auto co = std::make_shared<BtCoroutine>(context, co_id, "CoFindPathEx");
co->runing_cb = co->runing_cb =
[this, context, distance] () [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) behaviac::EBTStatus HeroAgent::CoStartMove(int min_val, int max_val)
{ {
if (status_ == behaviac::BT_RUNNING) { PRE_ENTER_COROUTINE();
return DoRunningCb();
}
float distance = a8::RandEx(min_val, max_val); float distance = a8::RandEx(min_val, max_val);
auto context = MAKE_BTCONTEXT auto context = MAKE_BTCONTEXT
( (
); );
auto co = std::make_shared<BtCoroutine>(context, "CoStartMove"); auto co = std::make_shared<BtCoroutine>(context, co_id, "CoStartMove");
co->runing_cb = co->runing_cb =
[this, context, distance] () [this, context, distance] ()
{ {
@ -607,9 +603,7 @@ behaviac::EBTStatus HeroAgent::CoStartMove(int min_val, int max_val)
behaviac::EBTStatus HeroAgent::CoSleep(int time) behaviac::EBTStatus HeroAgent::CoSleep(int time)
{ {
if (status_ == behaviac::BT_RUNNING) { PRE_ENTER_COROUTINE();
return DoRunningCb();
}
auto context = MAKE_BTCONTEXT auto context = MAKE_BTCONTEXT
( (
a8::XTimerWp timer_ptr; a8::XTimerWp timer_ptr;
@ -621,7 +615,7 @@ behaviac::EBTStatus HeroAgent::CoSleep(int time)
{ {
}, },
&owner_->xtimer_attacher); &owner_->xtimer_attacher);
auto co = std::make_shared<BtCoroutine>(context, "CoSleep"); auto co = std::make_shared<BtCoroutine>(context, co_id, "CoSleep");
co->runing_cb = co->runing_cb =
[this, context] () [this, context] ()
{ {
@ -663,39 +657,9 @@ void HeroAgent::UnSetFlag(int tag)
a8::UnSetBitFlag(flags_, 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<BtCoroutine> coroutine) behaviac::EBTStatus HeroAgent::StartCoroutine(std::shared_ptr<BtCoroutine> coroutine)
{ {
#ifdef DEBUG1
a8::XPrintf("StartCoroutine:%d %s\n", {owner_->GetUniId(), coroutine->GetName()});
#endif
coroutine_ = coroutine; coroutine_ = coroutine;
#ifdef DEBUG
last_status_ = behaviac::BT_INVALID;
status_frameno_ = owner_->room->GetFrameNo();
status_name_ = coroutine_->GetName();
#endif
status_ = behaviac::BT_RUNNING; status_ = behaviac::BT_RUNNING;
return status_; return status_;
} }
@ -707,15 +671,13 @@ behaviac::EBTStatus HeroAgent::RegisterEvents(behaviac::vector<BtEvent_e> events
behaviac::EBTStatus HeroAgent::CoMoveForward(int min_val, int max_val) behaviac::EBTStatus HeroAgent::CoMoveForward(int min_val, int max_val)
{ {
if (status_ == behaviac::BT_RUNNING) { PRE_ENTER_COROUTINE();
return DoRunningCb();
}
float distance = a8::RandEx(min_val, max_val); float distance = a8::RandEx(min_val, max_val);
auto context = MAKE_BTCONTEXT auto context = MAKE_BTCONTEXT
( (
); );
owner_->GetMovement()->CalcTargetPos(distance); owner_->GetMovement()->CalcTargetPos(distance);
auto co = std::make_shared<BtCoroutine>(context, "CoMoveForward"); auto co = std::make_shared<BtCoroutine>(context, co_id, "CoMoveForward");
co->runing_cb = co->runing_cb =
[this, context] () [this, context] ()
{ {
@ -961,3 +923,28 @@ bool HeroAgent::InternalUseSkill(int skill_id, int& wait_time)
} }
return false; 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;
}

View File

@ -140,7 +140,7 @@ public:
glm::vec3 out_point2 = glm::vec3(0.0f, 0.0f, 0.0f); glm::vec3 out_point2 = glm::vec3(0.0f, 0.0f, 0.0f);
protected: protected:
behaviac::EBTStatus DoRunningCb(); bool PreEnterCoroutine(int co_id, behaviac::EBTStatus& status);
behaviac::EBTStatus StartCoroutine(std::shared_ptr<BtCoroutine> coroutine); behaviac::EBTStatus StartCoroutine(std::shared_ptr<BtCoroutine> coroutine);
bool InternalUseSkill(int skill_id, int& wait_time); bool InternalUseSkill(int skill_id, int& wait_time);
@ -150,12 +150,8 @@ private:
long long flags_ = 0; long long flags_ = 0;
std::map<int, int> dyn_hash_; std::map<int, int> 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; behaviac::EBTStatus status_= behaviac::BT_SUCCESS;
std::shared_ptr<BtCoroutine> coroutine_; std::shared_ptr<BtCoroutine> coroutine_;
std::map<int, std::shared_ptr<BtCoroutine>> coroutines_hash_;
list_head coroutines_list_;
}; };