Merge pull request #23 from devZoGok/bf-2-pathfinding

Bf 2 pathfinding
This commit is contained in:
devZoGok
2023-09-27 15:52:29 +00:00
committed by GitHub
23 changed files with 246 additions and 143479 deletions
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -5,7 +5,7 @@ gui = {
size = {x = 300, y = 20},
guiType = GuiType.LISTBOX,
listboxType = ListboxType.CONSOLE,
numMaxDisplay = 20,
numMaxDisplay = 10,
closable = false
},
{
+3 -3
View File
@@ -2,7 +2,7 @@ numUnits = 4
UnitClass = {VESSEL = 0, ENGINEER = 1, SAMPLE_STRUCTURE = 2};
UnitType = {UNDERWATER = 0, SEA_LEVEL = 1, LAND = 2, AIR = 3};
UnitType = {UNDERWATER = 0, SEA_LEVEL = 1, HOVER = 2, LAND = 3, AIR = 4};
unitClass = {
UnitClass.VESSEL, UnitClass.VESSEL,
@@ -10,8 +10,8 @@ unitClass = {
};
unitType = {
UnitType.SEA_LEVEL, UnitType.UNDERWATER,
UnitType.LAND, UnitType.LAND
UnitType.HOVER, UnitType.SEA_LEVEL,
UnitType.LAND, UnitType.HOVER
}
isVehicle = {
+1 -1
View File
@@ -5,7 +5,7 @@ project(${GAME_NAME})
set(CMAKE_CXX_STANDART 17)
set(CMAKE_BUILD_TYPE Debug)
set(BUILD_TESTS OFF)
set(BUILD_TESTS ON)
cmake_policy(SET CMP0015 NEW)
set(OPTIONS_BUTTONS optionsButton.cpp tabButton.cpp okButton.cpp defaultsButton.cpp)
+20 -11
View File
@@ -276,21 +276,30 @@ namespace battleship{
Map *map = Map::getSingleton();
/*
for(Unit *u : mainPlayer->getSelectedUnits())
if(u->getType() == UnitType::UNDERWATER){
for(int i = 1; i < map->getNumTerrainObjects(); i++){
if(map->isPointWithinTerrainObject(u->getPos(), i) && map->isPointWithinTerrainObject(results[0].pos, i)){
vector<Ray::CollisionResult> res;
Vector3 pos = u->getPos();
Ray::retrieveCollisions(Vector3(pos.x, map->getTerrainObject(0).size.y, pos.z), Vector3(0, -1, 0), map->getTerrainObject(0).node->getChild(0), res);
Ray::sortResults(res);
results[0].pos.y = res[0].pos.y + depth * (map->getTerrainObject(i).pos.y - res[0].pos.y);
for(Unit *u : mainPlayer->getSelectedUnits()){
Vector3 pos = u->getPos();
Node *nodeParent = map->getNodeParent();
if(u->getType() == UnitType::UNDERWATER && nodeParent->getNumChildren() > 0){
vector<Ray::CollisionResult> res;
Ray::retrieveCollisions(Vector3(pos.x, 100, pos.z), Vector3(0, -1, 0), nodeParent->getChild(0), res);
Ray::sortResults(res);
Vector3 waterBodyPos = Vector3::VEC_ZERO;
Vector3 cellSize = map->getCellSize();
for(int i = 1; i < nodeParent->getNumChildren(); i++){
Vector3 wpos = nodeParent->getChild(i)->getPosition();
if(fabs(wpos.x - pos.x) < .5 * cellSize.x && fabs(wpos.z - pos.z) < .5 * cellSize.z){
waterBodyPos = wpos;
break;
}
}
results[0].pos.y = res[0].pos.y + depth * (waterBodyPos.y - res[0].pos.y);
}
*/
}
targets.push_back(Order::Target((it != unitData.end() ? unitData[node] : unit), results[0].pos));
}
+1
View File
@@ -272,6 +272,7 @@ namespace battleship{
lines.push_back("");
closable = false;
maxDisplay = (numLines > numMaxDisplay ? numMaxDisplay : numLines);
listbox = new Listbox(pos, size, lines, maxDisplay, fontPath, closable);
}
+83 -17
View File
@@ -20,6 +20,17 @@ using namespace gameBase;
namespace battleship{
using namespace configData;
//TODO check if edges have lower weight than impassible weight value for the Pathfinder
int Map::Cell::getEdgeWeight(int destCellId){
int weight = Pathfinder::getSingleton()->getImpassibleNodeVal();
for(Edge e : edges)
if(e.destCellId == destCellId)
weight = e.weight;
return weight;
}
Map *map = nullptr;
Map* Map::getSingleton(){
@@ -182,6 +193,12 @@ namespace battleship{
edges.push_back(Edge(edgeTable["weight"], edgeTable["srcCellId"], edgeTable["destCellId"]));
}
int numUnderWaterCells = cellTable["numUnderWaterCells"];
vector<int> underWaterCellIds;
for(int j = 0; j < numUnderWaterCells; j++)
underWaterCellIds.push_back((int)cellTable["underWaterCellId"][j + 1]);
Vector3 cellPos = Vector3(posTable["x"], posTable["y"], posTable["z"]);
Cell::Type cellType = (Cell::Type)cellTable["type"];
@@ -193,10 +210,11 @@ namespace battleship{
node->attachMesh(quad);
cellNode->attachChild(node);
cells.push_back(Cell(cellPos, cellType, edges));
cells.push_back(Cell(cellPos, cellType, edges, underWaterCellIds));
}
}
//TODO implement map size calculation when exporting maps
void Map::load(string mapName, bool empty) {
this->mapName = mapName;
@@ -207,8 +225,9 @@ namespace battleship{
preprareScene();
if(!empty){
sol::state_view SOL_LUA_STATE = generateView();
SOL_LUA_STATE.script_file(GameManager::getSingleton()->getPath() + "Models/Maps/" + mapName + "/" + mapName + ".lua");
SOL_LUA_STATE.script_file(path + "Models/Maps/" + mapName + "/" + mapName + ".lua");
sol::table sizeTable = SOL_LUA_STATE[mapTable]["size"];
mapSize = Vector3(sizeTable["x"], sizeTable["y"], sizeTable["z"]);
int numWaterbodies = SOL_LUA_STATE[mapTable]["numWaterBodies"];
loadSpawnPoints();
@@ -224,22 +243,69 @@ namespace battleship{
void Map::unload() {}
int Map::getCellId(Vector3 pos, int id){
/*
Vector3 regionSize = terrainObjects[id].size;
Vector3 regionPos = terrainObjects[id].pos;
Vector3 cellSize = terrainObjects[id].cellSize;
template<typename T> int Map::bsearch(vector<T> haystack, T needle, float eps){
T haystackMidVal;
bool sizeHaystackEven = (haystack.size() % 2 == 0);
int midValId = haystack.size() / 2;
int numCellsX = regionSize.x / cellSize.x;
int numCellsZ = regionSize.z / cellSize.z;
if(sizeHaystackEven)
haystackMidVal = (haystack[midValId - 1] + haystack[midValId]) / 2;
else
haystackMidVal = haystack[midValId];
Vector3 initPos = regionPos - Vector3(regionSize.x, 0, regionSize.z) * 0.5;
int x = fabs(pos.x - initPos.x) / cellSize.x;
int y = (cellSize.y > 0 ? (fabs(pos.y - initPos.y) / cellSize.y) : 0);
int z = fabs(pos.z - initPos.z) / cellSize.z;
int beginId, endId;
return (numCellsX * numCellsZ * y + (numCellsX * z + x));
*/
return 0;
if(fabs(haystackMidVal - needle) > eps){
if(fabs(haystackMidVal - needle) < eps){
beginId = 0;
endId = (midValId - 1);
}
else{
endId = haystack.size() - 1;
endId = (midValId + 1);
}
return bsearch(vector<T>(haystack.begin() + beginId, haystack.begin() + endId), needle);
}
else{
if(sizeHaystackEven)
return midValId - (needle > haystackMidVal ? 0 : 1);
else
return midValId;
}
}
//TODO replace search with binary search
int Map::getCellId(Vector3 pos){
int numHorCells = int(mapSize.x / CELL_SIZE.x), horId = -1;
for(int i = 0; i < numHorCells; i++)
if(fabs(cells[i].pos.x - pos.x) < .5 * CELL_SIZE.x){
horId = i;
break;
}
int numVertCells = int(mapSize.z / CELL_SIZE.z), vertId = -1;
for(int i = 0; i < numVertCells; i++)
if(fabs(cells[i * numHorCells].pos.z - pos.z) < .5 * CELL_SIZE.z){
vertId = i;
break;
}
int surfaceCellId = vertId * numHorCells + horId;
if(cells[surfaceCellId].type == Cell::Type::WATER && !cells[surfaceCellId].underWaterCellIds.empty()){
int cellId = surfaceCellId;
for(int i = 0; i <= cells[surfaceCellId].underWaterCellIds.size(); i++){
cellId = (i == 0 ? surfaceCellId : cells[surfaceCellId].underWaterCellIds[i - 1]);
if(fabs(cells[cellId].pos.y - pos.y) < .5 * CELL_SIZE.y)
return cellId;
}
}
else
return surfaceCellId;
}
}
+8 -3
View File
@@ -16,6 +16,7 @@ namespace vb01{
namespace battleship{
class Player;
struct Cell;
class Map {
public:
@@ -32,9 +33,11 @@ namespace battleship{
Type type;
vb01::Vector3 pos;
std::vector<Edge> edges;
std::vector<int> underWaterCellIds;
Cell(){}
Cell(vb01::Vector3 p, Type t, std::vector<Edge> e = std::vector<Edge>{}): pos(p), type(t), edges(e){}
Cell(vb01::Vector3 p, Type t, std::vector<Edge> e = std::vector<Edge>{}, std::vector<int> uc = std::vector<int>{}): pos(p), type(t), edges(e), underWaterCellIds(uc){}
int getEdgeWeight(int);
};
static Map* getSingleton();
@@ -42,7 +45,7 @@ namespace battleship{
void update();
void load(std::string, bool = false);
void unload();
int getCellId(vb01::Vector3, int);
int getCellId(vb01::Vector3);
bool isPointWithinTerrainObject(vb01::Vector3, int);
inline std::string getMapName(){return mapName;}
inline vb01::Node* getNodeParent(){return terrainNode;}
@@ -54,12 +57,13 @@ namespace battleship{
inline int getNumSpawnPoints(){return spawnPoints.size();}
inline vb01::Vector3 getSpawnPoint(int i){return spawnPoints[i];}
inline void addSpawnPoint(vb01::Vector3 sp){spawnPoints.push_back(sp);}
inline std::vector<Map::Cell>& getCells(){return cells;}
private:
std::string mapTable = "map";
vb01::Node *terrainNode = nullptr, *cellNode = nullptr;
vb01::Material *landCellMat = nullptr, *waterCellMat = nullptr;
std::string mapName;
vb01::Vector3 CELL_SIZE = vb01::Vector3(7, 7, 7);
vb01::Vector3 CELL_SIZE = vb01::Vector3(7, 7, 7), mapSize;
std::vector<vb01::Vector3> spawnPoints;
std::vector<Player*> players;
std::vector<Cell> cells;
@@ -71,6 +75,7 @@ namespace battleship{
void loadSkybox();
void loadCells();
void loadTerrainObject(int);
template<typename T> int bsearch(std::vector<T>, T, float);
};
}
+36 -16
View File
@@ -74,6 +74,7 @@ namespace battleship{
}
void MapEditorAppState::MapEditor::castSelectionRay(){
/*
Camera *cam = Root::getSingleton()->getCamera();
Vector3 startPos = cam->getPosition();
Vector3 endPos = screenToSpace(getCursorPos());
@@ -93,6 +94,7 @@ namespace battleship{
break;
}
}
*/
}
void MapEditorAppState::MapEditor::createWaterbody(){
@@ -101,11 +103,11 @@ namespace battleship{
mat->addBoolUniform("texturingEnabled", true);
mat->addTexUniform("textures[0]", waterTextures[0], false);
Vector3 size = Vector3(10, 10, 1);
Vector3 size = Vector3(30, 30, 1);
Quad *quad = new Quad(size, true);
quad->setMaterial(mat);
Vector3 pos = 0.1 * Vector3::VEC_J;
Vector3 pos = 12 * Vector3::VEC_J;
Node *node = new Node(pos);
node->attachMesh(quad);
@@ -351,35 +353,40 @@ namespace battleship{
cells.push_back(Map::Cell(pos, type, edges));
}
std::map<int, vector<int>> waterCellMap;
vector<Map::Cell> waterCells;
int currUnderWaterCellId = cells.size();
int weight = 2;
for(pair<int, float> p : waterBodyBedPoints){
int numUnderWaterCells = (int)((cells[p.first].pos.y - p.second) / cellSize.y);
vector<int> underWaterCellIds;
if(numUnderWaterCells)
if(numUnderWaterCells > 0){
cells[p.first].edges.push_back(Map::Edge(weight, p.first, currUnderWaterCellId));
for(int i = 0; i < numUnderWaterCells; i++, currUnderWaterCellId++)
underWaterCellIds.push_back(currUnderWaterCellId);
for(int i = 0; i < numUnderWaterCells; i++, currUnderWaterCellId++)
cells[p.first].underWaterCellIds.push_back(currUnderWaterCellId);
waterCellMap[p.first] = underWaterCellIds;
waterCells.push_back(cells[p.first]);
}
}
for(int i = 0; i < waterCells.size(); i++){
for(int j = 0; j < waterCells[i].underWaterCellIds.size(); j++){
int aboveCellId = (j == 0 ? waterCells[i].edges[0].srcCellId : j - 1);
vector<Map::Edge> edges = vector<Map::Edge>{Map::Edge(weight, waterCells[i].underWaterCellIds[j], aboveCellId)};
for(std::map<int, vector<int>>::iterator it = waterCellMap.begin(); it != waterCellMap.end(); ++it){
for(int i = 0; i < waterCellMap[it->first].size(); i++){
vector<Map::Edge> edges = vector<Map::Edge>{Map::Edge(weight, waterCellMap[it->first][i], it->first)};
if(waterCells[i].underWaterCellIds.size() > j + 1)
edges.push_back(Map::Edge(weight, waterCells[i].underWaterCellIds[j], waterCells[i].underWaterCellIds[j + 1]));
for(Map::Edge edge : cells[it->first].edges){
if(cells[edge.destCellId].type == Map::Cell::Type::WATER && waterCellMap[edge.destCellId].size() >= i){
edges.push_back(Map::Edge(weight, waterCellMap[it->first][i], waterCellMap[edge.destCellId][i]));
for(int k = 0; k < waterCells[i].edges.size(); k++){
Map::Cell adjacentUnderwaterCell = cells[waterCells[i].edges[k].destCellId];
if(adjacentUnderwaterCell.underWaterCellIds.size() >= j + 1){
edges.push_back(Map::Edge(weight, waterCells[i].underWaterCellIds[j], adjacentUnderwaterCell.underWaterCellIds[j]));
}
}
Vector3 cellPos = cells[it->first].pos - Vector3::VEC_J * cellSize.y * (i + 1);
Vector3 cellPos = waterCells[i].pos - Vector3::VEC_J * cellSize.y * (j + 1);
cells.push_back(Map::Cell(cellPos, Map::Cell::Type::WATER, edges));
}
}
@@ -390,6 +397,7 @@ namespace battleship{
void MapEditorAppState::MapEditor::generateMapScript(){
int numWaterBodies = map->getNodeParent()->getNumChildren() - 1;
string mapScript = "map = {\nnumWaterBodies = " + to_string(numWaterBodies) + ",\n";
mapScript += "size = {x = " + to_string(mapSize.x) + ", y = 100, z = " + to_string(mapSize.y) + "},\n";
mapScript += "impassibleNodeValue = " + to_string(IMPASS_NODE_VAL) + ",\n";
mapScript += "numPlayers = " + to_string(map->getNumPlayers()) + ",\n";
@@ -444,7 +452,19 @@ namespace battleship{
for(Map::Edge edge : cell.edges)
mapScript += "{srcCellId = " + to_string(edge.srcCellId) + ", destCellId = " + to_string(edge.destCellId) + ", weight = " + to_string(edge.weight) + "}, ";
mapScript += "}\n},\n";
int numSubCells = cell.underWaterCellIds.size();
mapScript += "}, numUnderWaterCells = " + to_string(numSubCells) + ",";
if(numSubCells > 0){
mapScript += "underWaterCellId = {";
for(int subCellId : cell.underWaterCellIds)
mapScript += to_string(subCellId) + ", ";
mapScript += "}";
}
mapScript += "},\n";
}
mapScript += "},\n";
+11 -13
View File
@@ -1,8 +1,7 @@
#include <algorithm>
#include <iostream>
#include "pathfinder.h"
#include "map.h"
#include "unit.h"
namespace battleship{
using namespace std;
@@ -20,21 +19,15 @@ namespace battleship{
Pathfinder::Pathfinder(){
}
vector<int> Pathfinder::findPath(u32 **weights, int size, int source, int dest){
vector<int> Pathfinder::findPath(vector<Map::Cell> &cells, int source, int dest, int unitType){
int size = cells.size();
u32 distances[size];
vector<int> paths[size];
paths[source].push_back(source);
for(int i = 0; i < size; i++){
for(int i = 0; i < size; i++)
distances[i] = (i == source ? 0 : impassibleNodeVal);
for(int j = 0; j < size; j++)
if(weights[i][j] > impassibleNodeVal){
cout << "Node val higher than allowed max value\n";
exit(-1);
}
}
vector<int> checkedNodes;
while(find(checkedNodes.begin(), checkedNodes.end(), dest) == checkedNodes.end()){
@@ -59,9 +52,14 @@ namespace battleship{
for(int i = 0; i < size; i++){
bool isChecked = find(checkedNodes.begin(), checkedNodes.end(), i) != checkedNodes.end();
bool canMoveToStrichCell = true;
bool ship = ((UnitType)unitType == UnitType::UNDERWATER || (UnitType)unitType == UnitType::SEA_LEVEL);
if(!isChecked && (distances[vertStrich] + weights[vertStrich][i] < distances[i])){
distances[i] = distances[vertStrich] + weights[vertStrich][i];
if((ship && cells[vertStrich].type != Map::Cell::WATER) || ((UnitType)unitType == UnitType::LAND && cells[vertStrich].type != Map::Cell::LAND))
canMoveToStrichCell = false;
if(!isChecked && (canMoveToStrichCell && distances[vertStrich] + cells[vertStrich].getEdgeWeight(i) < distances[i])){
distances[i] = distances[vertStrich] + cells[vertStrich].getEdgeWeight(i);
paths[i] = paths[vertStrich];
paths[i].push_back(i);
}
+3 -1
View File
@@ -1,6 +1,8 @@
#ifndef PATHFINDER_H
#define PATHFINDER_H
#include "map.h"
#include <vector>
#include <util.h>
@@ -9,7 +11,7 @@ namespace battleship{
class Pathfinder{
public:
static Pathfinder* getSingleton();
std::vector<int> findPath(vb01::u32**, int, int, int);
std::vector<int> findPath(std::vector<Map::Cell>&, int, int, int = -1);
inline vb01::u32 getImpassibleNodeVal(){return impassibleNodeVal;}
inline void setImpassibleNodeVal(vb01::u32 val){this->impassibleNodeVal = val;}
private:
+19 -26
View File
@@ -1,5 +1,6 @@
#include "pathfinderTest.h"
#include "pathfinder.h"
#include "map.h"
#include <util.h>
@@ -10,36 +11,28 @@ namespace battleship{
using namespace vb01;
void PathfinderTest::testFindPath(){
int size = 7;
const u16 INF = u16(0 - 1);
//pathfinder->setImpassibleNodeVal(INF);
u32 w[size][size] = {
{0, 2, 4, INF, INF, INF, INF},
{INF, 0, 1, 9, 13, INF, INF},
{INF, 2, 0, INF, 4, 5, INF},
{INF, INF, INF, 0, INF, INF, 1},
{1, INF, INF, 1, 0, INF, 3},
{INF, INF, INF, INF, 9, 0, 2},
{INF, INF, INF, INF, INF, INF, 0}
};
u32 **weights = new u32*[size];
vector<Map::Cell> cells = vector<Map::Cell>{
Map::Cell(Vector3::VEC_ZERO, Map::Cell::Type::LAND, vector<Map::Edge>{Map::Edge(0, 0, 0), Map::Edge(2, 0, 1), Map::Edge(4, 0, 2)}),
Map::Cell(Vector3::VEC_ZERO, Map::Cell::Type::LAND, vector<Map::Edge>{Map::Edge(0, 1, 1), Map::Edge(1, 1, 2), Map::Edge(9, 1, 3), Map::Edge(13, 1, 4)}),
Map::Cell(Vector3::VEC_ZERO, Map::Cell::Type::LAND, vector<Map::Edge>{Map::Edge(0, 2, 2), Map::Edge(2, 2, 1), Map::Edge(4, 2, 4), Map::Edge(5, 2, 5)}),
Map::Cell(Vector3::VEC_ZERO, Map::Cell::Type::LAND, vector<Map::Edge>{Map::Edge(0, 3, 3), Map::Edge(1, 3, 6)}),
Map::Cell(Vector3::VEC_ZERO, Map::Cell::Type::LAND, vector<Map::Edge>{Map::Edge(0, 4, 4), Map::Edge(1, 4, 0), Map::Edge(1, 4, 3), Map::Edge(3, 4, 6)}),
Map::Cell(Vector3::VEC_ZERO, Map::Cell::Type::LAND, vector<Map::Edge>{Map::Edge(0, 5, 5), Map::Edge(9, 5, 4), Map::Edge(2, 5, 6)}),
Map::Cell(Vector3::VEC_ZERO, Map::Cell::Type::LAND, vector<Map::Edge>{Map::Edge(0, 6, 6)})
};
for(int i = 0; i < size; i++){
weights[i] = new u32[size];
int size = cells.size();
const u16 INF = u16(0 - 1);
pathfinder->setImpassibleNodeVal(INF);
vector<int> path = pathfinder->findPath(cells, 0, size - 1);
CPPUNIT_ASSERT(path == vector<int>({0, 1, 2, 4, 3, 6}));
for(int j = 0; j < size; j++)
weights[i][j] = w[i][j];
}
int sumPathWeights = 0;
vector<int> path = pathfinder->findPath(weights, size, 0, size - 1);
CPPUNIT_ASSERT(path == vector<int>({0, 1, 2, 4, 3, 6}));
for(int i = 1; i < path.size(); i++)
sumPathWeights += cells[path[i - 1]].getEdgeWeight(path[i]);
int sumPathWeights = 0;
for(int i = 1; i < size; i++)
sumPathWeights += w[path[i - 1]][path[i]];
CPPUNIT_ASSERT(sumPathWeights == 9);
CPPUNIT_ASSERT(sumPathWeights == 9);
}
void PathfinderTest::setUp(){
+1 -1
View File
@@ -42,7 +42,7 @@ namespace battleship{
enum class MoveDir {LEFT, UP, FORW};
enum class Corner {FRONT_LEFT, FRONT_RIGHT, REAR_LEFT, REAR_RIGHT};
enum class UnitClass {VESSEL, ENGINEER, SAMPLE_BUILDING};
enum class UnitType {UNDERWATER, SEA_LEVEL, LAND, AIR};
enum class UnitType {UNDERWATER, SEA_LEVEL, HOVER, LAND, AIR, NONE = -1};
class Unit {
public:
+1
View File
@@ -2,6 +2,7 @@
#include "player.h"
#include "vehicle.h"
#include "engineer.h"
#include "defConfigs.h"
#include <solUtil.h>
+50 -30
View File
@@ -4,6 +4,7 @@
#include <util.h>
#include <ray.h>
#include <box.h>
#include <model.h>
#include <quaternion.h>
@@ -18,10 +19,16 @@ using namespace std;
namespace battleship{
Vehicle::Vehicle(Player *player, int id, Vector3 pos, Quaternion rot) : Unit(player, id, pos, rot){
initProperties();
debugMat = new Material(Root::getSingleton()->getLibPath() + "texture");
debugMat->addBoolUniform("lightingEnabled", false);
debugMat->addBoolUniform("texturingEnabled", false);
debugMat->addVec4Uniform("diffuseColor", Vector4::VEC_IJKL);
}
void Vehicle::halt(){
Unit::halt();
removeAllPathpoints();
patrolPointId = 0;
}
@@ -53,8 +60,7 @@ namespace battleship{
break;
}
pos = pos + dir * speed;
model->setPosition(pos);
placeUnit(pos + dir * speed);
}
void Vehicle::initProperties(){
@@ -101,9 +107,9 @@ namespace battleship{
}
if(type != UnitType::UNDERWATER && pos.getDistanceFrom(linDest) <= destOffset)
pathPoints.erase(pathPoints.begin());
removePathpoint();
else if(type == UnitType::UNDERWATER && fabs(pos.y - pathPoints[0].y) < 0.5 * height && pos.getDistanceFrom(linDest) <= destOffset)
pathPoints.erase(pathPoints.begin());
removePathpoint();
}
}
@@ -136,41 +142,55 @@ namespace battleship{
removeOrder(0);
}
//TODO add hover unit type
//TODO cleanup debug pathpoint removal
void Vehicle::preparePathpoints(Order order){
int srcObjId = 0, destObjId = 0;
removeAllPathpoints();
Map *map = Map::getSingleton();
vector<Map::Cell> &cells = map->getCells();
/*
for(int i = 1; i < map->getNumTerrainObjects(); i++){
if(map->isPointWithinTerrainObject(pos, i))
srcObjId = i;
int source = map->getCellId(pos);
int dest = map->getCellId(order.targets[0].pos);
if(map->isPointWithinTerrainObject(order.targets[0].pos, i))
destObjId = i;
if(type == UnitType::UNDERWATER || type == UnitType::SEA_LEVEL || type == UnitType::LAND){
Map::Cell::Type cellType = (type == UnitType::LAND ? Map::Cell::LAND : Map::Cell::WATER);
bool canReach = (cells[source].type == cellType && cells[dest].type == cellType);
if(!canReach) return;
}
*/
if(srcObjId != destObjId)
return;
int source = map->getCellId(pos, srcObjId);
int dest = map->getCellId(order.targets[0].pos, destObjId);
/*
Pathfinder *pathfinder = Pathfinder::getSingleton();
u32 **weights = map->getTerrainObject(srcObjId).weights;
vector<int> path = pathfinder->findPath(weights, map->getTerrainObject(srcObjId).numCells, source, dest);
vector<int> path = pathfinder->findPath(cells, source, dest, (int)type);
Node *rootNode = Root::getSingleton()->getRootNode();
bool impassibleNodePresent = false;
pathPoints.clear();
for(int p : path){
pathPoints.push_back(cells[p].pos);
for(int i = 1; i < path.size(); i++)
if(!impassibleNodePresent && weights[path[i - 1]][path[i]] == pathfinder->getImpassibleNodeVal())
impassibleNodePresent = true;
Box *b = new Box(Vector3::VEC_IJK);
b->setMaterial(debugMat);
Node *n = new Node(cells[p].pos);
n->attachMesh(b);
rootNode->attachChild(n);
debugPathPoints.push_back(n);
}
}
if(!(impassibleNodePresent || path.empty()))
for(int p : path)
pathPoints.push_back(map->getTerrainObject(srcObjId).cells[p].pos);
*/
void Vehicle::removePathpoint(int i){
Node *rootNode = Root::getSingleton()->getRootNode();
Node *debugPathPointNode = debugPathPoints[i];
rootNode->dettachChild(debugPathPointNode);
Mesh *mesh = debugPathPointNode->getMesh(0);
mesh->setMaterial(nullptr);
debugPathPoints.erase(debugPathPoints.begin() + i);
delete debugPathPointNode;
pathPoints.erase(pathPoints.begin() + i);
}
void Vehicle::removeAllPathpoints(){
while(!pathPoints.empty())
removePathpoint();
}
}
+8
View File
@@ -3,6 +3,10 @@
#include "unit.h"
namespace vb01{
class Material;
}
namespace battleship{
class Vehicle : public Unit{
public:
@@ -11,6 +15,8 @@ namespace battleship{
private:
int patrolPointId = 0;
float speed, maxTurnAngle, anglePrecision;
vb01::Material *debugMat = nullptr;
std::vector<vb01::Node*> debugPathPoints;
inline int getNextPatrolPointId(int numPoints) {return patrolPointId == numPoints - 1 ? 0 : patrolPointId + 1;}
void halt();
@@ -19,6 +25,8 @@ namespace battleship{
void initProperties();
void advance(float, MoveDir = MoveDir::FORW);
void preparePathpoints(Order);
void removePathpoint(int = 0);
void removeAllPathpoints();
protected:
std::vector<vb01::Vector3> pathPoints;