public Galaxy( SectorGenerationSettings settings, SectorBackgroundSettings background, NameGeneratorSettings nameGeneratorSettings, CultCache cache, Action <string> log, Action <string> progressCallback = null, uint seed = 0) { Background = background; Log = log; var factions = cache.GetAll <Faction>(); var random = new Random(seed == 0 ? (uint)(DateTime.Now.Ticks % uint.MaxValue) : seed); Factions = factions.OrderBy(x => random.NextFloat()).Take(settings.MegaCount).ToArray(); foreach (var f in Factions) { FactionRelationships[f] = FactionRelationship.Neutral; } Zones = GenerateZones(settings.ZoneCount, ref random, progressCallback); GenerateLinks(settings.LinkDensity, progressCallback); CalculateDistanceMatrix(progressCallback); // Exit is the most isolated zone (highest total distance to all other zones) Exit = Zones.MaxBy(z => z.Isolation); // Entrance is the zone furthest from the exit Entrance = Zones.MaxBy(z => Exit.Distance[z]); DiscoveredZones.Add(Entrance); foreach (var z in Entrance.AdjacentZones) { DiscoveredZones.Add(z); } PlaceFactionsMain(settings.BossCount, progressCallback); CalculateFactionInfluence(progressCallback); GenerateNames(cache, nameGeneratorSettings, ref random, progressCallback); progressCallback?.Invoke("Done!"); if (progressCallback != null) { Thread.Sleep(500); // Inserting Delay to make it seem like it's doing more work lmao } }
public Galaxy( TutorialGenerationSettings settings, SectorBackgroundSettings background, NameGeneratorSettings nameGeneratorSettings, CultCache cache, PlayerSettings playerSettings, DirectoryInfo narrativeDirectory, Action <string> log, Action <string> progressCallback = null, uint seed = 0) { Faction ResolveFaction(string name) => cache.GetAll <Faction>().FirstOrDefault(f => f.Name.StartsWith(name, StringComparison.InvariantCultureIgnoreCase)); Background = background; Log = log; var random = new Random(seed == 0 ? (uint)(DateTime.Now.Ticks % uint.MaxValue) : seed); var factions = new List <Faction>(); var protagonistFaction = ResolveFaction(settings.ProtagonistFaction); factions.Add(protagonistFaction); var antagonistFaction = ResolveFaction(settings.AntagonistFaction); factions.Add(antagonistFaction); var bufferFaction = ResolveFaction(settings.BufferFaction); factions.Add(bufferFaction); var questFaction = ResolveFaction(settings.QuestFaction); factions.Add(questFaction); var neutralFactions = settings.NeutralFactions .Select(ResolveFaction) .ToArray(); factions.AddRange(neutralFactions); Factions = factions.ToArray(); foreach (var faction in Factions) { FactionRelationships[faction] = FactionRelationship.Neutral; faction.InfluenceDistance = (faction.InfluenceDistance + 1) / 2; } Zones = GenerateZones(settings.ZoneCount, ref random, progressCallback); GenerateLinks(settings.LinkDensity, progressCallback); CalculateDistanceMatrix(progressCallback); HomeZones[protagonistFaction] = Zones .MaxBy(z => ConnectedRegion(z, protagonistFaction.InfluenceDistance).Count); HomeZones[antagonistFaction] = Zones .MaxBy(z => ConnectedRegion(z, antagonistFaction.InfluenceDistance).Count *z.Distance[HomeZones[protagonistFaction]]); HomeZones[protagonistFaction] = Zones .MaxBy(z => ConnectedRegion(z, protagonistFaction.InfluenceDistance).Count *sqrt(z.Distance[HomeZones[antagonistFaction]])); // var antagonistRegion = ConnectedRegion(HomeZones[antagonistFaction], antagonistFaction.InfluenceDistance); // var protagonistRegion = ConnectedRegion(HomeZones[protagonistFaction], protagonistFaction.InfluenceDistance); // Place the buffer faction in a zone where it has equal distance to the pro/antagonist HQs and where it can control the most territory var bufferDistance = Zones.Min(z => abs(z.Distance[HomeZones[antagonistFaction]] - z.Distance[HomeZones[protagonistFaction]])); var potentialBufferZones = Zones .Where(z => abs(z.Distance[HomeZones[antagonistFaction]] - z.Distance[HomeZones[protagonistFaction]]) == bufferDistance); HomeZones[bufferFaction] = potentialBufferZones.MaxBy(z => ConnectedRegion(z, bufferFaction.InfluenceDistance).Count); // Place neutral headquarters away from existing factions while also maximizing territory foreach (var faction in neutralFactions) { HomeZones[faction] = Zones.MaxBy(z => ConnectedRegion(z, faction.InfluenceDistance).Count * HomeZones.Values.Aggregate(1f, (i, os) => i * sqrt(os.Distance[z]))); } CalculateFactionInfluence(progressCallback); var potentialQuestZones = Zones .Where(z => z.Factions.Contains(antagonistFaction) && z.Factions.Contains(bufferFaction)); if (potentialQuestZones.Any()) { HomeZones[questFaction] = potentialQuestZones .MaxBy(z => z.Distance[HomeZones[antagonistFaction]] * ConnectedRegion(z, questFaction.InfluenceDistance).Count); } else { HomeZones[questFaction] = Zones .Where(z => z.Factions.Contains(antagonistFaction)) .MinBy(z => z.Distance[HomeZones[bufferFaction]]); } CalculateFactionInfluence(progressCallback); Entrance = Zones.Where(z => z.Owner == null).MinBy(z => z.Distance[HomeZones[protagonistFaction]]); DiscoveredZones.Add(Entrance); foreach (var z in Entrance.AdjacentZones) { DiscoveredZones.Add(z); } CalculateFactionInfluence(progressCallback); GenerateNames(cache, nameGeneratorSettings, ref random, progressCallback); progressCallback?.Invoke("Weaving Narrative"); var processor = new StoryProcessor(playerSettings, narrativeDirectory, this, ref random, Log); processor.ProcessStories(); progressCallback?.Invoke("Done!"); if (progressCallback != null) { Thread.Sleep(500); // Inserting Delay to make it seem like it's doing more work lmao } }