1
This commit is contained in:
parent
206f07055c
commit
2177988ca8
199
server/robotserver/base_agent.cc
Normal file
199
server/robotserver/base_agent.cc
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
80
server/robotserver/base_agent.h
Normal file
80
server/robotserver/base_agent.h
Normal 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_;
|
||||
};
|
8
server/robotserver/btcontext.cc
Normal file
8
server/robotserver/btcontext.cc
Normal file
@ -0,0 +1,8 @@
|
||||
#include "precompile.h"
|
||||
|
||||
#include "btcontext.h"
|
||||
#include "btevent.h"
|
||||
|
||||
BtContext::~BtContext()
|
||||
{
|
||||
}
|
13
server/robotserver/btcontext.h
Normal file
13
server/robotserver/btcontext.h
Normal 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_;
|
||||
|
||||
};
|
24
server/robotserver/btcoroutine.cc
Normal file
24
server/robotserver/btcoroutine.cc
Normal 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;
|
||||
}
|
35
server/robotserver/btcoroutine.h
Normal file
35
server/robotserver/btcoroutine.h
Normal 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;
|
||||
|
||||
};
|
42
server/robotserver/btevent.cc
Normal file
42
server/robotserver/btevent.cc
Normal 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;
|
||||
}
|
||||
}
|
34
server/robotserver/btevent.h
Normal file
34
server/robotserver/btevent.h
Normal 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_;
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user