From 6341a1a31f19a37c24a404c10fde9240943a931d Mon Sep 17 00:00:00 2001 From: aozhiwei Date: Thu, 6 Aug 2020 14:16:00 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=AF=BB=E8=B7=AF=E5=9F=BA?= =?UTF-8?q?=E7=A1=80=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/gameserver/human.cc | 8 +++++ server/gameserver/human.h | 2 ++ server/gameserver/mapsearchnode.cc | 46 ++++++++++++++++++++++++++ server/gameserver/mapsearchnode.h | 19 +++++++++++ server/gameserver/mapservice.cc | 53 ++++++++++++++++++++++++++++++ server/gameserver/mapservice.h | 10 +++++- server/gameserver/zombiemode.ai.cc | 51 ++++++++++++++++++++++++++-- server/gameserver/zombiemode.ai.h | 4 ++- 8 files changed, 189 insertions(+), 4 deletions(-) create mode 100644 server/gameserver/mapsearchnode.cc create mode 100644 server/gameserver/mapsearchnode.h diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index 8457009..3d48f6e 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -3163,6 +3163,14 @@ int Human::GetItemNum(int item_id) return itr != items_.end() ? itr->second : 0; } +void Human::ClearFindPathStatus() +{ + if (findpath_status_) { + room->map_service->DelFindPathRequest(this, findpath_status_); + findpath_status_ = nullptr; + } +} + void Human::AddItem(int item_id, int item_num) { auto itr = items_.find(item_id); diff --git a/server/gameserver/human.h b/server/gameserver/human.h index 0398b63..f8de066 100644 --- a/server/gameserver/human.h +++ b/server/gameserver/human.h @@ -265,6 +265,8 @@ class Human : public MoveableEntity int GetLevel() {return level_;}; int GetExp() {return exp_;}; FindPathStatus* GetFindPathStatus() { return findpath_status_; } + void SetFindPathStatus(FindPathStatus* status) { findpath_status_ = status; } + void ClearFindPathStatus(); void OnAttack() {}; void OnHit() {}; int GetItemNum(int item_id); diff --git a/server/gameserver/mapsearchnode.cc b/server/gameserver/mapsearchnode.cc new file mode 100644 index 0000000..4786ac0 --- /dev/null +++ b/server/gameserver/mapsearchnode.cc @@ -0,0 +1,46 @@ +#include "precompile.h" + +#include "mapsearchnode.h" + +float MapSearchNode::GoalDistanceEstimate(MapSearchNode &node_goal) +{ + float xd = float(((float)x - (float)node_goal.x)); + float yd = float(((float)y - (float)node_goal.y)); + + return xd + yd; +} + +bool MapSearchNode::IsGoal(MapSearchNode &node_goal) +{ + if (x == node_goal.x && y == node_goal.y) { + return true; + } else { + return false; + } +} + +bool MapSearchNode::GetSuccessors(AStarSearch *astarsearch, MapSearchNode *parent_node) +{ + return false; +} + +float MapSearchNode::GetCost(MapSearchNode &successor) +{ +#if 1 + return 1.0f; +#else + if (x != successor.x && y != successor.y) { + return (float) (NavTileHandle::pCurrNavTileHandle->getMap( x, y ) + 0.41421356/* ±¾ÉíÓÐÖÁÉÙ1µÄÖµ */); //sqrt(2) + } + return (float) NavTileHandle::pCurrNavTileHandle->getMap( x, y ); +#endif +} + +bool MapSearchNode::IsSameState(MapSearchNode &rhs) +{ + if (x == rhs.x && y == rhs.y) { + return true; + } else { + return false; + } +} diff --git a/server/gameserver/mapsearchnode.h b/server/gameserver/mapsearchnode.h new file mode 100644 index 0000000..f62e255 --- /dev/null +++ b/server/gameserver/mapsearchnode.h @@ -0,0 +1,19 @@ +#pragma once + +#include "framework/stlastar.h" + +class MapSearchNode +{ +public: + int x = 0; // the (x,y) positions of the node + int y = 0; + + MapSearchNode(int px, int py) {x = px; y = py; } + + float GoalDistanceEstimate(MapSearchNode &node_goal); + bool IsGoal(MapSearchNode &node_goal); + bool GetSuccessors(AStarSearch *astarsearch, MapSearchNode *parent_node); + float GetCost(MapSearchNode &successor); + bool IsSameState(MapSearchNode &rhs); + +}; diff --git a/server/gameserver/mapservice.cc b/server/gameserver/mapservice.cc index fb1a009..2019510 100644 --- a/server/gameserver/mapservice.cc +++ b/server/gameserver/mapservice.cc @@ -263,3 +263,56 @@ void MapService::DelFindPathRequest(Human* hum, FindPathStatus* status) A8_SAFE_DELETE(status); findpath_requests_hash_.erase(itr); } + +void MapService::FindPathUpdate(FindPathStatus* find_status) +{ + +} + +bool MapService::FindOk(FindPathStatus* find_status) +{ + return false; +} + +bool MapService::MoveDone(FindPathStatus* find_status) +{ + if (find_status->path_index >= (int)find_status->out_points.size() || + find_status->out_points.empty()) { + abort(); + } + if (find_status->path_index + 1 == (int)find_status->out_points.size()) { + MovePathPoint* point = &find_status->out_points[find_status->path_index]; + if (point->pos.ManhattanDistance(find_status->hum->GetPos()) > 2.0f) { + return false; + } + float distance = point->pos.Distance(find_status->hum->GetPos()); + if (distance < 0.000001f) { + return true; + } else { + return false; + } + } else { + return false; + } +} + +void MapService::DoMove(FindPathStatus* find_status) +{ + if (find_status->path_index >= (int)find_status->out_points.size() || + find_status->out_points.empty()) { + abort(); + } + Human* myself = find_status->hum; + MovePathPoint* point = &find_status->out_points[find_status->path_index]; + myself->move_dir = point->pos - myself->GetPos(); + myself->move_dir.Normalize(); + float target_distance = point->pos.Distance(myself->GetPos()); + float speed = std::min(myself->GetSpeed(), target_distance); + a8::Vec2 new_pos = myself->GetPos() + myself->move_dir * speed; + myself->SetPos(new_pos); + target_distance = point->pos.Distance(myself->GetPos()); + if (target_distance < 1.0001f) { + myself->SetPos(point->pos); + ++find_status->path_index; + } +} diff --git a/server/gameserver/mapservice.h b/server/gameserver/mapservice.h index f1c3186..b71bdb2 100644 --- a/server/gameserver/mapservice.h +++ b/server/gameserver/mapservice.h @@ -1,5 +1,7 @@ #pragma once +#include "framework/stlastar.h" + class Human; class ColliderComponent; @@ -24,7 +26,8 @@ struct FindPathStatus a8::Vec2 end_pos; int curr_step = 0; int max_step_num = 0; - std::vector out_ponits; + int path_index = 0; + std::vector out_points; list_head entry; FindPathStatus() @@ -49,11 +52,16 @@ class MapService float world_x, float world_y, std::set& colliders); + FindPathStatus* AddFindPathRequest(Human* hum, const a8::Vec2& start_pos, const a8::Vec2& end_pos, int max_step_num); void DelFindPathRequest(Human* hum, FindPathStatus* status); + void FindPathUpdate(FindPathStatus* find_status); + bool FindOk(FindPathStatus* find_status); + bool MoveDone(FindPathStatus* find_status); + void DoMove(FindPathStatus* find_status); private: int GetGridId(float world_x, float world_y); diff --git a/server/gameserver/zombiemode.ai.cc b/server/gameserver/zombiemode.ai.cc index 6faf655..f19bb7f 100644 --- a/server/gameserver/zombiemode.ai.cc +++ b/server/gameserver/zombiemode.ai.cc @@ -125,6 +125,11 @@ void ZombieModeAI::UpdateAI() UpdateFindPath(); } break; + case ZSE_FindPathMoving: + { + UpdateFindPathMoving(); + } + break; default: { abort(); @@ -203,14 +208,14 @@ void ZombieModeAI::UpdateAttack() //站桩 ChangeToState(ZSE_Thinking); } else { - #if 1 + #if 0 ChangeToState(ZSE_Pursuit); #else if (distance < node_->ai_meta->i->pursuit_radius()) { //追击 ChangeToState(ZSE_Pursuit); } else { - ChangeToState(ZSE_Thinking); + ChangeToState(ZSE_FindPath); } #endif } @@ -276,7 +281,34 @@ void ZombieModeAI::UpdatePursuit() void ZombieModeAI::UpdateFindPath() { + Human* myself = (Human*)owner; + FindPathStatus* find_status = myself->GetFindPathStatus(); + if (!find_status) { + ChangeToState(ZSE_Thinking); + } else { + if (myself->room->map_service->FindOk(find_status)) { + ChangeToState(ZSE_FindPathMoving); + } else { + myself->room->map_service->FindPathUpdate(find_status); + } + } +} +void ZombieModeAI::UpdateFindPathMoving() +{ + Human* myself = (Human*)owner; + FindPathStatus* find_status = myself->GetFindPathStatus(); + if (!find_status) { + ChangeToState(ZSE_Thinking); + } else { + if (myself->room->map_service->MoveDone(find_status)) { + myself->ClearFindPathStatus(); + ChangeToState(ZSE_Thinking); + } else { + node_->moving = false; + myself->room->map_service->DoMove(find_status); + } + } } void ZombieModeAI::DoMove() @@ -372,6 +404,21 @@ void ZombieModeAI::ChangeToState(ZombieState_e to_state) } break; case ZSE_FindPath: + { + hum->ClearFindPathStatus(); + FindPathStatus* status = hum->room->map_service->AddFindPathRequest + ( + hum, + hum->GetPos(), + node_->target->GetPos(), + 1000 + ); + if (status) { + hum->SetFindPathStatus(status); + } + } + break; + case ZSE_FindPathMoving: { } diff --git a/server/gameserver/zombiemode.ai.h b/server/gameserver/zombiemode.ai.h index f1ed986..f4ebb65 100644 --- a/server/gameserver/zombiemode.ai.h +++ b/server/gameserver/zombiemode.ai.h @@ -9,7 +9,8 @@ enum ZombieState_e ZSE_Attack = 2, ZSE_RandomWalk = 3, ZSE_Pursuit = 4, - ZSE_FindPath = 5 + ZSE_FindPath = 5, + ZSE_FindPathMoving = 6 }; class Human; @@ -32,6 +33,7 @@ private: void UpdateRandomWalk(); void UpdatePursuit(); void UpdateFindPath(); + void UpdateFindPathMoving(); void DoMove(); void ChangeToState(ZombieState_e to_state); void DoShot();