/** * Apply Template To Map * Method responsible for modifying the nodes to reflect the template. */ public void ApplyTemplateToMap(MapTemplate mapTemplate) { Debug.Log("ApplyTemplateToMap"); // Initialize perlin noise generator to make terrain m_envPerlinNoise = new PerlinNoise2D(GetMapRowCount(), GetMapColCount()); m_nodeList = new SortedDictionary <int, SortedDictionary <int, NodeV2> >(); Vector3 envPos; int col = 0; int row = 0; int N = -m_tileSize / 2; int S = m_tileSize / 2; int E = m_tileSize / 2; int W = -m_tileSize / 2; int westWallCol = GetMapColCount() - 1; int northWallRow = GetMapRowCount() - 1; //isPlayablePerimeter Vector3 westWallOffset = new Vector3(0, 0, -m_tileSize / 2); Vector3 eastWallOffset = new Vector3(0, 0, m_tileSize / 2); Vector3 southWallOffset = new Vector3(m_tileSize / 2, 0, 0); Vector3 northWallOffset = new Vector3(-m_tileSize / 2, 0, 0); int northRow = 0; int eastCol = GetMapRowCount() - 1; int westCol = 0; int southRow = GetMapColCount() - 1; Vector2Int cornerNE = new Vector2Int(northRow, eastCol); Vector2Int cornerSE = new Vector2Int(southRow, eastCol); Vector2Int cornerSW = new Vector2Int(southRow, westCol); Vector2Int cornerNW = new Vector2Int(northRow, westCol); //================================================== // UPDATE CAMERA LIMITATION //================================================== // Super sketch but effective if (m_sketchCameraBounds) { float axisVal; float posOffsetVal; axisVal = (m_tileSize * GetMapColCount() - 1) / 2F; posOffsetVal = transform.position.x; Vector2 rangeX = new Vector2(posOffsetVal, posOffsetVal) + new Vector2(-axisVal, axisVal - m_tileSize); axisVal = (m_tileSize * GetMapRowCount() - 1) / 2F; posOffsetVal = transform.position.z; Vector2 rangeZ = new Vector2(posOffsetVal, posOffsetVal) + new Vector2(-axisVal, axisVal - m_tileSize); axisVal = 100; posOffsetVal = transform.position.y + 5; Vector2 rangeY = new Vector2(posOffsetVal, posOffsetVal + axisVal); UpdateCameraLimitations(rangeX, rangeY, rangeZ); } //================================================== // GENERATE BASE TILES //================================================== // Generate Tiles float mapWidth = m_tileSize * GetMapColCount(); float mapHeight = m_tileSize * GetMapRowCount(); NodeTemplate nodeTemplate; for (row = 0; row < GetMapRowCount(); ++row) { m_nodeList.Add(row, new SortedDictionary <int, NodeV2>()); for (col = 0; col < GetMapColCount(); ++col) { //---------------------------------------------- // Create Tile at position float tileRowPosX = m_tileSize * col - mapWidth / 2; float tileRowPosZ = m_tileSize * row - mapHeight / 2; Vector3 tilePos = transform.position + new Vector3(tileRowPosX, 0, tileRowPosZ); // Decide which prefab nodeTemplate = mapTemplate.GetNode(row, col); GameObject prefab = nodeTemplate.type == "path" || nodeTemplate.type == "start" || nodeTemplate.type == "end" ? m_pathTile : m_grassTile; GameObject spawnNode = Instantiate(prefab, tilePos, Quaternion.identity, this.gameObject.transform); NodeV2 spawnInstance = spawnNode.GetComponent <NodeV2>(); m_nodeList[row].Add(col, spawnInstance); //---------------------------------------------- // Add vegitation to terrain if (nodeTemplate.type == "terrain" && nodeTemplate.isEnvPlacable) { OddsTable subCategoryTable; // Choose which table to role on if (nodeTemplate.isPlayablePerimeter) { subCategoryTable = m_shrubOddsTable; } else { string rolledKey; if (Random.Range(0F, 10f) / 10F > 0.2F) { rolledKey = m_environmentOddsTable.GetForNormalizedRoll(m_envPerlinNoise.GetValue(row, col)); } else { rolledKey = m_environmentOddsTable.Roll(); } subCategoryTable = (OddsTable)m_environmentOddsTable.GetPayload(rolledKey); } // Table exists if (subCategoryTable != null) { // Decide prefab at Random string rolledKey; if (Random.Range(0, 1) > 0.5) { rolledKey = subCategoryTable.GetForNormalizedRoll(Mathf.Clamp(Random.Range(-0.2F, 0.2F) + m_envPerlinNoise.GetValue(row, col), 0, 1)); } else { rolledKey = subCategoryTable.Roll(); } GameObject envPrefab = (GameObject)subCategoryTable.GetPayload(rolledKey); if (envPrefab != null) { SpawnNodeEnv(spawnInstance, envPrefab); } } } //________________________________________________ } } //================================================== // APPLY TILE DATA //================================================== // Read directly from the map NodeTemplate template; for (row = 0; row < GetMapRowCount(); ++row) { for (col = 0; col < GetMapColCount(); ++col) { if (GetNode(row, col)) { NodeV2 node = GetNode(row, col); template = mapTemplate.GetNode(row, col); node.SetNodeType(template.type); node.SetIsPlayablePerimeter(template.isPlayablePerimeter); node.SetIsTowerPlacable(template.isTowerPlacable); node.SetIsEnvPlacable(template.isEnvPlacable); node.SetCoordinate(new Vector2Int(col, row)); } } } //================================================== // DECORATE PATHS //================================================== m_pathSegments = mapTemplate.GetPathSegments(); int globalPathTileCount = 0; int segmentLargestIndex = m_pathSegments.Count - 1; int previousSegmentIndex = -1; Vector2Int currentPos = new Vector2Int(0, 0); Vector2Int previousPos = new Vector2Int(0, 0); for (int s = 0; s <= segmentLargestIndex; ++s) { bool isLastSegment = s == segmentLargestIndex; PathSegment segment = m_pathSegments[s]; int deltaX = segment.end.x - segment.start.x; int deltaY = segment.end.y - segment.start.y; int directionX = deltaX == 0 ? 0 : deltaX / Mathf.Abs(deltaX); int directionY = deltaY == 0 ? 0 : deltaY / Mathf.Abs(deltaY); //isLastTile, isFirstTile // Set up 2D iteration int dy = 0; int dx = 0; bool isLastIteration = false; bool isDone = false; while (!isDone) { // Set loop ending flag if (isLastIteration) { isDone = true; } //---------------------- // Execute for-loop contents with dx and dy // Get tile location row = segment.start.y + dy; col = segment.start.x + dx; // Select colour bool isFirstTile = globalPathTileCount == 0; bool isLastTile = isLastSegment && isLastIteration; bool isDirectionChange = s != previousSegmentIndex; currentPos = new Vector2Int(col, row); if (isFirstTile) { previousPos = currentPos; } //==================================================================== // If the segment is not overlapping form the last segment if (previousPos != currentPos || isFirstTile) { NodeV2 currentTile = GetNode(row, col); Transform parentTransform = currentTile.gameObject.transform; envPos = currentTile.gameObject.transform.position + currentTile.GetEnvOffset(); Vector3 wallPos; Quaternion wallRotation; nodeTemplate = mapTemplate.GetNode(row, col); // ------------------------------------------------------------------- // ADD PATH WALLS // ------------------------------------------------------------------- if (currentTile.GetNodeType() != "end" && m_pathWall != null) { if (nodeTemplate.hasWall[(int)NodeTemplate.Wall.N]) { wallPos = envPos + new Vector3(N, 0, 0); wallRotation = Quaternion.AngleAxis(90, Vector3.up); Instantiate(m_pathWall, wallPos, wallRotation, parentTransform); } if (nodeTemplate.hasWall[(int)NodeTemplate.Wall.S]) { wallPos = envPos + new Vector3(S, 0, 0); wallRotation = Quaternion.AngleAxis(-90, Vector3.up); Instantiate(m_pathWall, wallPos, wallRotation, parentTransform); } if (nodeTemplate.hasWall[(int)NodeTemplate.Wall.E]) { wallPos = envPos + new Vector3(0, 0, E); wallRotation = Quaternion.AngleAxis(180, Vector3.up); Instantiate(m_pathWall, wallPos, wallRotation, parentTransform); } if (nodeTemplate.hasWall[(int)NodeTemplate.Wall.W]) { wallPos = envPos + new Vector3(0, 0, W); wallRotation = Quaternion.AngleAxis(0, Vector3.up); Instantiate(m_pathWall, wallPos, wallRotation, parentTransform); } } // ------------------------------------------------------------------- // ADD PATH PILLARS // ------------------------------------------------------------------- Quaternion pillarRotation = Quaternion.identity; if (m_pathPiller != null) { if (nodeTemplate.hasPillar[(int)NodeTemplate.Pillar.NE]) { Vector3 pillarPos = envPos + new Vector3(N, 0, E); Instantiate(m_pathPiller, pillarPos, pillarRotation, parentTransform); } if (nodeTemplate.hasPillar[(int)NodeTemplate.Pillar.NW]) { Vector3 pillarPos = envPos + new Vector3(N, 0, W); Instantiate(m_pathPiller, pillarPos, pillarRotation, parentTransform); } if (nodeTemplate.hasPillar[(int)NodeTemplate.Pillar.SE]) { Vector3 pillarPos = envPos + new Vector3(S, 0, E); Instantiate(m_pathPiller, pillarPos, pillarRotation, parentTransform); } if (nodeTemplate.hasPillar[(int)NodeTemplate.Pillar.SW]) { Vector3 pillarPos = envPos + new Vector3(S, 0, W); Instantiate(m_pathPiller, pillarPos, pillarRotation, parentTransform); } } if (currentTile.GetIsPath() && currentTile.GetPlayablePerimeter() && currentTile.GetNodeType() != "end") { Quaternion pillarRot = Quaternion.identity; if (m_leftEntrancePillar != null) { Instantiate(m_leftEntrancePillar, envPos + westWallOffset + northWallOffset, pillarRot, this.gameObject.transform); } if (m_rightEntrancePillar != null) { Instantiate(m_rightEntrancePillar, envPos + westWallOffset + southWallOffset, pillarRot, this.gameObject.transform); } } /* * if (currentTile.GetNodeType() == "end") * { * Quaternion pillarRot = Quaternion.AngleAxis(180, Vector3.up); * Instantiate(m_pathPiller, envPos + eastWallOffset + southWallOffset, pillarRot, this.gameObject.transform); * Instantiate(m_pathPiller, envPos + eastWallOffset + northWallOffset, pillarRot, this.gameObject.transform); * } */ if (currentTile.GetNodeType() == "end" && m_finalScene != null) { currentTile.m_height = 11F; Vector3 endPos = currentTile.gameObject.transform.position; Quaternion endRot = Quaternion.AngleAxis(0, Vector3.up); Instantiate(m_finalScene, endPos, endRot, this.gameObject.transform); } if (currentTile.GetNodeType() == "start" && m_startScene != null) { Vector3 startPos = currentTile.gameObject.transform.position + new Vector3(0, 0, -m_tileSize);//HERE Quaternion startRot = Quaternion.AngleAxis(0, Vector3.up); Instantiate(m_startScene, startPos, startRot, this.gameObject.transform); } // ------------------------------------------------------------------- // ADD Tiles // ------------------------------------------------------------------- Quaternion tileRotation = Quaternion.identity; Vector3 tilePos; GameObject tilePrefrab = null; float tileOffset = 0; tilePos = envPos + new Vector3(N / 2, tileOffset, E / 2); tilePrefrab = (GameObject)m_tileOddsTable.GetPayload(m_tileOddsTable.Roll()); if (tilePrefrab != null) { Instantiate(tilePrefrab, tilePos, tileRotation, parentTransform); } tilePos = envPos + new Vector3(S / 2, tileOffset, E / 2); tilePrefrab = (GameObject)m_tileOddsTable.GetPayload(m_tileOddsTable.Roll()); if (tilePrefrab != null) { Instantiate(tilePrefrab, tilePos, tileRotation, parentTransform); } tilePos = envPos + new Vector3(S / 2, tileOffset, W / 2); tilePrefrab = (GameObject)m_tileOddsTable.GetPayload(m_tileOddsTable.Roll()); if (tilePrefrab != null) { Instantiate(tilePrefrab, tilePos, tileRotation, parentTransform); } tilePos = envPos + new Vector3(N / 2, tileOffset, W / 2); tilePrefrab = (GameObject)m_tileOddsTable.GetPayload(m_tileOddsTable.Roll()); if (tilePrefrab != null) { Instantiate(tilePrefrab, tilePos, tileRotation, parentTransform); } // ------------------------------------------------------------------- // ADD LAMPS // ------------------------------------------------------------------- if (currentTile.GetNodeType() != "end" && m_pathLamp != null) { float lampOffset = 3; Quaternion lampRotation = Quaternion.identity; if (nodeTemplate.hasLamp[(int)NodeTemplate.Pillar.NE]) { Vector3 pillarPos = envPos + new Vector3(N, lampOffset, E); lampRotation = Quaternion.AngleAxis(-90, Vector3.up); Instantiate(m_pathLamp, pillarPos, lampRotation, parentTransform); } if (nodeTemplate.hasLamp[(int)NodeTemplate.Pillar.SE]) { Vector3 pillarPos = envPos + new Vector3(S, lampOffset, E); lampRotation = Quaternion.AngleAxis(0, Vector3.up); Instantiate(m_pathLamp, pillarPos, lampRotation, parentTransform); } if (nodeTemplate.hasLamp[(int)NodeTemplate.Pillar.SW]) { Vector3 pillarPos = envPos + new Vector3(S, lampOffset, W); lampRotation = Quaternion.AngleAxis(90, Vector3.up); Instantiate(m_pathLamp, pillarPos, lampRotation, parentTransform); } if (nodeTemplate.hasLamp[(int)NodeTemplate.Pillar.NW]) { Vector3 pillarPos = envPos + new Vector3(N, lampOffset, W); lampRotation = Quaternion.AngleAxis(180, Vector3.up); Instantiate(m_pathLamp, pillarPos, lampRotation, parentTransform); } } } // End segment does not overlatp //==================================================================== // Increment tile could to tell first tile ++globalPathTileCount; //---------------------- // Increment loop if (dx != deltaX) { dx += directionX; } else if (dy != deltaY) { dy += directionY; } // Detect going on last iteration isLastIteration = (dx == deltaX && dy == deltaY); previousPos = currentPos; previousSegmentIndex = s; } } //================================================== // ADD OUTTER WALLS //================================================== if (m_outterWall != null) { // NORTH WALL for (int i = 0; i < GetMapRowCount(); ++i) { Vector2Int coord = new Vector2Int(northRow, i); NodeV2 nodeInst = GetNode(coord); Vector3 nodePos = nodeInst.gameObject.transform.position; if (!nodeInst.GetIsPath()) { Quaternion outterWallRot = Quaternion.AngleAxis(90, Vector3.up); Instantiate(m_outterWall, nodePos + nodeInst.GetEnvOffset() + northWallOffset, outterWallRot, this.gameObject.transform); } } // SOUTH WALL for (int i = 0; i < GetMapRowCount(); ++i) { Vector2Int coord = new Vector2Int(southRow, i); NodeV2 nodeInst = GetNode(coord); Vector3 nodePos = nodeInst.gameObject.transform.position; if (!nodeInst.GetIsPath()) { Quaternion outterWallRot = Quaternion.AngleAxis(-90, Vector3.up); Instantiate(m_outterWall, nodePos + nodeInst.GetEnvOffset() + southWallOffset, outterWallRot, this.gameObject.transform); } } // EAST WALL for (int i = 0; i < GetMapColCount(); ++i) { Vector2Int coord = new Vector2Int(i, eastCol); NodeV2 nodeInst = GetNode(coord); Vector3 nodePos = nodeInst.gameObject.transform.position; if (!nodeInst.GetIsPath()) { Quaternion outterWallRot = Quaternion.AngleAxis(180, Vector3.up); Instantiate(m_outterWall, nodePos + nodeInst.GetEnvOffset() + eastWallOffset, outterWallRot, this.gameObject.transform); } } // WEST WALL for (int i = 0; i < GetMapColCount(); ++i) { Vector2Int coord = new Vector2Int(i, westCol); NodeV2 nodeInst = GetNode(coord); Vector3 nodePos = nodeInst.gameObject.transform.position; if (!nodeInst.GetIsPath()) { Quaternion outterWallRot = Quaternion.AngleAxis(0, Vector3.up); Instantiate(m_outterWall, nodePos + nodeInst.GetEnvOffset() + westWallOffset, outterWallRot, this.gameObject.transform); } } } //================================================== // ADD OUTTER PILLARS //================================================== if (m_outterPillar != null) { // NE PILLAR if (true) { NodeV2 nodeInst = GetNode(cornerNE); Vector3 posOffset = northWallOffset + eastWallOffset; Vector3 nodePos = nodeInst.gameObject.transform.position; Instantiate(m_outterPillar, nodePos + nodeInst.GetEnvOffset() + posOffset, Quaternion.identity, this.gameObject.transform); } // NW PILLAR if (true) { NodeV2 nodeInst = GetNode(cornerNW); Vector3 posOffset = northWallOffset + westWallOffset; Vector3 nodePos = nodeInst.gameObject.transform.position; Instantiate(m_outterPillar, nodePos + nodeInst.GetEnvOffset() + posOffset, Quaternion.identity, this.gameObject.transform); } // SW PILLAR if (true) { NodeV2 nodeInst = GetNode(cornerSW); Vector3 posOffset = southWallOffset + westWallOffset; Vector3 nodePos = nodeInst.gameObject.transform.position; Instantiate(m_outterPillar, nodePos + nodeInst.GetEnvOffset() + posOffset, Quaternion.identity, this.gameObject.transform); } // SE PILLAR if (true) { NodeV2 nodeInst = GetNode(cornerSE); Vector3 posOffset = southWallOffset + eastWallOffset; Vector3 nodePos = nodeInst.gameObject.transform.position; Instantiate(m_outterPillar, nodePos + nodeInst.GetEnvOffset() + posOffset, Quaternion.identity, this.gameObject.transform); } } }