583 lines
20 KiB
C++
583 lines
20 KiB
C++
#include "precompile.h"
|
|
|
|
#include <a8/holder.h>
|
|
|
|
#include "hero_agent.h"
|
|
#include "hero.h"
|
|
#include "room.h"
|
|
#include "movement.h"
|
|
#include "trigger.h"
|
|
#include "glmhelper.h"
|
|
#include "mapinstance.h"
|
|
#include "human.h"
|
|
|
|
#include "mt/Map.h"
|
|
|
|
HeroAgent::HeroAgent():BaseAgent()
|
|
{
|
|
|
|
}
|
|
|
|
HeroAgent::~HeroAgent()
|
|
{
|
|
}
|
|
|
|
behaviac::EBTStatus HeroAgent::DoRandomWalk()
|
|
{
|
|
if (status_ == behaviac::BT_RUNNING) {
|
|
return DoRunningCb();
|
|
}
|
|
|
|
glm::vec3 dir = GetOwner()->GetMoveDir();
|
|
GlmHelper::RotateY(dir, (10 + rand() % 360)/ 180.0f);
|
|
GlmHelper::Normalize(dir);
|
|
GetOwner()->SetMoveDir(dir);
|
|
GetOwner()->SetAttackDir(dir);
|
|
GetOwner()->GetMovement()->CalcTargetPos(200);
|
|
if (GetOwner()->GetMovement()->GetPathSize() <= 0) {
|
|
return behaviac::BT_FAILURE;
|
|
}
|
|
|
|
auto context = A8_MAKE_SMART_ANON_STRUCT_SHARED
|
|
(
|
|
CreatureWeakPtr owner;
|
|
CreatureWeakPtr last_attacker;
|
|
long long last_attacked_frameno = 0;
|
|
std::weak_ptr<EventHandlerPtr> handler;
|
|
);
|
|
|
|
context->owner = GetOwner()->GetWeakPtrRef();
|
|
context->handler = GetOwner()->GetTrigger()->AddListener
|
|
(
|
|
kAttacked,
|
|
[context_wp = context->GetWp()] (const a8::Args& args)
|
|
{
|
|
if (!context_wp.expired()) {
|
|
auto context = context_wp.lock();
|
|
Creature* c = args.Get<Creature*>(0);
|
|
context->last_attacker = c->GetWeakPtrRef();
|
|
context->last_attacked_frameno = c->room->GetFrameNo();
|
|
}
|
|
});
|
|
context->_destory_cb =
|
|
(
|
|
[context = context.get()] ()
|
|
{
|
|
if (context->owner.Get()) {
|
|
context->owner.Get()->GetTrigger()->RemoveEventHandler(context->handler);
|
|
}
|
|
});
|
|
|
|
auto co = std::make_shared<BtCoroutine>(context, "CoRandomWalk");
|
|
co->runing_cb =
|
|
[this, context] ()
|
|
{
|
|
if (GetOwner()->GetMovement()->GetPathSize() <= 0) {
|
|
return behaviac::BT_SUCCESS;
|
|
} else {
|
|
return behaviac::BT_RUNNING;
|
|
}
|
|
};
|
|
co->event_cb =
|
|
[this, context]
|
|
(bool is_test, bool& has_event) mutable
|
|
{
|
|
has_event = context->last_attacker.Get() && !context->last_attacker.Get()->dead ? true : false;
|
|
if (!is_test && has_event) {
|
|
FireEvent("OnAttacked",
|
|
context->last_attacker.Get()->GetUniId(),
|
|
context->last_attacked_frameno);
|
|
}
|
|
};
|
|
|
|
return StartCoroutine(co);
|
|
}
|
|
|
|
behaviac::EBTStatus HeroAgent::DoRandomShot()
|
|
{
|
|
if (status_ == behaviac::BT_RUNNING) {
|
|
return DoRunningCb();
|
|
}
|
|
|
|
glm::vec3 dir = GetOwner()->GetMoveDir();
|
|
GlmHelper::RotateY(dir, (10 + rand() % 360)/ 180.0f);
|
|
GlmHelper::Normalize(dir);
|
|
GetOwner()->SetMoveDir(dir);
|
|
GetOwner()->SetAttackDir(dir);
|
|
bool shot_ok = false;
|
|
glm::vec3 shot_dir = dir;
|
|
GetOwner()->Shot(shot_dir, shot_ok, 0, 0);
|
|
|
|
auto context = A8_MAKE_SMART_ANON_STRUCT_SHARED
|
|
(
|
|
CreatureWeakPtr owner;
|
|
CreatureWeakPtr last_attacker;
|
|
long long last_attacked_frameno = 0;
|
|
long long last_frameno = 0;
|
|
std::weak_ptr<EventHandlerPtr> handler;
|
|
);
|
|
|
|
context->owner = GetOwner()->GetWeakPtrRef();
|
|
context->last_frameno = GetOwner()->room->GetFrameNo();
|
|
context->handler = GetOwner()->GetTrigger()->AddListener
|
|
(
|
|
kAttacked,
|
|
[context_wp = context->GetWp()] (const a8::Args& args)
|
|
{
|
|
if (!context_wp.expired()) {
|
|
auto context = context_wp.lock();
|
|
Creature* c = args.Get<Creature*>(0);
|
|
context->last_attacker = c->GetWeakPtrRef();
|
|
context->last_attacked_frameno = c->room->GetFrameNo();
|
|
}
|
|
});
|
|
context->_destory_cb =
|
|
(
|
|
[context = context.get()] ()
|
|
{
|
|
if (context->owner.Get()) {
|
|
context->owner.Get()->GetTrigger()->RemoveEventHandler(context->handler);
|
|
}
|
|
});
|
|
|
|
auto co = std::make_shared<BtCoroutine>(context, "CoRandomShot");
|
|
co->runing_cb =
|
|
[this, context] ()
|
|
{
|
|
if (GetOwner()->room->GetFrameNo() - context->last_frameno > SERVER_FRAME_RATE * 3) {
|
|
return behaviac::BT_SUCCESS;
|
|
} else {
|
|
bool shot_ok = false;
|
|
glm::vec3 shot_dir = GetOwner()->GetAttackDir();
|
|
GetOwner()->Shot(shot_dir, shot_ok, 0, 0);
|
|
|
|
return behaviac::BT_RUNNING;
|
|
}
|
|
};
|
|
co->event_cb =
|
|
[this, context]
|
|
(bool is_test, bool& has_event) mutable
|
|
{
|
|
has_event = context->last_attacker.Get() && !context->last_attacker.Get()->dead ? true : false;
|
|
if (!is_test && has_event) {
|
|
FireEvent("OnAttacked",
|
|
context->last_attacker.Get()->GetUniId(),
|
|
context->last_attacked_frameno);
|
|
}
|
|
};
|
|
return StartCoroutine(co);
|
|
}
|
|
|
|
behaviac::EBTStatus HeroAgent::DoAttack()
|
|
{
|
|
if (status_ == behaviac::BT_RUNNING) {
|
|
return DoRunningCb();
|
|
}
|
|
Creature* enemy = GetOwner()->room->FindEnemy(GetOwner(), 300);
|
|
if (!enemy) {
|
|
return behaviac::BT_FAILURE;
|
|
}
|
|
if (GlmHelper::IsEqual2D(GetOwner()->GetPos().ToGlmVec3(), enemy->GetPos().ToGlmVec3())) {
|
|
return behaviac::BT_FAILURE;
|
|
}
|
|
#if 0
|
|
enemy = ((Hero*)GetOwner())->master.Get();
|
|
#endif
|
|
|
|
glm::vec3 dir = GetOwner()->GetPos().CalcDir(enemy->GetPos());
|
|
GlmHelper::Normalize(dir);
|
|
GetOwner()->SetMoveDir(dir);
|
|
GetOwner()->SetAttackDir(dir);
|
|
bool shot_ok = false;
|
|
glm::vec3 shot_dir = dir;
|
|
if (bullet_trace_mode_) {
|
|
GetOwner()->Shot(shot_dir, shot_ok, 0, enemy->GetUniId());
|
|
} else {
|
|
GetOwner()->Shot(shot_dir, shot_ok, 0, 0);
|
|
}
|
|
|
|
auto context = A8_MAKE_SMART_ANON_STRUCT_SHARED
|
|
(
|
|
CreatureWeakPtr owner;
|
|
CreatureWeakPtr target;
|
|
long long last_frameno = 0;
|
|
CreatureWeakPtr last_attacker;
|
|
long long last_attacked_frameno = 0;
|
|
std::weak_ptr<EventHandlerPtr> handler;
|
|
);
|
|
|
|
context->owner = GetOwner()->GetWeakPtrRef();
|
|
context->target = enemy->GetWeakPtrRef();
|
|
context->last_frameno = GetOwner()->room->GetFrameNo();
|
|
|
|
if (GetOwner()->AsHero()->master.Get()) {
|
|
context->handler = GetOwner()->AsHero()->master.Get()->GetTrigger()->AddListener
|
|
(
|
|
kBulletHitEvent,
|
|
[context_wp = context->GetWp()] (const a8::Args& args)
|
|
{
|
|
if (!context_wp.expired()) {
|
|
auto context = context_wp.lock();
|
|
Creature* c = args.Get<Creature*>(1);
|
|
context->last_attacker = c->GetWeakPtrRef();
|
|
context->last_attacked_frameno = c->room->GetFrameNo();
|
|
}
|
|
});
|
|
}
|
|
context->_destory_cb =
|
|
(
|
|
[context = context.get()] ()
|
|
{
|
|
if (!context->handler.expired() && context->owner.Get()) {
|
|
if (context->owner.Get()->IsEntityType(ET_Hero)) {
|
|
Hero* hero = (Hero*)context->owner.Get();
|
|
if (hero->master.Get()) {
|
|
hero->master.Get()->GetTrigger()->RemoveEventHandler(context->handler);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
auto co = std::make_shared<BtCoroutine>(context, "CoAttack");
|
|
co->runing_cb =
|
|
[this, context] ()
|
|
{
|
|
if (GetOwner()->room->GetFrameNo() - context->last_frameno > SERVER_FRAME_RATE * 3) {
|
|
status_ = behaviac::BT_SUCCESS;
|
|
return behaviac::BT_SUCCESS;
|
|
} else {
|
|
if (!context->target.Get()) {
|
|
return behaviac::BT_SUCCESS;
|
|
}
|
|
if (context->target.Get()->dead) {
|
|
return behaviac::BT_SUCCESS;
|
|
}
|
|
if (GlmHelper::IsEqual2D(GetOwner()->GetPos().ToGlmVec3(),
|
|
context->target.Get()->GetPos().ToGlmVec3())) {
|
|
return behaviac::BT_FAILURE;
|
|
}
|
|
if (GetOwner()->dead) {
|
|
return behaviac::BT_FAILURE;
|
|
}
|
|
if (GetOwner()->CanShot(true)) {
|
|
bool shot_ok = false;
|
|
glm::vec3 shot_dir = GetOwner()->GetPos().CalcDir(context->target.Get()->GetPos());;
|
|
GlmHelper::Normalize(shot_dir);
|
|
GetOwner()->SetAttackDir(shot_dir);
|
|
if (bullet_trace_mode_) {
|
|
GetOwner()->Shot(shot_dir, shot_ok, 0, context->target.Get()->GetUniId());
|
|
} else {
|
|
GetOwner()->Shot(shot_dir, shot_ok, 0, context->target.Get()->GetUniId());
|
|
}
|
|
}
|
|
return behaviac::BT_RUNNING;
|
|
}
|
|
};
|
|
co->event_cb =
|
|
[this, context]
|
|
(bool is_test, bool& has_event) mutable
|
|
{
|
|
has_event = context->last_attacker.Get() && !context->last_attacker.Get()->dead ? true : false;
|
|
if (!is_test && has_event) {
|
|
FireEvent("OnMasterAttackTarget", context->last_attacker.Get()->GetUniId());
|
|
}
|
|
};
|
|
return StartCoroutine(co);
|
|
}
|
|
|
|
behaviac::EBTStatus HeroAgent::DoPursuit()
|
|
{
|
|
if (status_ == behaviac::BT_RUNNING) {
|
|
return DoRunningCb();
|
|
}
|
|
Creature* enemy = GetOwner()->room->FindEnemy(GetOwner(), 500);
|
|
if (!enemy) {
|
|
return behaviac::BT_FAILURE;
|
|
}
|
|
|
|
auto context = A8_MAKE_SMART_ANON_STRUCT_SHARED
|
|
(
|
|
CreatureWeakPtr owner;
|
|
CreatureWeakPtr target;
|
|
long long last_frameno = 0;
|
|
long long last_pursuit_frameno = 0;
|
|
);
|
|
|
|
context->owner = GetOwner()->GetWeakPtrRef();
|
|
context->target = enemy->GetWeakPtrRef();
|
|
context->last_frameno = GetOwner()->room->GetFrameNo();
|
|
context->last_pursuit_frameno = GetOwner()->room->GetFrameNo();
|
|
|
|
auto co = std::make_shared<BtCoroutine>(context, "CoPursuit");
|
|
co->runing_cb =
|
|
[this, context] ()
|
|
{
|
|
if (GetOwner()->room->GetFrameNo() - context->last_frameno > SERVER_FRAME_RATE * 10 ||
|
|
!context->target.Get() || context->target.Get()->dead) {
|
|
status_ = behaviac::BT_SUCCESS;
|
|
return behaviac::BT_SUCCESS;
|
|
} else {
|
|
glm::vec3 dir = GetOwner()->GetPos().CalcDir(context->target.Get()->GetPos());
|
|
if (GlmHelper::Norm(dir) <= 1.0f) {
|
|
GetOwner()->GetMovement()->CalcTargetPos(60);
|
|
context->last_pursuit_frameno = GetOwner()->room->GetFrameNo();
|
|
} else {
|
|
bool is_shot = false;
|
|
if (GlmHelper::Norm(dir) > 300) {
|
|
if (GetOwner()->GetMovement()->GetPathSize() < 1) {
|
|
GlmHelper::Normalize(dir);
|
|
GetOwner()->SetMoveDir(dir);
|
|
GetOwner()->SetAttackDir(dir);
|
|
GetOwner()->GetMovement()->CalcTargetPos(200);
|
|
context->last_pursuit_frameno = GetOwner()->room->GetFrameNo();
|
|
} else {
|
|
if (GetOwner()->room->GetFrameNo() - context->last_pursuit_frameno > SERVER_FRAME_RATE * 1) {
|
|
GlmHelper::Normalize(dir);
|
|
GetOwner()->SetMoveDir(dir);
|
|
GetOwner()->SetAttackDir(dir);
|
|
GetOwner()->GetMovement()->CalcTargetPos(200);
|
|
context->last_pursuit_frameno = GetOwner()->room->GetFrameNo();
|
|
}
|
|
}
|
|
} else {
|
|
GlmHelper::Normalize(dir);
|
|
is_shot = true;
|
|
}
|
|
if (is_shot) {
|
|
bool shot_ok = false;
|
|
glm::vec3 shot_dir = dir;
|
|
GetOwner()->SetAttackDir(dir);
|
|
GetOwner()->Shot(shot_dir, shot_ok, 0, 0);
|
|
}
|
|
}
|
|
return behaviac::BT_RUNNING;
|
|
}
|
|
};
|
|
co->event_cb =
|
|
[this, context]
|
|
(bool is_test, bool& has_event) mutable
|
|
{
|
|
};
|
|
return StartCoroutine(co);
|
|
}
|
|
|
|
behaviac::EBTStatus HeroAgent::DoHelpAttack(int target_uniid)
|
|
{
|
|
if (status_ == behaviac::BT_RUNNING) {
|
|
return DoRunningCb();
|
|
}
|
|
Creature* enemy = GetOwner()->room->GetCreatureByUniId(target_uniid);
|
|
if (!enemy) {
|
|
return behaviac::BT_FAILURE;
|
|
}
|
|
if (enemy->dead) {
|
|
return behaviac::BT_FAILURE;
|
|
}
|
|
if (GlmHelper::IsEqual2D(GetOwner()->GetPos().ToGlmVec3(), enemy->GetPos().ToGlmVec3())) {
|
|
return behaviac::BT_FAILURE;
|
|
}
|
|
float distance = enemy->GetPos().Distance2D2(GetOwner()->GetPos());
|
|
if (distance > GetAttackRange()) {
|
|
return behaviac::BT_FAILURE;
|
|
}
|
|
glm::vec3 dir = GetOwner()->GetPos().CalcDir(enemy->GetPos());
|
|
GlmHelper::Normalize(dir);
|
|
GetOwner()->SetMoveDir(dir);
|
|
GetOwner()->SetAttackDir(dir);
|
|
bool shot_ok = false;
|
|
glm::vec3 shot_dir = dir;
|
|
if (bullet_trace_mode_) {
|
|
GetOwner()->Shot(shot_dir, shot_ok, 0, enemy->GetUniId());
|
|
} else {
|
|
GetOwner()->Shot(shot_dir, shot_ok, 0, 0);
|
|
}
|
|
|
|
auto context = A8_MAKE_SMART_ANON_STRUCT_SHARED
|
|
(
|
|
CreatureWeakPtr target;
|
|
long long last_frameno = 0;
|
|
);
|
|
|
|
context->target = enemy->GetWeakPtrRef();
|
|
context->last_frameno = GetOwner()->room->GetFrameNo();
|
|
|
|
auto co = std::make_shared<BtCoroutine>(context, "CoHelpAttack");
|
|
co->runing_cb =
|
|
[this, context] ()
|
|
{
|
|
if (GetOwner()->room->GetFrameNo() - context->last_frameno > SERVER_FRAME_RATE * 3) {
|
|
status_ = behaviac::BT_SUCCESS;
|
|
return behaviac::BT_SUCCESS;
|
|
} else {
|
|
if (!context->target.Get()) {
|
|
return behaviac::BT_SUCCESS;
|
|
}
|
|
if (context->target.Get()->dead) {
|
|
return behaviac::BT_SUCCESS;
|
|
}
|
|
if (GlmHelper::IsEqual2D(GetOwner()->GetPos().ToGlmVec3(),
|
|
context->target.Get()->GetPos().ToGlmVec3())) {
|
|
return behaviac::BT_FAILURE;
|
|
}
|
|
float distance = context->target.Get()->GetPos().Distance2D2(GetOwner()->GetPos());
|
|
if (distance > GetAttackRange()) {
|
|
return behaviac::BT_FAILURE;
|
|
}
|
|
bool shot_ok = false;
|
|
glm::vec3 shot_dir = GetOwner()->GetPos().CalcDir(context->target.Get()->GetPos());;
|
|
GlmHelper::Normalize(shot_dir);
|
|
GetOwner()->SetAttackDir(shot_dir);
|
|
if (bullet_trace_mode_) {
|
|
GetOwner()->Shot(shot_dir, shot_ok, 0, context->target.Get()->GetUniId());
|
|
} else {
|
|
GetOwner()->Shot(shot_dir, shot_ok, 0, 0);
|
|
}
|
|
|
|
return behaviac::BT_RUNNING;
|
|
}
|
|
};
|
|
co->event_cb =
|
|
[this, context]
|
|
(bool is_test, bool& has_event) mutable
|
|
{
|
|
};
|
|
return StartCoroutine(co);
|
|
}
|
|
|
|
behaviac::EBTStatus HeroAgent::DoFlyToMasterAround()
|
|
{
|
|
if (!GetOwner()->AsHero()->master.Get()) {
|
|
return behaviac::BT_FAILURE;
|
|
}
|
|
glm::vec3 point;
|
|
#if 1
|
|
glm::vec3 move_dir = GlmHelper::UP;
|
|
GlmHelper::RotateY(move_dir, a8::RandAngle());
|
|
float move_distance = 30 + rand() % 20;
|
|
|
|
glm::vec3 start = GetOwner()->AsHero()->master.Get()->GetPos().ToGlmVec3();
|
|
glm::vec3 end = start + move_dir * move_distance;
|
|
GetOwner()->room->map_instance->Scale(start);
|
|
GetOwner()->room->map_instance->Scale(end);
|
|
|
|
glm::vec3 hit_point = glm::vec3(0.0f, 0.0f, 0.0f);
|
|
bool hit_result = false;
|
|
bool ret = GetOwner()->room->map_instance->Raycast
|
|
(
|
|
start,
|
|
end,
|
|
hit_point,
|
|
hit_result);
|
|
if (ret) {
|
|
GetOwner()->room->map_instance->UnScale(hit_point);
|
|
point = hit_point;
|
|
} else {
|
|
point = GetOwner()->AsHero()->master.Get()->GetPos().ToGlmVec3();
|
|
}
|
|
#else
|
|
glm::vec3 ref_point = GetOwner()->AsHero()->master.Get()->GetPos().ToGlmVec3();
|
|
glm::vec3 point = GetOwner()->AsHero()->master.Get()->GetPos().ToGlmVec3();
|
|
GetOwner()->room->map_instance->Scale(ref_point);
|
|
if (GetOwner()->room->map_instance->FindRandomPointAroundCircle
|
|
(
|
|
ref_point,
|
|
0.21 * GetOwner()->room->GetMapMeta()->scale(),
|
|
point
|
|
)) {
|
|
GetOwner()->room->map_instance->UnScale(point);
|
|
#ifdef DEBUG
|
|
a8::XPrintf("DoFlyToMasteraround1: %f,%f,%f %f,%f,%f distance:%f\n",
|
|
{point.x,
|
|
point.y,
|
|
point.z,
|
|
GetOwner()->GetPos().GetX(),
|
|
GetOwner()->GetPos().GetY(),
|
|
GetOwner()->GetPos().GetZ(),
|
|
GlmHelper::Norm(GetOwner()->GetPos().ToGlmVec3() - point)
|
|
});
|
|
#endif
|
|
} else {
|
|
point = GetOwner()->AsHero()->master.Get()->GetPos().ToGlmVec3();
|
|
#ifdef DEBUG
|
|
a8::XPrintf("DoFlyToMasteraround2: %f,%f,%f %f,%f,%f distance:%f\n",
|
|
{point.x,
|
|
point.y,
|
|
point.z,
|
|
GetOwner()->GetPos().GetX(),
|
|
GetOwner()->GetPos().GetY(),
|
|
GetOwner()->GetPos().GetZ(),
|
|
GlmHelper::Norm(GetOwner()->GetPos().ToGlmVec3() - point)
|
|
});
|
|
#endif
|
|
}
|
|
#endif
|
|
Global::Instance()->verify_set_pos = 1;
|
|
GetOwner()->GetMutablePos().FromGlmVec3(point);
|
|
Global::Instance()->verify_set_pos = 0;
|
|
GetOwner()->GetMovement()->ClearPath();
|
|
GetOwner()->room->grid_service->MoveCreature(GetOwner());
|
|
GetOwner()->SetAttackDir(GetOwner()->AsHero()->master.Get()->GetAttackDir());
|
|
return behaviac::BT_SUCCESS;
|
|
}
|
|
|
|
behaviac::EBTStatus HeroAgent::DoFollowMaster()
|
|
{
|
|
if (status_ == behaviac::BT_RUNNING) {
|
|
return DoRunningCb();
|
|
}
|
|
if (GetOwner()->AsHero()->master.Get()->dead) {
|
|
return behaviac::BT_FAILURE;
|
|
}
|
|
|
|
auto context = A8_MAKE_SMART_ANON_STRUCT_SHARED
|
|
(
|
|
long long last_frameno = 0;
|
|
long long last_follow_frameno = 0;
|
|
);
|
|
|
|
context->last_frameno = GetOwner()->room->GetFrameNo();
|
|
context->last_follow_frameno = GetOwner()->room->GetFrameNo();
|
|
|
|
auto co = std::make_shared<BtCoroutine>(context, "CoFollowMaster");
|
|
co->runing_cb =
|
|
[this, context] ()
|
|
{
|
|
if (GetOwner()->room->GetFrameNo() - context->last_frameno > SERVER_FRAME_RATE * 10 ||
|
|
!GetOwner()->AsHero()->master.Get() || GetOwner()->AsHero()->master.Get()->dead) {
|
|
status_ = behaviac::BT_SUCCESS;
|
|
return behaviac::BT_SUCCESS;
|
|
} else {
|
|
if (GlmHelper::IsEqual2D(GetOwner()->GetPos().ToGlmVec3(),
|
|
GetOwner()->AsHero()->master.Get()->GetPos().ToGlmVec3())) {
|
|
return behaviac::BT_SUCCESS;
|
|
}
|
|
glm::vec3 dir = GetOwner()->GetPos().CalcDir(GetOwner()->AsHero()->master.Get()->GetPos());
|
|
if (GlmHelper::Norm(dir) < 60) {
|
|
return behaviac::BT_SUCCESS;
|
|
}
|
|
if (GlmHelper::Norm(dir) > 60) {
|
|
GlmHelper::Normalize(dir);
|
|
GetOwner()->SetMoveDir(dir);
|
|
GetOwner()->SetAttackDir(dir);
|
|
GetOwner()->GetMovement()->CalcTargetPos(60);
|
|
context->last_follow_frameno = GetOwner()->room->GetFrameNo();
|
|
}
|
|
return behaviac::BT_RUNNING;
|
|
}
|
|
};
|
|
co->event_cb =
|
|
[this, context]
|
|
(bool is_test, bool& has_event) mutable
|
|
{
|
|
};
|
|
return StartCoroutine(co);
|
|
}
|
|
|
|
float HeroAgent::GetMasterDistance()
|
|
{
|
|
if (!GetOwner()->AsHero()->master.Get()) {
|
|
return 0.0f;
|
|
}
|
|
return GetOwner()->GetPos().Distance2D2(GetOwner()->AsHero()->master.Get()->GetPos());
|
|
}
|