Exemplo n.º 1
0
        public static FileInfo GetPresetFor(MapParent mapParent, LocationDef locationDef)
        {
            if (locationDef != null)
            {
                string   path = "";
                FileInfo file = null;
                if (locationDef.filePreset != null && locationDef.filePreset.Length > 0)
                {
                    path = Path.GetFullPath(locationDef.modContentPack.RootDir + "/" + locationDef.filePreset);
                    file = new FileInfo(path);
                }
                else if (locationDef.folderWithPresets != null && locationDef.folderWithPresets.Length > 0)
                {
                    path = Path.GetFullPath(locationDef.modContentPack.RootDir + "/" + locationDef.folderWithPresets);
                    DirectoryInfo directoryInfo = new DirectoryInfo(path);
                    if (directoryInfo.Exists)
                    {
                        file = directoryInfo.GetFiles().RandomElement();
                    }
                }

                if (file != null)
                {
                    return(file);
                }
            }
            return(null);
        }
Exemplo n.º 2
0
 public static IntVec3 GetOffsetPosition(LocationDef locationDef, IntVec3 cell, IntVec3 offset)
 {
     if (locationDef != null)
     {
         if (locationDef.disableCenterCellOffset)
         {
             return(cell);
         }
         return(cell + offset + locationDef.additionalCenterCellOffset);
     }
     return(cell + offset);
 }
Exemplo n.º 3
0
 public static void InitialiseLocationGeneration(Map map, FileInfo file, LocationDef locationDef)
 {
     if (locationDef != null && file != null)
     {
         var comp = map.GetComponent <MapComponentGeneration>();
         if (comp.path.Length == 0)
         {
             comp.doGeneration = true;
             comp.path         = file.FullName;
             comp.locationDef  = locationDef;
         }
     }
 }
Exemplo n.º 4
0
 public static FileInfo GetPresetFor(MapParent mapParent, out LocationDef locationDef)
 {
     locationDef = GetLocationDefForMapParent(mapParent);
     return(GetPresetFor(mapParent, locationDef));
 }
