private void GenerateNames(CultCache cache, NameGeneratorSettings nameGeneratorSettings, ref Random random, Action <string> progressCallback = null) { for (var i = 0; i < Factions.Length; i++) { progressCallback?.Invoke($"Feeding Markov Chains: {i + 1} / {Factions.Length}"); //if(progressCallback!=null) Thread.Sleep(250); // Inserting Delay to make it seem like it's doing more work lmao var faction = Factions[i]; _nameGenerators[faction] = new MarkovNameGenerator(ref random, cache.Get <NameFile>(faction.GeonameFile).Names, nameGeneratorSettings); } // Generate zone name using the owner's name generator, otherwise assign catalogue ID foreach (var zone in Zones) { if (zone.Owner != null) { zone.Name = _nameGenerators[zone.Owner].NextName.Trim(); } else { zone.Name = $"EAC-{random.NextInt(9999).ToString()}"; } } }
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(CultCache cultCache, SavedGame savedGame, Action <string> log) { Log = log; Background = savedGame.Background; Factions = savedGame.Factions.Select(cultCache.Get <Faction>).ToArray(); for (var i = 0; i < Factions.Length; i++) { FactionRelationships[Factions[i]] = savedGame.Relationships[i]; } Zones = savedGame.Zones.Select(zone => { return(new GalaxyZone { Name = zone.Name, Position = zone.Position, PackedContents = zone.Contents }); }).ToArray(); foreach (var i in savedGame.DiscoveredZones) { DiscoveredZones.Add(Zones[i]); } for (var i = 0; i < Zones.Length; i++) { Zones[i].AdjacentZones = savedGame.Zones[i].AdjacentZones.Select(azi => Zones[azi]).ToList(); Zones[i].Factions = savedGame.Zones[i].Factions.Select(mi => Factions[mi]).ToArray(); Zones[i].Owner = savedGame.Zones[i].Owner < 0 ? null : Factions[savedGame.Zones[i].Owner]; } HomeZones = savedGame.HomeZones.ToDictionary( x => Factions[x.Key], x => Zones[x.Value]); BossZones = savedGame.BossZones.ToDictionary( x => Factions[x.Key], x => Zones[x.Value]); Entrance = Zones[savedGame.Entrance]; if (savedGame.Exit != -1) { Exit = Zones[savedGame.Exit]; } CalculateDistanceMatrix(); }
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 } }
// public double Time // { // get => _time; // set // { // _deltaTime = (float) (value - _time); // _time = value; // //Log($"GameContext delta time: {_deltaTime}"); // } // } // private readonly Dictionary<CraftedItemData, int> Tier = new Dictionary<CraftedItemData, int>(); public ItemManager(CultCache itemData, GameplaySettings settings, Action <string> logger) { ItemData = itemData; GameplaySettings = settings; _logger = logger; }
public static RethinkQueryStatus RethinkConnect(CultCache cache, string connectionString, string dbName, bool syncLocalChanges = true) { // Add Unity.Mathematics serialization support to RethinkDB Driver JsonConvert.DefaultSettings = () => new JsonSerializerSettings { Converters = new List <JsonConverter> { new MathJsonConverter(), Converter.DateTimeConverter, Converter.BinaryConverter, Converter.GroupingConverter, Converter.PocoExprConverter } }; var syncTables = typeof(DatabaseEntry).GetAllChildClasses() .Select(t => t.GetCustomAttribute <RethinkTableAttribute>()?.TableName ?? "Default").Distinct(); var connectionStringDomainLength = connectionString.IndexOf(':'); if (connectionStringDomainLength < 1) { throw new ArgumentException("Illegal Connection String: must include port!"); } var portString = connectionString.Substring(connectionStringDomainLength + 1); if (!int.TryParse(portString, out var port)) { throw new ArgumentException($"Illegal connection string! \"{portString}\" is not a valid port number!"); } var connection = R.Connection() .Hostname(connectionString.Substring(0, connectionStringDomainLength)) .Port(port).Timeout(60).Connect(); var tables = R.Db(dbName).TableList().RunAtom <string[]>(connection); foreach (var st in syncTables.Where(st => !tables.Contains(st))) { R.Db(dbName).TableCreate(st).RunNoReply(connection); } if (syncLocalChanges) { // When entries are changed locally, push the changes to RethinkDB cache.OnDataUpdateLocal += async entry => { var table = entry.GetType().GetCustomAttribute <RethinkTableAttribute>()?.TableName ?? "Other"; var result = await R .Db(dbName) .Table(table) .Get(entry.ID) .Replace(entry) .RunAsync(connection); }; cache.OnDataInsertLocal += async entry => { var table = entry.GetType().GetCustomAttribute <RethinkTableAttribute>()?.TableName ?? "Other"; var result = await R .Db(dbName) .Table(table) .Insert(entry) .RunAsync(connection); }; cache.OnDataRemoveLocal += async entry => { var table = entry.GetType().GetCustomAttribute <RethinkTableAttribute>()?.TableName ?? "Other"; var result = await R .Db(dbName) .Table(table) .Get(entry.ID) .Delete() .RunAsync(connection); }; } var status = new RethinkQueryStatus(); foreach (var table in syncTables) { // Get entries from RethinkDB Task.Run(async() => { status.TotalEntries += R .Db(dbName) .Table(table) .Count().RunAtom <int>(connection); var result = await R .Db(dbName) .Table(table) .RunCursorAsync <DatabaseEntry>(connection); while (await result.MoveNextAsync()) { var entry = result.Current; cache.Add(entry, true); status.RetrievedEntries++; } }).WrapAwait(); // Subscribe to changes from RethinkDB Task.Run(async() => { var result = await R .Db(dbName) .Table(table) .Changes() .RunChangesAsync <DatabaseEntry>(connection); while (await result.MoveNextAsync()) { var change = result.Current; cache.Add(change.NewValue, true); } }).WrapAwait(); } return(status); }