public GridPoint GetFreeGridPoint(int clearance, int attempts = 5) { if (attempts == -1) { return(null); } attempts--; GridPoint testPoint = GenRan.RandomFromList(FreePoints); for (int x = -clearance; x <= clearance; x++) { for (int z = -clearance; z <= clearance; z++) { Vec2i p = testPoint.GridPos + new Vec2i(x, z); if (GridPlacement.InGridBounds(p)) { GridPoint gp = GameGen.GridPlacement.GridPoints[p.x, p.z]; if (gp == null) { continue; } if (gp.HasNonSettlementStructure) { return(GetFreeGridPoint(clearance, attempts)); } } } } FreePoints.Remove(testPoint); testPoint.HasNonSettlementStructure = true; return(testPoint); }
/// <summary> /// We generate all grid points for the world /// Each is equally spaced /// </summary> public void GenerateInitialGridPoints() { for (int x = 0; x < GridSize; x++) { for (int z = 0; z < GridSize; z++) { /* Vec2i cPos = new Vec2i(Mathf.Clamp(x * GridPointSize + (int)GenRan.GaussianFloat(0, GridPointSize/6), 0, World.WorldSize-1), * Mathf.Clamp(z * GridPointSize + (int)GenRan.GaussianFloat(0, GridPointSize/6), 0, World.WorldSize - 1));*/ Vec2i cPos = new Vec2i(x * GridPointSize, z * GridPointSize); GridPoints[x, z] = new GridPoint(new Vec2i(x, z), cPos); if (GameGen.TerGen.ChunkBases[cPos.x, cPos.z].Biome != ChunkBiome.ocean) { GridPoints[x, z].IsValid = true; } else { GridPoints[x, z].IsValid = false; } } } for (int x = 0; x < GridSize; x++) { for (int z = 0; z < GridSize; z++) { if (GridPoints[x, z] != null) { //We iterate all nearest neighbors of this grid point for (int i = 0; i < WorldEventPathFinder.DIRS.Length; i++) { int x_ = x + WorldEventPathFinder.DIRS[i].x; int z_ = z + WorldEventPathFinder.DIRS[i].z; Vec2i p = new Vec2i(x_, z_); //Check this neighbor is in bounds, and is a valid grid point if (GridPlacement.InGridBounds(p) && GridPoints[p.x, p.z] != null && GridPoints[p.x, p.z].IsValid) { GridPoints[x, z].NearestNeighbors.Add(p); } } } } } CalculateEnclosedBiomes(); }
public bool InBounds(Vec2i v) { return(GridPlacement.InGridBounds(v)); }
/// <summary> /// Iterates through all grid points and checks for valid ones (on land, no settlement or tactloc). /// We then add them to a weighted random list, with locations surrounded by settlements having a lower weighting /// we then return this list for use /// </summary> /// <returns></returns> private WeightedRandomList <GridPoint> FindFreeGridPoints() { WeightedRandomList <GridPoint> gridPoints = new WeightedRandomList <GridPoint>(); int radius = 2; for (int x = 0; x < GridPlacement.GridSize; x++) { for (int z = 0; z < GridPlacement.GridSize; z++) { GridPoint gp = GameGen.GridPlacement.GridPoints[x, z]; if (!gp.IsValid) { continue; } if (gp.ChunkPos.QuickDistance(GameGen.TerGen.EvilDragonMountainPeak) < 100 * 100) { continue; } if (gp.ChunkPos.QuickDistance(GameGen.TerGen.GoodDragonMountainPeak) < 60 * 60) { continue; } float weight = 10; //If there is something here, then we ignore this point if (gp.Shell != null) { continue; } Debug.Log("No shell"); for (int rx = -radius; rx <= radius; rx++) { if (weight <= 0) { break; } for (int rz = -radius; rz <= radius; rz++) { Vec2i testPos = new Vec2i(x + rx, z + rz); //Distance from gridpoint to this point float dist = Mathf.Sqrt(rx * rx + rz * rz); if (GridPlacement.InGridBounds(testPos)) { //Get near point GridPoint gp2 = GameGen.GridPlacement.GridPoints[testPos.x, testPos.z]; if (gp2.Shell != null) { //If too close, then point not valid if (dist <= 1) { weight -= 5; } else { weight -= 3f / dist; } } } } } if (weight > 0) { gridPoints.AddElement(gp, weight); } } } return(gridPoints); }
/// <summary> /// Calculates the location data for the supplied shell /// </summary> /// <param name="shell">The shell to generate and store data to</param> private void GenerateLocationData(Shell shell) { GridPoint gp = shell.GridPoint; bool onBorder = false; bool onRiver = false; bool onCoast = false; bool onLake = false; //Get the chunk this grid point is on ChunkBase2 cb = GameGen.TerGen.ChunkBases[gp.ChunkPos.x, gp.ChunkPos.z]; int kingdomID = cb.KingdomID; if (kingdomID == -1) { Debug.Error("Shell " + shell + " lays on unclaimed territory - not valid"); } //iterate away from search point for (int i = 1; i < GridPlacement.GridPointSize; i++) { //Search in 4 directions foreach (Vec2i v in Vec2i.OCT_DIRDIR) { //Find the point in this direction Vec2i p = cb.Pos + v * i; //Ensure in world bounds if (GameGenerator2.InBounds(p)) { //Get chunk here ChunkBase2 cb_p = GameGen.TerGen.ChunkBases[p.x, p.z]; if (cb_p.Biome == ChunkBiome.ocean) { onCoast = true; } if (cb_p.KingdomID != -1 && cb_p.KingdomID != kingdomID) { onBorder = true; } if (cb_p.ChunkFeature is ChunkRiverNode) { onRiver = true; } } } } //Define entraces bool[] entrances = new bool[8]; for (int i = 0; i < 8; i++) { foreach (Vec2i v in Vec2i.OCT_DIRDIR) { Vec2i p = gp.GridPos + v; if (GridPlacement.InGridBounds(p)) { GridPoint gp2 = GameGen.GridPlacement.GridPoints[p.x, p.z]; if (gp2.HasRoad) { entrances[i] = true; } else { entrances[i] = false; } } } } LocationData ld = new LocationData() { OnCoast = onCoast, OnLake = onLake, OnRiver = onRiver, OnBorder = onBorder, EntranceDirections = entrances }; shell.SetLocationData(ld); Vec2i size = shell.GetSize(); ChunkBase2[,] bases = new ChunkBase2[size.x, size.z]; //Iterate chunk bases that belong to this shell, add them to the array for (int x = 0; x < size.x; x++) { for (int z = 0; z < size.z; z++) { bases[x, z] = GameGen.TerGen.ChunkBases[x, z]; } } //Set bases shell.SetChunkBases(bases); }