#include "precompile.h" #include "base_agent.h" #include #include "room.h" BaseAgent::BaseAgent():behaviac::Agent() { } BaseAgent::~BaseAgent() { } 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 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(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(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); } } }