| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- using System.Collections.Generic;
- using UnityEngine;
- public class SettlementGenerator
- {
- private readonly List<string> usedNames = new List<string>();
- private static readonly string[] townNames = {
- "Ashford", "Brookhaven", "Clearwater", "Drakemoor", "Emberfall",
- "Frostholm", "Goldmeadow", "Ironbridge", "Moonhaven", "Oakenford",
- "Ravenshollow", "Silverdale", "Thornwick", "Wolfsburg", "Brightwater"
- };
- private static readonly string[] villageNames = {
- "Millbrook", "Stonefield", "Greenhill", "Redrock", "Fairhaven",
- "Smallwood", "Riverside", "Hillcrest", "Meadowbrook", "Pinewood",
- "Sunset", "Morning", "Pleasant", "Quiet", "Little"
- };
- public void GenerateSettlements(MapData mapData)
- {
- // Clear used names for new generation
- usedNames.Clear();
- GenerateTowns(mapData);
- GenerateVillages(mapData);
- }
- private void GenerateTowns(MapData mapData)
- {
- int townCount = Random.Range(2, 5);
- int attempts = 0;
- int maxAttempts = 100;
- while (mapData.GetTowns().Count < townCount && attempts < maxAttempts)
- {
- attempts++;
- int x = Random.Range(15, mapData.Width - 15);
- int y = Random.Range(15, mapData.Height - 15);
- if (CanPlaceSettlement(mapData, x, y, 3, 20))
- {
- CreateTown(mapData, x, y);
- }
- }
- }
- private void GenerateVillages(MapData mapData)
- {
- int villageCount = Random.Range(8, 15);
- int attempts = 0;
- int maxAttempts = 100;
- while (mapData.GetVillages().Count < villageCount && attempts < maxAttempts)
- {
- attempts++;
- int x = Random.Range(5, mapData.Width - 5);
- int y = Random.Range(5, mapData.Height - 5);
- if (CanPlaceSettlement(mapData, x, y, 1, 10))
- {
- CreateVillage(mapData, x, y);
- }
- }
- }
- private bool CanPlaceSettlement(MapData mapData, int x, int y, int size, int minDistance)
- {
- // Check if area is suitable (plains terrain)
- for (int dx = -size / 2; dx <= size / 2; dx++)
- {
- for (int dy = -size / 2; dy <= size / 2; dy++)
- {
- int checkX = x + dx;
- int checkY = y + dy;
- if (!mapData.IsValidPosition(checkX, checkY))
- return false;
- MapTile tile = mapData.GetTile(checkX, checkY);
- if (tile.terrainType != TerrainType.Plains &&
- tile.terrainType != TerrainType.Shore)
- return false;
- }
- }
- // Check distance from other settlements
- foreach (var settlement in mapData.GetTowns())
- {
- float distance = Vector2.Distance(new Vector2(x, y),
- new Vector2(settlement.position.x, settlement.position.y));
- if (distance < minDistance)
- return false;
- }
- foreach (var settlement in mapData.GetVillages())
- {
- float distance = Vector2.Distance(new Vector2(x, y),
- new Vector2(settlement.position.x, settlement.position.y));
- if (distance < minDistance)
- return false;
- }
- return true;
- }
- private void CreateTown(MapData mapData, int centerX, int centerY)
- {
- string name = GetUniqueRandomName(townNames);
- var settlement = new Settlement(name, SettlementType.Town, new Vector2Int(centerX, centerY));
- // Create 3x3 town area
- for (int dx = -1; dx <= 1; dx++)
- {
- for (int dy = -1; dy <= 1; dy++)
- {
- int x = centerX + dx;
- int y = centerY + dy;
- if (mapData.IsValidPosition(x, y))
- {
- mapData.GetTile(x, y).featureType = FeatureType.Town;
- mapData.GetTile(x, y).name = name;
- settlement.tiles.Add(new Vector2Int(x, y));
- }
- }
- }
- mapData.AddSettlement(settlement);
- }
- private void CreateVillage(MapData mapData, int x, int y)
- {
- string name = GetUniqueRandomName(villageNames);
- var settlement = new Settlement(name, SettlementType.Village, new Vector2Int(x, y));
- mapData.GetTile(x, y).featureType = FeatureType.Village;
- mapData.GetTile(x, y).name = name;
- settlement.tiles.Add(new Vector2Int(x, y));
- mapData.AddSettlement(settlement);
- }
- private string GetUniqueRandomName(string[] nameArray)
- {
- // Find available names not already used
- List<string> availableNames = new List<string>();
- foreach (string name in nameArray)
- {
- if (!usedNames.Contains(name))
- {
- availableNames.Add(name);
- }
- }
- // If all names are used, fallback to numbered names
- if (availableNames.Count == 0)
- {
- string baseName = nameArray[Random.Range(0, nameArray.Length)];
- int counter = 2;
- string numberedName;
- do
- {
- numberedName = $"{baseName} {counter}";
- counter++;
- } while (usedNames.Contains(numberedName));
- usedNames.Add(numberedName);
- return numberedName;
- }
- // Select random name from available names
- string selectedName = availableNames[Random.Range(0, availableNames.Count)];
- usedNames.Add(selectedName);
- return selectedName;
- }
- }
|