game2006/server/gameserver/base_agent.cc
aozhiwei b3c10edf1c 1
2023-11-04 21:57:02 +08:00

202 lines
4.6 KiB
C++

#include "precompile.h"
#include "base_agent.h"
#include <f8/btmgr.h>
#include "room.h"
#include "perf.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 DEBUG1
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);
}
}
}