From 268ea14f4a77db64d976acbd60ebdb6ac9f3bc74 Mon Sep 17 00:00:00 2001 From: devZoGok Date: Mon, 16 Feb 2026 12:14:43 +0200 Subject: [PATCH] refactored path point generation exposed Pathfinder to Lua --- Assets/Scripts/Core/player.lua | 21 +++++++++++++++- gameManager.cpp | 17 +++++++++++++ map.h | 1 + pathfinder.cpp | 3 +++ vehicle.cpp | 46 +++++++++++++++++++++++----------- vehicle.h | 2 ++ 6 files changed, 75 insertions(+), 15 deletions(-) diff --git a/Assets/Scripts/Core/player.lua b/Assets/Scripts/Core/player.lua index 0af5c47..475c33e 100644 --- a/Assets/Scripts/Core/player.lua +++ b/Assets/Scripts/Core/player.lua @@ -331,8 +331,27 @@ function Player:formTaskForces(arguments) return BTNodeResult.SUCCESS end +--TODO remove heuristics +function Player:landRouteToSpawnpoint(mapPoint) + map = Map.getSingleton() + dest = map:getCellId(mapPoint, false) + source = map:getCellId(map:getSpawnPoint(self:getSpawnPointId()), false) + + pf = Pathfinder.getSingleton() + cells = map:getCells() + heurs = pf:calcHeuristics(cells, dest) + path = pf:findPath(cells, heurs, source, dest, nil) + + for i = 1, #path do + if cells[path[i]].type == 1 then return false end + end + + return true +end + function Player:isLandRouteToSpawnpoint(arguments) - return BTNodeResult.SUCCESS + mapPoint = Map.getSingleton():getSpawnPoint(self.taskForces[arguments.taskForceId].spawnPointId) + return (self:landRouteToSpawnpoint(mapPoint) and BTNodeResult.SUCCESS or BTNodeResult.FAILURE) end function Player:occupySpawnPoint(arguments) diff --git a/gameManager.cpp b/gameManager.cpp index 4b476fd..008de60 100755 --- a/gameManager.cpp +++ b/gameManager.cpp @@ -19,6 +19,7 @@ #include "engineer.h" #include "destructable.h" #include "pointDefense.h" +#include "pathfinder.h" #include "resourceDeposit.h" using namespace std; @@ -165,13 +166,29 @@ namespace battleship{ "multVec", [](Quaternion q, Vector3 v){return q * v;} ); + SOL_LUA_STATE.new_usertype( + "Cell", + "pos", &Map::Cell::pos, + "type", &Map::Cell::type + ); + SOL_LUA_STATE.new_usertype( "Map", "getSingleton", &Map::getSingleton, + "getCell", &Map::getCell, + "getCells", &Map::getCells, + "getCellId", &Map::getCellId, "getMapSize", &Map::getMapSize, "getSpawnPoint", &Map::getSpawnPoint, "getNumSpawnPoints", &Map::getNumSpawnPoints ); + + SOL_LUA_STATE.new_usertype( + "Pathfinder", + "getSingleton", &Pathfinder::getSingleton, + "calcHeuristics", &Pathfinder::calcHeuristics, + "findPath", &Pathfinder::findPath + ); } void GameManager::initLua(string gameDir){ diff --git a/map.h b/map.h index 700ac67..c9d0b4a 100755 --- a/map.h +++ b/map.h @@ -83,6 +83,7 @@ namespace battleship{ std::vector getSurroundingCells(vb01::Vector3, int); void blockCells(Unit*); void unblockCells(Unit*); + inline Map::Cell getCell(int i){return cells[i];} inline std::string getMapName(){return mapName;} inline vb01::Node* getNodeParent(){return terrainNode;} inline vb01::Vector3 getCellSize(){return CELL_SIZE;} diff --git a/pathfinder.cpp b/pathfinder.cpp index c0b3924..b693387 100644 --- a/pathfinder.cpp +++ b/pathfinder.cpp @@ -26,6 +26,9 @@ namespace battleship{ } vector Pathfinder::findPath(vector &cells, vector &heuristics, int source, int dest, Vehicle *vehicle){ + if(heuristics.empty() || (heuristics.size() == 1 && heuristics[0] == 0.0)) + heuristics = calcHeuristics(cells, dest); + const int size = cells.size(); u32 *distances = new u32[size]; vector *paths = new vector[size]; diff --git a/vehicle.cpp b/vehicle.cpp index d61f979..ded8ccc 100644 --- a/vehicle.cpp +++ b/vehicle.cpp @@ -316,22 +316,20 @@ namespace battleship{ //TODO allow ships to attack land targets and vice versa //TODO recursively search for vacant dest cell neibourghss - void Vehicle::preparePathpoints(Order &order, Vector3 destPos, bool appendDestPos){ - removeAllPathpoints(); - + bool Vehicle::canReachTarget(Vector3 destPos, int &source, int &dest){ Map *map = Map::getSingleton(); vector &cells = map->getCells(); - int source = map->getCellId(pos); + source = map->getCellId(pos); bool ship = (type == UnitType::UNDERWATER || type == UnitType::SEA_LEVEL); bool waterVehCanMove = (ship && cells[source].type == Map::Cell::WATER); bool landVehCanMove = (type == UnitType::LAND && cells[source].type == Map::Cell::LAND); - if(type != UnitType::HOVER && !(waterVehCanMove || landVehCanMove)) return; + if(type != UnitType::HOVER && !(waterVehCanMove || landVehCanMove)) return false; - int dest = map->getCellId(destPos); + dest = map->getCellId(destPos); - if(type != UnitType::UNDERWATER && type == UnitType::SEA_LEVEL && fabs(destPos.y - cells[dest].pos.y) > .1) return; + if(type != UnitType::UNDERWATER && type == UnitType::SEA_LEVEL && fabs(destPos.y - cells[dest].pos.y) > .1) return false; if(cells[dest].blockedBy){ vector surrCellIds = map->getSurroundingCells(cells[dest].pos, 1); @@ -343,14 +341,13 @@ namespace battleship{ } } - Pathfinder *pf = Pathfinder::getSingleton(); - vector heuristics = pf->calcHeuristics(cells, dest); - vector path = pf->findPath(cells, heuristics, source, dest, this); + return true; + } - if(path.empty()) return; - - path.erase(path.begin()); + bool Vehicle::truncatePath(Order &order, vector &path, Vector3 destPos, bool appendDestPos){ bool pathTruncated = false; + bool ship = (type == UnitType::UNDERWATER || type == UnitType::SEA_LEVEL); + vector &cells = Map::getSingleton()->getCells(); for(int i = 0; i < path.size(); i++){ if((ship && cells[path[i]].type != Map::Cell::WATER) || (order.type != Order::TYPE::GARRISON && type == UnitType::LAND && cells[path[i]].type != Map::Cell::LAND)){ @@ -361,7 +358,7 @@ namespace battleship{ break; } else if(order.type == Order::TYPE::GARRISON && type == UnitType::LAND && cells[path[i]].type != Map::Cell::LAND && path.size() - 1 != i) - return; + return false; } for(int p : path) addPathpoint(cells[p].pos); @@ -410,6 +407,27 @@ namespace battleship{ if(appendDestPos && !pathTruncated) addPathpoint(destPos); + + return true; + } + + void Vehicle::preparePathpoints(Order &order, Vector3 destPos, bool appendDestPos){ + removeAllPathpoints(); + + vector &cells = Map::getSingleton()->getCells(); + int source, dest; + + if(!canReachTarget(destPos, source, dest)) return; + + vector heurs; + Pathfinder *pf = Pathfinder::getSingleton(); + vector path = pf->findPath(cells, heurs, source, dest, this); + + if(path.empty()) return; + + path.erase(path.begin()); + + if(!truncatePath(order, path, destPos, appendDestPos)) return; } void Vehicle::removePathpoint(int i){ diff --git a/vehicle.h b/vehicle.h index 056199f..9b5bf64 100644 --- a/vehicle.h +++ b/vehicle.h @@ -25,6 +25,8 @@ namespace battleship{ vb01::s64 lastBuildTime = 0; inline int getNextPatrolPointId(int numPoints) {return patrolPointId == numPoints - 1 ? 0 : patrolPointId + 1;} + bool canReachTarget(vb01::Vector3, int&, int&); + bool truncatePath(Order&, std::vector&, vb01::Vector3, bool); void startCurrentOrder(); bool validateGarrisonOrder(Order); void enterGarrisonable();