diff --git a/server/gameserver/CMakeLists.txt b/server/gameserver/CMakeLists.txt index cf3815f6..310ba7dc 100644 --- a/server/gameserver/CMakeLists.txt +++ b/server/gameserver/CMakeLists.txt @@ -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 diff --git a/server/gameserver/ai/base/co_attack_target.cc b/server/gameserver/ai/base/co_attack_target.cc new file mode 100644 index 00000000..85596b8f --- /dev/null +++ b/server/gameserver/ai/base/co_attack_target.cc @@ -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(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); +} diff --git a/server/gameserver/ai/base/doidle.cc b/server/gameserver/ai/base/doidle.cc new file mode 100644 index 00000000..febf6838 --- /dev/null +++ b/server/gameserver/ai/base/doidle.cc @@ -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(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(context, "CoIdle"); + co->runing_cb = + [this, context] () + { + if (!context->timer_ptr.expired()) { + return behaviac::BT_RUNNING; + } else { + return behaviac::BT_SUCCESS; + } + }; + return StartCoroutine(co); +} diff --git a/server/gameserver/ai/base/douseskill.cc b/server/gameserver/ai/base/douseskill.cc new file mode 100644 index 00000000..9b544c74 --- /dev/null +++ b/server/gameserver/ai/base/douseskill.cc @@ -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; +} diff --git a/server/gameserver/ai/hero/do_attack.cc b/server/gameserver/ai/hero/do_attack.cc new file mode 100644 index 00000000..a4bbb0ae --- /dev/null +++ b/server/gameserver/ai/hero/do_attack.cc @@ -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(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(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); +} diff --git a/server/gameserver/ai/hero/do_flyto_master_around.cc b/server/gameserver/ai/hero/do_flyto_master_around.cc new file mode 100644 index 00000000..65bc65de --- /dev/null +++ b/server/gameserver/ai/hero/do_flyto_master_around.cc @@ -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; +} diff --git a/server/gameserver/ai/hero/do_follow_master.cc b/server/gameserver/ai/hero/do_follow_master.cc new file mode 100644 index 00000000..d3c827df --- /dev/null +++ b/server/gameserver/ai/hero/do_follow_master.cc @@ -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(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); +} diff --git a/server/gameserver/ai/hero/do_help_attack.cc b/server/gameserver/ai/hero/do_help_attack.cc new file mode 100644 index 00000000..b167c102 --- /dev/null +++ b/server/gameserver/ai/hero/do_help_attack.cc @@ -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(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); +} diff --git a/server/gameserver/ai/hero/do_pursuit.cc b/server/gameserver/ai/hero/do_pursuit.cc new file mode 100644 index 00000000..4b8a4412 --- /dev/null +++ b/server/gameserver/ai/hero/do_pursuit.cc @@ -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(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); +} diff --git a/server/gameserver/ai/hero/do_random_shot.cc b/server/gameserver/ai/hero/do_random_shot.cc new file mode 100644 index 00000000..cced9d77 --- /dev/null +++ b/server/gameserver/ai/hero/do_random_shot.cc @@ -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 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(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(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); +} diff --git a/server/gameserver/ai/hero/do_random_walk.cc b/server/gameserver/ai/hero/do_random_walk.cc new file mode 100644 index 00000000..b6b416d6 --- /dev/null +++ b/server/gameserver/ai/hero/do_random_walk.cc @@ -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(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(context, "CoRandomWalk"); + co->runing_cb = + [this, context] () + { + if (GetOwner()->GetMovement()->GetPathSize() <= 0) { + return behaviac::BT_SUCCESS; + } else { + return behaviac::BT_RUNNING; + } + }; + return StartCoroutine(co); +} diff --git a/server/gameserver/base_agent.cc b/server/gameserver/base_agent.cc index 752a7c31..7dc12651 100644 --- a/server/gameserver/base_agent.cc +++ b/server/gameserver/base_agent.cc @@ -115,105 +115,6 @@ behaviac::EBTStatus BaseAgent::StartCoroutine(std::shared_ptr 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(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(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(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(), diff --git a/server/gameserver/hero_agent.cc b/server/gameserver/hero_agent.cc index de86ffbc..a7ccd502 100644 --- a/server/gameserver/hero_agent.cc +++ b/server/gameserver/hero_agent.cc @@ -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(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(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 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(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(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(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(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(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(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(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()) {