static void Main() { var mapgen = new Landmass(); mapgen.GenerateLandmass(); Console.ReadKey; }
//gets an array of points representing the center points //of islands or continents on the map. These points are //used to generate the continents and islands. private List <Point> GetLandSeeds(Grid grid, Landmass worldLandmass) { int numSeeds = 0; switch (worldLandmass) { case Landmass.Archipelago: numSeeds = 12; break; case Landmass.Pangaea: numSeeds = 1; break; case Landmass.Continents: numSeeds = 6; break; } List <Point> seeds = new List <Point>(); Point center = new Point(grid.Size.Width / 2, grid.Size.Height / 2); int x; int y; for (int i = 0; i < numSeeds; i++) { x = RandomNumber.Between(0, grid.Size.Width); y = RandomNumber.Between(0, grid.Size.Height); seeds.Add(new Point(x, y)); } return(seeds); }
public static Landmass landmass; //Instance of landmass to be used to store the main landmass //Creates a new landmass and flood fills to work out all containing tiles public static void FloodFillLandmass(Tile startingTile) { ClearPreviousValues(); landmass = new Landmass(FindTilesInLandmass(startingTile)); //Changes all tiles that aren't in the central or closer surrounding landmasses to water foreach (Tile tile in Generator.tileGrid) { if (!landmass.GetTiles().Contains(tile)) { tile.ChangeTileType(Tile.Type.water); } } }
public void SetLandmassInfo(Landmass landmass) { if (landmass == null) { LandmassName.text = ""; LandmassSize.text = ""; LandmassArea.text = ""; } else { LandmassName.text = landmass.Name; LandmassSize.text = landmass.Size.ToString() + (landmass.Size == 1 ? " Region" : " Regions"); LandmassArea.text = landmass.Area.ToString("0.00") + " km²"; } }
public List <Landmass> FindLandmasses() { var result = new List <Landmass>(); var unprocessed = new List <MapCell>(); unprocessed.AddRange(this.Map.MapCells.Values.Where(x => x.IsLand)); uint landmassId = 0; while (unprocessed.Count > 0) { var root = unprocessed.RemoveRandom <MapCell>(); var scanned = new List <MapCell>() { root }; var adjacencies = new List <MapCell>(); adjacencies.AddRange(root.AdjacentMapCells.Where(x => x.IsLand)); while (adjacencies.Count > 0) { var landcell = adjacencies[adjacencies.Count - 1]; scanned.Add(landcell); adjacencies.Remove(landcell); unprocessed.Remove(landcell); adjacencies.AddRange(landcell.AdjacentMapCells.Where(x => x.IsLand && !scanned.Contains(x))); } scanned.AddRange(adjacencies); var landmass = new Landmass() { MapCells = scanned, MapCellIds = scanned.Select(x => x.Id).ToList(), Id = landmassId++ }; landmass.X = (int)landmass.MapCells.Average(cell => cell.X); landmass.Y = (int)landmass.MapCells.Average(cell => cell.Y); result.Add(landmass); } return(result); }
public LandmassPrinter(Landmass landmass, World world) { _landmass = landmass; _world = world; }
public void Build_WithSpecifiedDimensions_ReturnsLandmass(int width, int height) { _ = Landmass.Build(new Dimensions(width, height)); }
/// <summary> /// Now at the open tag of a single object in our XML, we want to dump the entire contents into an XDocument. /// If we have a World Construction it's a new item so it needs to be added, /// in other cases, it already exists and details need to be added to the existing items. /// Individual object reads are separated out to allow us to work past failing to load any specific XML item for any reason. /// </summary> private static void PlusLoadItem <T>(IDictionary <int, T> worldList, World world, XmlReader xReader) where T : XMLObject { XDocument xdoc = null; try { xdoc = XDocument.Load(xReader.ReadSubtree()); var id = Convert.ToInt32(xdoc.Root.Element("id").Value); if (!worldList.ContainsKey(id)) { if (typeof(T) == typeof(WorldConstruction)) { var newWc = new WorldConstruction(xdoc, world); world.WorldConstructions[newWc.Id] = newWc; return; } if (typeof(T) == typeof(Landmass)) { var newLandmass = new Landmass(xdoc, world); world.Landmasses.Add(newLandmass.Id, newLandmass); return; } if (typeof(T) == typeof(Mountain)) { var newMountain = new Mountain(xdoc, world); world.Mountains.Add(newMountain.Id, newMountain); return; } if (typeof(T) == typeof(River)) { var newRiver = new River(xdoc, world); world.Rivers.Add(newRiver.Id, newRiver); return; } if (typeof(T) == typeof(Army)) { var newArmy = new Army(xdoc, world); world.Armies.Add(newArmy.Id, newArmy); return; } if (typeof(T) == typeof(Unit)) { var newUnit = new Unit(xdoc, world); world.Units.Add(newUnit.Id, newUnit); return; } if (typeof(T) == typeof(Engraving)) { var newEngraving = new Engraving(xdoc, world); world.Engravings.Add(newEngraving.Id, newEngraving); return; } if (typeof(T) == typeof(Report)) { var newReport = new Report(xdoc, world); world.Reports.Add(newReport.Id, newReport); return; } if (typeof(T) == typeof(Building)) { var newBuilding = new Building(xdoc, world); world.Buildings.Add(newBuilding.Id, newBuilding); return; } if (typeof(T) == typeof(Construction)) { var newConstruction = new Construction(xdoc, world); world.Constructions.Add(newConstruction.Id, newConstruction); return; } if (typeof(T) == typeof(Item)) { var newItem = new Item(xdoc, world); world.Items.Add(newItem.Id, newItem); return; } if (typeof(T) == typeof(Plant)) { var newPlant = new Plant(xdoc, world); world.Plants.Add(newPlant.Id, newPlant); return; } if (typeof(T) == typeof(Squad)) { var newSquad = new Squad(xdoc, world); world.Squads.Add(newSquad.Id, newSquad); return; } if (typeof(T) == typeof(WrittenContent)) { var newWrittenContent = new WrittenContent(xdoc, world); world.WrittenContents.Add(newWrittenContent.Id, newWrittenContent); return; } if (typeof(T) == typeof(PoeticForm)) { var newPoeticForm = new PoeticForm(xdoc, world); world.PoeticForms.Add(newPoeticForm.Id, newPoeticForm); Console.WriteLine(newPoeticForm.Id); return; } if (typeof(T) == typeof(MusicalForm)) { var newMusicalForm = new MusicalForm(xdoc, world); world.MusicalForms.Add(newMusicalForm.Id, newMusicalForm); return; } if (typeof(T) == typeof(DanceForm)) { var newDanceForm = new DanceForm(xdoc, world); world.DanceForms.Add(newDanceForm.Id, newDanceForm); return; } } if (typeof(T) == typeof(Race)) { var key = xdoc.Root.Element("key").Value.ToLower(); var associatedRace = world.FindRace(key) ?? world.FindRace(xdoc.Root.Element("nameS").Value.ToLower()) ?? world.FindRace(xdoc.Root.Element("nameP").Value.ToLower()); if (associatedRace == null || associatedRace.Id > 0) { var newRace = new Race(xdoc, world) { AddedOrder = world.Races.Keys.Min() - 1 }; if (!world.Races.TryAdd(id, newRace)) { Program.Log(LogType.Error, "Failed to add race - " + newRace.ToString() + " while adding Plus XML"); } return; } id = associatedRace.AddedOrder; } if (worldList.ContainsKey(id)) { worldList[id].Plus(xdoc); } } catch (OutOfMemoryException e) { Program.Log(LogType.Error, "Error reading XML item: id\n" + e.Message); var fi = new FileInfo(_path); Program.Log(LogType.Error, "XML file is" + Math.Round(fi.Length / 1024f / 1024f / 1024f, 2) + " GB"); Program.Log(LogType.Error, $"Running {(Environment.Is64BitProcess ? "64" : "32")} Bit World Viewer"); Program.Log(LogType.Error, $"Running {(Environment.Is64BitOperatingSystem ? "64" : "32")} Bit Operating System"); if (!Environment.Is64BitOperatingSystem) //Running 32 bit OS { Program.Log(LogType.Error, "32 Bit World Viewer does not support Huge XML files"); } else if (!Environment.Is64BitProcess) //Running 32 bit app in 64 bit OS { Program.Log(LogType.Error, "Recommend using 64 Bit World Viewer"); } else { Program.Log(LogType.Error, "Please report Log"); } MemoryFailureQuitParsing = true; } catch (Exception e) { try { if (xdoc != null) { var id = int.Parse(((XElement)xdoc.Root.Nodes().ToArray()[1]).Value); if (id < 0) { switch (xdoc.Root.Name.LocalName) { case "historical_event": if (!_workflowDetected) { Program.Log(LogType.Error, "Negative ID historical event. Likely due to dfHack Workflow, ignoring\n" + xdoc); _workflowDetected = true; } break; case "historical_figure": if (!_autochopDetected) { Program.Log(LogType.Error, "Negative ID historical figure detected. Likely due to autochop, ignoring\n" + xdoc); _autochopDetected = true; } break; default: Program.Log(LogType.Error, "Negative ID " + xdoc.Root.Name.LocalName + " detected. Unknown cause, ignoring\n" + xdoc); break; } } else { Program.Log(LogType.Error, "Error reading XML item: id\n" + e.Message); } } } catch (Exception) { Program.Log(LogType.Error, "Error reading XML item: id\n" + e.Message); throw; } } }
/// <summary> /// Starts a new server session. /// </summary> /// <param name="worldSize"></param> /// <param name="age"></param> /// <param name="climate"></param> /// <param name="landmass"></param> /// <param name="temperature"></param> /// <param name="waterCoverage"></param> /// <param name="barbarianAggressiveness"></param> /// <param name="difficulty"></param> /// <param name="rules"></param> public void StartServer(WorldSize worldSize, Age age, Temperature temperature, Climate climate, Landmass landmass, WaterCoverage waterCoverage, BarbarianAggressiveness barbarianAggressiveness, Difficulty difficulty, Rules rules) { OnServerStarting(); this.rules = rules; OnStatusChanged(new StatusChangedEventArgs(ServerResources.CreatingMap, 5)); GridBuilder builder = new GridBuilder(); this.grid = builder.Build(worldSize, age, temperature, climate, landmass, waterCoverage, this.ruleset); OnStatusChanged(new StatusChangedEventArgs(ServerResources.AddingVillages, 10)); AddVillages(worldSize); this.year = -4000; OnServerStarted(); }
/// <summary> /// Generates a map with the specified parameters. /// </summary> /// <param name="worldSize"></param> /// <param name="worldAge"></param> /// <param name="worldTemperature"></param> /// <param name="worldClimate"></param> /// <param name="worldLandmass"></param> /// <param name="worldWaterCoverage"></param> /// <param name="ruleset"></param> /// <returns></returns> public Grid Build(WorldSize worldSize, Age worldAge, Temperature worldTemperature, Climate worldClimate, Landmass worldLandmass, WaterCoverage worldWaterCoverage, Ruleset ruleset) { Size size = GetDimensions(worldSize); this.grid = BuildGrid(size); this.ruleset = ruleset; List <Point> seeds = GetLandSeeds(grid, worldLandmass); GrowLandSeeds(seeds, worldWaterCoverage); GenerateHeightMap(worldAge); GenerateTemperatureMap(worldTemperature); GenerateClimateMap(worldClimate); AddTerrain(); AddRivers(); AddLakes(); AddResources(); return(grid); }
void CreateMap(HexGrid hexGrid, SetupData setupData, WorldController worldController) { //LAND OR OCEAN foreach (HexCell cell in hexGrid.Cells) { List <HexCell> neighborLandTiles = new List <HexCell>(); neighborLandTiles.PopulateListWithMatchingConditions(cell.Neighbors, (c) => c.IsLand == true); if (neighborLandTiles.Count == 0) { bool isNewLand = setupData.newLandmassChance > HexMetrics.SampleHashGrid(cell.Position).a; cell.IsLand = isNewLand; if (isNewLand) { Landmass newLandmass = new Landmass(); worldController.Landmasses.Add(newLandmass); cell.Landmass = newLandmass; } } else { bool isLand = setupData.landByLandChance * neighborLandTiles.Count > HexMetrics.SampleHashGrid(cell.Position).a; //Add all nearby landmasses to list List <Landmass> neighboringLandmasses = new List <Landmass>(); foreach (var landCell in neighborLandTiles) { if (neighboringLandmasses.Contains(landCell.Landmass)) { continue; } neighboringLandmasses.Add(landCell.Landmass); } //Get size of all nearby landmasses int totalSize = 0; foreach (var landmass in neighboringLandmasses) { totalSize += landmass.landCells.Count; } //If exceeding maximum landmasssize after conversion to land (and combining any landmasses previously not connected, then abort if (totalSize + 1 > setupData.landMassMaxSize) { isLand = false; } cell.IsLand = isLand; if (isLand) { cell.Landmass = neighborLandTiles[0].Landmass; } } } //SET HEXES SURROUNDED BY LAND AS LAND foreach (HexCell cell in hexGrid.Cells) { List <HexCell> neighborLandTiles = new List <HexCell>(); neighborLandTiles.PopulateListWithMatchingConditions(cell.Neighbors, (c) => c.IsLand == true); if (neighborLandTiles.Count == 6) { cell.IsLand = true; cell.Landmass = neighborLandTiles[0].Landmass; } } //Clear empty landmasses for (int i = 0; i < worldController.Landmasses.Count; i++) { if (worldController.Landmasses[i].landCells.Count < 1) { worldController.Landmasses.RemoveAt(i); i--; } } //BITMASK AND VISUALS foreach (HexCell cell in hexGrid.Cells) { cell.CalculateBitmask(); SetTerrainCellVisual(cell); } //HARBORS AND POINTS OF INTERESTS int strongholds = 0; for (int i = 0; i < worldController.Landmasses.Count; i++) { Landmass landmass = worldController.Landmasses[i]; HexCell poiCell = Utility.ReturnRandom(landmass.GetShores(), setupData.Seed); landmass.poiLocationCell = poiCell; PointOfInterest.Type typeToSpawn = PointOfInterest.Type.Harbor; if (HexMetrics.SampleHashGrid(poiCell.Position).c < setupData.strongholdSpawnChance && strongholds < setupData.strongholdsToSpawn) { typeToSpawn = PointOfInterest.Type.Stronghold; strongholds++; } landmass.TypeOfPOI = typeToSpawn; } int remainingStrongholdsToSpawn = setupData.strongholdsToSpawn - strongholds; while (remainingStrongholdsToSpawn > 0) { Landmass newPoiLandmass = Utility.ReturnRandomElementWithCondition(worldController.Landmasses, (landmass) => landmass.TypeOfPOI != PointOfInterest.Type.Stronghold); newPoiLandmass.TypeOfPOI = PointOfInterest.Type.Stronghold; remainingStrongholdsToSpawn--; } //Setup point of interests foreach (Landmass landmass in worldController.Landmasses) { switch (landmass.TypeOfPOI) { case PointOfInterest.Type.Harbor: worldController.Harbors.Add(AddHarbor(landmass.poiLocationCell, setupData)); break; case PointOfInterest.Type.Stronghold: worldController.Strongholds.Add(AddStronghold(landmass.poiLocationCell, setupData)); break; } } }
public void Generate_WithSpecifiedDimensions_ReturnsLandmass(int width, int height) { var boundary = Boundary.FromDimensions(new Dimensions(width, height), 0, 0); _ = Landmass.Generate(boundary); }