Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma strict
- var map: Map;
- var gameManager: GameManager;
- var magic: boolean;
- private var setInit = true;
- private var init: float;
- private var biomesCount = System.Enum.GetValues(TileType).length;
- function Update()
- {
- var i: int;
- var j: int;
- if (magic)
- {
- doCrude = true;
- doHeuristic = true;
- magic = false;
- }
- if (doCrude)
- {
- // if (setInit)
- // init = Time.realtimeSinceStartup;
- for (i = 0; i < map.size; i++)
- for (j = 0; j < map.size; j++)
- {
- map.matrix[i,j].cleanDisabledStates();
- map.matrix[i,j].setType(WATER);
- }
- createCrudeMap();
- doCrude = false;
- }
- if (doHeuristic)
- {
- createPonds();
- makeEdges();
- doMapMassage(3, 5);
- createRivers();
- doMapMassage(3, 3);
- findAllIslesAndContinent();
- destroyAnomalies();
- findAllIslesAndContinent();
- connectAllIslesToBiggest();
- findAllBiomes();
- if (hasAllBiomes() && !hasBiomesAnomalies() && specialMassageForIslesConection())
- {
- findWaterBorders();
- // Debug.Log("End: " + (Time.realtimeSinceStartup - init));
- gameManager.onMapEndCreation();
- doHeuristic = false;
- setInit = true;
- }
- else
- {
- setInit = false;
- doHeuristic = true;
- doCrude = true;
- }
- }
- if (doEdges)
- {
- makeEdges();
- doEdges = false;
- }
- if (doPonds)
- {
- createPonds();
- doPonds = false;
- }
- if (doSolos)
- {
- removeSolos(soloSensivity);
- doSolos = false;
- }
- if (doIsles)
- {
- findAllIslesAndContinent();
- connectAllIslesToBiggest();
- doIsles = false;
- }
- if (doAnomalies)
- {
- findAllIslesAndContinent();
- destroyAnomalies();
- doAnomalies = false;
- }
- if (doRivers)
- {
- createRivers();
- doRivers = false;
- }
- }
- @Header("Start")
- @Range(1,10) var recursionLevel: int; // Creates tiles using Paint's bucket tool recursive strategy.
- @Range(25,100) var recursionChance: int; // Chance that the 'bucket tool' will create one tile.
- @Range(0,100) var minimumWaterTiles: float;
- @Header("Do Options")
- var doCrude: boolean;
- var doHeuristic: boolean;
- var doSolos: boolean;
- var doEdges: boolean;
- var doPonds: boolean;
- var doIsles: boolean;
- var doAnomalies: boolean;
- var doRivers: boolean;
- @Header("Attributes")
- @Range(2,7) var biomeLevel: int; // Set biomesCount here (only numbers for Range).
- @Range(1,2) var typeRepetition: int;
- @Range(0,8) var soloSensivity: int;
- @Range(0,100) var edgeRefinement: int;
- @Range(0,15) var ponds: int;
- @Range(0,7) var rivers: int;
- @Range(0,100) var anomalyThreshold: int;
- var continentOnlyAnomalyCheck: boolean;
- private var waterTiles: int;
- function onMapStartCreation(level: MapLevel)
- {
- if (level.level > 1)
- typeRepetition = 1;
- biomeLevel = level.biomeLevel;
- }
- function createCrudeMap()
- {
- waterTiles = map.size * map.size;
- var ri: int;
- var rj: int;
- var type = 1;
- for (var i = 0; i < map.size; i++)
- for (var j = 0; j < map.size; j++)
- {
- // map.matrix[i,j].explored = false;
- // map.matrix[i,j].removeFog();
- }
- while (waterTiles > minimumWaterTiles*0.01*map.size*map.size)
- {
- ri = Random.Range(0, map.size);
- rj = Random.Range(0, map.size);
- createBiome(ri, rj, recursionLevel, type, true);
- type++;
- if (type == biomeLevel)
- type = 1;
- }
- }
- function removeSolos(sensivity: int)
- {
- for (var k = 0; k < biomesCount; k++)
- removeSoloType(k, sensivity);
- }
- function removeSoloType(type: TileType, sensivity: int)
- {
- for (var i = 0; i < map.size; i++)
- for (var j = 0; j < map.size; j++)
- {
- var tile = map.matrix[i,j];
- if (tile.type == type)
- if (getTypeNeighbourCount(tile, type) <= sensivity)
- setTypeFromRandomNeighbour(tile);
- }
- }
- function makeEdges()
- {
- for (var k = 0; k < map.size; k++)
- {
- // Vertical Left.
- map.matrix[k,0].setType(WATER);
- if (Random.Range(0, 100) < edgeRefinement)
- map.matrix[k,1].setType(WATER);
- // Vertical Right.
- map.matrix[k,map.size-1].setType(WATER);
- if (Random.Range(0, 100) < edgeRefinement)
- map.matrix[k,map.size-2].setType(WATER);
- // Horizontal Top.
- map.matrix[0,k].setType(WATER);
- if (Random.Range(0, 100) < edgeRefinement)
- map.matrix[1,k].setType(WATER);
- // Horizontal Bot.
- map.matrix[map.size-1,k].setType(WATER);
- if (Random.Range(0, 100) < edgeRefinement)
- map.matrix[map.size-2,k].setType(WATER);
- }
- }
- function createPonds()
- {
- var k = ponds;
- var ri: int;
- var rj: int;
- while (k > 0)
- {
- ri = Random.Range(0, map.size);
- rj = Random.Range(0, map.size);
- createBiome(ri, rj, recursionLevel-1, 0, false);
- k--;
- }
- }
- /*
- Method that copys Paint's bucket tool recursive algorithm.
- */
- function createBiome(i: int, j: int, level: int, type: TileType, onlyOnWater: boolean)
- {
- if (level == 0)
- return;
- if (Position.isInsideMapMatrix(i, j, map.size))
- {
- if (onlyOnWater && map.matrix[i,j].type == WATER)
- {
- waterTiles--;
- map.matrix[i,j].setType(type);
- }
- else if (!onlyOnWater)
- {
- if (map.matrix[i,j].type == WATER)
- waterTiles--;
- map.matrix[i,j].setType(type);
- }
- else
- return;
- }
- else
- return;
- // WEST.
- if (Random.Range(0, 100) < recursionChance)
- createBiome(i, j+1, level-1, type, onlyOnWater);
- // NORTH.
- if (Random.Range(0, 100) < recursionChance)
- createBiome(i-1, j, level-1, type, onlyOnWater);
- // EAST.
- if (Random.Range(0, 100) < recursionChance)
- createBiome(i, j-1, level-1, type, onlyOnWater);
- // SOUTH.
- if (Random.Range(0, 100) < recursionChance)
- createBiome(i+1, j, level-1, type, onlyOnWater);
- }
- function getTypeNeighbourCount(tile: Tile, type: TileType)
- {
- var counter = 0;
- for (n in tile.neighbourhood)
- if (n.type == type)
- counter++;
- return counter;
- }
- function setTypeFromRandomNeighbour(tile: Tile)
- {
- tile.setType(tile.neighbourhood[Random.Range(0, tile.neighbourhood.Count)].type);
- }
- class GroupOfTiles
- {
- var tiles: List.<Tile>;
- function GroupOfTiles()
- {
- tiles = new List.<Tile>();
- }
- function addTile(tile: Tile)
- {
- tiles.Add(tile);
- }
- function getSize()
- {
- return tiles.Count;
- }
- function isThisTileInside(tile: Tile)
- {
- for (t in tiles)
- if (t == tile)
- return true;
- return false;
- }
- function getCenterPosition()
- {
- var averagePosition = new Position(0,0);
- for (var k = 0; k < getSize(); k++)
- averagePosition.add(tiles[k].position);
- averagePosition.i /= getSize();
- averagePosition.j /= getSize();
- return averagePosition;
- }
- function getRandomTile()
- {
- return tiles[Random.Range(0, getSize())];
- }
- function getRandomPosition()
- {
- return tiles[Random.Range(0, getSize())].position;
- }
- function setAllTilesAsWater()
- {
- for (t in tiles)
- t.setType(WATER);
- }
- function isThisGroupInside(isle: GroupOfTiles)
- {
- var counter = 0;
- for (var i = 0; i < isle.getSize(); i++)
- if (isThisTileInside(isle.tiles[i]))
- counter++;
- return counter == isle.getSize();
- }
- }
- class Biome extends GroupOfTiles
- {
- var tilesForObstacle: List.<Tile>;
- var tilesForItem: List.<Tile>;
- var tilesForUnit: List.<Tile>;
- function Biome()
- {
- tilesForObstacle = new List.<Tile>();
- tilesForItem = new List.<Tile>();
- tilesForUnit = new List.<Tile>();
- }
- function getType() // For biome only, not isles.
- {
- return tiles[0].type;
- }
- function refreshItemStates()
- {
- tilesForItem.Clear();
- for (t in tiles)
- if (t.canReceiveItem())
- tilesForItem.Add(t);
- }
- function refreshObstacleStates()
- {
- tilesForObstacle.Clear();
- for (t in tiles)
- if (t.canReceiveObstacle())
- tilesForObstacle.Add(t);
- }
- function refreshUnitStates()
- {
- tilesForUnit.Clear();
- for (t in tiles)
- if (t.canReceiveUnit())
- tilesForUnit.Add(t);
- }
- function getRandomTileToReceiveObstacle(): Tile
- {
- if (tilesForObstacle.Count == 0)
- return null;
- var tile: Tile;
- var randomIndex = Random.Range(0, tilesForObstacle.Count);
- // Debug.Log("Biome: " + getType() + ", RI: " + randomIndex + ", Total: " + tilesForObstacle.Count);
- tile = tilesForObstacle[randomIndex];
- if (tile != null)
- {
- tilesForObstacle.RemoveAt(randomIndex);
- return tile;
- }
- else
- return null;
- }
- function getRandomTileToReceiveItem(): Tile
- {
- if (tilesForItem.Count == 0)
- return null;
- var tile: Tile;
- var randomIndex = Random.Range(0, tilesForItem.Count);
- // Debug.Log("Biome: " + getType() + ", RI: " + randomIndex + ", Total: " + tilesForItem.Count);
- tile = tilesForItem[randomIndex];
- if (tile != null)
- {
- tilesForItem.RemoveAt(randomIndex);
- return tile;
- }
- else
- return null;
- }
- function getRandomTileToReceiveUnit(): Tile
- {
- if (tilesForUnit.Count == 0)
- return null;
- var tile: Tile;
- var randomIndex = Random.Range(0, tilesForUnit.Count);
- // Debug.Log("Biome: " + getType() + ", RI: " + randomIndex + ", Total: " + tilesForUnit.Count);
- tile = tilesForUnit[randomIndex];
- if (tile != null)
- {
- tilesForUnit.RemoveAt(randomIndex);
- return tile;
- }
- else
- return null;
- }
- }
- private var checkedTiles: boolean[ , ];
- var isles: List.<GroupOfTiles>;
- private var currentIsle: int;
- private var continent: GroupOfTiles;
- function findAllIslesAndContinent()
- {
- currentIsle = 0;
- checkedTiles = new boolean[map.size, map.size];
- isles = new List.<GroupOfTiles>();
- for (var i = 0; i < map.size; i++)
- for (var j = 0; j < map.size; j++)
- {
- if (checkedTiles[i,j] == false)
- {
- if (map.matrix[i,j].type == WATER)
- checkWaterByFloodFill(i, j);
- else
- {
- isles.Add(new GroupOfTiles());
- checkTerrainByFloodFill(i, j);
- currentIsle++;
- }
- }
- }
- var biggestSize = 0;
- for (var k = 0; k < isles.Count; k++)
- {
- if (isles[k].getSize() > biggestSize)
- {
- biggestSize = isles[k].getSize();
- continent = isles[k];
- }
- }
- }
- function connectAllIslesToBiggest()
- {
- for (var k = 0; k < isles.Count; k++)
- {
- if (isles[k] != continent)
- connecIsles(isles[k], continent);
- }
- }
- function checkWaterByFloodFill(i: int, j: int)
- {
- if (Position.isInsideMapMatrix(i, j, map.size))
- {
- if (map.matrix[i,j].type == WATER && checkedTiles[i,j] == false)
- {
- checkedTiles[i,j] = true;
- // WEST.
- checkWaterByFloodFill(i, j+1);
- // NORTH.
- checkWaterByFloodFill(i-1, j);
- // EAST.
- checkWaterByFloodFill(i, j-1);
- // SOUTH.
- checkWaterByFloodFill(i+1, j);
- }
- else
- return;
- }
- else
- return;
- }
- function checkTerrainByFloodFill(i: int, j: int)
- {
- if (Position.isInsideMapMatrix(i, j, map.size))
- {
- if (map.matrix[i,j].type != WATER && checkedTiles[i,j] == false)
- {
- isles[currentIsle].addTile(map.matrix[i,j]);
- checkedTiles[i,j] = true;
- // WEST.
- checkTerrainByFloodFill(i, j+1);
- // NORTH.
- checkTerrainByFloodFill(i-1, j);
- // EAST.
- checkTerrainByFloodFill(i, j-1);
- // SOUTH.
- checkTerrainByFloodFill(i+1, j);
- }
- else
- return;
- }
- else
- return;
- }
- function connecIsles(smaller: GroupOfTiles, bigger: GroupOfTiles)
- {
- var movingPosition = new Position(smaller.getRandomPosition());
- var lastTile: Tile;
- var findTerrain = false;
- var targetPosition = new Position(bigger.getRandomPosition());
- var currentTile: Tile;
- while (movingPosition.isInsideMapMatrix(map.size) && movingPosition.getDistanceTo(targetPosition) > 0)
- {
- if (!findTerrain)
- lastTile = map.matrix[movingPosition.i, movingPosition.j];
- movingPosition.moveOneStepTowards(targetPosition);
- currentTile = map.matrix[movingPosition.i, movingPosition.j];
- if (findTerrain)
- {
- if (currentTile.type != WATER)
- {
- if (!smaller.isThisTileInside(currentTile))
- lastTile = currentTile; // Update tile type when finding another terrain that is not continent.
- if (bigger.isThisTileInside(currentTile))
- {
- currentTile.disableObstacleAndItemReceiveForMeAndNeighbourhood();
- return; // Connected!
- }
- }
- else
- {
- currentTile.setType(lastTile.type);
- currentTile.disableObstacleAndItemReceiveForMeAndNeighbourhood();
- }
- }
- else if (currentTile.type == WATER)
- {
- // Found water.
- findTerrain = true;
- currentTile.setType(lastTile.type);
- currentTile.disableObstacleAndItemReceiveForMeAndNeighbourhood();
- }
- }
- }
- var biomes: List.<Biome>;
- function destroyAnomalies()
- {
- findAllBiomes();
- for (var k = 0; k < biomes.Count; k++)
- {
- if (biomes[k].getSize() < anomalyThreshold)
- {
- if (continentOnlyAnomalyCheck)
- {
- if (continent.isThisGroupInside(biomes[k]))
- {
- biomes[k].setAllTilesAsWater();
- biomes.RemoveAt(k);
- k--;
- }
- }
- else
- {
- biomes[k].setAllTilesAsWater();
- biomes.RemoveAt(k);
- k--;
- }
- }
- }
- }
- function checkEqualTerrainsByFloodFill(i: int, j: int, type: TileType)
- {
- if (Position.isInsideMapMatrix(i, j, map.size))
- {
- if (map.matrix[i,j].type == type && checkedTiles[i,j] == false)
- {
- map.matrix[i,j].biome = biomes[currentIsle];
- biomes[currentIsle].addTile(map.matrix[i,j]);
- checkedTiles[i,j] = true;
- // WEST.
- checkEqualTerrainsByFloodFill(i, j+1, type);
- // NORTH.
- checkEqualTerrainsByFloodFill(i-1, j, type);
- // EAST.
- checkEqualTerrainsByFloodFill(i, j-1, type);
- // SOUTH.
- checkEqualTerrainsByFloodFill(i+1, j, type);
- }
- else
- return;
- }
- else
- return;
- }
- function hasAllBiomes()
- {
- var counterPerType = new int[biomeLevel-1];
- for (var type = 1; type < biomeLevel; type++)
- for (var i = 0; i < biomes.Count; i++)
- if (biomes[i].getType() == type)
- {
- counterPerType[type-1] += 1;
- }
- var satisfieds = 0;
- for (var j = 0; j < biomeLevel-1; j++)
- // Usar == vira exatamente a quantidade, usar >= vira 'NO MÍNIMO typeRepetition DE CADA'.
- if (counterPerType[j] >= typeRepetition)
- satisfieds++;
- return satisfieds == biomeLevel-1; // Except water.
- }
- var sides: boolean[];
- function createRivers()
- {
- for (var i = 0; i < rivers; i++)
- createOneRiver();
- }
- function createOneRiver()
- {
- sides = new boolean[4];
- for (s in sides)
- s = true;
- var initialTile = getRandomTileSide();
- while (initialTile == null)
- initialTile = getRandomTileSide();
- var targetTile = getRandomTileSide();
- while (targetTile == null)
- targetTile = getRandomTileSide();
- var movingPosition = new Position(initialTile.position);
- var targetPosition = new Position(targetTile.position);
- map.matrix[movingPosition.i, movingPosition.j].setType(WATER);
- while (movingPosition.isInsideMapMatrix(map.size) && movingPosition.getDistanceTo(targetPosition) > 0)
- {
- movingPosition.moveOneStepTowards(targetPosition);
- map.matrix[movingPosition.i, movingPosition.j].setMeAndAllNeighboursType(WATER);
- }
- }
- function getRandomTileSide(): Tile
- {
- var random = Random.Range(0, 4);
- var tile: Tile = null;
- if (random == 0 && sides[random] == true)
- tile = map.matrix[Random.Range(0, map.size),map.size-1];
- if (random == 1 && sides[random] == true)
- tile = map.matrix[0,Random.Range(0, map.size)];
- if (random == 2 && sides[random] == true)
- tile = map.matrix[Random.Range(0, map.size), 0];
- if (random == 3 && sides[random] == true)
- tile = map.matrix[map.size-1,Random.Range(0, map.size)];
- sides[random] = false;
- return tile;
- }
- // Massage means smoothing the map.
- function doMapMassage(startSensivity: int, repetitions: int)
- {
- for (var i = startSensivity; i >= 0; i--)
- for (var j = 0; j < repetitions; j++)
- removeSolos(i);
- }
- function findAllBiomes()
- {
- currentIsle = 0;
- checkedTiles = new boolean[map.size, map.size];
- biomes = new List.<Biome>();
- biomes.Clear();
- for (var i = 0; i < map.size; i++)
- for (var j = 0; j < map.size; j++)
- {
- if (checkedTiles[i,j] == false)
- {
- if (map.matrix[i,j].type == WATER)
- checkWaterByFloodFill(i, j);
- else
- {
- biomes.Add(new Biome());
- checkEqualTerrainsByFloodFill(i, j, map.matrix[i,j].type);
- currentIsle++;
- }
- }
- }
- }
- function hasBiomesAnomalies()
- {
- for (b in biomes)
- if (b.getSize() < anomalyThreshold)
- {
- Debug.Log(b.getType() + ": Anomaly after map creation!");
- return true;
- }
- return false;
- }
- function getBiomes()
- {
- return biomes;
- }
- var waterBorders: List.<Tile>;
- function findWaterBorders()
- {
- waterBorders = new List.<Tile>();
- var water: Tile;
- for (var i = 0; i < map.size; i++)
- for (var j = 0; j < map.size; j++)
- {
- water = map.matrix[i,j].hasOneWaterNeighbour();
- if (water)
- waterBorders.Add(water);
- }
- }
- function specialMassageForIslesConection()
- {
- for (var type = 0; type < biomeLevel; type++)
- for (var i = 0; i < map.size; i++)
- for (var j = 0; j < map.size; j++)
- {
- var tile = map.matrix[i,j];
- if (tile.type == type)
- if (getTypeNeighbourCount(tile, type) <= 1)
- {
- setTypeFromRandomNeighbour(tile);
- var trys = 10;
- while (tile.type == WATER && trys > 0)
- {
- setTypeFromRandomNeighbour(tile);
- trys--;
- }
- if (trys == 0)
- {
- Debug.Log("Bug for special massage: Could not set tile to other type than WATER.");
- return false;
- }
- }
- }
- return true;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement