From 7c9b047cb381314c69b84249c3d43580ee12b14c Mon Sep 17 00:00:00 2001 From: aozhiwei Date: Fri, 24 Mar 2023 10:13:59 +0800 Subject: [PATCH] 1 --- server/gameserver/hero_agent.cc | 308 ++++++++++++++++++++++++++++++++ server/gameserver/hero_agent.h | 25 +++ server/gameserver/room.cc | 24 +++ server/gameserver/room.h | 1 + 4 files changed, 358 insertions(+) create mode 100644 server/gameserver/hero_agent.cc create mode 100644 server/gameserver/hero_agent.h diff --git a/server/gameserver/hero_agent.cc b/server/gameserver/hero_agent.cc new file mode 100644 index 00000000..cee941a1 --- /dev/null +++ b/server/gameserver/hero_agent.cc @@ -0,0 +1,308 @@ +#include "precompile.h" + +#include "hero_agent.h" +#include "hero.h" +#include "room.h" +#include "movement.h" +#include "trigger.h" +#include "glmhelper.h" + +HeroAgent::HeroAgent():BaseAgent() +{ + +} + +HeroAgent::~HeroAgent() +{ +} + +State_e HeroAgent::GetState() +{ +#ifdef DEBUG1 + a8::XPrintf("GetState\n", {}); +#endif + return kPreBattle; +} + +behaviac::EBTStatus HeroAgent::DoIdle(int min_time, int max_time) +{ + if (status_ == behaviac::BT_RUNNING) { + return DoRunningCb(); + } + + int idle_time = a8::RandEx(min_time, max_time); + a8::XTimerWp timer_ptr = GetOwner()->room->xtimer.SetTimeoutWpEx + ( + idle_time / FRAME_RATE_MS, + [] (int event, const a8::Args* args) + { + }, + &GetOwner()->xtimer_attacher); + + std::shared_ptr last_attacker = std::make_shared(); + std::shared_ptr last_attacked_frameno = std::make_shared(0); + std::weak_ptr handler = GetOwner()->GetTrigger()->AddListener + ( + kAttacked, + [this, last_attacker, last_attacked_frameno] (const a8::Args& args) + { + Creature* c = args.Get(0); + *last_attacker = c->GetWeakPtrRef(); + *last_attacked_frameno = c->room->GetFrameNo(); + }); + + return StartCoroutine + ( + [this, timer_ptr, handler] () + { + if (!timer_ptr.expired()) { + return behaviac::BT_RUNNING; + } else { + if (!handler.expired()) { + GetOwner()->GetTrigger()->RemoveEventHandler(handler); + } + return behaviac::BT_SUCCESS; + } + }, + [this, timer_ptr, handler, last_attacker, last_attacked_frameno] + (bool is_test, bool& has_event) mutable + { + has_event = last_attacker->Get() && !last_attacker->Get()->dead ? true : false; + if (!is_test && has_event) { + if (!timer_ptr.expired()) { + GetOwner()->room->xtimer.Delete(timer_ptr); + } + if (!handler.expired()) { + GetOwner()->GetTrigger()->RemoveEventHandler(handler); + + } + FireEvent("OnAttacked", last_attacker->Get()->GetUniId(), *last_attacked_frameno); + } + }, + "CoIdle" + ); +} + +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; + } + + std::shared_ptr last_attacker = std::make_shared(); + std::shared_ptr last_attacked_frameno = std::make_shared(0); + std::weak_ptr handler = GetOwner()->GetTrigger()->AddListener + ( + kAttacked, + [this, last_attacker, last_attacked_frameno] (const a8::Args& args) + { + Creature* c = args.Get(0); + *last_attacker = c->GetWeakPtrRef(); + *last_attacked_frameno = c->room->GetFrameNo(); + }); + + return StartCoroutine + ( + [this, handler] () + { + if (GetOwner()->GetMovement()->GetPathSize() <= 0) { + if (!handler.expired()) { + GetOwner()->GetTrigger()->RemoveEventHandler(handler); + } + return behaviac::BT_SUCCESS; + } else { + return behaviac::BT_RUNNING; + } + }, + [this, handler, last_attacker, last_attacked_frameno] + (bool is_test, bool& has_event) mutable + { + has_event = last_attacker->Get() && !last_attacker->Get()->dead ? true : false; + if (!is_test && has_event) { + if (!handler.expired()) { + GetOwner()->GetTrigger()->RemoveEventHandler(handler); + } + FireEvent("OnAttacked", last_attacker->Get()->GetUniId(), *last_attacked_frameno); + } + }, + "CoRandomWalk" + ); +} + +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); + + std::shared_ptr last_attacker = std::make_shared(); + std::shared_ptr last_attacked_frameno = std::make_shared(0); + std::weak_ptr handler = GetOwner()->GetTrigger()->AddListener + ( + kAttacked, + [this, last_attacker, last_attacked_frameno] (const a8::Args& args) + { + Creature* c = args.Get(0); + *last_attacker = c->GetWeakPtrRef(); + *last_attacked_frameno = c->room->GetFrameNo(); + }); + + long long last_frameno = GetOwner()->room->GetFrameNo(); + return StartCoroutine + ( + [this, last_frameno, handler] () + { + if (GetOwner()->room->GetFrameNo() - last_frameno > SERVER_FRAME_RATE * 3) { + if (!handler.expired()) { + GetOwner()->GetTrigger()->RemoveEventHandler(handler); + } + 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; + } + }, + [this, handler, last_attacker, last_attacked_frameno] + (bool is_test, bool& has_event) mutable + { + has_event = last_attacker->Get() && !last_attacker->Get()->dead ? true : false; + if (!is_test && has_event) { + if (!handler.expired()) { + GetOwner()->GetTrigger()->RemoveEventHandler(handler); + } + FireEvent("OnAttacked", last_attacker->Get()->GetUniId(), *last_attacked_frameno); + } + }, + "CoRandomShot" + ); +} + +behaviac::EBTStatus HeroAgent::DoAttack() +{ + if (status_ == behaviac::BT_RUNNING) { + return DoRunningCb(); + } + Creature* enemy = GetOwner()->room->FindEnemy(GetOwner(), 300); + if (!enemy) { + 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; + GetOwner()->Shot(shot_dir, shot_ok, 0, 0); + + long long last_frameno = GetOwner()->room->GetFrameNo(); + return StartCoroutine + ( + [this, last_frameno] () + { + if (GetOwner()->room->GetFrameNo() - last_frameno > SERVER_FRAME_RATE * 3) { + status_ = behaviac::BT_SUCCESS; + 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; + } + }, + [this] (bool is_test, bool& has_event) + { + + }, + "CoAttack" + ); +} + +behaviac::EBTStatus HeroAgent::DoPursuit() +{ + if (status_ == behaviac::BT_RUNNING) { + return DoRunningCb(); + } + Creature* enemy = GetOwner()->room->FindEnemy(GetOwner(), 500); + if (!enemy) { + return behaviac::BT_FAILURE; + } + + CreatureWeakPtr target = enemy->GetWeakPtrRef(); + long long last_frameno = GetOwner()->room->GetFrameNo(); + long long last_pursuit_frameno = GetOwner()->room->GetFrameNo(); + return StartCoroutine + ( + [this, last_frameno, target, last_pursuit_frameno] () mutable + { + if (GetOwner()->room->GetFrameNo() - last_frameno > SERVER_FRAME_RATE * 10 || + !target.Get() || target.Get()->dead) { + status_ = behaviac::BT_SUCCESS; + return behaviac::BT_SUCCESS; + } else { + glm::vec3 dir = GetOwner()->GetPos().CalcDir(target.Get()->GetPos()); + if (GlmHelper::Norm(dir) <= 1.0f) { + GetOwner()->GetMovement()->CalcTargetPos(60); + 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); + last_pursuit_frameno = GetOwner()->room->GetFrameNo(); + } else { + if (GetOwner()->room->GetFrameNo() - last_pursuit_frameno > SERVER_FRAME_RATE * 1) { + GlmHelper::Normalize(dir); + GetOwner()->SetMoveDir(dir); + GetOwner()->SetAttackDir(dir); + GetOwner()->GetMovement()->CalcTargetPos(200); + last_pursuit_frameno = GetOwner()->room->GetFrameNo(); + } + } + } else { + GlmHelper::Normalize(dir); + is_shot = true; + } + if (is_shot) { + bool shot_ok = false; + glm::vec3 shot_dir = dir; + GetOwner()->SetAttackDir(dir); + GetOwner()->Shot(shot_dir, shot_ok, 0, 0); + } + } + return behaviac::BT_RUNNING; + } + }, + [this] (bool is_test, bool& has_event) + { + + }, + "CoPursuit" + ); +} diff --git a/server/gameserver/hero_agent.h b/server/gameserver/hero_agent.h new file mode 100644 index 00000000..1b3a9e3a --- /dev/null +++ b/server/gameserver/hero_agent.h @@ -0,0 +1,25 @@ +#pragma once + +#include "base_agent.h" + +class Hero; +class HeroAgent : public BaseAgent +{ +public: + HeroAgent(); + + virtual ~HeroAgent(); + + BEHAVIAC_DECLARE_AGENTTYPE(HeroAgent, BaseAgent) + + State_e GetState(); + + behaviac::EBTStatus DoIdle(int min_time, int max_time); + behaviac::EBTStatus DoRandomWalk(); + behaviac::EBTStatus DoRandomShot(); + behaviac::EBTStatus DoAttack(); + behaviac::EBTStatus DoPursuit(); + +private: + Hero* owner_ = nullptr; +}; diff --git a/server/gameserver/room.cc b/server/gameserver/room.cc index 0786548d..8b4ab229 100644 --- a/server/gameserver/room.cc +++ b/server/gameserver/room.cc @@ -442,6 +442,30 @@ Human* Room::FindEnemy(Human* hum, float range) return target; } +Creature* Room::FindEnemy(Creature* c, float range) +{ + Creature* myself = c; + Creature* target = nullptr; + float last_distance = range + 1; + TraverseHumanList + ( + [&target, myself, range, &last_distance] (Human* hum) + { + if (!hum->dead && + hum->team_id != myself->team_id) { + float distance = hum->GetPos().Distance2D2(myself->GetPos()); + if (distance <= range) { + if (distance < last_distance) { + target = hum; + last_distance = distance; + } + } + } + return true; + }); + return target; +} + void Room::FillSMJoinedNotify(Player* self_hum, cs::SMJoinedNotify& msg) { msg.set_team_mode(msg.team_mode()); diff --git a/server/gameserver/room.h b/server/gameserver/room.h index 01ff0b8e..b6ae97b8 100644 --- a/server/gameserver/room.h +++ b/server/gameserver/room.h @@ -114,6 +114,7 @@ public: Player* NewPlayer(); void AddPlayer(Player* hum, std::shared_ptr init_born_point = nullptr, bool no_matchteam = false); Human* FindEnemy(Human* hum, float range); + Creature* FindEnemy(Creature* c, float range); void AddTeam(class MatchTeam* team);