1
This commit is contained in:
parent
e5f524d1c8
commit
1ecf5ad0c4
@ -81,6 +81,18 @@ aux_source_directory(buff
|
||||
SRC_LIST
|
||||
)
|
||||
|
||||
aux_source_directory(ai/base
|
||||
SRC_LIST
|
||||
)
|
||||
|
||||
aux_source_directory(ai/hero
|
||||
SRC_LIST
|
||||
)
|
||||
|
||||
aux_source_directory(ai/android
|
||||
SRC_LIST
|
||||
)
|
||||
|
||||
execute_process(
|
||||
COMMAND touch -a cs_proto.pb.h
|
||||
COMMAND touch -a cs_proto.pb.cc
|
||||
|
112
server/gameserver/ai/base/co_attack_target.cc
Normal file
112
server/gameserver/ai/base/co_attack_target.cc
Normal file
@ -0,0 +1,112 @@
|
||||
#include "precompile.h"
|
||||
|
||||
#include "base_agent.h"
|
||||
#include "creature.h"
|
||||
#include "room.h"
|
||||
#include "glmhelper.h"
|
||||
#include "movement.h"
|
||||
|
||||
#include "btcontext.h"
|
||||
#include "btevent.h"
|
||||
#include "btcoroutine.h"
|
||||
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
auto context = MAKE_BTCONTEXT
|
||||
(
|
||||
CreatureWeakPtr target;
|
||||
long long frameno = 0;
|
||||
long long last_pursuit_frameno = 0;
|
||||
);
|
||||
context->target = target;
|
||||
context->frameno = GetOwner()->room->GetFrameNo();
|
||||
context->last_pursuit_frameno = GetOwner()->room->GetFrameNo();
|
||||
|
||||
auto co = std::make_shared<BtCoroutine>(context, "CoAttackTarget");
|
||||
co->runing_cb =
|
||||
[this, context] ()
|
||||
{
|
||||
if (GetOwner()->room->GetFrameNo() - context->frameno > SERVER_FRAME_RATE * 10 ||
|
||||
!context->target.Get() || context->target.Get()->dead) {
|
||||
GetOwner()->shot_hold = false;
|
||||
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 use_skill_ok = false;
|
||||
if (context->target.Get() &&
|
||||
!context->target.Get()->dead) {
|
||||
int skill_id = GetUseableSkill(context->target.Get());
|
||||
if (skill_id >= 0) {
|
||||
GetOwner()->shot_hold = false;
|
||||
int wait_time = 0;
|
||||
use_skill_ok = InternalUseSkill(skill_id, context->target, wait_time);
|
||||
if (use_skill_ok) {
|
||||
Sleep(wait_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG1
|
||||
if (context->target.Get()->IsPlayer()) {
|
||||
a8::XPrintf("DoAttack %d use_skill_ok:%d time:%d\n",
|
||||
{GetOwner()->GetUniId(),
|
||||
use_skill_ok ? 1 : 0,
|
||||
GetOwner()->GetMainSkill() ? GetOwner()->GetMainSkill()->GetLeftTime() : 0
|
||||
});
|
||||
}
|
||||
#endif
|
||||
if (!use_skill_ok) {
|
||||
bool shot_ok = false;
|
||||
glm::vec3 shot_dir = dir;
|
||||
GetOwner()->SetAttackDir(dir);
|
||||
GetOwner()->shot_hold = true;
|
||||
GetOwner()->Shot(shot_dir, shot_ok, 0, 0);
|
||||
}
|
||||
} else {
|
||||
GetOwner()->shot_hold = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return behaviac::BT_RUNNING;
|
||||
};
|
||||
return StartCoroutine(co);
|
||||
}
|
72
server/gameserver/ai/base/doidle.cc
Normal file
72
server/gameserver/ai/base/doidle.cc
Normal file
@ -0,0 +1,72 @@
|
||||
#include "precompile.h"
|
||||
|
||||
#include "base_agent.h"
|
||||
#include "creature.h"
|
||||
#include "room.h"
|
||||
#include "glmhelper.h"
|
||||
#include "movement.h"
|
||||
#include "trigger.h"
|
||||
#include "btcontext.h"
|
||||
#include "btevent.h"
|
||||
#include "btcoroutine.h"
|
||||
|
||||
behaviac::EBTStatus BaseAgent::DoIdle(int min_time, int max_time)
|
||||
{
|
||||
if (status_ == behaviac::BT_RUNNING) {
|
||||
return DoRunningCb();
|
||||
}
|
||||
if (a8::HasBitFlag(GetOwner()->status, CS_DisableAttackAndroid)) {
|
||||
return behaviac::BT_FAILURE;
|
||||
}
|
||||
|
||||
auto context = MAKE_BTCONTEXT
|
||||
(
|
||||
a8::XTimerWp timer_ptr;
|
||||
);
|
||||
context->timer_ptr = GetOwner()->room->xtimer.SetTimeoutWpEx
|
||||
(
|
||||
a8::RandEx(min_time, max_time) / FRAME_RATE_MS,
|
||||
[] (int event, const a8::Args* args)
|
||||
{
|
||||
},
|
||||
&GetOwner()->xtimer_attacher);
|
||||
context->AddHandler
|
||||
(
|
||||
GetOwner()->GetWeakPtrRef(),
|
||||
GetOwner()->GetTrigger()->AddListener
|
||||
(
|
||||
kAttacked,
|
||||
[context_wp = a8::SpToWp(context)] (const a8::Args& args)
|
||||
{
|
||||
if (!context_wp.expired()) {
|
||||
auto context = context_wp.lock();
|
||||
Creature* c = args.Get<Creature*>(0);
|
||||
context->events.push_back
|
||||
(
|
||||
BtEvent::Create
|
||||
(
|
||||
kBetOnAttack,
|
||||
a8::Args({
|
||||
c->GetUniId(),
|
||||
c->room->GetFrameNo()
|
||||
}),
|
||||
[c_wp = c->GetWeakPtrRef(), frameno = c->room->GetFrameNo()] () mutable
|
||||
{
|
||||
return c_wp.Get() && !c_wp.Get()->dead;
|
||||
})
|
||||
);
|
||||
}
|
||||
}));
|
||||
|
||||
auto co = std::make_shared<BtCoroutine>(context, "CoIdle");
|
||||
co->runing_cb =
|
||||
[this, context] ()
|
||||
{
|
||||
if (!context->timer_ptr.expired()) {
|
||||
return behaviac::BT_RUNNING;
|
||||
} else {
|
||||
return behaviac::BT_SUCCESS;
|
||||
}
|
||||
};
|
||||
return StartCoroutine(co);
|
||||
}
|
16
server/gameserver/ai/base/douseskill.cc
Normal file
16
server/gameserver/ai/base/douseskill.cc
Normal file
@ -0,0 +1,16 @@
|
||||
#include "precompile.h"
|
||||
|
||||
#include "base_agent.h"
|
||||
#include "creature.h"
|
||||
#include "room.h"
|
||||
#include "glmhelper.h"
|
||||
#include "movement.h"
|
||||
#include "trigger.h"
|
||||
#include "btcontext.h"
|
||||
#include "btevent.h"
|
||||
#include "btcoroutine.h"
|
||||
|
||||
behaviac::EBTStatus BaseAgent::DoUseSkill(int skill_id)
|
||||
{
|
||||
return behaviac::BT_SUCCESS;
|
||||
}
|
116
server/gameserver/ai/hero/do_attack.cc
Normal file
116
server/gameserver/ai/hero/do_attack.cc
Normal file
@ -0,0 +1,116 @@
|
||||
#include "precompile.h"
|
||||
|
||||
#include "hero_agent.h"
|
||||
#include "creature.h"
|
||||
#include "room.h"
|
||||
#include "glmhelper.h"
|
||||
#include "movement.h"
|
||||
#include "trigger.h"
|
||||
#include "btcontext.h"
|
||||
#include "btevent.h"
|
||||
#include "btcoroutine.h"
|
||||
#include "hero.h"
|
||||
|
||||
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 = MAKE_BTCONTEXT
|
||||
(
|
||||
CreatureWeakPtr target;
|
||||
long long last_frameno = 0;
|
||||
);
|
||||
|
||||
context->target = enemy->GetWeakPtrRef();
|
||||
context->last_frameno = GetOwner()->room->GetFrameNo();
|
||||
|
||||
if (GetOwner()->AsHero()->master.Get()) {
|
||||
context->AddHandler
|
||||
(GetOwner()->AsHero()->master,
|
||||
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*>(0);
|
||||
context->events.push_back
|
||||
(
|
||||
BtEvent::Create
|
||||
(
|
||||
kBetOnAttack,
|
||||
a8::Args({
|
||||
c->GetUniId(),
|
||||
c->room->GetFrameNo()
|
||||
}),
|
||||
[c_wp = c->GetWeakPtrRef(), frameno = c->room->GetFrameNo()] () mutable
|
||||
{
|
||||
return c_wp.Get() && !c_wp.Get()->dead;
|
||||
})
|
||||
);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
return StartCoroutine(co);
|
||||
}
|
89
server/gameserver/ai/hero/do_flyto_master_around.cc
Normal file
89
server/gameserver/ai/hero/do_flyto_master_around.cc
Normal file
@ -0,0 +1,89 @@
|
||||
#include "precompile.h"
|
||||
|
||||
#include "hero_agent.h"
|
||||
#include "creature.h"
|
||||
#include "room.h"
|
||||
#include "glmhelper.h"
|
||||
#include "movement.h"
|
||||
#include "trigger.h"
|
||||
#include "btcontext.h"
|
||||
#include "btevent.h"
|
||||
#include "btcoroutine.h"
|
||||
#include "mapinstance.h"
|
||||
#include "hero.h"
|
||||
|
||||
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;
|
||||
}
|
60
server/gameserver/ai/hero/do_follow_master.cc
Normal file
60
server/gameserver/ai/hero/do_follow_master.cc
Normal file
@ -0,0 +1,60 @@
|
||||
#include "precompile.h"
|
||||
|
||||
#include "hero_agent.h"
|
||||
#include "creature.h"
|
||||
#include "room.h"
|
||||
#include "glmhelper.h"
|
||||
#include "movement.h"
|
||||
#include "trigger.h"
|
||||
#include "btcontext.h"
|
||||
#include "btevent.h"
|
||||
#include "btcoroutine.h"
|
||||
#include "hero.h"
|
||||
|
||||
behaviac::EBTStatus HeroAgent::DoFollowMaster()
|
||||
{
|
||||
if (status_ == behaviac::BT_RUNNING) {
|
||||
return DoRunningCb();
|
||||
}
|
||||
if (GetOwner()->AsHero()->master.Get()->dead) {
|
||||
return behaviac::BT_FAILURE;
|
||||
}
|
||||
|
||||
auto context = MAKE_BTCONTEXT
|
||||
(
|
||||
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;
|
||||
}
|
||||
};
|
||||
return StartCoroutine(co);
|
||||
}
|
90
server/gameserver/ai/hero/do_help_attack.cc
Normal file
90
server/gameserver/ai/hero/do_help_attack.cc
Normal file
@ -0,0 +1,90 @@
|
||||
#include "precompile.h"
|
||||
|
||||
#include "hero_agent.h"
|
||||
#include "creature.h"
|
||||
#include "room.h"
|
||||
#include "glmhelper.h"
|
||||
#include "movement.h"
|
||||
#include "trigger.h"
|
||||
#include "btcontext.h"
|
||||
#include "btevent.h"
|
||||
#include "btcoroutine.h"
|
||||
|
||||
|
||||
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 = MAKE_BTCONTEXT
|
||||
(
|
||||
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;
|
||||
}
|
||||
};
|
||||
return StartCoroutine(co);
|
||||
}
|
109
server/gameserver/ai/hero/do_pursuit.cc
Normal file
109
server/gameserver/ai/hero/do_pursuit.cc
Normal file
@ -0,0 +1,109 @@
|
||||
#include "precompile.h"
|
||||
|
||||
#include "hero_agent.h"
|
||||
#include "creature.h"
|
||||
#include "room.h"
|
||||
#include "glmhelper.h"
|
||||
#include "movement.h"
|
||||
#include "trigger.h"
|
||||
#include "btcontext.h"
|
||||
#include "btevent.h"
|
||||
#include "btcoroutine.h"
|
||||
|
||||
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 = MAKE_BTCONTEXT
|
||||
(
|
||||
CreatureWeakPtr target;
|
||||
long long last_frameno = 0;
|
||||
long long last_pursuit_frameno = 0;
|
||||
);
|
||||
|
||||
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 use_skill_ok = false;
|
||||
if (context->target.Get() &&
|
||||
!context->target.Get()->dead) {
|
||||
int skill_id = GetUseableSkill(context->target.Get());
|
||||
if (skill_id >= 0) {
|
||||
GetOwner()->shot_hold = false;
|
||||
int wait_time = 0;
|
||||
use_skill_ok = InternalUseSkill(skill_id, context->target, wait_time);
|
||||
if (use_skill_ok) {
|
||||
Sleep(wait_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG1
|
||||
if (context->target.Get()->IsPlayer()) {
|
||||
a8::XPrintf("DoPursuit %d use_skill_ok:%d time:%d\n",
|
||||
{GetOwner()->GetUniId(),
|
||||
use_skill_ok ? 1 : 0,
|
||||
GetOwner()->GetMainSkill() ? GetOwner()->GetMainSkill()->GetLeftTime() : 0
|
||||
});
|
||||
}
|
||||
#endif
|
||||
if (!use_skill_ok) {
|
||||
bool shot_ok = false;
|
||||
glm::vec3 shot_dir = dir;
|
||||
GetOwner()->shot_hold = true;
|
||||
GetOwner()->SetAttackDir(shot_dir);
|
||||
#if 0
|
||||
GetOwner()->Shot(AdjustShotDir(shot_dir), shot_ok, 0, 0);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
GetOwner()->shot_hold = false;
|
||||
}
|
||||
}
|
||||
return behaviac::BT_RUNNING;
|
||||
}
|
||||
};
|
||||
return StartCoroutine(co);
|
||||
}
|
77
server/gameserver/ai/hero/do_random_shot.cc
Normal file
77
server/gameserver/ai/hero/do_random_shot.cc
Normal file
@ -0,0 +1,77 @@
|
||||
#include "precompile.h"
|
||||
|
||||
#include "hero_agent.h"
|
||||
#include "creature.h"
|
||||
#include "room.h"
|
||||
#include "glmhelper.h"
|
||||
#include "movement.h"
|
||||
#include "trigger.h"
|
||||
#include "btcontext.h"
|
||||
#include "btevent.h"
|
||||
#include "btcoroutine.h"
|
||||
|
||||
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 = MAKE_BTCONTEXT
|
||||
(
|
||||
long long last_frameno = 0;
|
||||
std::weak_ptr<EventHandlerPtr> handler;
|
||||
);
|
||||
|
||||
context->last_frameno = GetOwner()->room->GetFrameNo();
|
||||
context->AddHandler
|
||||
(GetOwner()->GetWeakPtrRef(),
|
||||
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->events.push_back
|
||||
(
|
||||
BtEvent::Create
|
||||
(
|
||||
kBetOnAttack,
|
||||
a8::Args({
|
||||
c->GetUniId(),
|
||||
c->room->GetFrameNo()
|
||||
}),
|
||||
[c_wp = c->GetWeakPtrRef(), frameno = c->room->GetFrameNo()] () mutable
|
||||
{
|
||||
return c_wp.Get() && !c_wp.Get()->dead;
|
||||
})
|
||||
);
|
||||
}
|
||||
}));
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
return StartCoroutine(co);
|
||||
}
|
72
server/gameserver/ai/hero/do_random_walk.cc
Normal file
72
server/gameserver/ai/hero/do_random_walk.cc
Normal file
@ -0,0 +1,72 @@
|
||||
#include "precompile.h"
|
||||
|
||||
#include "hero_agent.h"
|
||||
#include "creature.h"
|
||||
#include "room.h"
|
||||
#include "glmhelper.h"
|
||||
#include "movement.h"
|
||||
#include "trigger.h"
|
||||
#include "btcontext.h"
|
||||
#include "btevent.h"
|
||||
#include "btcoroutine.h"
|
||||
|
||||
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 = MAKE_BTCONTEXT
|
||||
(
|
||||
);
|
||||
|
||||
context->AddHandler
|
||||
(
|
||||
GetOwner()->GetWeakPtrRef(),
|
||||
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->events.push_back
|
||||
(
|
||||
BtEvent::Create
|
||||
(
|
||||
kBetOnAttack,
|
||||
a8::Args({
|
||||
c->GetUniId(),
|
||||
c->room->GetFrameNo()
|
||||
}),
|
||||
[c_wp = c->GetWeakPtrRef(), frameno = c->room->GetFrameNo()] () mutable
|
||||
{
|
||||
return c_wp.Get() && !c_wp.Get()->dead;
|
||||
})
|
||||
);
|
||||
}
|
||||
}));
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
return StartCoroutine(co);
|
||||
}
|
@ -115,105 +115,6 @@ behaviac::EBTStatus BaseAgent::StartCoroutine(std::shared_ptr<BtCoroutine> corou
|
||||
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;
|
||||
}
|
||||
|
||||
auto context = MAKE_BTCONTEXT
|
||||
(
|
||||
CreatureWeakPtr target;
|
||||
long long frameno = 0;
|
||||
long long last_pursuit_frameno = 0;
|
||||
);
|
||||
context->target = target;
|
||||
context->frameno = GetOwner()->room->GetFrameNo();
|
||||
context->last_pursuit_frameno = GetOwner()->room->GetFrameNo();
|
||||
|
||||
auto co = std::make_shared<BtCoroutine>(context, "CoAttackTarget");
|
||||
co->runing_cb =
|
||||
[this, context] ()
|
||||
{
|
||||
if (GetOwner()->room->GetFrameNo() - context->frameno > SERVER_FRAME_RATE * 10 ||
|
||||
!context->target.Get() || context->target.Get()->dead) {
|
||||
GetOwner()->shot_hold = false;
|
||||
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 use_skill_ok = false;
|
||||
if (context->target.Get() &&
|
||||
!context->target.Get()->dead) {
|
||||
int skill_id = GetUseableSkill(context->target.Get());
|
||||
if (skill_id >= 0) {
|
||||
GetOwner()->shot_hold = false;
|
||||
int wait_time = 0;
|
||||
use_skill_ok = InternalUseSkill(skill_id, context->target, wait_time);
|
||||
if (use_skill_ok) {
|
||||
Sleep(wait_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG1
|
||||
if (context->target.Get()->IsPlayer()) {
|
||||
a8::XPrintf("DoAttack %d use_skill_ok:%d time:%d\n",
|
||||
{GetOwner()->GetUniId(),
|
||||
use_skill_ok ? 1 : 0,
|
||||
GetOwner()->GetMainSkill() ? GetOwner()->GetMainSkill()->GetLeftTime() : 0
|
||||
});
|
||||
}
|
||||
#endif
|
||||
if (!use_skill_ok) {
|
||||
bool shot_ok = false;
|
||||
glm::vec3 shot_dir = dir;
|
||||
GetOwner()->SetAttackDir(dir);
|
||||
GetOwner()->shot_hold = true;
|
||||
GetOwner()->Shot(shot_dir, shot_ok, 0, 0);
|
||||
}
|
||||
} else {
|
||||
GetOwner()->shot_hold = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return behaviac::BT_RUNNING;
|
||||
};
|
||||
return StartCoroutine(co);
|
||||
}
|
||||
|
||||
bool BaseAgent::HasBuffEffect(int buff_effect)
|
||||
{
|
||||
return owner_->HasBuffEffect(buff_effect);
|
||||
@ -232,67 +133,6 @@ void BaseAgent::SetBulletTraceMode(bool mode)
|
||||
bullet_trace_mode_ = mode;
|
||||
}
|
||||
|
||||
behaviac::EBTStatus BaseAgent::DoIdle(int min_time, int max_time)
|
||||
{
|
||||
if (status_ == behaviac::BT_RUNNING) {
|
||||
return DoRunningCb();
|
||||
}
|
||||
if (a8::HasBitFlag(GetOwner()->status, CS_DisableAttackAndroid)) {
|
||||
return behaviac::BT_FAILURE;
|
||||
}
|
||||
|
||||
auto context = MAKE_BTCONTEXT
|
||||
(
|
||||
a8::XTimerWp timer_ptr;
|
||||
);
|
||||
context->timer_ptr = GetOwner()->room->xtimer.SetTimeoutWpEx
|
||||
(
|
||||
a8::RandEx(min_time, max_time) / FRAME_RATE_MS,
|
||||
[] (int event, const a8::Args* args)
|
||||
{
|
||||
},
|
||||
&GetOwner()->xtimer_attacher);
|
||||
context->AddHandler
|
||||
(
|
||||
GetOwner()->GetWeakPtrRef(),
|
||||
GetOwner()->GetTrigger()->AddListener
|
||||
(
|
||||
kAttacked,
|
||||
[context_wp = a8::SpToWp(context)] (const a8::Args& args)
|
||||
{
|
||||
if (!context_wp.expired()) {
|
||||
auto context = context_wp.lock();
|
||||
Creature* c = args.Get<Creature*>(0);
|
||||
context->events.push_back
|
||||
(
|
||||
BtEvent::Create
|
||||
(
|
||||
kBetOnAttack,
|
||||
a8::Args({
|
||||
c->GetUniId(),
|
||||
c->room->GetFrameNo()
|
||||
}),
|
||||
[c_wp = c->GetWeakPtrRef(), frameno = c->room->GetFrameNo()] () mutable
|
||||
{
|
||||
return c_wp.Get() && !c_wp.Get()->dead;
|
||||
})
|
||||
);
|
||||
}
|
||||
}));
|
||||
|
||||
auto co = std::make_shared<BtCoroutine>(context, "CoIdle");
|
||||
co->runing_cb =
|
||||
[this, context] ()
|
||||
{
|
||||
if (!context->timer_ptr.expired()) {
|
||||
return behaviac::BT_RUNNING;
|
||||
} else {
|
||||
return behaviac::BT_SUCCESS;
|
||||
}
|
||||
};
|
||||
return StartCoroutine(co);
|
||||
}
|
||||
|
||||
bool BaseAgent::CanUseSkill(int skill_id)
|
||||
{
|
||||
return false;
|
||||
@ -338,11 +178,6 @@ int BaseAgent::GetUseableSkill(Creature* target)
|
||||
return -1;
|
||||
}
|
||||
|
||||
behaviac::EBTStatus BaseAgent::DoUseSkill(int skill_id)
|
||||
{
|
||||
return behaviac::BT_SUCCESS;
|
||||
}
|
||||
|
||||
bool BaseAgent::InternalUseSkill(int skill_id, CreatureWeakPtr target, int& wait_time)
|
||||
{
|
||||
if (GlmHelper::IsEqual2D(GetOwner()->GetPos().ToGlmVec3(),
|
||||
|
@ -27,537 +27,6 @@ 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 = MAKE_BTCONTEXT
|
||||
(
|
||||
);
|
||||
|
||||
context->AddHandler
|
||||
(
|
||||
GetOwner()->GetWeakPtrRef(),
|
||||
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->events.push_back
|
||||
(
|
||||
BtEvent::Create
|
||||
(
|
||||
kBetOnAttack,
|
||||
a8::Args({
|
||||
c->GetUniId(),
|
||||
c->room->GetFrameNo()
|
||||
}),
|
||||
[c_wp = c->GetWeakPtrRef(), frameno = c->room->GetFrameNo()] () mutable
|
||||
{
|
||||
return c_wp.Get() && !c_wp.Get()->dead;
|
||||
})
|
||||
);
|
||||
}
|
||||
}));
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
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 = MAKE_BTCONTEXT
|
||||
(
|
||||
long long last_frameno = 0;
|
||||
std::weak_ptr<EventHandlerPtr> handler;
|
||||
);
|
||||
|
||||
context->last_frameno = GetOwner()->room->GetFrameNo();
|
||||
context->AddHandler
|
||||
(GetOwner()->GetWeakPtrRef(),
|
||||
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->events.push_back
|
||||
(
|
||||
BtEvent::Create
|
||||
(
|
||||
kBetOnAttack,
|
||||
a8::Args({
|
||||
c->GetUniId(),
|
||||
c->room->GetFrameNo()
|
||||
}),
|
||||
[c_wp = c->GetWeakPtrRef(), frameno = c->room->GetFrameNo()] () mutable
|
||||
{
|
||||
return c_wp.Get() && !c_wp.Get()->dead;
|
||||
})
|
||||
);
|
||||
}
|
||||
}));
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
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 = MAKE_BTCONTEXT
|
||||
(
|
||||
CreatureWeakPtr target;
|
||||
long long last_frameno = 0;
|
||||
);
|
||||
|
||||
context->target = enemy->GetWeakPtrRef();
|
||||
context->last_frameno = GetOwner()->room->GetFrameNo();
|
||||
|
||||
if (GetOwner()->AsHero()->master.Get()) {
|
||||
context->AddHandler
|
||||
(GetOwner()->AsHero()->master,
|
||||
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*>(0);
|
||||
context->events.push_back
|
||||
(
|
||||
BtEvent::Create
|
||||
(
|
||||
kBetOnAttack,
|
||||
a8::Args({
|
||||
c->GetUniId(),
|
||||
c->room->GetFrameNo()
|
||||
}),
|
||||
[c_wp = c->GetWeakPtrRef(), frameno = c->room->GetFrameNo()] () mutable
|
||||
{
|
||||
return c_wp.Get() && !c_wp.Get()->dead;
|
||||
})
|
||||
);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
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 = MAKE_BTCONTEXT
|
||||
(
|
||||
CreatureWeakPtr target;
|
||||
long long last_frameno = 0;
|
||||
long long last_pursuit_frameno = 0;
|
||||
);
|
||||
|
||||
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 use_skill_ok = false;
|
||||
if (context->target.Get() &&
|
||||
!context->target.Get()->dead) {
|
||||
int skill_id = GetUseableSkill(context->target.Get());
|
||||
if (skill_id >= 0) {
|
||||
GetOwner()->shot_hold = false;
|
||||
int wait_time = 0;
|
||||
use_skill_ok = InternalUseSkill(skill_id, context->target, wait_time);
|
||||
if (use_skill_ok) {
|
||||
Sleep(wait_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG1
|
||||
if (context->target.Get()->IsPlayer()) {
|
||||
a8::XPrintf("DoPursuit %d use_skill_ok:%d time:%d\n",
|
||||
{GetOwner()->GetUniId(),
|
||||
use_skill_ok ? 1 : 0,
|
||||
GetOwner()->GetMainSkill() ? GetOwner()->GetMainSkill()->GetLeftTime() : 0
|
||||
});
|
||||
}
|
||||
#endif
|
||||
if (!use_skill_ok) {
|
||||
bool shot_ok = false;
|
||||
glm::vec3 shot_dir = dir;
|
||||
GetOwner()->shot_hold = true;
|
||||
GetOwner()->SetAttackDir(shot_dir);
|
||||
#if 0
|
||||
GetOwner()->Shot(AdjustShotDir(shot_dir), shot_ok, 0, 0);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
GetOwner()->shot_hold = false;
|
||||
}
|
||||
}
|
||||
return behaviac::BT_RUNNING;
|
||||
}
|
||||
};
|
||||
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 = MAKE_BTCONTEXT
|
||||
(
|
||||
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;
|
||||
}
|
||||
};
|
||||
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 = MAKE_BTCONTEXT
|
||||
(
|
||||
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;
|
||||
}
|
||||
};
|
||||
return StartCoroutine(co);
|
||||
}
|
||||
|
||||
float HeroAgent::GetMasterDistance()
|
||||
{
|
||||
if (!GetOwner()->AsHero()->master.Get()) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user