Exemplo n.º 5
0
        public static HashSet <IntVec3> DoSettlementGeneration(Map map, string path, LocationDef locationDef, Faction faction, bool disableFog)
        {
            Log.Message("DoSettlementGeneration: GetOrGenerateMapPatch.locationData: " + GetOrGenerateMapPatch.locationData?.locationDef);
            Log.Message("DoSettlementGeneration: path: " + path);
            Log.Message("DoSettlementGeneration: locationDef: " + locationDef);
            GetOrGenerateMapPatch.locationData   = null;
            GetOrGenerateMapPatch.caravanArrival = false;
            var mapComp = map.GetComponent <MapComponentGeneration>();

            try
            {
                if (locationDef != null && locationDef.destroyEverythingOnTheMapBeforeGeneration)
                {
                    var thingsToDespawn = map.listerThings.AllThings;
                    if (thingsToDespawn != null && thingsToDespawn.Count > 0)
                    {
                        for (int i = thingsToDespawn.Count - 1; i >= 0; i--)
                        {
                            try
                            {
                                if (thingsToDespawn[i].Spawned)
                                {
                                    thingsToDespawn[i].DeSpawn(DestroyMode.WillReplace);
                                }
                            }
                            catch (Exception ex)
                            {
                                Log.Error("4 Cant despawn: " + thingsToDespawn[i] + " - "
                                          + thingsToDespawn[i].Position + "error: " + ex);
                            }
                        }
                    }
                }

                if (locationDef != null && locationDef.factionDefForNPCsAndTurrets != null)
                {
                    faction = Find.FactionManager.FirstFactionOfDef(locationDef.factionDefForNPCsAndTurrets);
                }
                else if (faction == Faction.OfPlayer || faction == null)
                {
                    faction = Faction.OfAncients;
                }

                List <Thing>      thingsToDestroy = new List <Thing>();
                HashSet <IntVec3> tilesToProcess  = new HashSet <IntVec3>();

                int radiusToClear = 0;
                //
                //foreach (var building in map.listerThings.AllThings
                //    .Where(x => x is Building && x.Faction == faction && !(x is Mineable)))
                //{
                //    foreach (var pos in GenRadial.RadialCellsAround(building.Position, radiusToClear, true))
                //    {
                //        if (GenGrid.InBounds(pos, map))
                //        {
                //            tilesToProcess.Add(pos);
                //        }
                //    }
                //    thingsToDestroy.Add(building);
                //}
                List <Corpse>   corpses     = new List <Corpse>();
                List <Pawn>     pawnCorpses = new List <Pawn>();
                List <Pawn>     pawns       = new List <Pawn>();
                List <Building> buildings   = new List <Building>();
                List <Thing>    things      = new List <Thing>();
                List <Filth>    filths      = new List <Filth>();
                List <Plant>    plants      = new List <Plant>();
                Dictionary <IntVec3, TerrainDef> terrains = new Dictionary <IntVec3, TerrainDef>();
                Dictionary <IntVec3, RoofDef>    roofs    = new Dictionary <IntVec3, RoofDef>();
                HashSet <IntVec3> tilesToSpawnPawnsOnThem = new HashSet <IntVec3>();

                Scribe.loader.InitLoading(path);
                Scribe_Collections.Look <Pawn>(ref pawnCorpses, "PawnCorpses", LookMode.Deep, new object[0]);
                Scribe_Collections.Look <Corpse>(ref corpses, "Corpses", LookMode.Deep, new object[0]);
                Scribe_Collections.Look <Pawn>(ref pawns, "Pawns", LookMode.Deep, new object[0]);
                Scribe_Collections.Look <Building>(ref buildings, "Buildings", LookMode.Deep, new object[0]);
                Scribe_Collections.Look <Filth>(ref filths, "Filths", LookMode.Deep, new object[0]);
                Scribe_Collections.Look <Thing>(ref things, "Things", LookMode.Deep, new object[0]);
                Scribe_Collections.Look <Plant>(ref plants, "Plants", LookMode.Deep, new object[0]);

                Scribe_Collections.Look <IntVec3, TerrainDef>(ref terrains, "Terrains", LookMode.Value, LookMode.Def, ref terrainKeys, ref terrainValues);
                Scribe_Collections.Look <IntVec3, RoofDef>(ref roofs, "Roofs", LookMode.Value, LookMode.Def, ref roofsKeys, ref roofsValues);
                Scribe_Collections.Look <IntVec3>(ref tilesToSpawnPawnsOnThem, "tilesToSpawnPawnsOnThem", LookMode.Value);
                Scribe.loader.FinalizeLoading();
                if (corpses is null)
                {
                    corpses = new List <Corpse>();
                }
                else
                {
                    corpses.RemoveAll(x => x is null);
                }
                if (pawnCorpses is null)
                {
                    pawnCorpses = new List <Pawn>();
                }
                else
                {
                    pawnCorpses.RemoveAll(x => x is null);
                }
                if (pawns is null)
                {
                    pawns = new List <Pawn>();
                }
                else
                {
                    pawns.RemoveAll(x => x is null);
                }
                if (buildings is null)
                {
                    buildings = new List <Building>();
                }
                else
                {
                    buildings.RemoveAll(x => x is null);
                }
                if (things is null)
                {
                    things = new List <Thing>();
                }
                else
                {
                    things.RemoveAll(x => x is null);
                }
                if (filths is null)
                {
                    filths = new List <Filth>();
                }
                else
                {
                    filths.RemoveAll(x => x is null);
                }
                if (plants is null)
                {
                    plants = new List <Plant>();
                }
                else
                {
                    plants.RemoveAll(x => x is null);
                }

                var cells = new List <IntVec3>(tilesToSpawnPawnsOnThem);
                cells.AddRange(buildings.Select(x => x.Position).ToList());
                var centerCell = GetCellCenterFor(cells);
                var offset     = map.Center - centerCell;

                if (corpses != null && corpses.Count > 0)
                {
                    foreach (var corpse in corpses)
                    {
                        try
                        {
                            var position = GetOffsetPosition(locationDef, corpse.Position, offset);
                            if (GenGrid.InBounds(position, map))
                            {
                                GenSpawn.Spawn(corpse, position, map, WipeMode.Vanish);
                            }
                        }
                        catch (Exception ex)
                        {
                            Log.Error("1 Error in map generating, cant spawn " + corpse + " - " + ex);
                        }
                    }
                }

                if (pawns != null && pawns.Count > 0)
                {
                    foreach (var pawn in pawns)
                    {
                        try
                        {
                            var position = GetOffsetPosition(locationDef, pawn.Position, offset);
                            if (GenGrid.InBounds(position, map))
                            {
                                pawn.pather = new Pawn_PathFollower(pawn);
                                GenSpawn.Spawn(pawn, position, map, WipeMode.Vanish);
                                if (pawn.Faction != faction)
                                {
                                    pawn.SetFaction(faction);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            Log.Error("2 Error in map generating, cant spawn " + pawn + " - " + ex);
                        }
                    }
                }

                if (tilesToSpawnPawnsOnThem != null && tilesToSpawnPawnsOnThem.Count > 0)
                {
                    foreach (var tile in tilesToSpawnPawnsOnThem)
                    {
                        var position = GetOffsetPosition(locationDef, tile, offset);
                        try
                        {
                            if (GenGrid.InBounds(position, map))
                            {
                                var things2 = map.thingGrid.ThingsListAt(position);
                                foreach (var thing in things2)
                                {
                                    if (thing is Building || (thing is Plant plant && plant.def != ThingDefOf.Plant_Grass) || IsChunk(thing))
                                    {
                                        thingsToDestroy.Add(thing);
                                    }
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            Log.Error("3 Error in map generating, cant spawn " + position + " - " + ex);
                        }
                    }
                }

                if (buildings != null && buildings.Count > 0)
                {
                    foreach (var building in buildings)
                    {
                        var position = GetOffsetPosition(locationDef, building.Position, offset);

                        foreach (var pos in GenRadial.RadialCellsAround(position, radiusToClear, true))
                        {
                            if (GenGrid.InBounds(pos, map))
                            {
                                tilesToProcess.Add(pos);
                            }
                        }
                    }
                    if (tilesToProcess != null && tilesToProcess.Count > 0)
                    {
                        foreach (var pos in tilesToProcess)
                        {
                            if (pos.InBounds(map))
                            {
                                var things2 = map.thingGrid.ThingsListAt(pos);
                                foreach (var thing in things2)
                                {
                                    if (thing is Building || (thing is Plant plant && plant.def != ThingDefOf.Plant_Grass) || IsChunk(thing))
                                    {
                                        thingsToDestroy.Add(thing);
                                    }
                                }
                                var terrain = pos.GetTerrain(map);

                                if (terrain != null)
                                {
                                    if (terrain.IsWater)
                                    {
                                        map.terrainGrid.SetTerrain(pos, TerrainDefOf.Soil);
                                    }
                                    if (map.terrainGrid.CanRemoveTopLayerAt(pos))
                                    {
                                        map.terrainGrid.RemoveTopLayer(pos, false);
                                    }
                                }
                                var roof = pos.GetRoof(map);
                                if (roof != null && (!map.roofGrid.RoofAt(pos).isNatural || map.roofGrid.RoofAt(pos) == RoofDefOf.RoofRockThin))
                                {
                                    map.roofGrid.SetRoof(pos, null);
                                }
                            }
                        }
                    }

                    if (thingsToDestroy != null && thingsToDestroy.Count > 0)
                    {
                        for (int i = thingsToDestroy.Count - 1; i >= 0; i--)
                        {
                            try
                            {
                                if (thingsToDestroy[i].Spawned)
                                {
                                    thingsToDestroy[i].DeSpawn(DestroyMode.WillReplace);
                                }
                            }
                            catch (Exception ex)
                            {
                                Log.Error("4 Cant despawn: " + thingsToDestroy[i] + " - "
                                          + thingsToDestroy[i].Position + "error: " + ex);
                            }
                        }
                    }

                    foreach (var building in buildings)
                    {
                        var position = GetOffsetPosition(locationDef, building.Position, offset);
                        try
                        {
                            if (GenGrid.InBounds(position, map))
                            {
                                GenSpawn.Spawn(building, position, map, building.Rotation, WipeMode.Vanish);
                                if (building.def.CanHaveFaction && building.Faction != faction)
                                {
                                    building.SetFaction(faction);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            Log.Error("5 Error in map generating, cant spawn " + building + " - " + position + " - " + ex);
                        }
                    }
                }
                if (filths != null && filths.Count > 0)
                {
                    foreach (var filth in filths)
                    {
                        try
                        {
                            var position = GetOffsetPosition(locationDef, filth.Position, offset);
                            if (position.InBounds(map))
                            {
                                GenSpawn.Spawn(filth, position, map, WipeMode.Vanish);
                            }
                        }
                        catch (Exception ex)
                        {
                            Log.Error("6.5 Error in map generating, cant spawn " + filth + " - " + ex);
                        }
                    }
                }

                if (plants != null && plants.Count > 0)
                {
                    foreach (var plant in plants)
                    {
                        try
                        {
                            var position = GetOffsetPosition(locationDef, plant.Position, offset);
                            if (position.InBounds(map) && map.fertilityGrid.FertilityAt(position) >= plant.def.plant.fertilityMin)
                            {
                                GenSpawn.Spawn(plant, position, map, WipeMode.Vanish);
                            }
                        }
                        catch (Exception ex)
                        {
                            Log.Error("6 Error in map generating, cant spawn " + plant + " - " + ex);
                        }
                    }
                }

                var containers = map.listerThings.AllThings.Where(x => x is Building_Storage).ToList();
                if (things != null && things.Count > 0)
                {
                    foreach (var thing in things)
                    {
                        try
                        {
                            var position = GetOffsetPosition(locationDef, thing.Position, offset);
                            if (position.InBounds(map))
                            {
                                GenSpawn.Spawn(thing, position, map, WipeMode.Vanish);
                                if (locationDef != null && locationDef.moveThingsToShelves)
                                {
                                    TryDistributeTo(thing, map, containers, faction != Faction.OfPlayer);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            Log.Error("7 Error in map generating, cant spawn " + thing + " - " + ex);
                        }
                    }
                }
                if (locationDef != null && locationDef.moveThingsToShelves)
                {
                    foreach (var item in map.listerThings.AllThings)
                    {
                        if (item.IsForbidden(Faction.OfPlayer))
                        {
                            TryDistributeTo(item, map, containers, faction != Faction.OfPlayer);
                        }
                    }
                }

                if (terrains != null && terrains.Count > 0)
                {
                    foreach (var terrain in terrains)
                    {
                        try
                        {
                            var position = GetOffsetPosition(locationDef, terrain.Key, offset);
                            if (GenGrid.InBounds(position, map))
                            {
                                map.terrainGrid.SetTerrain(position, terrain.Value);
                            }
                        }
                        catch (Exception ex)
                        {
                            Log.Error("8 Error in map generating, cant spawn " + terrain.Key + " - " + ex);
                        }
                    }
                }
                if (roofs != null && roofs.Count > 0)
                {
                    foreach (var roof in roofs)
                    {
                        try
                        {
                            var position = GetOffsetPosition(locationDef, roof.Key, offset);
                            if (GenGrid.InBounds(position, map))
                            {
                                map.roofGrid.SetRoof(position, roof.Value);
                            }
                        }
                        catch (Exception ex)
                        {
                            Log.Error("9 Error in map generating, cant spawn " + roof.Key + " - " + ex);
                        }
                    }
                }
                if (locationDef != null && (locationDef.percentOfDamagedWalls.HasValue || locationDef.percentOfDestroyedWalls.HasValue) || locationDef.percentOfDamagedFurnitures.HasValue)
                {
                    var walls = map.listerThings.AllThings.Where(x => x.def.IsEdifice() && x.def.defName.ToLower().Contains("wall")).ToList();
                    if (locationDef.percentOfDestroyedWalls.HasValue)
                    {
                        var percent        = locationDef.percentOfDestroyedWalls.Value.RandomInRange * 100f;
                        var countToTake    = (int)((percent * walls.Count()) / 100f);
                        var wallsToDestroy = walls.InRandomOrder().Take(countToTake).ToList();
                        for (int num = wallsToDestroy.Count - 1; num >= 0; num--)
                        {
                            walls.Remove(wallsToDestroy[num]);
                            wallsToDestroy[num].DeSpawn();
                        }
                    }
                    if (locationDef.percentOfDamagedWalls.HasValue)
                    {
                        var percent       = locationDef.percentOfDamagedWalls.Value.RandomInRange * 100f;
                        var countToTake   = (int)((percent * walls.Count()) / 100f);
                        var wallsToDamage = walls.InRandomOrder().Take(countToTake).ToList();
                        for (int num = wallsToDamage.Count - 1; num >= 0; num--)
                        {
                            var damagePercent   = Rand.Range(0.3f, 0.6f);
                            var hitpointsToTake = (int)(wallsToDamage[num].MaxHitPoints * damagePercent);
                            wallsToDamage[num].HitPoints = hitpointsToTake;
                        }
                    }
                    if (locationDef.percentOfDamagedFurnitures.HasValue)
                    {
                        var furnitures         = map.listerThings.AllThings.Where(x => !walls.Contains(x) && x.def.IsBuildingArtificial).ToList();
                        var percent            = locationDef.percentOfDamagedFurnitures.Value.RandomInRange * 100f;
                        var countToTake        = (int)((percent * furnitures.Count()) / 100f);
                        var furnituresToDamage = furnitures.InRandomOrder().Take(countToTake).ToList();
                        for (int num = furnituresToDamage.Count - 1; num >= 0; num--)
                        {
                            var damagePercent   = Rand.Range(0.3f, 0.6f);
                            var hitpointsToTake = (int)(furnituresToDamage[num].MaxHitPoints * damagePercent);
                            furnituresToDamage[num].HitPoints = hitpointsToTake;
                        }
                    }
                }

                if (faction.def.HasModExtension <SettlementOptionModExtension>())
                {
                    var options = faction.def.GetModExtension <SettlementOptionModExtension>();
                    if (options.removeVanillaGeneratedPawns)
                    {
                        for (int i = map.mapPawns.PawnsInFaction(faction).Count - 1; i >= 0; i--)
                        {
                            map.mapPawns.PawnsInFaction(faction)[i].DeSpawn(DestroyMode.Vanish);
                        }
                    }
                    if (options.pawnsToGenerate != null && options.pawnsToGenerate.Count > 0 && tilesToSpawnPawnsOnThem != null && tilesToSpawnPawnsOnThem.Count > 0)
                    {
                        foreach (var pawn in options.pawnsToGenerate)
                        {
                            foreach (var i in Enumerable.Range(1, (int)pawn.selectionWeight))
                            {
                                var settler = PawnGenerator.GeneratePawn(new PawnGenerationRequest(pawn.kind, faction));
                                try
                                {
                                    var pos = tilesToSpawnPawnsOnThem.Where(x => map.thingGrid.ThingsListAt(x)
                                                                            .Where(y => y is Building).Count() == 0).RandomElement();
                                    GenSpawn.Spawn(settler, pos, map);
                                }
                                catch (Exception ex)
                                {
                                    Log.Error("10 Error in map generating, cant spawn " + settler + " - " + ex);
                                }
                            }
                        }
                    }
                }

                foreach (var pawn in map.mapPawns.PawnsInFaction(faction))
                {
                    var lord = pawn.GetLord();
                    if (lord != null)
                    {
                        map.lordManager.RemoveLord(lord);
                    }
                    var lordJob = new LordJob_DefendBase();
                    if (tilesToSpawnPawnsOnThem != null && tilesToSpawnPawnsOnThem.Count > 0)
                    {
                        lordJob = new LordJob_DefendBase(faction, tilesToSpawnPawnsOnThem.RandomElement());
                    }
                    else
                    {
                        lordJob = new LordJob_DefendBase(faction, pawn.Position);
                    }
                    LordMaker.MakeNewLord(faction, lordJob, map, null).AddPawn(pawn);
                }

                if (disableFog != true)
                {
                    try
                    {
                        FloodFillerFog.DebugRefogMap(map);
                    }
                    catch
                    {
                        foreach (var cell in map.AllCells)
                        {
                            if (!tilesToProcess.Contains(cell) && !(cell.GetFirstBuilding(map) is Mineable))
                            {
                                var item = cell.GetFirstItem(map);
                                if (item != null)
                                {
                                    var room = item.GetRoom();
                                    if (room != null)
                                    {
                                        if (room.PsychologicallyOutdoors)
                                        {
                                            FloodFillerFog.FloodUnfog(cell, map);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    mapComp.reFog = true;
                }
                mapComp.doGeneration = false;
                mapComp.path         = null;
                GetOrGenerateMapPatch.caravanArrival = false;
                return(tilesToSpawnPawnsOnThem.Select(x => GetOffsetPosition(locationDef, x, offset)).ToHashSet());
            }
            catch (Exception ex)
            {
                Log.Error("Error in DoSettlementGeneration: " + ex);
            }
            mapComp.doGeneration = false;
            mapComp.path         = null;
            return(null);
        }