diff --git a/server/gameserver/hero.ai.cc b/server/gameserver/hero.ai.cc index 1879fb2..bbb5d56 100644 --- a/server/gameserver/hero.ai.cc +++ b/server/gameserver/hero.ai.cc @@ -8,8 +8,6 @@ #include "metamgr.h" #include "player.h" -const int SHUA_RANGE = 580; - enum ShotType_e { kShotNone = 0, @@ -17,20 +15,6 @@ enum ShotType_e kShotHold = 2, }; -/* -nn目标:ai可切换,降级/升级(根据系统当前负载) - -ai级别 -1: 木桩(不射击) -2: 站桩间隔开枪 -3: 站桩描边射击 -4: 站桩扫射(连续射击) -5: 跑动间隔开枪 -6: 跑动描边射击 -7: 跑动扫射 -8: 跑动射击 -*/ - HeroAI::~HeroAI() { } @@ -96,6 +80,11 @@ void HeroAI::UpdateAI() UpdatePursuit(); } break; + case HSE_FollowMaster: + { + UpdateFollowMaster(); + } + break; default: { abort(); @@ -128,6 +117,12 @@ void HeroAI::UpdateThinking() ChangeToStateAI(HSE_RandomWalk); } } else { + if (hero->HasBuffEffect(kBET_FollowMaster) && + hero->master.Get() && + hero->master.Get()->GetPos().ManhattanDistance(hero->GetPos()) > 200) { + ChangeToStateAI(HSE_FollowMaster); + return; + } Creature* target = GetTarget(); if (target) { node_.target.Attach(target); @@ -227,19 +222,35 @@ void HeroAI::UpdatePursuit() } } +void HeroAI::UpdateFollowMaster() +{ + Hero* myself = (Hero*)owner; + if (myself->master.Get()) { + float mdistance = myself->GetPos().ManhattanDistance(node_.target_pos); + if (mdistance < 10) { + ChangeToStateAI(HSE_Thinking); + } + } +} + void HeroAI::DoMoveAI() { Hero* hero = (Hero*)owner; if (std::abs(hero->GetMoveDir().x) > FLT_EPSILON || std::abs(hero->GetMoveDir().y) > FLT_EPSILON) { + auto old_on_move_collision_func = hero->on_move_collision; hero->on_move_collision = [this] () { - ChangeToStateAI(HSE_RandomWalk); + if (node_.main_state == HSE_FollowMaster) { + ChangeToStateAI(HSE_FollowMaster); + } else { + ChangeToStateAI(HSE_RandomWalk); + } return false; }; int speed = std::max(1, (int)hero->GetSpeed()) * 1; hero->_UpdateMove(speed); - hero->on_move_collision = nullptr; + hero->on_move_collision = old_on_move_collision_func; } } @@ -315,6 +326,22 @@ void HeroAI::ChangeToStateAI(HeroState_e to_state) } } break; + case HSE_FollowMaster: + { + moving_ = true; + if (hero->master.Get()) { + a8::Vec2 target_pos = hero->master.Get()->GetPos(); + a8::Vec2 target_dir = a8::Vec2::UP; + target_dir.Rotate(a8::RandAngle()); + target_pos = target_pos + target_dir * 80; + a8::Vec2 move_dir = target_pos - hero->GetPos(); + move_dir.Normalize(); + hero->SetMoveDir(move_dir); + hero->attack_dir = hero->GetMoveDir(); + node_.target_pos = target_pos; + } + } + break; } node_.main_state = to_state; node_.frameno = hero->room->GetFrameNo(); diff --git a/server/gameserver/hero.ai.h b/server/gameserver/hero.ai.h index d3c5fb1..24ec9fa 100644 --- a/server/gameserver/hero.ai.h +++ b/server/gameserver/hero.ai.h @@ -14,7 +14,8 @@ enum HeroState_e HSE_Thinking = 1, HSE_Attack = 2, HSE_RandomWalk = 3, - HSE_Pursuit = 4 + HSE_Pursuit = 4, + HSE_FollowMaster = 5 }; class Human; @@ -35,6 +36,7 @@ public: CreatureWeakPtr nearest_human; long long last_check_nearest_human_frameno = 0; a8::Vec2 shot_dir; + a8::Vec2 target_pos; }; class HeroAI : public AIComponent @@ -52,6 +54,7 @@ private: void UpdateAttack(); void UpdateRandomWalk(); void UpdatePursuit(); + void UpdateFollowMaster(); void DoMoveAI(); void ChangeToStateAI(HeroState_e to_state); void DoShotAI(); diff --git a/server/gameserver/hero.cc b/server/gameserver/hero.cc index dead4e4..e8897c8 100644 --- a/server/gameserver/hero.cc +++ b/server/gameserver/hero.cc @@ -47,7 +47,7 @@ void Hero::FillMFObjectFull(Room* room, Human* hum, cs::MFObjectFull* full_data) TypeConvert::ToPb(GetPos(), p->mutable_pos()); TypeConvert::ToPb(GetMoveDir(), p->mutable_dir()); p->set_heroid(meta->i->id()); - p->set_master_uniid(master ? master->GetEntityUniId() : 0); + p->set_master_uniid(master.Get() ? master.Get()->GetEntityUniId() : 0); } void Hero::Update(int delta_time) diff --git a/server/gameserver/hero.h b/server/gameserver/hero.h index 98247dd..fe459a4 100644 --- a/server/gameserver/hero.h +++ b/server/gameserver/hero.h @@ -3,6 +3,7 @@ #include "creature.h" #include "cs_proto.pb.h" +#include "weakptr.h" namespace MetaData { @@ -16,7 +17,7 @@ class Creature; class Hero : public Creature { public: - Creature* master = nullptr; + CreatureWeakPtr master; MetaData::Player* meta = nullptr; bool shot_hold = false; diff --git a/server/gameserver/room.cc b/server/gameserver/room.cc index 97bac02..800d460 100644 --- a/server/gameserver/room.cc +++ b/server/gameserver/room.cc @@ -605,7 +605,7 @@ Hero* Room::CreateHero(Creature* master, { Hero* hero = EntityFactory::Instance()->MakeHero(AllocUniid()); hero->meta = meta; - hero->master = master; + hero->master.Attach(master); hero->room = this; hero->SetPos(pos); hero->SetMoveDir(dir);