mirror of
https://github.com/ApfelTeeSaft/PlanetFleet.git
synced 2026-08-26 19:33:38 +00:00
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
@@ -5,7 +5,7 @@ gui = {
|
||||
size = {x = 300, y = 20},
|
||||
guiType = GuiType.LISTBOX,
|
||||
listboxType = ListboxType.CONSOLE,
|
||||
numMaxDisplay = 20,
|
||||
numMaxDisplay = 10,
|
||||
closable = false
|
||||
},
|
||||
{
|
||||
|
||||
@@ -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
@@ -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
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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(){
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "player.h"
|
||||
#include "vehicle.h"
|
||||
#include "engineer.h"
|
||||
#include "defConfigs.h"
|
||||
|
||||
#include <solUtil.h>
|
||||
|
||||
|
||||
+50
-30
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user