From ee0005663c5d333d20bd3d7c88ae3ab538589a93 Mon Sep 17 00:00:00 2001 From: aozhiwei Date: Tue, 8 Jun 2021 19:54:24 +0800 Subject: [PATCH] =?UTF-8?q?ai=E9=87=8D=E6=9E=84ok?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/gameserver/aicomponent.h | 5 + server/gameserver/android.ai.cc | 189 ++++++++++++++++++----------- server/gameserver/android.ai.h | 60 ++------- server/gameserver/hero.ai.cc | 144 +++++++++++++--------- server/gameserver/hero.ai.h | 41 +------ server/gameserver/zombiemode.ai.cc | 9 ++ server/gameserver/zombiemode.ai.h | 11 +- 7 files changed, 237 insertions(+), 222 deletions(-) diff --git a/server/gameserver/aicomponent.h b/server/gameserver/aicomponent.h index 31ab08c..5f88c05 100644 --- a/server/gameserver/aicomponent.h +++ b/server/gameserver/aicomponent.h @@ -1,5 +1,10 @@ #pragma once +namespace MetaData +{ + class AI; +} + class MoveableEntity; class AIComponent { diff --git a/server/gameserver/android.ai.cc b/server/gameserver/android.ai.cc index 22b0bbf..f9bc3bb 100644 --- a/server/gameserver/android.ai.cc +++ b/server/gameserver/android.ai.cc @@ -18,6 +18,52 @@ enum ShotType_e kShotHold = 2, }; +enum AndroidState_e : int +{ + AS_thinking, + AS_moving, + AS_attack +}; + +enum AndroidStateEx_e : int +{ + ASE_Idle = 0, + ASE_Thinking = 1, + ASE_Attack = 2, + ASE_RandomWalk = 3, + ASE_Pursuit = 4 +}; + +class Human; +class AINode +{ +public: + AndroidStateEx_e main_state = ASE_Idle; + long long frameno = 0; + long long exec_frame_num = 0; + long long start_shot_frameno = 0; + long long next_random_move_frameno = 0; + int shot_times = 0; + int total_shot_times = 0; + int next_total_shot_times = 0; + + long long param1 = 0; + CreatureWeakPtr target; + CreatureWeakPtr nearest_human; + long long last_check_nearest_human_frameno = 0; + a8::Vec2 shot_dir; +}; + +struct OldAiData +{ + AndroidState_e state = AS_thinking; + int state_elapsed_time = 0; + CreatureWeakPtr last_target; + long long last_attack_frameno = 0; + long long last_findenemy_frameno = 0; + long long series_attack_frames = 0; +}; + /* nn目标:ai可切换,降级/升级(根据系统当前负载) @@ -32,13 +78,21 @@ ai级别 8: 跑动射击 */ +AndroidNewAI::AndroidNewAI() +{ + old_ai_data_ = new OldAiData(); + node_ = new AINode(); +} + AndroidNewAI::~AndroidNewAI() { + A8_SAFE_DELETE(old_ai_data_); + A8_SAFE_DELETE(node_); } void AndroidNewAI::Update(int delta_time) { - old_ai_data_.state_elapsed_time += delta_time; + old_ai_data_->state_elapsed_time += delta_time; Human* hum = (Human*)owner; if (hum->poisoning) { hum->poisoning_time += delta_time; @@ -67,10 +121,10 @@ float AndroidNewAI::GetAttackRate() void AndroidNewAI::DefaultAi() { - switch (old_ai_data_.state) { + switch (old_ai_data_->state) { case AS_thinking: { - if (old_ai_data_.state_elapsed_time > 1500 + rand() % 3000) { + if (old_ai_data_->state_elapsed_time > 1500 + rand() % 3000) { int rnd = rand(); if (rnd % 100 < 30) { ChangeToStateOldAI(AS_moving); @@ -82,7 +136,7 @@ void AndroidNewAI::DefaultAi() break; case AS_moving: { - if (old_ai_data_.state_elapsed_time < 1000 + rand() % 2000) { + if (old_ai_data_->state_elapsed_time < 1000 + rand() % 2000) { DoMoveOldAI(); } else { int rnd = rand(); @@ -96,8 +150,8 @@ void AndroidNewAI::DefaultAi() break; case AS_attack: { - if ((old_ai_data_.state_elapsed_time < 3000 && old_ai_data_.last_target.Get()) || - (old_ai_data_.state_elapsed_time < 1100)) { + if ((old_ai_data_->state_elapsed_time < 3000 && old_ai_data_->last_target.Get()) || + (old_ai_data_->state_elapsed_time < 1100)) { DoAttackOldAI(); } else { int rnd = rand(); @@ -114,9 +168,9 @@ void AndroidNewAI::DefaultAi() void AndroidNewAI::ChangeToStateOldAI(AndroidState_e to_state) { - old_ai_data_.state = to_state; - old_ai_data_.state_elapsed_time = 0; - switch (old_ai_data_.state) { + old_ai_data_->state = to_state; + old_ai_data_->state_elapsed_time = 0; + switch (old_ai_data_->state) { case AS_moving: { Human* hum = (Human*)owner; @@ -186,7 +240,7 @@ void AndroidNewAI::DoAttackOldAI() bool shot_ok = false; sender->Shot(shot_dir, shot_ok, DEFAULT_FLY_DISTANCE); } - old_ai_data_.last_target.Attach(enemy); + old_ai_data_->last_target.Attach(enemy); } } } @@ -206,9 +260,9 @@ void AndroidNewAI::UpdateNewAI() if (hum->playing_skill) { hum->UpdateSkill(); } - ++node_.exec_frame_num; + ++node_->exec_frame_num; hum->shot_hold = false; - switch (node_.main_state) { + switch (node_->main_state) { case ASE_Idle: { UpdateIdle(); @@ -248,7 +302,7 @@ void AndroidNewAI::UpdateNewAI() void AndroidNewAI::UpdateIdle() { Human* hum = (Human*)owner; - if (hum->room->GetFrameNo() > node_.frameno + node_.param1) { + if (hum->room->GetFrameNo() > node_->frameno + node_->param1) { ChangeToStateNewAI(ASE_Thinking); } } @@ -268,10 +322,10 @@ void AndroidNewAI::UpdateThinking() } else { Creature* target = GetTarget(); if (target) { - node_.target.Attach(target); + node_->target.Attach(target); ChangeToStateNewAI(ASE_Attack); } else { - if (hum->room->GetFrameNo() >= node_.next_random_move_frameno) { + if (hum->room->GetFrameNo() >= node_->next_random_move_frameno) { if ((rand() % 7) < 4) { ChangeToStateNewAI(ASE_Idle); } else { @@ -279,7 +333,7 @@ void AndroidNewAI::UpdateThinking() } } else { ChangeToStateNewAI(ASE_Idle); - node_.param1 = node_.next_random_move_frameno - hum->room->GetFrameNo(); + node_->param1 = node_->next_random_move_frameno - hum->room->GetFrameNo(); } } } @@ -288,11 +342,11 @@ void AndroidNewAI::UpdateThinking() void AndroidNewAI::UpdateAttack() { Human* myself = (Human*)owner; - if (!node_.target.Get() || node_.target.Get()->dead) { + if (!node_->target.Get() || node_->target.Get()->dead) { ChangeToStateNewAI(ASE_Thinking); return; } - if (node_.exec_frame_num > SERVER_FRAME_RATE * 8) { + if (node_->exec_frame_num > SERVER_FRAME_RATE * 8) { ChangeToStateNewAI(ASE_Thinking); return; } @@ -305,7 +359,7 @@ void AndroidNewAI::UpdateAttack() if (myself->HasBuffEffect(kBET_Vertigo)) { return; } - float distance = myself->GetPos().Distance(node_.target.Get()->GetPos()); + float distance = myself->GetPos().Distance(node_->target.Get()->GetPos()); if (distance > GetAttackRange()) { if (ai_meta->i->pursuit_radius() <= 0) { //站桩 @@ -325,12 +379,12 @@ void AndroidNewAI::UpdateAttack() case kShotClick: { if (ai_meta->i->attack_interval() > 0) { - if (node_.shot_times < GetAttackTimes()) { + if (node_->shot_times < GetAttackTimes()) { DoShotNewAI(); } else { ChangeToStateNewAI(ASE_Idle); - node_.next_total_shot_times = node_.total_shot_times; - node_.param1 = ai_meta->i->attack_interval() / 1000 * SERVER_FRAME_RATE; + node_->next_total_shot_times = node_->total_shot_times; + node_->param1 = ai_meta->i->attack_interval() / 1000 * SERVER_FRAME_RATE; } } else { myself->shot_hold = true; @@ -355,7 +409,7 @@ void AndroidNewAI::UpdateAttack() void AndroidNewAI::UpdateRandomWalk() { Human* hum = (Human*)owner; - if (hum->room->GetFrameNo() > node_.frameno + node_.param1) { + if (hum->room->GetFrameNo() > node_->frameno + node_->param1) { ChangeToStateNewAI(ASE_Thinking); } } @@ -363,19 +417,19 @@ void AndroidNewAI::UpdateRandomWalk() void AndroidNewAI::UpdatePursuit() { Human* myself = (Human*)owner; - if (node_.target.Get()) { - float distance = myself->GetPos().Distance(node_.target.Get()->GetPos()); + if (node_->target.Get()) { + float distance = myself->GetPos().Distance(node_->target.Get()->GetPos()); if (!myself->HasBuffEffect(kBET_Jump) && !a8::HasBitFlag(myself->status, HS_DisableAttack) && distance < GetAttackRange()) { ChangeToStateNewAI(ASE_Attack); } else { - if (node_.exec_frame_num > 100 * 2) { + if (node_->exec_frame_num > 100 * 2) { ChangeToStateNewAI(ASE_RandomWalk); } } } else { - if (node_.exec_frame_num > 100 * 2) { + if (node_->exec_frame_num > 100 * 2) { ChangeToStateNewAI(ASE_RandomWalk); } } @@ -397,11 +451,11 @@ void AndroidNewAI::DoMoveNewAI() int speed = std::max(1, (int)hum->GetSpeed()) * 1; hum->_UpdateMove(speed); hum->on_move_collision = nullptr; - if (node_.nearest_human.Get()) { - if (node_.main_state != ASE_Pursuit && - hum->GetPos().ManhattanDistance(node_.nearest_human.Get()->GetPos()) < 200) { + if (node_->nearest_human.Get()) { + if (node_->main_state != ASE_Pursuit && + hum->GetPos().ManhattanDistance(node_->nearest_human.Get()->GetPos()) < 200) { ChangeToStateNewAI(ASE_Thinking); - } else if (hum->GetPos().ManhattanDistance(node_.nearest_human.Get()->GetPos()) > 800) { + } else if (hum->GetPos().ManhattanDistance(node_->nearest_human.Get()->GetPos()) > 800) { GetTarget(); } } @@ -414,57 +468,57 @@ void AndroidNewAI::ChangeToStateNewAI(AndroidStateEx_e to_state) switch (to_state) { case ASE_Idle: { - node_.target.Reset(); - node_.param1 = 0; - node_.start_shot_frameno = 0; - node_.shot_times = 0; + node_->target.Reset(); + node_->param1 = 0; + node_->start_shot_frameno = 0; + node_->shot_times = 0; moving_ = false; if (hum->room->GetGasData().gas_mode == GasInactive || hum->room->IsWaitingStart() || hum->HasBuffEffect(kBET_Jump)) { - node_.param1 = rand() % (3 * SERVER_FRAME_RATE); + node_->param1 = rand() % (3 * SERVER_FRAME_RATE); } else { - node_.param1 = rand() % (2 * SERVER_FRAME_RATE); + node_->param1 = rand() % (2 * SERVER_FRAME_RATE); } } break; case ASE_Thinking: { - node_.target.Reset(); - node_.param1 = 0; - node_.start_shot_frameno = 0; - node_.shot_times = 0; + node_->target.Reset(); + node_->param1 = 0; + node_->start_shot_frameno = 0; + node_->shot_times = 0; moving_ = false; } break; case ASE_Attack: { - node_.param1 = 0; - node_.start_shot_frameno = 0; - node_.shot_times = 0; + node_->param1 = 0; + node_->start_shot_frameno = 0; + node_->shot_times = 0; moving_ = false; - node_.shot_times = 0; + node_->shot_times = 0; } break; case ASE_RandomWalk: { moving_ = true; - node_.target.Reset(); + node_->target.Reset(); #if 1 - node_.param1 = SERVER_FRAME_RATE * ai_meta->GetMoveTime(); + node_->param1 = SERVER_FRAME_RATE * ai_meta->GetMoveTime(); #else - node_.param1 = SERVER_FRAME_RATE * 5 + rand() % (SERVER_FRAME_RATE * 3); + node_->param1 = SERVER_FRAME_RATE * 5 + rand() % (SERVER_FRAME_RATE * 3); #endif - node_.start_shot_frameno = 0; - node_.shot_times = 0; - node_.next_random_move_frameno = hum->room->GetFrameNo() + + node_->start_shot_frameno = 0; + node_->shot_times = 0; + node_->next_random_move_frameno = hum->room->GetFrameNo() + SERVER_FRAME_RATE * ai_meta->GetMoveIdleTime(); a8::Vec2 move_dir = a8::Vec2(1.0f, 0); move_dir.Rotate(a8::RandAngle()); move_dir.Normalize(); hum->SetMoveDir(move_dir); hum->SetAttackDir(hum->GetMoveDir()); - if (node_.param1 <= 1) { + if (node_->param1 <= 1) { moving_ = false; } } @@ -472,8 +526,8 @@ void AndroidNewAI::ChangeToStateNewAI(AndroidStateEx_e to_state) case ASE_Pursuit: { moving_ = true; - if (node_.target.Get()) { - a8::Vec2 move_dir = node_.target.Get()->GetPos() - hum->GetPos(); + if (node_->target.Get()) { + a8::Vec2 move_dir = node_->target.Get()->GetPos() - hum->GetPos(); move_dir.Normalize(); hum->SetMoveDir(move_dir); hum->SetAttackDir(hum->GetMoveDir()); @@ -481,9 +535,9 @@ void AndroidNewAI::ChangeToStateNewAI(AndroidStateEx_e to_state) } break; } - node_.main_state = to_state; - node_.frameno = hum->room->GetFrameNo(); - node_.exec_frame_num = 0; + node_->main_state = to_state; + node_->frameno = hum->room->GetFrameNo(); + node_->exec_frame_num = 0; } Creature* AndroidNewAI::GetTarget() @@ -511,8 +565,8 @@ Creature* AndroidNewAI::GetTarget() } }); if (target) { - node_.nearest_human.Attach(target); - node_.last_check_nearest_human_frameno = myself->room->GetFrameNo(); + node_->nearest_human.Attach(target); + node_->last_check_nearest_human_frameno = myself->room->GetFrameNo(); float distance = myself->GetPos().Distance(target->GetPos()); if (distance > GetAttackRange()) { target = nullptr; @@ -535,15 +589,15 @@ float AndroidNewAI::GetAttackRange() void AndroidNewAI::DoShotNewAI() { Human* myself = (Human*)owner; - if (!node_.target.Get()) { + if (!node_->target.Get()) { return; } bool shot_ok = false; a8::Vec2 shot_dir = myself->GetAttackDir(); - if (node_.total_shot_times >= node_.next_total_shot_times) { - shot_dir = node_.target.Get()->GetPos() - myself->GetPos(); - node_.next_total_shot_times += 7 + (rand() % 6); + if (node_->total_shot_times >= node_->next_total_shot_times) { + shot_dir = node_->target.Get()->GetPos() - myself->GetPos(); + node_->next_total_shot_times += 7 + (rand() % 6); myself->SetAttackDir(shot_dir); } if (std::abs(shot_dir.x) > FLT_EPSILON || @@ -563,11 +617,11 @@ void AndroidNewAI::DoShotNewAI() myself->Shot(shot_dir, shot_ok, DEFAULT_FLY_DISTANCE); myself->SetAttackDir(old_attack_dir); if (shot_ok) { - if (node_.shot_times <= 0) { - node_.start_shot_frameno = myself->room->GetFrameNo(); + if (node_->shot_times <= 0) { + node_->start_shot_frameno = myself->room->GetFrameNo(); } - ++node_.shot_times; - ++node_.total_shot_times; + ++node_->shot_times; + ++node_->total_shot_times; } } } @@ -581,4 +635,3 @@ int AndroidNewAI::GetAttackTimes() return ai_meta->i->attack_times(); } } - diff --git a/server/gameserver/android.ai.h b/server/gameserver/android.ai.h index 7603c18..b96f25b 100644 --- a/server/gameserver/android.ai.h +++ b/server/gameserver/android.ai.h @@ -3,62 +3,16 @@ #include "aicomponent.h" #include "weakptr.h" -enum AndroidState_e -{ - AS_thinking, - AS_moving, - AS_attack -}; - -enum AndroidStateEx_e -{ - ASE_Idle = 0, - ASE_Thinking = 1, - ASE_Attack = 2, - ASE_RandomWalk = 3, - ASE_Pursuit = 4 -}; - -class Human; -class AINode -{ -public: - AndroidStateEx_e main_state = ASE_Idle; - long long frameno = 0; - long long exec_frame_num = 0; - long long start_shot_frameno = 0; - long long next_random_move_frameno = 0; - int shot_times = 0; - int total_shot_times = 0; - int next_total_shot_times = 0; - - long long param1 = 0; - CreatureWeakPtr target; - CreatureWeakPtr nearest_human; - long long last_check_nearest_human_frameno = 0; - a8::Vec2 shot_dir; -}; - -struct OldAiData -{ - AndroidState_e state = AS_thinking; - int state_elapsed_time = 0; - CreatureWeakPtr last_target; - long long last_attack_frameno = 0; - long long last_findenemy_frameno = 0; - long long series_attack_frames = 0; -}; - -namespace MetaData -{ - class AI; -} - +enum AndroidStateEx_e : int; +enum AndroidState_e : int; +struct OldAiData; +struct AINode; class Human; class AndroidNewAI : public AIComponent { public: + AndroidNewAI(); virtual ~AndroidNewAI() override; virtual void Update(int delta_time) override; float GetAttackRate(); @@ -84,9 +38,9 @@ private: int GetAttackTimes(); private: - OldAiData old_ai_data_; + OldAiData* old_ai_data_ = nullptr; MetaData::AI* ai_meta = nullptr; - AINode node_; + AINode* node_ = nullptr; bool moving_ = false; }; diff --git a/server/gameserver/hero.ai.cc b/server/gameserver/hero.ai.cc index ea88ec1..a9fff1d 100644 --- a/server/gameserver/hero.ai.cc +++ b/server/gameserver/hero.ai.cc @@ -15,8 +15,44 @@ enum ShotType_e kShotHold = 2, }; +enum HeroState_e : int +{ + HSE_Idle = 0, + HSE_Thinking = 1, + HSE_Attack = 2, + HSE_RandomWalk = 3, + HSE_Pursuit = 4, + HSE_FollowMaster = 5 +}; + +class HeroAINode +{ +public: + HeroState_e main_state = HSE_Idle; + long long frameno = 0; + long long exec_frame_num = 0; + long long start_shot_frameno = 0; + long long next_random_move_frameno = 0; + int shot_times = 0; + int total_shot_times = 0; + int next_total_shot_times = 0; + + long long param1 = 0; + CreatureWeakPtr target; + CreatureWeakPtr nearest_human; + long long last_check_nearest_human_frameno = 0; + a8::Vec2 shot_dir; + a8::Vec2 target_pos; +}; + +HeroAI::HeroAI() +{ + node_ = new HeroAINode(); +} + HeroAI::~HeroAI() { + A8_SAFE_DELETE(node_); } void HeroAI::Update(int delta_time) @@ -52,9 +88,9 @@ void HeroAI::UpdateAI() abort(); } } - ++node_.exec_frame_num; + ++node_->exec_frame_num; hero->shot_hold = false; - switch (node_.main_state) { + switch (node_->main_state) { case HSE_Idle: { UpdateIdle(); @@ -99,7 +135,7 @@ void HeroAI::UpdateAI() void HeroAI::UpdateIdle() { Hero* hero = (Hero*)owner; - if (hero->room->GetFrameNo() > node_.frameno + node_.param1) { + if (hero->room->GetFrameNo() > node_->frameno + node_->param1) { ChangeToStateAI(HSE_Thinking); } } @@ -125,10 +161,10 @@ void HeroAI::UpdateThinking() } Creature* target = GetTarget(); if (target) { - node_.target.Attach(target); + node_->target.Attach(target); ChangeToStateAI(HSE_Attack); } else { - if (hero->room->GetFrameNo() >= node_.next_random_move_frameno) { + if (hero->room->GetFrameNo() >= node_->next_random_move_frameno) { if ((rand() % 7) < 4) { ChangeToStateAI(HSE_Idle); } else { @@ -136,7 +172,7 @@ void HeroAI::UpdateThinking() } } else { ChangeToStateAI(HSE_Idle); - node_.param1 = node_.next_random_move_frameno - hero->room->GetFrameNo(); + node_->param1 = node_->next_random_move_frameno - hero->room->GetFrameNo(); } } } @@ -145,18 +181,18 @@ void HeroAI::UpdateThinking() void HeroAI::UpdateAttack() { Hero* myself = (Hero*)owner; - if (!node_.target.Get() || node_.target.Get()->dead) { + if (!node_->target.Get() || node_->target.Get()->dead) { ChangeToStateAI(HSE_Thinking); return; } - if (node_.exec_frame_num > SERVER_FRAME_RATE * 8) { + if (node_->exec_frame_num > SERVER_FRAME_RATE * 8) { ChangeToStateAI(HSE_Thinking); return; } if (myself->HasBuffEffect(kBET_Vertigo)) { return; } - float distance = myself->GetPos().Distance(node_.target.Get()->GetPos()); + float distance = myself->GetPos().Distance(node_->target.Get()->GetPos()); if (distance > GetAttackRange()) { if (ai_meta->i->pursuit_radius() <= 0) { //站桩 @@ -176,12 +212,12 @@ void HeroAI::UpdateAttack() case kShotClick: { if (ai_meta->i->attack_interval() > 0) { - if (node_.shot_times < GetAttackTimes()) { + if (node_->shot_times < GetAttackTimes()) { DoShotAI(); } else { ChangeToStateAI(HSE_Idle); - node_.next_total_shot_times = node_.total_shot_times; - node_.param1 = ai_meta->i->attack_interval() / 1000 * SERVER_FRAME_RATE; + node_->next_total_shot_times = node_->total_shot_times; + node_->param1 = ai_meta->i->attack_interval() / 1000 * SERVER_FRAME_RATE; } } else { myself->shot_hold = true; @@ -206,7 +242,7 @@ void HeroAI::UpdateAttack() void HeroAI::UpdateRandomWalk() { Hero* hero = (Hero*)owner; - if (hero->room->GetFrameNo() > node_.frameno + node_.param1) { + if (hero->room->GetFrameNo() > node_->frameno + node_->param1) { ChangeToStateAI(HSE_Thinking); } } @@ -214,12 +250,12 @@ void HeroAI::UpdateRandomWalk() void HeroAI::UpdatePursuit() { Hero* myself = (Hero*)owner; - float distance = myself->GetPos().Distance(node_.target.Get()->GetPos()); + float distance = myself->GetPos().Distance(node_->target.Get()->GetPos()); if (!myself->HasBuffEffect(kBET_Jump) && distance < GetAttackRange()) { ChangeToStateAI(HSE_Attack); } else { - if (node_.exec_frame_num > 100 * 2) { + if (node_->exec_frame_num > 100 * 2) { ChangeToStateAI(HSE_RandomWalk); } } @@ -229,7 +265,7 @@ void HeroAI::UpdateFollowMaster() { Hero* myself = (Hero*)owner; if (myself->master.Get()) { - float mdistance = myself->GetPos().ManhattanDistance(node_.target_pos); + float mdistance = myself->GetPos().ManhattanDistance(node_->target_pos); if (mdistance < 10) { ChangeToStateAI(HSE_Thinking); } @@ -247,7 +283,7 @@ void HeroAI::DoMoveAI() auto old_on_move_collision_func = hero->on_move_collision; hero->on_move_collision = [this] () { - if (node_.main_state == HSE_FollowMaster) { + if (node_->main_state == HSE_FollowMaster) { ChangeToStateAI(HSE_FollowMaster); } else { ChangeToStateAI(HSE_RandomWalk); @@ -266,57 +302,57 @@ void HeroAI::ChangeToStateAI(HeroState_e to_state) switch (to_state) { case HSE_Idle: { - node_.target.Reset(); - node_.param1 = 0; - node_.start_shot_frameno = 0; - node_.shot_times = 0; + node_->target.Reset(); + node_->param1 = 0; + node_->start_shot_frameno = 0; + node_->shot_times = 0; moving_ = false; if (hero->room->GetGasData().gas_mode == GasInactive || hero->room->IsWaitingStart() || hero->HasBuffEffect(kBET_Jump)) { - node_.param1 = rand() % (3 * SERVER_FRAME_RATE); + node_->param1 = rand() % (3 * SERVER_FRAME_RATE); } else { - node_.param1 = rand() % (2 * SERVER_FRAME_RATE); + node_->param1 = rand() % (2 * SERVER_FRAME_RATE); } } break; case HSE_Thinking: { - node_.target.Reset(); - node_.param1 = 0; - node_.start_shot_frameno = 0; - node_.shot_times = 0; + node_->target.Reset(); + node_->param1 = 0; + node_->start_shot_frameno = 0; + node_->shot_times = 0; moving_ = false; } break; case HSE_Attack: { - node_.param1 = 0; - node_.start_shot_frameno = 0; - node_.shot_times = 0; + node_->param1 = 0; + node_->start_shot_frameno = 0; + node_->shot_times = 0; moving_ = false; - node_.shot_times = 0; + node_->shot_times = 0; } break; case HSE_RandomWalk: { moving_ = true; - node_.target.Reset(); + node_->target.Reset(); #if 1 - node_.param1 = SERVER_FRAME_RATE * ai_meta->GetMoveTime(); + node_->param1 = SERVER_FRAME_RATE * ai_meta->GetMoveTime(); #else - node_.param1 = SERVER_FRAME_RATE * 5 + rand() % (SERVER_FRAME_RATE * 3); + node_->param1 = SERVER_FRAME_RATE * 5 + rand() % (SERVER_FRAME_RATE * 3); #endif - node_.start_shot_frameno = 0; - node_.shot_times = 0; - node_.next_random_move_frameno = hero->room->GetFrameNo() + + node_->start_shot_frameno = 0; + node_->shot_times = 0; + node_->next_random_move_frameno = hero->room->GetFrameNo() + SERVER_FRAME_RATE * ai_meta->GetMoveIdleTime(); a8::Vec2 move_dir = a8::Vec2(1.0f, 0); move_dir.Rotate(a8::RandAngle()); move_dir.Normalize(); hero->SetMoveDir(move_dir); hero->SetAttackDir(hero->GetMoveDir()); - if (node_.param1 <= 1) { + if (node_->param1 <= 1) { moving_ = false; } } @@ -324,8 +360,8 @@ void HeroAI::ChangeToStateAI(HeroState_e to_state) case HSE_Pursuit: { moving_ = true; - if (node_.target.Get()) { - a8::Vec2 move_dir = node_.target.Get()->GetPos() - hero->GetPos(); + if (node_->target.Get()) { + a8::Vec2 move_dir = node_->target.Get()->GetPos() - hero->GetPos(); move_dir.Normalize(); hero->SetMoveDir(move_dir); hero->SetAttackDir(hero->GetMoveDir()); @@ -344,14 +380,14 @@ void HeroAI::ChangeToStateAI(HeroState_e to_state) move_dir.Normalize(); hero->SetMoveDir(move_dir); hero->SetAttackDir(hero->GetMoveDir()); - node_.target_pos = target_pos; + node_->target_pos = target_pos; } } break; } - node_.main_state = to_state; - node_.frameno = hero->room->GetFrameNo(); - node_.exec_frame_num = 0; + node_->main_state = to_state; + node_->frameno = hero->room->GetFrameNo(); + node_->exec_frame_num = 0; } Creature* HeroAI::GetTarget() @@ -379,8 +415,8 @@ Creature* HeroAI::GetTarget() } }); if (target) { - node_.nearest_human.Attach(target); - node_.last_check_nearest_human_frameno = myself->room->GetFrameNo(); + node_->nearest_human.Attach(target); + node_->last_check_nearest_human_frameno = myself->room->GetFrameNo(); float distance = myself->GetPos().Distance(target->GetPos()); if (distance > GetAttackRange()) { target = nullptr; @@ -403,15 +439,15 @@ float HeroAI::GetAttackRange() void HeroAI::DoShotAI() { Hero* myself = (Hero*)owner; - if (!node_.target.Get()) { + if (!node_->target.Get()) { return; } bool shot_ok = false; a8::Vec2 shot_dir = myself->GetAttackDir(); - if (node_.total_shot_times >= node_.next_total_shot_times) { - shot_dir = node_.target.Get()->GetPos() - myself->GetPos(); - node_.next_total_shot_times += 7 + (rand() % 6); + if (node_->total_shot_times >= node_->next_total_shot_times) { + shot_dir = node_->target.Get()->GetPos() - myself->GetPos(); + node_->next_total_shot_times += 7 + (rand() % 6); myself->SetAttackDir(shot_dir); } if (std::abs(shot_dir.x) > FLT_EPSILON || @@ -431,11 +467,11 @@ void HeroAI::DoShotAI() myself->Shot(shot_dir, shot_ok, DEFAULT_FLY_DISTANCE); myself->SetAttackDir(old_attack_dir); if (shot_ok) { - if (node_.shot_times <= 0) { - node_.start_shot_frameno = myself->room->GetFrameNo(); + if (node_->shot_times <= 0) { + node_->start_shot_frameno = myself->room->GetFrameNo(); } - ++node_.shot_times; - ++node_.total_shot_times; + ++node_->shot_times; + ++node_->total_shot_times; } } } diff --git a/server/gameserver/hero.ai.h b/server/gameserver/hero.ai.h index 24ec9fa..be57785 100644 --- a/server/gameserver/hero.ai.h +++ b/server/gameserver/hero.ai.h @@ -3,46 +3,13 @@ #include "aicomponent.h" #include "weakptr.h" -namespace MetaData -{ - class AI; -} - -enum HeroState_e -{ - HSE_Idle = 0, - HSE_Thinking = 1, - HSE_Attack = 2, - HSE_RandomWalk = 3, - HSE_Pursuit = 4, - HSE_FollowMaster = 5 -}; - -class Human; -class HeroAINode -{ -public: - HeroState_e main_state = HSE_Idle; - long long frameno = 0; - long long exec_frame_num = 0; - long long start_shot_frameno = 0; - long long next_random_move_frameno = 0; - int shot_times = 0; - int total_shot_times = 0; - int next_total_shot_times = 0; - - long long param1 = 0; - CreatureWeakPtr target; - CreatureWeakPtr nearest_human; - long long last_check_nearest_human_frameno = 0; - a8::Vec2 shot_dir; - a8::Vec2 target_pos; -}; - +enum HeroState_e : int; +class HeroAINode; class HeroAI : public AIComponent { public: + HeroAI(); virtual ~HeroAI() override; virtual void Update(int delta_time) override; float GetAttackRate(); @@ -65,6 +32,6 @@ private: private: MetaData::AI* ai_meta = nullptr; - HeroAINode node_; + HeroAINode* node_ = nullptr; bool moving_ = false; }; diff --git a/server/gameserver/zombiemode.ai.cc b/server/gameserver/zombiemode.ai.cc index 89f759e..102dc89 100644 --- a/server/gameserver/zombiemode.ai.cc +++ b/server/gameserver/zombiemode.ai.cc @@ -19,6 +19,15 @@ enum ShotType_e kShotHold = 2, }; +enum ZombieState_e : int +{ + ZSE_Idle = 0, + ZSE_Thinking = 1, + ZSE_Attack = 2, + ZSE_RandomWalk = 3, + ZSE_Pursuit = 4 +}; + class ZombieAINode { public: diff --git a/server/gameserver/zombiemode.ai.h b/server/gameserver/zombiemode.ai.h index 34696c2..ec8e359 100644 --- a/server/gameserver/zombiemode.ai.h +++ b/server/gameserver/zombiemode.ai.h @@ -2,16 +2,7 @@ #include "aicomponent.h" -enum ZombieState_e -{ - ZSE_Idle = 0, - ZSE_Thinking = 1, - ZSE_Attack = 2, - ZSE_RandomWalk = 3, - ZSE_Pursuit = 4 -}; - -class Human; +enum ZombieState_e : int; class Creature; class ZombieAINode; class ZombieModeAI : public AIComponent