mirror of
https://github.com/devZoGok/PlanetFleet.git
synced 2026-08-26 19:43:29 +00:00
using dest clamping to determine whether to build naval factories for CPU players
This commit is contained in:
@@ -126,33 +126,41 @@ function Player:landRouteToSpawnpoint_(mapPoint)
|
|||||||
source = map:getCellId(map:getSpawnPoint(self:getSpawnPointId()), false)
|
source = map:getCellId(map:getSpawnPoint(self:getSpawnPointId()), false)
|
||||||
|
|
||||||
pf = Pathfinder.getSingleton()
|
pf = Pathfinder.getSingleton()
|
||||||
cells = map:getCells()
|
forwClampedDest = pf:clampDestToSourceRegion(source, dest)
|
||||||
heurs = pf:calcHeuristics(cells, dest)
|
|
||||||
path = pf:findPath(cells, heurs, source, dest, UnitType.HOVER)
|
|
||||||
|
|
||||||
embarkCellId = nil
|
if dest ~= forwClampedDest then
|
||||||
disembarkCellId = nil
|
cells = map:getCells()
|
||||||
navalSupportCellId = nil
|
|
||||||
navalRallyCellId = nil
|
|
||||||
|
|
||||||
for i = 1, #path do
|
embarkCellId = nil
|
||||||
if map:getCell(path[i]).type == 1 then
|
navalRallyCellId = nil
|
||||||
navalRallyCellId = path[i]
|
embarkCellId = forwClampedDest
|
||||||
embarkCellId = path[i - 1]
|
|
||||||
if not self.navalFactoryCellId then self.navalFactoryCellId = path[i] end
|
for i = 1, #cells[embarkCellId + 1].edges do
|
||||||
break;
|
destCellId = cells[embarkCellId + 1].edges[i].destCellId
|
||||||
|
|
||||||
|
if cells[destCellId + 1].type == 1 then
|
||||||
|
if not self.navalFactoryCellId then self.navalFactoryCellId = destCellId end
|
||||||
|
|
||||||
|
navalRallyCellId = destCellId
|
||||||
|
break
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
for i = #path, 1, -1 do
|
disembarkCellId = nil
|
||||||
if map:getCell(path[i]).type == 1 then
|
navalSupportCellId = nil
|
||||||
navalSupportCellId = path[i]
|
backwClampedDest = pf:clampDestToSourceRegion(dest, source)
|
||||||
disembarkCellId = path[i + 1]
|
disembarkCellId = backwClampedDest
|
||||||
break;
|
|
||||||
|
for i = 1, #cells[disembarkCellId + 1].edges do
|
||||||
|
destCellId = cells[disembarkCellId + 1].edges[i].destCellId
|
||||||
|
|
||||||
|
if cells[destCellId + 1].type == 1 then
|
||||||
|
navalSupportCellId = destCellId
|
||||||
|
break
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
if embarkCellId or disembarkCellId then
|
|
||||||
return {
|
return {
|
||||||
reachable = false,
|
reachable = false,
|
||||||
embarkCellId = embarkCellId,
|
embarkCellId = embarkCellId,
|
||||||
@@ -160,7 +168,9 @@ function Player:landRouteToSpawnpoint_(mapPoint)
|
|||||||
navalSupportCellId = navalSupportCellId,
|
navalSupportCellId = navalSupportCellId,
|
||||||
disembarkCellId = disembarkCellId
|
disembarkCellId = disembarkCellId
|
||||||
}
|
}
|
||||||
else return {reachable = true} end
|
else
|
||||||
|
return {reachable = true}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Player:landRouteToSpawnpoint(arguments)
|
function Player:landRouteToSpawnpoint(arguments)
|
||||||
|
|||||||
+8
-1
@@ -201,10 +201,16 @@ namespace battleship{
|
|||||||
"multVec", [](Quaternion q, Vector3 v){return q * v;}
|
"multVec", [](Quaternion q, Vector3 v){return q * v;}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
SOL_LUA_STATE.new_usertype<Map::Edge>(
|
||||||
|
"Edge",
|
||||||
|
"destCellId", &Map::Edge::destCellId
|
||||||
|
);
|
||||||
|
|
||||||
SOL_LUA_STATE.new_usertype<Map::Cell>(
|
SOL_LUA_STATE.new_usertype<Map::Cell>(
|
||||||
"Cell",
|
"Cell",
|
||||||
"pos", &Map::Cell::pos,
|
"pos", &Map::Cell::pos,
|
||||||
"type", &Map::Cell::type
|
"type", &Map::Cell::type,
|
||||||
|
"edges", &Map::Cell::edges
|
||||||
);
|
);
|
||||||
|
|
||||||
SOL_LUA_STATE.new_usertype<Map>(
|
SOL_LUA_STATE.new_usertype<Map>(
|
||||||
@@ -221,6 +227,7 @@ namespace battleship{
|
|||||||
SOL_LUA_STATE.new_usertype<Pathfinder>(
|
SOL_LUA_STATE.new_usertype<Pathfinder>(
|
||||||
"Pathfinder",
|
"Pathfinder",
|
||||||
"getSingleton", &Pathfinder::getSingleton,
|
"getSingleton", &Pathfinder::getSingleton,
|
||||||
|
"clampDestToSourceRegion", &Pathfinder::clampDestToSourceRegion,
|
||||||
"calcHeuristics", &Pathfinder::calcHeuristics,
|
"calcHeuristics", &Pathfinder::calcHeuristics,
|
||||||
"findPath", &Pathfinder::findPath
|
"findPath", &Pathfinder::findPath
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -16,6 +16,36 @@ namespace battleship{
|
|||||||
return pathfinder;
|
return pathfinder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Pathfinder::clampDestToSourceRegion(int source, int dest){
|
||||||
|
Map *map = Map::getSingleton();
|
||||||
|
vector<Map::Cell> &cells = map->getCells();
|
||||||
|
pair<Map::Cell::Type, vector<Map::Cell*>> srcRegion;
|
||||||
|
|
||||||
|
for(int i = 0; i < map->getNumRegions(); i++){
|
||||||
|
pair<Map::Cell::Type, vector<Map::Cell*>> region = map->getRegion(i);
|
||||||
|
|
||||||
|
if(find(region.second.begin(), region.second.end(), &cells[source]) != region.second.end()){
|
||||||
|
srcRegion = map->getRegion(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(find(srcRegion.second.begin(), srcRegion.second.end(), &cells[dest]) == srcRegion.second.end()){
|
||||||
|
int minDistId = 0;
|
||||||
|
|
||||||
|
for(int i = 0; i < srcRegion.second.size(); i++){
|
||||||
|
float currDist = cells[dest].pos.getDistanceFrom(srcRegion.second[i]->pos);
|
||||||
|
float minDist = cells[dest].pos.getDistanceFrom(srcRegion.second[minDistId]->pos);
|
||||||
|
|
||||||
|
if(currDist < minDist) minDistId = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
dest = map->getCellId(srcRegion.second[minDistId]->pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
vector<float> Pathfinder::calcHeuristics(vector<Map::Cell> &cells, int dest){
|
vector<float> Pathfinder::calcHeuristics(vector<Map::Cell> &cells, int dest){
|
||||||
vector<float> heuristics;
|
vector<float> heuristics;
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ namespace battleship{
|
|||||||
class Pathfinder{
|
class Pathfinder{
|
||||||
public:
|
public:
|
||||||
static Pathfinder* getSingleton();
|
static Pathfinder* getSingleton();
|
||||||
|
int clampDestToSourceRegion(int, int);
|
||||||
std::vector<float> calcHeuristics(std::vector<Map::Cell>&, int);
|
std::vector<float> calcHeuristics(std::vector<Map::Cell>&, int);
|
||||||
std::vector<int> findPath(std::vector<Map::Cell>&, std::vector<float>&, int, int, int = -1);
|
std::vector<int> findPath(std::vector<Map::Cell>&, std::vector<float>&, int, int, int = -1);
|
||||||
inline vb01::u32 getImpassibleNodeVal(){return impassibleNodeVal;}
|
inline vb01::u32 getImpassibleNodeVal(){return impassibleNodeVal;}
|
||||||
|
|||||||
+40
-86
@@ -317,100 +317,66 @@ namespace battleship{
|
|||||||
debugPathPoints.push_back(n);
|
debugPathPoints.push_back(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO allow ships to attack land targets and vice versa
|
|
||||||
//TODO recursively search for vacant dest cell neibourghss
|
//TODO recursively search for vacant dest cell neibourghss
|
||||||
bool Vehicle::adjustDest(Vector3 destPos, int &source, int &dest){
|
void Vehicle::preparePathpoints(Order &order, Vector3 destPos, bool appendDestPos){
|
||||||
|
removeAllPathpoints();
|
||||||
|
|
||||||
Map *map = Map::getSingleton();
|
Map *map = Map::getSingleton();
|
||||||
vector<Map::Cell> &cells = map->getCells();
|
vector<Map::Cell> &cells = map->getCells();
|
||||||
source = map->getCellId(pos);
|
|
||||||
|
|
||||||
|
int source = map->getCellId(pos);
|
||||||
bool ship = (type == UnitType::UNDERWATER || type == UnitType::SEA_LEVEL);
|
bool ship = (type == UnitType::UNDERWATER || type == UnitType::SEA_LEVEL);
|
||||||
bool waterVehCanMove = (ship && cells[source].type == Map::Cell::WATER);
|
bool waterVehCanMove = (ship && cells[source].type == Map::Cell::WATER);
|
||||||
bool landVehCanMove = (type == UnitType::LAND && cells[source].type == Map::Cell::LAND);
|
bool landVehCanMove = (type == UnitType::LAND && cells[source].type == Map::Cell::LAND);
|
||||||
|
|
||||||
if(type != UnitType::HOVER && !(waterVehCanMove || landVehCanMove)) return false;
|
if(type != UnitType::HOVER && !(waterVehCanMove || landVehCanMove)) return;
|
||||||
|
|
||||||
dest = map->getCellId(destPos);
|
int dest = map->getCellId(destPos);
|
||||||
|
|
||||||
if(type == UnitType::SEA_LEVEL && fabs(destPos.y - cells[dest].pos.y) > .1) return false;
|
if(type == UnitType::SEA_LEVEL && fabs(destPos.y - cells[dest].pos.y) > .1) return;
|
||||||
|
|
||||||
if(type != UnitType::HOVER){
|
Pathfinder *pf = Pathfinder::getSingleton();
|
||||||
pair<Map::Cell::Type, vector<Map::Cell*>> srcRegion;
|
|
||||||
|
|
||||||
for(int i = 0; i < map->getNumRegions(); i++){
|
if(type != UnitType::HOVER)
|
||||||
pair<Map::Cell::Type, vector<Map::Cell*>> region = map->getRegion(i);
|
dest = pf->clampDestToSourceRegion(source, dest);
|
||||||
|
|
||||||
if(find(region.second.begin(), region.second.end(), &cells[source]) != region.second.end()){
|
|
||||||
srcRegion = map->getRegion(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(find(srcRegion.second.begin(), srcRegion.second.end(), &cells[dest]) == srcRegion.second.end()){
|
|
||||||
int minDistId = 0;
|
|
||||||
|
|
||||||
for(int i = 0; i < srcRegion.second.size(); i++){
|
|
||||||
float currDist = cells[dest].pos.getDistanceFrom(srcRegion.second[i]->pos);
|
|
||||||
float minDist = cells[dest].pos.getDistanceFrom(srcRegion.second[minDistId]->pos);
|
|
||||||
|
|
||||||
if(currDist < minDist) minDistId = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
dest = map->getCellId(srcRegion.second[minDistId]->pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(cells[dest].blockedBy){
|
if(cells[dest].blockedBy){
|
||||||
vector<int> surrCellIds = map->getSurroundingCells(cells[dest].pos, 1);
|
vector<int> surrCellIds = map->getSurroundingCells(cells[dest].pos, 1);
|
||||||
|
|
||||||
for(int scid : surrCellIds){
|
for(int scid : surrCellIds){
|
||||||
|
int altDest = -1;
|
||||||
|
|
||||||
if(!cells[scid].blockedBy)
|
if(!cells[scid].blockedBy)
|
||||||
switch(type){
|
switch(type){
|
||||||
case UnitType::HOVER:
|
case UnitType::HOVER:
|
||||||
dest = scid;
|
altDest = scid;
|
||||||
return true;
|
break;
|
||||||
case UnitType::LAND:
|
case UnitType::LAND:
|
||||||
if(cells[scid].type == Map::Cell::LAND){
|
if(cells[scid].type == Map::Cell::LAND)
|
||||||
dest = scid;
|
altDest = scid;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case UnitType::SEA_LEVEL:
|
case UnitType::SEA_LEVEL:
|
||||||
case UnitType::UNDERWATER:
|
case UnitType::UNDERWATER:
|
||||||
if(cells[scid].type == Map::Cell::WATER){
|
if(cells[scid].type == Map::Cell::WATER)
|
||||||
dest = scid;
|
altDest = scid;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
if(altDest != -1){
|
||||||
|
dest = altDest;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else return true;
|
vector<float> heurs;
|
||||||
}
|
vector<int> path = pf->findPath(cells, heurs, source, dest, (int)type);
|
||||||
|
Vector3 *truncPoint = nullptr;
|
||||||
|
|
||||||
bool Vehicle::truncatePath(Order &order, vector<int> &path, Vector3 destPos, bool appendDestPos){
|
if(order.targets[0].unit){
|
||||||
bool pathTruncated = false;
|
|
||||||
bool ship = (type == UnitType::UNDERWATER || type == UnitType::SEA_LEVEL);
|
|
||||||
vector<Map::Cell> &cells = Map::getSingleton()->getCells();
|
|
||||||
|
|
||||||
for(int i = 1; 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)){
|
|
||||||
path = vector<int>(path.begin(), path.begin() + i);
|
|
||||||
order.targets[0].unit = nullptr;
|
|
||||||
order.targets[0].pos = cells[path[i - 1]].pos;
|
|
||||||
pathTruncated = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if(order.type == Order::TYPE::GARRISON && type == UnitType::LAND && cells[path[i]].type != Map::Cell::LAND && path.size() - 1 != i)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int p : path) addPathpoint(cells[p].pos);
|
|
||||||
|
|
||||||
if(order.targets[0].unit && !pathTruncated){
|
|
||||||
GameObject *targObj = order.targets[0].unit;
|
GameObject *targObj = order.targets[0].unit;
|
||||||
|
|
||||||
for(int i = path.size() - 1; i >= 0; i--){
|
for(int i = path.size() - 1; i >= 0; i--){
|
||||||
@@ -443,35 +409,23 @@ namespace battleship{
|
|||||||
if(dirAngle <= a1) dist = (.5 * length) / cos(dirAngle);
|
if(dirAngle <= a1) dist = (.5 * length) / cos(dirAngle);
|
||||||
else if(leftAngle <= a2) dist = (.5 * width) / cos(leftAngle);
|
else if(leftAngle <= a2) dist = (.5 * width) / cos(leftAngle);
|
||||||
|
|
||||||
addPathpoint(targPos + pointDir.norm() * dist);
|
truncPoint = new Vector3;
|
||||||
pathTruncated = true;
|
*truncPoint = (targPos + pointDir.norm() * dist);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else removePathpoint(pathPoints.size() - 1);
|
else path.pop_back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(appendDestPos && !pathTruncated)
|
for(int p : path) addPathpoint(cells[p].pos);
|
||||||
|
|
||||||
|
if(appendDestPos && !truncPoint)
|
||||||
addPathpoint(destPos);
|
addPathpoint(destPos);
|
||||||
|
else if(truncPoint){
|
||||||
return true;
|
addPathpoint(*truncPoint);
|
||||||
}
|
delete truncPoint;
|
||||||
|
}
|
||||||
void Vehicle::preparePathpoints(Order &order, Vector3 destPos, bool appendDestPos){
|
|
||||||
removeAllPathpoints();
|
|
||||||
|
|
||||||
Map *map = Map::getSingleton();
|
|
||||||
vector<Map::Cell> &cells = map->getCells();
|
|
||||||
int source, dest;
|
|
||||||
|
|
||||||
if(!adjustDest(destPos, source, dest)) return;
|
|
||||||
|
|
||||||
vector<float> heurs;
|
|
||||||
Pathfinder *pf = Pathfinder::getSingleton();
|
|
||||||
vector<int> path = pf->findPath(cells, heurs, source, dest, (int)type);
|
|
||||||
|
|
||||||
if(path.empty() || !truncatePath(order, path, destPos, appendDestPos)) return;
|
|
||||||
|
|
||||||
path.erase(path.begin());
|
path.erase(path.begin());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user