131 lines
4.1 KiB
C++
131 lines
4.1 KiB
C++
#include "precompile.h"
|
|
|
|
#include "base_agent.h"
|
|
#include "room.h"
|
|
#include "creature.h"
|
|
#include "human.h"
|
|
#include "movehelper.h"
|
|
|
|
#include "framework/cpp/btmgr.h"
|
|
|
|
BaseAgent::BaseAgent():behaviac::Agent()
|
|
{
|
|
|
|
}
|
|
|
|
BaseAgent::~BaseAgent()
|
|
{
|
|
}
|
|
|
|
bool BaseAgent::IsGameOver()
|
|
{
|
|
return GetOwner()->room->IsGameOver();
|
|
}
|
|
|
|
void BaseAgent::Exec()
|
|
{
|
|
last_exec_status_ = f8::BtMgr::Instance()->BtExec(this);
|
|
}
|
|
|
|
bool BaseAgent::HasTarget(float range)
|
|
{
|
|
Human* enemy = GetOwner()->room->FindEnemy(GetOwner()->AsHuman(), range);
|
|
return enemy != nullptr;
|
|
}
|
|
|
|
behaviac::EBTStatus BaseAgent::DoRunningCb()
|
|
{
|
|
if (status_ != behaviac::BT_RUNNING) {
|
|
abort();
|
|
}
|
|
status_ = status_runing_cb_();
|
|
#ifdef DEBUG
|
|
if ((GetOwner()->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) {
|
|
status_runing_cb_ = nullptr;
|
|
}
|
|
return status_;
|
|
}
|
|
|
|
behaviac::EBTStatus BaseAgent::StartCoroutine(std::function<behaviac::EBTStatus()> cb,
|
|
const char* name)
|
|
{
|
|
#ifdef DEBUG
|
|
last_status_ = behaviac::BT_INVALID;
|
|
status_frameno_ = GetOwner()->room->GetFrameNo();
|
|
status_name_ = name;
|
|
#endif
|
|
status_runing_cb_ = std::move(cb);
|
|
status_ = behaviac::BT_RUNNING;
|
|
return status_;
|
|
}
|
|
|
|
behaviac::EBTStatus BaseAgent::CoAttackTarget(int target_id)
|
|
{
|
|
if (status_ == behaviac::BT_RUNNING) {
|
|
return DoRunningCb();
|
|
}
|
|
Entity* entity = GetOwner()->room->GetEntityByUniId(target_id);
|
|
if (!entity || !entity->IsCreature(GetOwner()->room)) {
|
|
return behaviac::BT_FAILURE;
|
|
}
|
|
CreatureWeakPtr target = ((Creature*)entity)->GetWeakPtrRef();
|
|
if (target.Get()->dead) {
|
|
return behaviac::BT_FAILURE;
|
|
}
|
|
|
|
long long frameno = GetOwner()->room->GetFrameNo();
|
|
long long last_pursuit_frameno = GetOwner()->room->GetFrameNo();
|
|
return StartCoroutine
|
|
(
|
|
[this, target, frameno, last_pursuit_frameno] () mutable
|
|
{
|
|
if (GetOwner()->room->GetFrameNo() - frameno > SERVER_FRAME_RATE * 10 ||
|
|
!target.Get() || target.Get()->dead) {
|
|
return behaviac::BT_SUCCESS;
|
|
} else {
|
|
a8::Vec2 dir = target.Get()->GetPos() - GetOwner()->GetPos();
|
|
if (dir.Norm() <= 1.0f) {
|
|
GetOwner()->GetMoveHelper()->CalcTargetPos(60);
|
|
last_pursuit_frameno = GetOwner()->room->GetFrameNo();
|
|
} else {
|
|
bool is_shot = false;
|
|
if (dir.Norm() > 300) {
|
|
if (GetOwner()->GetMoveHelper()->GetPathSize() < 1) {
|
|
dir.Normalize();
|
|
GetOwner()->SetMoveDir(dir);
|
|
GetOwner()->SetAttackDir(dir);
|
|
GetOwner()->GetMoveHelper()->CalcTargetPos(200);
|
|
last_pursuit_frameno = GetOwner()->room->GetFrameNo();
|
|
} else {
|
|
if (GetOwner()->room->GetFrameNo() - last_pursuit_frameno > SERVER_FRAME_RATE * 1) {
|
|
dir.Normalize();
|
|
GetOwner()->SetMoveDir(dir);
|
|
GetOwner()->SetAttackDir(dir);
|
|
GetOwner()->GetMoveHelper()->CalcTargetPos(200);
|
|
last_pursuit_frameno = GetOwner()->room->GetFrameNo();
|
|
}
|
|
}
|
|
} else {
|
|
dir.Normalize();
|
|
is_shot = true;
|
|
}
|
|
if (is_shot) {
|
|
bool shot_ok = false;
|
|
a8::Vec2 shot_dir = dir;
|
|
GetOwner()->SetAttackDir(dir);
|
|
GetOwner()->Shot(shot_dir, shot_ok, 0, 0);
|
|
}
|
|
}
|
|
}
|
|
return behaviac::BT_RUNNING;
|
|
},
|
|
"CoAttackTarget"
|
|
);
|
|
}
|