This commit is contained in:
aozhiwei 2023-11-25 10:09:23 +08:00
parent 206f07055c
commit 2177988ca8
8 changed files with 435 additions and 0 deletions

View File

@ -0,0 +1,199 @@
#include "precompile.h"
#include "base_agent.h"
#include <f8/btmgr.h>
BaseAgent::BaseAgent():behaviac::Agent()
{
++Perf::Instance()->agent_num;
}
BaseAgent::~BaseAgent()
{
--Perf::Instance()->agent_num;
}
bool BaseAgent::IsGameOver()
{
return GetRoom()->IsGameOver();
}
int BaseAgent::GetTickCount()
{
return GetRoom()->GetFrameNo() * FRAME_RATE_MS;
}
int BaseAgent::RandRange(int min_val, int max_val)
{
return a8::RandEx(min_val, max_val);
}
int BaseAgent::Rand()
{
return rand();
}
bool BaseAgent::IsChiJiMode()
{
return !GetRoom()->IsMobaModeRoom();
}
bool BaseAgent::IsMobaMode()
{
return GetRoom()->IsMobaModeRoom();
}
float BaseAgent::RandRangeAsFloat(float min_val, float max_val)
{
return RandRange(min_val, max_val);
}
void BaseAgent::Exec()
{
behaviac::EBTStatus status = f8::BtMgr::Instance()->BtExec(this);
if (status == behaviac::BT_RUNNING) {
CheckCoroutineEvent();
}
}
behaviac::EBTStatus BaseAgent::StartCoroutine(std::shared_ptr<BtCoroutine> co)
{
coroutines_hash_[co->GetId()] = co;
list_add_tail(&coroutines_list_, &co->entry);
return behaviac::BT_RUNNING;
}
bool BaseAgent::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 (co->IsAbort()) {
list_del_init(&co->entry);
coroutines_hash_.erase(itr);
return false;
}
co->status = co->runing_cb(co.get());
status = co->status;
if (co->status != behaviac::BT_RUNNING) {
list_del_init(&co->entry);
coroutines_hash_.erase(itr);
}
return true;
}
void BaseAgent::CheckCoroutineEvent()
{
int co_id = -1;
bool has_abort_co = false;
{
list_head* pos = nullptr;
list_head* next = nullptr;
list_head* head = &coroutines_list_;
list_for_each_safe(pos, next, head) {
BtCoroutine* co = list_entry(pos, BtCoroutine, entry);
if (co->GetContext()->HasEvent()) {
co_id = co->GetId();
break;
}
}
}
if (co_id >= 0) {
auto itr = coroutines_hash_.find(co_id);
if (itr == coroutines_hash_.end()) {
abort();
}
auto co = itr->second;
coroutines_hash_.clear();
INIT_LIST_HEAD(&coroutines_list_);
co->GetContext()->FireEvent(this);
}
}
int BaseAgent::Test(int p1)
{
#ifdef MYDEBUG1
a8::XPrintf("Test output:%d\n", {p1});
#endif
return p1;
}
behaviac::EBTStatus BaseAgent::CoTest1(int time)
{
PRE_ENTER_COROUTINE();
auto context = MAKE_BTCONTEXT
(
int time = 0;
);
context->time = time;
auto co = std::make_shared<BtCoroutine>(context, co_id, "CoTest1");
co->runing_cb =
[this, context] (BtCoroutine* co)
{
if (co->IsAbort()) {
return behaviac::BT_FAILURE;
}
if ((GetRoom()->GetFrameNo() - context->frameno) * FRAME_RATE_MS <
context->time) {
return behaviac::BT_RUNNING;
} else {
return behaviac::BT_SUCCESS;
}
};
return StartCoroutine(co);
}
behaviac::EBTStatus BaseAgent::CoTest(int time)
{
PRE_ENTER_COROUTINE();
auto context = MAKE_BTCONTEXT
(
int time = 0;
);
context->time = time;
auto co = std::make_shared<BtCoroutine>(context, co_id, "CoTest");
co->runing_cb =
[this, context] (BtCoroutine* co)
{
if (co->IsAbort()) {
return behaviac::BT_FAILURE;
}
if ((GetRoom()->GetFrameNo() - context->frameno) * FRAME_RATE_MS <
context->time) {
return behaviac::BT_RUNNING;
} else {
return behaviac::BT_SUCCESS;
}
};
return StartCoroutine(co);
}
int BaseAgent::DeltaTime(int time)
{
return GetTickCount() - time;
}
void BaseAgent::AbortCoroutine(int co_id)
{
auto itr = coroutines_hash_.find(co_id);
if (itr != coroutines_hash_.end()) {
if (!itr->second->IsAbort()) {
itr->second->Abort(GetRoom()->GetFrameNo());
itr->second->runing_cb(itr->second.get());
itr->second->runing_cb = nullptr;
list_del_init(&itr->second->entry);
coroutines_hash_.erase(itr);
}
}
}

View File

