Exemplo n.º 1
0
    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()}";
            }
        }
    }
Exemplo n.º 2
0
    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
        }
    }
Exemplo n.º 3
0
    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();
    }
Exemplo n.º 4
0
    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
        }
    }
Exemplo n.º 5
0
    // 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;
    }
Exemplo n.º 6
0
    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);
    }