示例#1
0
 public async Task <Result> PlaceInStartingArea(OwFeature feature)
 {
     if (this.startingRegion == -1)
     {
         var tasks  = new List <GenerationTask>();
         var sorted = new List <OwRegion>();
         foreach (var w in this.Traversable_regionlist)
         {
             if (w.RegionType == OverworldTiles.LAND_REGION)
             {
                 sorted.Add(w);
             }
         }
         sorted.Sort((OwRegion x, OwRegion y) => (x.Points.Count - y.Points.Count));
         foreach (var w in sorted)
         {
             tasks.Add(() => new OverworldState(this).StartingAreaPlacement(feature, w));
         }
         return(new Result(tasks));
     }
     else
     {
         return(await this.StartingAreaPlacement(feature, this.StartingRegion));
     }
 }
示例#2
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));
            }
        }
示例#3
0
        public async Task <Result> PlaceInMountains(OwFeature feature)
        {
            var tasks = new List <GenerationTask>();

            foreach (var w in this.Traversable_regionlist)
            {
                if (w.RegionType == OverworldTiles.MOUNTAIN_REGION)
                {
                    foreach (var i in w.Adjacent)
                    {
                        if (this.Traversable_regionlist[i].RegionType == OverworldTiles.RIVER_REGION)
                        {
                            var river = this.Traversable_regionlist[i];
                            var v     = this.CheckIndirectAirshipAccess(river);
                            if (v.Item1)
                            {
                                tasks.Add(() => new OverworldState(this).MountainRiverPlacement(feature, w, river));
                            }
                        }
                    }
                }
            }
            tasks.Shuffle(this.rng);
            await Task.Yield();

            return(new Result(tasks));
        }
示例#4
0
        public async Task <Result> PlaceInTitanWestRegion(OwFeature feature)
        {
            var p      = this.FeatureCoordinates["TitansTunnelWest"];
            var region = this.Traversable_regionlist[this.Traversable_regionmap[p.Y + 1, p.X]];
            var r      = this.PlaceFeature(this.Traversable_regionmap, region, feature);

            if (r.Item1)
            {
                return(await this.NextStep());
            }
            else
            {
                return(new Result(false));
            }
        }
示例#5
0
 public async Task <Result> PlaceInBridgedRegion(OwFeature feature)
 {
     if (this.bridgedRegion == -1)
     {
         return(await this.NextStep());
     }
     for (int i = 0; i < 8; i++)
     {
         var v = this.PlaceFeature(this.Traversable_regionmap, this.Traversable_regionlist[this.bridgedRegion], feature, i);
         if (v.Item1)
         {
             return(await this.NextStep());
         }
     }
     return(new Result(false));
 }
示例#6
0
        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));
        }
示例#7
0
        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));
        }
示例#8
0
        public async Task <Result> PlaceInCanalRegion(OwFeature feature)
        {
            var p      = this.FeatureCoordinates["Canal"];
            var region = this.Traversable_regionlist[this.Traversable_regionmap[p.Y, p.X]];

            foreach (var adj in region.Adjacent)
            {
                if (this.Traversable_regionlist[adj].RegionType == OverworldTiles.LAND_REGION)
                {
                    var r = this.PlaceFeature(this.Traversable_regionmap, this.Traversable_regionlist[adj], feature);
                    if (r.Item1)
                    {
                        return(await this.NextStep());
                    }
                }
            }
            return(new Result(false));
        }
示例#9
0
        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));
        }
示例#10
0
        public async Task <Result> PlaceOnCoast(OwFeature feature, bool eastOnly)
        {
            var tasks = new List <GenerationTask>();

            foreach (var w in this.Traversable_regionlist)
            {
                if (w.RegionType == OverworldTiles.LAND)
                {
                    if (w.Adjacent.Contains(OverworldTiles.MainOceanRegionId) &&
                        (this.CheckReachableByRiver(w, false) || CheckIndirectAirshipAccess(w).Item1))
                    {
                        tasks.Add(() => new OverworldState(this).CoastalPlacement(feature, w, false, eastOnly));
                    }
                }
            }
            tasks.Shuffle(this.rng);
            await Task.Yield();

            return(new Result(tasks));
        }
示例#11
0
        public async Task <Result> PlaceWaterfall(OwFeature feature)
        {
            var tasks = new List <GenerationTask>();

            foreach (var w in this.Traversable_regionlist)
            {
                if (w.RegionType == OverworldTiles.RIVER_REGION)
                {
                    var v = this.CheckIndirectAirshipAccess(w);
                    if (v.Item1)
                    {
                        tasks.Add(() => new OverworldState(this).WaterfallPlacement(feature, w));
                    }
                }
            }
            tasks.Shuffle(this.rng);
            await Task.Yield();

            return(new Result(tasks));
        }
示例#12
0
        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());
        }
示例#13
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));
            }
        }