@ -0,0 +1,80 @@
#pragma once
#include "precompile.h"
#if 0
#include "behaviac/behaviac.h"
#include "behaviac_customized_types.h"
#endif
#include "btcoroutine.h"
#include "btcontext.h"
#define PRE_ENTER_COROUTINE() \
const int co_id = 1000 + __LINE__; \
{ \
behaviac::EBTStatus status; \
if (PreEnterCoroutine(co_id, status)) { \
return status; \
} \
}
#define PRE_ENTER_COROUTINE_EX(ID) \
const int co_id = ID; \
{ \
behaviac::EBTStatus status; \
if (PreEnterCoroutine(co_id, status)) { \
return status; \
} \
}
#define MAKE_BTCONTEXT(...) \
[] (BaseAgent* agent) \
{ \
class Context : public BtContext \
{public: \
__VA_ARGS__; \
long long frameno = 0; \
}; \
auto context = std::make_shared<Context>(); \
context->frameno = agent->GetRoom()->GetFrameNo(); \
return context; \
}(this)
class Room;
class BtCoroutine;
class BaseAgent : public behaviac::Agent
{
public:
BaseAgent();
virtual ~BaseAgent();
BEHAVIAC_DECLARE_AGENTTYPE(BaseAgent, behaviac::Agent)
void Exec();
bool IsGameOver();
int GetTickCount();
int RandRange(int min_val, int max_val);
float RandRangeAsFloat(float min_val, float max_val);
int Rand();
bool IsChiJiMode();
bool IsMobaMode();
int Test(int p1);
int DeltaTime(int time);
void AbortCoroutine(int co_id);
virtual Room* GetRoom() = 0;
behaviac::EBTStatus CoTest1(int time);
behaviac::EBTStatus CoTest(int time);
protected:
bool PreEnterCoroutine(int co_id, behaviac::EBTStatus& status);
behaviac::EBTStatus StartCoroutine(std::shared_ptr<BtCoroutine> co);
void CheckCoroutineEvent();
protected:
std::map<int, std::shared_ptr<BtCoroutine>> coroutines_hash_;
list_head coroutines_list_;
};

View File

@ -0,0 +1,8 @@
#include "precompile.h"
#include "btcontext.h"
#include "btevent.h"
BtContext::~BtContext()
{
}

View File

@ -0,0 +1,13 @@
#pragma once
class BtEvent;
class BtContext : public std::enable_shared_from_this<BtContext>
{
public:
virtual ~BtContext();
private:
std::vector<std::shared_ptr<BtEvent>> events_;
};

View File

@ -0,0 +1,24 @@
#include "precompile.h"
#include "btcoroutine.h"
#include "base_agent.h"
#include "btcontext.h"
#include "btevent.h"
BtCoroutine::BtCoroutine(std::shared_ptr<BtContext> context, int id, const char* name)
{
context_ = context;
id_ = id;
name_ = name;
INIT_LIST_HEAD(&entry);
}
BtCoroutine::~BtCoroutine()
{
}
void BtCoroutine::Abort(long long frameno)
{
is_abort_ = true;
abort_frameno = frameno;
}

View File

@ -0,0 +1,35 @@
#pragma once
//#include "behaviac/behaviac.h"
//#include "behaviac_customized_types.h"
class BtContext;
class BaseAgent;
class BtCoroutine
{
public:
std::function<behaviac::EBTStatus(BtCoroutine*)> runing_cb;
long long sleep_end_frameno = 0;
int sleep_time = 0;
list_head entry;
long long abort_exec_times = 0;
long long abort_frameno = 0;
behaviac::EBTStatus status = behaviac::BT_RUNNING;
BtCoroutine(std::shared_ptr<BtContext> context, int id, const char* name);
virtual ~BtCoroutine();
const char* GetName() const { return name_; }
auto GetContext() { return context_; }
int GetId() { return id_; }
bool IsAbort() { return is_abort_; }
void Abort(long long frameno);
private:
std::shared_ptr<BtContext> context_;
const char* name_ = nullptr;
int id_ = 0;
bool is_abort_ = false;
};

View File

@ -0,0 +1,42 @@
#include "precompile.h"
#include "btevent.h"
#include "creature.h"
#include "trigger.h"
#include "base_agent.h"
#include "base_agent.h"
std::shared_ptr<BtEvent> BtEvent::Create(int event_id,
a8::Args event_params,
std::function<bool()> has_event_cb
)
{
return std::make_shared<BtEvent>(
event_id,
event_params,
has_event_cb
);
}
void BtEvent::FireEvent(BaseAgent* agent)
{
switch (event_id_) {
case kBetOnAttack:
{
agent->FireEvent("OnAttacked",
event_params_.Get<int>(0),
event_params_.Get<long long>(1));
}
break;
case kBetOnCrazeMode:
{
agent->FireEvent("OnCrazeMode");
}
break;
default:
{
abort();
}
break;
}
}

View File

@ -0,0 +1,34 @@
#pragma once
enum BtEventType_e
{
kBetOnAttack = 1,
kBetOnCrazeMode,
};
class HeroAgent;
class BaseAgent;
class BtEvent
{
public:
int GetEventId() const { return event_id_; }
const a8::Args& GetParams() const { return event_params_; }
bool HasEvent() const { return has_event_cb_(); }
void FireEvent(BaseAgent* agent);
static std::shared_ptr<BtEvent> Create(int event_id,
a8::Args event_params,
std::function<bool()> has_event_cb
);
BtEvent(int event_id,
a8::Args event_params,
std::function<bool()> has_event_cb):
event_id_(event_id), event_params_(event_params), has_event_cb_(has_event_cb) {}
private:
int event_id_ = 0;
a8::Args event_params_;
std::function<bool()> has_event_cb_;
};