#include #include #include #include #include #include #include "map.h" #include "player.h" #include "unitFactory.h" #include "pathfinder.h" #include "gameManager.h" #include "defConfigs.h" using namespace std; using namespace vb01; using namespace gameBase; namespace battleship{ using namespace configData; Map *map = nullptr; Map* Map::getSingleton(){ if(!map) map = new Map; return map; } void Map::update(){ for(Player *p : players) p->update(); } void Map::loadSkybox(){ LuaManager *lm = LuaManager::getSingleton(); string skyboxName = lm->getStringFromTable(mapTable, vector{Index("skybox")}); string basePath = GameManager::getSingleton()->getPath() + "Textures/Skyboxes/" + skyboxName; const int numPaths = 6; string path[numPaths] = { basePath + "/left.jpg", basePath + "/right.jpg", basePath + "/up.jpg", basePath + "/down.jpg", basePath + "/front.jpg", basePath + "/back.jpg" }; for(int i = 0; i < numPaths; i++) AssetManager::getSingleton()->load(path[i]); Root::getSingleton()->createSkybox(path); } void Map::loadTerrainObject(int id){ LuaManager *luaManager = LuaManager::getSingleton(); string terrainTable = (id == -1 ? "terrain" : "waterBodies"); vector baseIndices = (id == -1 ? vector{Index(terrainTable)} : vector{Index(terrainTable), Index(id + 1)}); Vector3 pos = Vector3::VEC_ZERO, size = Vector3::VEC_ZERO; Index terrInd = Index("terrain"), waterInd = Index("waterBodies"), idIndex = Index(id + 1), posInd = Index("pos"), sizeInd = Index("size"), xInd = Index("x"), yInd = Index("y"), zInd = Index("z"), nodeInd = Index("nodes"); vector sizeBaseInd; if(id == -1){ sizeBaseInd.push_back(terrInd); } else{ float x = luaManager->getFloatFromTable(mapTable, vector{waterInd, idIndex, posInd, xInd}); float y = luaManager->getFloatFromTable(mapTable, vector{waterInd, idIndex, posInd, yInd}); float z = luaManager->getFloatFromTable(mapTable, vector{waterInd, idIndex, posInd, zInd}); pos = Vector3(x, y, z); sizeBaseInd = vector{waterInd, idIndex}; } sizeBaseInd.push_back(sizeInd); vector indVecX = sizeBaseInd; vector indVecY = sizeBaseInd; vector indVecZ = sizeBaseInd; indVecX.push_back(xInd); indVecY.push_back(yInd); indVecZ.push_back(zInd); float x = luaManager->getFloatFromTable(mapTable, indVecX); float y = luaManager->getFloatFromTable(mapTable, indVecY); float z = luaManager->getFloatFromTable(mapTable, indVecZ); size = Vector3(x, y, z); vector baseNodeInd = baseIndices; baseNodeInd.push_back(nodeInd); vector ind = baseNodeInd; ind.push_back(Index("numCells")); int numCells = luaManager->getIntFromTable(mapTable, ind); u32 **weights = new u32*[numCells]; Cell *cells = new Cell[numCells]; for(int i = 0; i < numCells; i++){ weights[i] = new u32[numCells]; for(int j = 0; j < numCells; j++){ int wid = i * numCells + j; ind = baseNodeInd; ind.push_back(Index("weights")); ind.push_back(Index(wid + 1)); u32 w = luaManager->getIntFromTable(mapTable, ind); weights[i][j] = w; } ind = baseNodeInd; ind.push_back(Index("impassible")); ind.push_back(Index(i + 1)); bool impassible = luaManager->getFloatFromTable(mapTable, ind); vector posBaseInd = baseNodeInd; posBaseInd.push_back(posInd); posBaseInd.push_back(Index(i + 1)); vector indVecX = posBaseInd; vector indVecY = posBaseInd; vector indVecZ = posBaseInd; indVecX.push_back(xInd); indVecY.push_back(yInd); indVecZ.push_back(zInd); float x = luaManager->getFloatFromTable(mapTable, indVecX); float y = luaManager->getFloatFromTable(mapTable, indVecY); float z = luaManager->getFloatFromTable(mapTable, indVecZ); cells[i] = Cell(Vector3(x, y, z), (id == -1), impassible); } Node *node = nullptr; Quad *quad = nullptr; TerrainObject::Type type; string basePath = GameManager::getSingleton()->getPath(); string texPath = basePath; //TODO remove this quick fix for landmass model loading if(id == -1){ type = TerrainObject::LANDMASS; string mapPathSuffix = "Models/Maps/" + mapName + "/"; texPath += mapPathSuffix; string terrainFile = basePath + mapPathSuffix + luaManager->getStringFromTable(mapTable, vector{terrInd, Index("model")}); AssetManager::getSingleton()->load(terrainFile); node = (Model*)((new Model(terrainFile))->getChild(0)); Node *par = node->getParent(); par->dettachChild(node); delete par; } else{ type = TerrainObject::RECT_WATERBODY; node = new Node(); quad = new Quad(Vector3(size.x, size.z, 1), true); node->attachMesh(quad); texPath += "Textures/Water/"; } nodeParent->attachChild(node); node->setPosition(pos); Material *mat = new Material(Root::getSingleton()->getLibPath() + "texture"); mat->addBoolUniform("texturingEnabled", true); mat->addBoolUniform("lightingEnabled", false); ind = baseIndices; ind.push_back(Index("albedoMap")); texPath += luaManager->getStringFromTable(mapTable, ind); string fr[]{texPath}; AssetManager::getSingleton()->load(fr[0]); Texture *t = new Texture(fr, 1, false); mat->addTexUniform("textures[0]", t, true); if(id == -1) ((Model*)node)->setMaterial(mat); else quad->setMaterial(mat); terrainObjects.push_back(TerrainObject(pos, size, Vector3(cellSize.x, (id == -1 ? 0 : cellSize.y), cellSize.z), type, node, numCells, cells, weights)); } void Map::loadSpawnPoints(){ LuaManager *lm = LuaManager::getSingleton(); int numSpawnPoints = lm->getIntFromTable(mapTable, vector{Index("numSpawnPoints")}); string spawnPointInd = "spawnPoints"; for(int i = 0; i < numSpawnPoints; i++){ float x = lm->getFloatFromTable(mapTable, vector{Index(spawnPointInd), Index(i + 1), Index("x")}); float y = lm->getFloatFromTable(mapTable, vector{Index(spawnPointInd), Index(i + 1), Index("y")}); float z = lm->getFloatFromTable(mapTable, vector{Index(spawnPointInd), Index(i + 1), Index("z")}); spawnPoints.push_back(Vector3(x, y, z)); } } //TODO simplify the dubplicatory field extraction statements void Map::loadPlayers(){ AssetManager *assetManager = AssetManager::getSingleton(); string path = GameManager::getSingleton()->getPath(); assetManager->load(path + DEFAULT_TEXTURE); LuaManager *lm = LuaManager::getSingleton(); assetManager->load(path + lm->getString("modelPrefix"), true); int numPlayers = lm->getIntFromTable(mapTable, vector{Index("numPlayers")}); string playerInd = "players", unitInd = "units", spawnPointInd = "spawnPointId", posInd = "pos", rotInd = "rot"; for(int i = 0; i < numPlayers; i++){ int spawnPointId = lm->getIntFromTable(mapTable, vector{Index(playerInd), Index(i + 1), Index(spawnPointId)}); int numUnits = lm->getIntFromTable(mapTable, vector{Index(playerInd), Index(i + 1), Index("numUnits")}); players.push_back(new Player(0, 0, 0, spawnPoints[i])); for(int j = 0; j < numUnits; j++){ float posX = lm->getFloatFromTable(mapTable, vector{Index(playerInd), Index(i + 1), Index(unitInd), Index(j + 1), Index(posInd), Index("x")}); float posY = lm->getFloatFromTable(mapTable, vector{Index(playerInd), Index(i + 1), Index(unitInd), Index(j + 1), Index(posInd), Index("y")}); float posZ = lm->getFloatFromTable(mapTable, vector{Index(playerInd), Index(i + 1), Index(unitInd), Index(j + 1), Index(posInd), Index("z")}); Vector3 pos = Vector3(posX, posY, posZ); float rotW = lm->getFloatFromTable(mapTable, vector{Index(playerInd), Index(i + 1), Index(unitInd), Index(j + 1), Index(rotInd), Index("w")}); float rotX = lm->getFloatFromTable(mapTable, vector{Index(playerInd), Index(i + 1), Index(unitInd), Index(j + 1), Index(rotInd), Index("x")}); float rotY = lm->getFloatFromTable(mapTable, vector{Index(playerInd), Index(i + 1), Index(unitInd), Index(j + 1), Index(rotInd), Index("y")}); float rotZ = lm->getFloatFromTable(mapTable, vector{Index(playerInd), Index(i + 1), Index(unitInd), Index(j + 1), Index(rotInd), Index("z")}); Quaternion rot = Quaternion(rotW, rotX, rotY, rotZ); int id = lm->getIntFromTable(mapTable, vector{Index(playerInd), Index(i + 1), Index(unitInd), Index("id")}); players[i]->addUnit(UnitFactory::createUnit(players[i], id, pos, rot)); } } } void Map::preprareScene(){ nodeParent = new Node(); Root *root = Root::getSingleton(); root->getRootNode()->attachChild(nodeParent); Camera *cam = root->getCamera(); cam->setPosition(Vector3(1, 1, 1) * 40); cam->lookAt(Vector3(-1, -1, -1).norm(), Vector3(-1, 1, -1).norm()); } void Map::load(string mapName, bool empty) { this->mapName = mapName; cellSize = Vector3(7, 6, 7); Pathfinder::getSingleton()->setImpassibleNodeVal(u16(0 - 1)); preprareScene(); if(!empty){ LuaManager *lm = LuaManager::getSingleton(); lm->buildScript(vector{GameManager::getSingleton()->getPath() + "Models/Maps/" + mapName + "/" + mapName + ".lua"}); int numWaterbodies = lm->getIntFromTable(mapTable, vector{Index("numWaterBodies")}); loadSpawnPoints(); loadPlayers(); loadSkybox(); loadTerrainObject(-1); for(int i = 0; i < numWaterbodies; i++) loadTerrainObject(i); } } 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; int numCellsX = regionSize.x / cellSize.x; int numCellsZ = regionSize.z / cellSize.z; 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; return (numCellsX * numCellsZ * y + (numCellsX * z + x)); } bool Map::isPointWithinTerrainObject(Vector3 p, int id){ bool within; Vector3 pos = terrainObjects[id].pos, size = terrainObjects[id].size; if(terrainObjects[id].type == TerrainObject::RECT_WATERBODY) within = (fabs(pos.x - p.x) < 0.5 * size.x && fabs(pos.z - p.z) < 0.5 * size.z); else if(terrainObjects[id].type == TerrainObject::ROUND_WATERBODY) within = Vector2(pos.x, pos.z).getDistanceFrom(Vector2(p.x, p.z)) < size.x; else within = true; return within; } void Map::addTerrainObject(TerrainObject obj){ nodeParent->attachChild(obj.node); terrainObjects.push_back(obj); } }