示例#14
0
        public async Task <Result> PlaceIsolated(OwFeature feature, bool requireAirshipAccess)
        {
            var tasks = new List <GenerationTask>();

            foreach (var w in this.Traversable_regionlist)
            {
                if (w.RegionType == OverworldTiles.LAND_REGION &&
                    !this.Reachable_regions.Contains(w.RegionId))
                {
                    if (feature.MountainCave)
                    {
                        var caveCandidate = false;
                        foreach (var adj in w.Adjacent)
                        {
                            if (this.Traversable_regionlist[adj].RegionType == OverworldTiles.MOUNTAIN_REGION)
                            {
                                caveCandidate = true;
                                break;
                            }
                        }
                        if (!caveCandidate)
                        {
                            continue;
                        }
                    }
                    var r = this.CheckIndirectAirshipAccess(w);
                    if (r.Item1 || !requireAirshipAccess)
                    {
                        if (!this.CheckReachableByRiver(w, false))
                        {
                            tasks.Add(() => new OverworldState(this).IsolatedPlacement(feature, w, requireAirshipAccess));
                        }
                    }
                }
            }
            tasks.Shuffle(this.rng);
            await Task.Yield();

            return(new Result(tasks));
        }
示例#15
0
        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));
            }
        }
示例#16
0
        public async Task <Result> PlaceRequiringCanoe(OwFeature feature)
        {
            var tasks = new List <GenerationTask>();

            foreach (var w in this.Traversable_regionlist)
            {
                if (w.RegionType == OverworldTiles.LAND_REGION)
                {
                    var r = CheckAirshipAccess(w);
                    if (!r.Item1)
                    {
                        if (this.CheckReachableByRiver(w, true))
                        {
                            tasks.Add(() => new OverworldState(this).RequiresCanoePlacement(feature, w));
                        }
                    }
                }
            }
            tasks.Shuffle(this.rng);
            await Task.Yield();

            return(new Result(tasks));
        }
示例#17
0
        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);
        }
示例#18
0
        public async Task <Result> PlaceInBiome(OwFeature feature, int[] biomes,
                                                bool shipReachable,
                                                bool canoeReachable,
                                                bool airshipReachable,
                                                bool preferIslands)
        {
            var        walkable = new List <OwRegion>();
            List <int> biomelist;

            if (biomes == null)
            {
                biomelist = new List <int> {
                    OverworldTiles.LAND_REGION,
                    OverworldTiles.GRASS_REGION,
                    OverworldTiles.MARSH_REGION,
                    OverworldTiles.FOREST_REGION,
                    OverworldTiles.DESERT_REGION
                };
            }
            else
            {
                biomelist = new List <int>(biomes);
            }

            var islands = new List <OwRegion>();

            foreach (var w in this.Biome_regionlist)
            {
                bool found = false;
                if (biomelist.Contains(w.RegionType) && w.Points.Count > 0)
                {
                    var trav = this.Traversable_regionlist[this.Traversable_regionmap[w.Points[0].Y, w.Points[0].X]];
                    if (shipReachable &&
                        !this.Exclude_docks.Contains(trav.RegionId) &&
                        (trav.Adjacent.Contains(OverworldTiles.MainOceanRegionId) || this.Reachable_regions.Contains(trav.RegionId)))
                    {
                        found = true;
                    }
                    else if (airshipReachable && canoeReachable && this.CheckIndirectAirshipAccess(trav).Item1)
                    {
                        found = true;
                    }
                    else if (airshipReachable && this.CheckAirshipAccess(trav).Item1)
                    {
                        found = true;
                    }
                    else if (canoeReachable && this.CheckReachableByRiver(trav, false))
                    {
                        found = true;
                    }
                    else if (airshipReachable == false && shipReachable == false && canoeReachable == false &&
                             this.Reachable_regions.Contains(trav.RegionId))
                    {
                        // bridge or titan's tunnel access
                        found = true;
                    }
                    if (found)
                    {
                        if (preferIslands && trav.Adjacent.Count == 1 && trav.Adjacent[0] == OverworldTiles.MainOceanRegionId)
                        {
                            islands.Add(w);
                        }
                        else
                        {
                            walkable.Add(w);
                        }
                    }
                }
            }

            var tasks = new List <GenerationTask>();

            walkable.Shuffle(this.rng);
            islands.Shuffle(this.rng);

            int maxweight;

            if (feature.MountainCave)
            {
                maxweight = 0;
            }
            else
            {
                maxweight = 8;
            }
            for (int i = 0; i <= maxweight; i++)
            {
                foreach (var w in islands)
                {
                    var r = await new OverworldState(this).BiomePlacement(feature, w, shipReachable, i);
                    if (r.Success)
                    {
                        return(r);
                    }
                }
                foreach (var w in walkable)
                {
                    var r = await new OverworldState(this).BiomePlacement(feature, w, shipReachable, i);
                    if (r.Success)
                    {
                        return(r);
                    }
                }
            }

            return(new Result(false));
        }