public ValueTuple <bool, SCCoords> CheckIndirectAirshipAccess(OwRegion region, List <int> checkedRegions = null) { if (checkedRegions == null) { checkedRegions = new List <int>(); } if (checkedRegions.Contains(region.RegionId)) { return(ValueTuple.Create(false, new SCCoords(0, 0))); } checkedRegions.Add(region.RegionId); if (region.RegionType == OverworldTiles.LAND_REGION) { var r = this.CheckAirshipAccess(region); if (r.Item1) { return(r); } } foreach (var adj in region.Adjacent) { if (this.Traversable_regionlist[adj].RegionType == OverworldTiles.LAND_REGION || this.Traversable_regionlist[adj].RegionType == OverworldTiles.RIVER_REGION) { var r = this.CheckIndirectAirshipAccess(this.Traversable_regionlist[adj], checkedRegions); if (r.Item1) { return(r); } } } return(ValueTuple.Create(false, new SCCoords(0, 0))); }
public async Task <Result> IsolatedPlacement(OwFeature feature, OwRegion region, bool requireAirshipAccess) { var v = this.PlaceFeature(this.Traversable_regionmap, region, feature); if (v.Item1) { this.OwnPlacements(); var exclude = new List <int>(); this.FindAllReachableByRiver(region, exclude); foreach (var e in exclude) { if (!this.Exclude_docks.Contains(e)) { this.Exclude_docks.Add(e); } } if (!requireAirshipAccess) { if (!this.Exclude_airship.Contains(region.RegionId)) { this.Exclude_airship.Add(region.RegionId); } } return(await this.NextStep()); } else { return(new Result(false)); } }
public bool CheckReachableByRiver(OwRegion region, bool requireRiver, bool traversedRiver = false, List <int> checkedRegions = null) { if (checkedRegions == null) { checkedRegions = new List <int>(); } if (checkedRegions.Contains(region.RegionId)) { return(false); } checkedRegions.Add(region.RegionId); if (region.RegionType == OverworldTiles.LAND_REGION) { if (this.Reachable_regions.Contains(region.RegionId)) { if (requireRiver) { return(traversedRiver); } else { return(true); } } } if (region.RegionType == OverworldTiles.RIVER_REGION) { if (region.Adjacent.Contains(OverworldTiles.MainOceanRegionId)) { return(true); } traversedRiver = true; } foreach (var adj in region.Adjacent) { if (this.Traversable_regionlist[adj].RegionType == OverworldTiles.RIVER_REGION || this.Traversable_regionlist[adj].RegionType == OverworldTiles.LAND_REGION) { if (this.CheckReachableByRiver(this.Traversable_regionlist[adj], requireRiver, traversedRiver, checkedRegions)) { return(true); } } } return(false); }
public async Task <Result> CoastalPlacement(OwFeature feature, OwRegion region, bool fill, bool eastOnly) { var points = new List <SCCoords>(region.Points); points.Shuffle(this.rng); int w = feature.Tiles.GetLength(1); int h = feature.Tiles.GetLength(0); foreach (var p in points) { if (p.Y + h - 1 >= OverworldState.MAPSIZE || p.X + w >= OverworldState.MAPSIZE) { continue; } int makeland = 0; if (!eastOnly && this.Traversable_regionmap[p.Y + h - 2, p.X - 1] == OverworldTiles.MainOceanRegionId) { makeland = w - 1; } else if (this.Traversable_regionmap[p.Y + h - 2, p.X + w] == OverworldTiles.MainOceanRegionId) { makeland = 0; } else { continue; } var pf = this.PlaceFeatureAt(this.Traversable_regionmap, region, p, feature); if (!pf.Item1) { continue; } if (fill) { this.Tilemap[p.Y + h - 1, p.X + makeland] = OverworldTiles.LAND; this.Tilemap[p.Y + h - 2, p.X + makeland] = OverworldTiles.LAND; } if (feature.Entrances.ContainsKey("Ship")) { this.OwnPlacements(); var s = feature.Entrances["Ship"]; this.DockPlacements.Add(new ValueTuple <short, SCCoords>(region.RegionId, new SCCoords(p.X + s.X, p.Y + s.Y))); } return(await this.NextStep()); } return(new Result(false)); }
public void FindAllReachableByRiver(OwRegion region, List <int> checkedRegions) { if (checkedRegions.Contains(region.RegionId)) { return; } checkedRegions.Add(region.RegionId); foreach (var adj in region.Adjacent) { if (this.Traversable_regionlist[adj].RegionType == OverworldTiles.RIVER_REGION || this.Traversable_regionlist[adj].RegionType == OverworldTiles.LAND_REGION) { this.FindAllReachableByRiver(this.Traversable_regionlist[adj], checkedRegions); } } }
public async Task <Result> CanalPlacement(OwRegion region) { var points = new List <SCCoords>(region.Points); points.Shuffle(this.rng); bool placed = false; foreach (var p in points) { var ep = p.OwRight; if (this.Traversable_regionmap[ep.Y, ep.X] == OverworldTiles.MainOceanRegionId) { var r = this.PlaceFeatureAt(this.Traversable_regionmap, region, new SCCoords(p.X - 5, p.Y - 2), OverworldTiles.E_CANAL_STRUCTURE, true); if (r.Item1) { placed = true; break; } } var wp = p.OwLeft; if (this.Traversable_regionmap[wp.Y, wp.X] == OverworldTiles.MainOceanRegionId) { var r = this.PlaceFeatureAt(this.Traversable_regionmap, region, new SCCoords(p.X, p.Y - 2), OverworldTiles.W_CANAL_STRUCTURE, true); if (r.Item1) { placed = true; break; } } } if (placed) { this.OwnPlacements(); if (!this.Exclude_docks.Contains(region.RegionId)) { this.Exclude_docks.Add(region.RegionId); } return(await this.NextStep()); } return(new Result(false)); }
public async Task <Result> WaterfallPlacement(OwFeature feature, OwRegion region) { var points = new List <SCCoords>(region.Points); points.Shuffle(this.rng); foreach (var p in points) { if (this.Tilemap[p.Y, p.X - 1] == OverworldTiles.MOUNTAIN && this.Tilemap[p.Y, p.X + 1] == OverworldTiles.MOUNTAIN && this.Tilemap[p.Y - 1, p.X] == OverworldTiles.RIVER && this.Tilemap[p.Y + 1, p.X] == OverworldTiles.RIVER) { this.PlaceFeatureAt(this.Traversable_regionmap, region, new SCCoords(p.X - 1, p.Y - 1), feature, false); return(await this.NextStep()); } } return(new Result(false)); }
public async Task <Result> MountainRiverPlacement(OwFeature feature, OwRegion mtnRegion, OwRegion riverRegion) { var points = new List <SCCoords>(mtnRegion.Points); points.Shuffle(this.rng); OwFeature caveFeature = null; if (feature.MountainCave) { caveFeature = feature; if (this.rng.Between(0, 1) == 0) { feature = OverworldTiles.MOUNTAIN_CAVE_FEATURE; } else { feature = OverworldTiles.FOREST_MOUNTAIN_CAVE_FEATURE; } } else { feature = feature.NoneToMarsh(); } int w = feature.Tiles.GetLength(1); int h = feature.Tiles.GetLength(0); foreach (var p in points) { if (this.Traversable_regionmap[p.Y + h, p.X + (w / 2)] == riverRegion.RegionId) { var v = this.PlaceFeatureAt(this.Traversable_regionmap, mtnRegion, p, feature, true); if (v.Item1) { if (caveFeature != null) { this.PlaceFeatureAt(this.Traversable_regionmap, mtnRegion, new SCCoords(p.X + 2, p.Y + 1), caveFeature, false); } return(await this.NextStep()); } } } return(new Result(false)); }
public async Task <Result> BiomePlacement(OwFeature feature, OwRegion region, bool shipReachable, int maxweight) { var trav = this.Traversable_regionlist[this.Traversable_regionmap[region.Points[0].Y, region.Points[0].X]]; var v = this.PlaceFeature(this.Biome_regionmap, region, feature, maxweight); if (!v.Item1) { return(new Result(false)); } if (shipReachable) { var d = this.DockPlacement(trav); if (!this.Reachable_regions.Contains(trav.RegionId)) { return(new Result(false)); } } return(await this.NextStep()); }
public ValueTuple <bool, SCCoords> CheckAirshipAccess(OwRegion region) { foreach (var p in region.Points) { if (this.Tilemap[p.Y, p.X] == OverworldTiles.LAND || this.Tilemap[p.Y, p.X] == OverworldTiles.GRASS) { var count = 0; var up = p.OwUp; var right = p.OwRight; var down = p.OwDown; var left = p.OwLeft; if (this.Tilemap[up.Y, up.X] == OverworldTiles.OCEAN) { count++; } if (this.Tilemap[right.Y, right.X] == OverworldTiles.OCEAN) { count++; } if (this.Tilemap[down.Y, down.X] == OverworldTiles.OCEAN) { count++; } if (this.Tilemap[left.Y, left.X] == OverworldTiles.OCEAN) { count++; } // Don't consider tiles that are bordered on two // or more sides by water, there is a possibility // that they get modified or eliminated by later // filters. if (count < 2) { return(ValueTuple.Create(true, p)); } } } return(ValueTuple.Create(false, new SCCoords(0, 0))); }
public async Task <Result> StartingAreaPlacement(OwFeature feature, OwRegion region) { var v = this.PlaceFeature(this.Traversable_regionmap, region, feature); if (v.Item1) { this.OwnPlacements(); if (this.startingRegion == -1) { this.startingRegion = region.RegionId; this.DockPlacement(this.StartingRegion); } this.Reachable_regions.Add(region.RegionId); return(await this.NextStep()); } else { return(new Result(false)); } }
public async Task <Result> RequiresCanoePlacement(OwFeature feature, OwRegion region) { var v = this.PlaceFeature(this.Traversable_regionmap, region, feature); if (v.Item1) { this.OwnPlacements(); var exclude = new List <int>(); if (!this.Exclude_docks.Contains(region.RegionId)) { this.Exclude_docks.Add(region.RegionId); } if (!this.Exclude_airship.Contains(region.RegionId)) { this.Exclude_airship.Add(region.RegionId); } return(await this.NextStep()); } else { return(new Result(false)); } }
public bool DockPlacement(OwRegion region) { var points = new List <SCCoords>(region.Points); points.Shuffle(this.rng); OwFeature placed = null; SCCoords placedAt = new SCCoords(0, 0); foreach (var p in points) { var np = p.OwUp; if (this.Traversable_regionmap[np.Y, np.X] == OverworldTiles.MainOceanRegionId) { var r = this.PlaceFeatureAt(this.Traversable_regionmap, region, new SCCoords(p.X - 2, p.Y), OverworldTiles.N_DOCK_STRUCTURE, true); if (r.Item1) { placedAt = p; placed = OverworldTiles.N_DOCK_STRUCTURE; break; } } var ep = p.OwRight; if (this.Traversable_regionmap[ep.Y, ep.X] == OverworldTiles.MainOceanRegionId) { var r = this.PlaceFeatureAt(this.Traversable_regionmap, region, new SCCoords(p.X - 3, p.Y - 2), OverworldTiles.E_DOCK_STRUCTURE, true); if (r.Item1) { placedAt = p; placed = OverworldTiles.E_DOCK_STRUCTURE; break; } } var sp = p.OwDown; if (this.Traversable_regionmap[sp.Y, sp.X] == OverworldTiles.MainOceanRegionId) { var r = this.PlaceFeatureAt(this.Traversable_regionmap, region, new SCCoords(p.X - 2, p.Y - 2), OverworldTiles.S_DOCK_STRUCTURE, true); if (r.Item1) { placedAt = p; placed = OverworldTiles.S_DOCK_STRUCTURE; break; } } var wp = p.OwLeft; if (this.Traversable_regionmap[wp.Y, wp.X] == OverworldTiles.MainOceanRegionId) { var r = this.PlaceFeatureAt(this.Traversable_regionmap, region, new SCCoords(p.X, p.Y - 2), OverworldTiles.W_DOCK_STRUCTURE, true); if (r.Item1) { placedAt = p; placed = OverworldTiles.W_DOCK_STRUCTURE; break; } } } if (placed != null) { this.OwnPlacements(); var s = placed.Entrances["Ship"]; this.DockPlacements.Add(new ValueTuple <short, SCCoords>(region.RegionId, new SCCoords(placedAt.X + s.X, placedAt.Y + s.Y))); if (!this.Reachable_regions.Contains(region.RegionId)) { this.Reachable_regions.Add(region.RegionId); } return(true); } return(false); }
public async Task <Result> BridgePlacement(OwRegion originRegion, OwRegion riverRegion) { var points = new List <SCCoords>(riverRegion.Points); points.Shuffle(this.rng); short nextRegion = -1; foreach (var p in points) { for (int i = 0; i < 2; i++) { short c1, c2; if (i == 0) { c1 = this.Traversable_regionmap[p.Y - 1, p.X]; c2 = this.Traversable_regionmap[p.Y + 1, p.X]; } else { c1 = this.Traversable_regionmap[p.Y, p.X - 1]; c2 = this.Traversable_regionmap[p.Y, p.X + 1]; } if (c1 == originRegion.RegionId && c2 != originRegion.RegionId && c2 != this.startingRegion && this.Traversable_regionlist[c2].RegionType == OverworldTiles.LAND_REGION) { this.OwnPlacements(); this.FeatureCoordinates["Bridge"] = p; nextRegion = c2; break; } if (c1 != originRegion.RegionId && c2 == originRegion.RegionId && c1 != this.startingRegion && this.Traversable_regionlist[c1].RegionType == OverworldTiles.LAND_REGION) { this.OwnPlacements(); this.FeatureCoordinates["Bridge"] = p; nextRegion = c1; break; } } } if (nextRegion != -1) { this.OwnPlacements(); this.bridgedRegion = nextRegion; this.Reachable_regions.Add(nextRegion); this.Exclude_docks.Add(nextRegion); if (!this.DockPlacement(originRegion)) { return(new Result(false)); } this.OwnRegions(); this.OwnTilemap(); // turn bridged region into ocean foreach (var p in riverRegion.Points) { this.Tilemap[p.Y, p.X] = OverworldTiles.OCEAN; } this.Traversable_regionlist[riverRegion.RegionId] = new OwRegion(riverRegion); this.Traversable_regionlist[riverRegion.RegionId].RegionType = OverworldTiles.OCEAN_REGION; riverRegion = this.Biome_regionlist[this.Biome_regionmap[riverRegion.Points[0].Y, riverRegion.Points[0].X]]; this.Biome_regionlist[riverRegion.RegionId] = new OwRegion(riverRegion); this.Biome_regionlist[riverRegion.RegionId].RegionType = OverworldTiles.OCEAN_REGION; //this.Tilemap[this.FeatureCoordinates["Bridge"].Y, this.FeatureCoordinates["Bridge"].X] = OverworldTiles.DOCK_W; return(await this.NextStep()); } return(new Result(false)); }