From 3b520ac69ca32eb3047d08345794b0d3aebfb203 Mon Sep 17 00:00:00 2001 From: Ed <96445749+TheShuEd@users.noreply.github.com> Date: Fri, 1 Nov 2024 18:08:57 +0300 Subject: [PATCH] Demiplan modifiers (#526) * simple modifiers * modifier tag filtering * Update CP14DemiplanSystem.Generation.cs * Update rocks.yml * move loot to modifier * move enemies to modificators * fix filtering * modifier rariry * reward and difficulty limits * rebalance and optimize calculation * Update test.yml * wizden PR copy * move all alchemy reagents to modifiers --- .../DungeonJob/DungeonJob.OreDunGen.cs | 63 ++--- .../CP14DemiplanSystem.Generation.cs | 91 ++++++- .../CP14DemiplaneGeneratorDataComponent.cs | 14 +- .../Jobs/CP14SpawnRandomDemiplaneJob.cs | 35 ++- .../Procedural/DungeonLayers/OreDunGen.cs | 11 +- .../CP14DemiplaneLocationPrototype.cs | 14 +- .../CP14DemiplaneModifierPrototype.cs | 62 +++++ .../Procedural/Magnet/asteroid_ore_gens.yml | 31 ++- Resources/Prototypes/Procedural/vgroid.yml | 68 +++++- .../_CP14/Entities/Mobs/NPC/xeno_test.yml | 6 - .../_CP14/Entities/Structures/Flora/rocks.yml | 2 + .../_CP14/Entities/subdimensionGenTEST.yml | 5 +- .../{ => Locations}/T1_Caves/config.yml | 35 +-- .../T1_Grassland_island/config.yml | 36 +-- .../T1_Grassland_island/exterier.yml | 0 .../Procedural/Demiplane/Modifiers/test.yml | 227 ++++++++++++++++++ .../_CP14/Procedural/Demiplane/tags.yml | 11 + .../_CP14/Procedural/biome_template_caves.yml | 18 -- .../Procedural/biome_template_grasslands.yml | 70 ------ 19 files changed, 564 insertions(+), 235 deletions(-) create mode 100644 Content.Shared/_CP14/Demiplane/Prototypes/CP14DemiplaneModifierPrototype.cs rename Resources/Prototypes/_CP14/Procedural/Demiplane/{ => Locations}/T1_Caves/config.yml (79%) rename Resources/Prototypes/_CP14/Procedural/Demiplane/{ => Locations}/T1_Grassland_island/config.yml (82%) rename Resources/Prototypes/_CP14/Procedural/Demiplane/{ => Locations}/T1_Grassland_island/exterier.yml (100%) create mode 100644 Resources/Prototypes/_CP14/Procedural/Demiplane/Modifiers/test.yml create mode 100644 Resources/Prototypes/_CP14/Procedural/Demiplane/tags.yml diff --git a/Content.Server/Procedural/DungeonJob/DungeonJob.OreDunGen.cs b/Content.Server/Procedural/DungeonJob/DungeonJob.OreDunGen.cs index 679eecb4f7..0f08766c6d 100644 --- a/Content.Server/Procedural/DungeonJob/DungeonJob.OreDunGen.cs +++ b/Content.Server/Procedural/DungeonJob/DungeonJob.OreDunGen.cs @@ -1,4 +1,5 @@ using System.Threading.Tasks; +using Content.Shared.Maps; using Content.Shared.Procedural; using Content.Shared.Procedural.Components; using Content.Shared.Procedural.DungeonLayers; @@ -20,44 +21,50 @@ public sealed partial class DungeonJob { // Doesn't use dungeon data because layers and we don't need top-down support at the moment. - var emptyTiles = false; var replaceEntities = new Dictionary(); var availableTiles = new List(); + var tiles = _maps.GetAllTilesEnumerator(_gridUid, _grid); - foreach (var node in dungeon.AllTiles) + while (tiles.MoveNext(out var tileRef)) { - // Empty tile, skip if relevant. - if (!emptyTiles && (!_maps.TryGetTile(_grid, node, out var tile) || tile.IsEmpty)) - continue; + var tile = tileRef.Value.GridIndices; - // Check if it's a valid spawn, if so then use it. - var enumerator = _maps.GetAnchoredEntitiesEnumerator(_gridUid, _grid, node); - var found = false; - - // We use existing entities as a mark to spawn in place - // OR - // We check for any existing entities to see if we can spawn there. - while (enumerator.MoveNext(out var uid)) + //Tile mask filtering + if (gen.TileMask is not null) { - // We can't replace so just stop here. - if (gen.Replacement == null) - break; + if (!gen.TileMask.Contains(((ContentTileDefinition) _tileDefManager[tileRef.Value.Tile.TypeId]).ID)) + continue; - var prototype = _entManager.GetComponent(uid.Value).EntityPrototype; - - if (prototype?.ID == gen.Replacement) - { - replaceEntities[node] = uid.Value; - found = true; - break; - } + //If entity mask null - we ignore the tiles that have anything on them. + if (gen.EntityMask is null && !_anchorable.TileFree(_grid, tile, DungeonSystem.CollisionLayer, DungeonSystem.CollisionMask)) + continue; } - if (!found) - continue; + //Entity mask filtering + if (gen.EntityMask is not null) + { + var found = false; + var enumerator2 = _maps.GetAnchoredEntitiesEnumerator(_gridUid, _grid, tile); + while (enumerator2.MoveNext(out var uid)) + { + var prototype = _entManager.GetComponent(uid.Value).EntityPrototype; + + if (prototype?.ID is null) + continue; + + if (!gen.EntityMask.Contains(prototype.ID)) + continue; + + replaceEntities[tile] = uid.Value; + found = true; + } + + if (!found) + continue; + } // Add it to valid nodes. - availableTiles.Add(node); + availableTiles.Add(tile); await SuspendDungeon(); @@ -139,7 +146,7 @@ public sealed partial class DungeonJob if (groupSize > 0) { - _sawmill.Warning($"Found remaining group size for ore veins of {gen.Replacement ?? "null"}!"); + _sawmill.Warning($"Found remaining group size for ore veins of {gen.Entity.Id ?? "null"}!"); } } } diff --git a/Content.Server/_CP14/Demiplane/CP14DemiplanSystem.Generation.cs b/Content.Server/_CP14/Demiplane/CP14DemiplanSystem.Generation.cs index 587cf317cc..276aca9d78 100644 --- a/Content.Server/_CP14/Demiplane/CP14DemiplanSystem.Generation.cs +++ b/Content.Server/_CP14/Demiplane/CP14DemiplanSystem.Generation.cs @@ -1,3 +1,4 @@ +using System.Linq; using System.Threading; using Content.Server._CP14.Demiplane.Components; using Content.Server._CP14.Demiplane.Jobs; @@ -42,7 +43,7 @@ public sealed partial class CP14DemiplaneSystem /// /// Generates a new random demiplane based on the specified parameters /// - public void SpawnRandomDemiplane(ProtoId location, out Entity demiplan, out MapId mapId) + public void SpawnRandomDemiplane(ProtoId location, List> modifiers, out Entity demiplan, out MapId mapId) { var mapUid = _mapSystem.CreateMap(out mapId, runMapInit: false); var demiComp = EntityManager.EnsureComponent(mapUid); @@ -61,6 +62,7 @@ public sealed partial class CP14DemiplaneSystem mapUid, mapId, location, + modifiers, _random.Next(-10000, 10000), cancelToken.Token); @@ -70,7 +72,7 @@ public sealed partial class CP14DemiplaneSystem private void GeneratorUsedInHand(Entity generator, ref UseInHandEvent args) { - if (generator.Comp.LocationConfig is null) + if (generator.Comp.Location is null) return; //We cant open demiplan in another demiplan @@ -80,7 +82,7 @@ public sealed partial class CP14DemiplaneSystem return; } - SpawnRandomDemiplane(generator.Comp.LocationConfig.Value, out var demiplane, out var mapId); + SpawnRandomDemiplane(generator.Comp.Location.Value, generator.Comp.Modifiers, out var demiplane, out var mapId); //Admin log needed //TEST @@ -116,12 +118,93 @@ public sealed partial class CP14DemiplaneSystem } var selectedConfig = _random.Pick(suitableConfigs); - generator.Comp.LocationConfig = selectedConfig; + generator.Comp.Location = selectedConfig; //Modifier generation + Dictionary suitableModifiersWeights = new(); + foreach (var modifier in _proto.EnumeratePrototypes()) + { + var passed = true; + //Tag blacklist filter + foreach (var configTag in selectedConfig.Tags) + { + if (modifier.BlacklistTags.Count != 0 && modifier.BlacklistTags.Contains(configTag)) + { + passed = false; + break; + } + } + + //Tag required filter + foreach (var reqTag in modifier.RequiredTags) + { + if (!selectedConfig.Tags.Contains(reqTag)) + { + passed = false; + break; + } + } + + if (passed) + { + suitableModifiersWeights.Add(modifier, modifier.GenerationWeight); + } + } + + var difficulty = 0f; + var reward = 0f; + while (generator.Comp.Modifiers.Count < generator.Comp.MaxModifiers && suitableModifiersWeights.Count > 0) + { + var selectedModifier = ModifierPick(suitableModifiersWeights, _random); + if (difficulty + selectedModifier.Difficulty > generator.Comp.DifficultyLimit) + { + suitableModifiersWeights.Remove(selectedModifier); + continue; + } + + if (reward + selectedModifier.Reward > generator.Comp.RewardLimit) + { + suitableModifiersWeights.Remove(selectedModifier); + continue; + } + + generator.Comp.Modifiers.Add(selectedModifier); + reward += selectedModifier.Reward; + difficulty += selectedModifier.Difficulty; + + if (selectedModifier.Unique) + suitableModifiersWeights.Remove(selectedModifier); + } //Scenario generation //ETC generation } + + + /// + /// Optimization moment: avoid re-indexing for weight selection + /// + private static CP14DemiplaneModifierPrototype ModifierPick(Dictionary weights, IRobustRandom random) + { + var picks = weights; + var sum = picks.Values.Sum(); + var accumulated = 0f; + + var rand = random.NextFloat() * sum; + + foreach (var (key, weight) in picks) + { + accumulated += weight; + + if (accumulated >= rand) + { + return key; + } + } + + // Shouldn't happen + throw new InvalidOperationException($"Invalid weighted pick in CP14DemiplanSystem.Generation!"); + } + } diff --git a/Content.Server/_CP14/Demiplane/Components/CP14DemiplaneGeneratorDataComponent.cs b/Content.Server/_CP14/Demiplane/Components/CP14DemiplaneGeneratorDataComponent.cs index 3ac74d7901..e553bacfcd 100644 --- a/Content.Server/_CP14/Demiplane/Components/CP14DemiplaneGeneratorDataComponent.cs +++ b/Content.Server/_CP14/Demiplane/Components/CP14DemiplaneGeneratorDataComponent.cs @@ -11,7 +11,17 @@ namespace Content.Server._CP14.Demiplane.Components; public sealed partial class CP14DemiplaneGeneratorDataComponent : Component { [DataField] - public ProtoId? LocationConfig; + public ProtoId? Location; - //Generation settings + [DataField] + public List> Modifiers = new(); + + [DataField] + public float DifficultyLimit = 1; + + [DataField] + public float RewardLimit = 1; + + [DataField] + public int MaxModifiers = 6; } diff --git a/Content.Server/_CP14/Demiplane/Jobs/CP14SpawnRandomDemiplaneJob.cs b/Content.Server/_CP14/Demiplane/Jobs/CP14SpawnRandomDemiplaneJob.cs index 1ddc894b15..4744f342be 100644 --- a/Content.Server/_CP14/Demiplane/Jobs/CP14SpawnRandomDemiplaneJob.cs +++ b/Content.Server/_CP14/Demiplane/Jobs/CP14SpawnRandomDemiplaneJob.cs @@ -24,6 +24,7 @@ public sealed class CP14SpawnRandomDemiplaneJob : Job private readonly SharedMapSystem _map; private readonly ProtoId _config; + private readonly List> _modifiers; private readonly int _seed; public readonly EntityUid DemiplaneMapUid; @@ -43,6 +44,7 @@ public sealed class CP14SpawnRandomDemiplaneJob : Job EntityUid demiplaneMapUid, MapId demiplaneMapId, ProtoId config, + List> modifiers, int seed, CancellationToken cancellation = default) : base(maxTime, cancellation) { @@ -55,6 +57,7 @@ public sealed class CP14SpawnRandomDemiplaneJob : Job DemiplaneMapUid = demiplaneMapUid; _demiplaneMapId = demiplaneMapId; _config = config; + _modifiers = modifiers; _seed = seed; _sawmill = logManager.GetSawmill("cp14_expedition_job"); @@ -70,18 +73,33 @@ public sealed class CP14SpawnRandomDemiplaneJob : Job _metaData.SetEntityName(DemiplaneMapUid, "TODO: MAP Expedition name generation"); _metaData.SetEntityName(grid, "TODO: GRID Expedition name generation"); - //Spawn island config + //Setup demiplane config var expeditionConfig = _prototypeManager.Index(_config); - var locationConfig = _prototypeManager.Index(expeditionConfig.LocationConfig); - _dungeon.GenerateDungeon(locationConfig, + var indexedLocation = _prototypeManager.Index(expeditionConfig.LocationConfig); + + //Add map components + _entManager.AddComponents(DemiplaneMapUid, expeditionConfig.Components); + + //Apply modifiers + foreach (var modifier in _modifiers) + { + if (!_prototypeManager.TryIndex(modifier, out var indexedModifier)) + continue; + + indexedLocation.Layers.AddRange(indexedModifier.Layers); + _entManager.AddComponents(DemiplaneMapUid, indexedModifier.Components); + } + + _mapManager.DoMapInitialize(_demiplaneMapId); + _mapManager.SetMapPaused(_demiplaneMapId, false); + + //Spawn modified config + _dungeon.GenerateDungeon(indexedLocation, grid, grid, Vector2i.Zero, _seed); //Not async, because dont work with biomespawner boilerplate - //Add map components - _entManager.AddComponents(DemiplaneMapUid, expeditionConfig.Components); - //Setup gravity var gravity = _entManager.EnsureComponent(DemiplaneMapUid); gravity.Enabled = true; @@ -94,11 +112,6 @@ public sealed class CP14SpawnRandomDemiplaneJob : Job var mixture = new GasMixture(moles, Atmospherics.T20C); _entManager.System().SetMapAtmosphere(DemiplaneMapUid, false, mixture); - _mapManager.DoMapInitialize(_demiplaneMapId); - _mapManager.SetMapPaused(_demiplaneMapId, false); - - //Dungeon - return true; } } diff --git a/Content.Shared/Procedural/DungeonLayers/OreDunGen.cs b/Content.Shared/Procedural/DungeonLayers/OreDunGen.cs index 308e44b4cc..3c2c4db441 100644 --- a/Content.Shared/Procedural/DungeonLayers/OreDunGen.cs +++ b/Content.Shared/Procedural/DungeonLayers/OreDunGen.cs @@ -1,3 +1,4 @@ +using Content.Shared.Maps; using Robust.Shared.Prototypes; namespace Content.Shared.Procedural.DungeonLayers; @@ -12,10 +13,16 @@ namespace Content.Shared.Procedural.DungeonLayers; public partial class OreDunGen : IDunGenLayer { /// - /// If the vein generation should occur on top of existing entities what are we replacing. + /// This vein can only be generated by replacing the specified entities. /// [DataField] - public EntProtoId? Replacement; + public HashSet? EntityMask; + + /// + /// This vein can only be generated on the specified tiles + /// + [DataField] + public HashSet>? TileMask; /// /// Entity to spawn. diff --git a/Content.Shared/_CP14/Demiplane/Prototypes/CP14DemiplaneLocationPrototype.cs b/Content.Shared/_CP14/Demiplane/Prototypes/CP14DemiplaneLocationPrototype.cs index abc9bcd069..2590e4bde1 100644 --- a/Content.Shared/_CP14/Demiplane/Prototypes/CP14DemiplaneLocationPrototype.cs +++ b/Content.Shared/_CP14/Demiplane/Prototypes/CP14DemiplaneLocationPrototype.cs @@ -1,4 +1,5 @@ using Content.Shared.Procedural; +using Content.Shared.Tag; using Robust.Shared.Prototypes; namespace Content.Shared._CP14.Demiplane.Prototypes; @@ -14,12 +15,15 @@ public sealed partial class CP14DemiplaneLocationPrototype : IPrototype [DataField(required: true)] public ProtoId LocationConfig; + /// + /// Components that will be automatically added to the demiplane when it is generated + /// [DataField] public ComponentRegistry Components = new(); - //Player faced description - - //Tier restriction - - //Some abstract restriction? + /// + /// Tags allow modifiers to filter which ones can apply to the current location and which ones cannot. + /// + [DataField] + public List> Tags = new(); } diff --git a/Content.Shared/_CP14/Demiplane/Prototypes/CP14DemiplaneModifierPrototype.cs b/Content.Shared/_CP14/Demiplane/Prototypes/CP14DemiplaneModifierPrototype.cs new file mode 100644 index 0000000000..34bc691777 --- /dev/null +++ b/Content.Shared/_CP14/Demiplane/Prototypes/CP14DemiplaneModifierPrototype.cs @@ -0,0 +1,62 @@ +using Content.Shared.Procedural; +using Content.Shared.Tag; +using Robust.Shared.Prototypes; + +namespace Content.Shared._CP14.Demiplane.Prototypes; + +/// +/// Demiplane modifier prototype. The answer to the question “Which” in terms of the combinatorics of demiplane generation is +/// +[Prototype("cp14DemiplaneModifier")] +public sealed partial class CP14DemiplaneModifierPrototype : IPrototype +{ + [IdDataField] public string ID { get; } = default!; + + /// + /// Abstract danger of this modifier. The demiplane has a threat limit, which it gains from modifiers until it reaches the limit. + /// + [DataField] + public float Difficulty = 0; + + /// + /// The abstract value of this modifier. The demiplane has a limit of rewards it gains from modifiers until it reaches the limit. + /// + [DataField] + public float Reward = 0; + + /// + /// How often can this modifier be generated? Determined by weight from all modifiers available for the location + /// + [DataField] + public float GenerationWeight = 1; + + /// + /// Can this modifier be generated multiple times within a single demiplane? + /// + [DataField] + public bool Unique = true; + + /// + /// Generation layers that will be added to the location generation after the main layers. + /// + [DataField] + public List Layers = new(); + + /// + /// Components that will be added to the map + /// + [DataField] + public ComponentRegistry Components = new(); + + /// + /// Modifier cannot be applied to locations with the following tags. Leave empty for disable + /// + [DataField] + public List> BlacklistTags = new(); + + /// + /// Modifier can only be applied to locations that have all of the following tags. Leave empty for disable + /// + [DataField] + public List> RequiredTags = new(); +} diff --git a/Resources/Prototypes/Procedural/Magnet/asteroid_ore_gens.yml b/Resources/Prototypes/Procedural/Magnet/asteroid_ore_gens.yml index 661350f6de..e097380a48 100644 --- a/Resources/Prototypes/Procedural/Magnet/asteroid_ore_gens.yml +++ b/Resources/Prototypes/Procedural/Magnet/asteroid_ore_gens.yml @@ -14,7 +14,8 @@ - type: oreDunGen id: OreIron - replacement: AsteroidRock + entityMask: + - AsteroidRock entity: AsteroidRockTin count: 5 minGroupSize: 5 @@ -22,7 +23,8 @@ - type: oreDunGen id: OreQuartz - replacement: AsteroidRock + entityMask: + - AsteroidRock entity: AsteroidRockQuartz count: 5 minGroupSize: 5 @@ -30,7 +32,8 @@ - type: oreDunGen id: OreCoal - replacement: AsteroidRock + entityMask: + - AsteroidRock entity: AsteroidRockCoal count: 3 minGroupSize: 5 @@ -38,7 +41,8 @@ - type: oreDunGen id: OreSalt - replacement: AsteroidRock + entityMask: + - AsteroidRock entity: AsteroidRockSalt count: 3 minGroupSize: 5 @@ -46,7 +50,8 @@ - type: oreDunGen id: OreGold - replacement: AsteroidRock + entityMask: + - AsteroidRock entity: AsteroidRockGold count: 4 minGroupSize: 5 @@ -54,7 +59,8 @@ - type: oreDunGen id: OreSilver - replacement: AsteroidRock + entityMask: + - AsteroidRock entity: AsteroidRockSilver count: 4 minGroupSize: 5 @@ -62,7 +68,8 @@ - type: oreDunGen id: OrePlasma - replacement: AsteroidRock + entityMask: + - AsteroidRock entity: AsteroidRockPlasma count: 4 minGroupSize: 5 @@ -70,7 +77,8 @@ - type: oreDunGen id: OreUranium - replacement: AsteroidRock + entityMask: + - AsteroidRock entity: AsteroidRockUranium count: 4 minGroupSize: 5 @@ -78,7 +86,8 @@ - type: oreDunGen id: OreBananium - replacement: AsteroidRock + entityMask: + - AsteroidRock entity: AsteroidRockBananium count: 6 minGroupSize: 3 @@ -86,10 +95,10 @@ - type: oreDunGen id: OreArtifactFragment - replacement: AsteroidRock + entityMask: + - AsteroidRock entity: AsteroidRockArtifactFragment count: 5 minGroupSize: 1 maxGroupSize: 2 - diff --git a/Resources/Prototypes/Procedural/vgroid.yml b/Resources/Prototypes/Procedural/vgroid.yml index 0747a58b30..bb7c12483b 100644 --- a/Resources/Prototypes/Procedural/vgroid.yml +++ b/Resources/Prototypes/Procedural/vgroid.yml @@ -28,65 +28,111 @@ proto: VGRoidFill # Ores - !type:OreDunGen - replacement: IronRock + entityMask: + - IronRock entity: IronRockIron count: 50 minGroupSize: 10 maxGroupSize: 15 - !type:OreDunGen - replacement: IronRock + entityMask: + - IronRock entity: IronRockCoal count: 50 minGroupSize: 8 maxGroupSize: 12 - !type:OreDunGen - replacement: IronRock + entityMask: + - IronRock entity: IronRockQuartz count: 50 minGroupSize: 10 maxGroupSize: 15 - !type:OreDunGen - replacement: IronRock + entityMask: + - IronRock entity: IronRockSalt count: 50 minGroupSize: 8 maxGroupSize: 12 - !type:OreDunGen - replacement: IronRock + entityMask: + - IronRock entity: IronRockGold count: 40 minGroupSize: 8 maxGroupSize: 12 - !type:OreDunGen - replacement: IronRock + entityMask: + - IronRock entity: IronRockSilver count: 40 minGroupSize: 8 maxGroupSize: 12 - !type:OreDunGen - replacement: IronRock + entityMask: + - IronRock entity: IronRockPlasma count: 35 minGroupSize: 4 maxGroupSize: 8 - !type:OreDunGen - replacement: IronRock + entityMask: + - IronRock entity: IronRockUranium count: 35 minGroupSize: 4 maxGroupSize: 8 - !type:OreDunGen - replacement: IronRock + entityMask: + - IronRock entity: IronRockArtifactFragment count: 25 minGroupSize: 1 maxGroupSize: 3 - !type:OreDunGen - replacement: IronRock + entityMask: + - IronRock entity: IronRockDiamond count: 15 minGroupSize: 1 maxGroupSize: 2 + # Decoration + - !type:OreDunGen + tileMask: + - FloorAsteroidSand + entity: CrystalGreen + count: 10 + minGroupSize: 3 + maxGroupSize: 5 + - !type:OreDunGen + tileMask: + - FloorAsteroidSand + entity: CrystalPink + count: 10 + minGroupSize: 3 + maxGroupSize: 5 + - !type:OreDunGen + tileMask: + - FloorAsteroidSand + entity: CrystalOrange + count: 10 + minGroupSize: 3 + maxGroupSize: 5 + - !type:OreDunGen + tileMask: + - FloorAsteroidSand + entity: CrystalBlue + count: 10 + minGroupSize: 3 + maxGroupSize: 5 + - !type:OreDunGen + tileMask: + - FloorAsteroidSand + entity: CrystalCyan + count: 10 + minGroupSize: 3 + maxGroupSize: 5 # Configs - type: dungeonConfig @@ -225,4 +271,4 @@ layers: - !type:FillGridDunGen allowedTiles: - - FloorAsteroidSand + - FloorAsteroidSand \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/Entities/Mobs/NPC/xeno_test.yml b/Resources/Prototypes/_CP14/Entities/Mobs/NPC/xeno_test.yml index 42ae8ba418..81aa17926a 100644 --- a/Resources/Prototypes/_CP14/Entities/Mobs/NPC/xeno_test.yml +++ b/Resources/Prototypes/_CP14/Entities/Mobs/NPC/xeno_test.yml @@ -3,7 +3,6 @@ parent: MobXeno categories: [ ForkFiltered ] components: - - type: CP14OutPVSDespawn - type: NpcFactionMember factions: - CP14HostileEveryone @@ -13,7 +12,6 @@ parent: MobXenoDrone categories: [ ForkFiltered ] components: - - type: CP14OutPVSDespawn - type: NpcFactionMember factions: - CP14HostileEveryone @@ -24,7 +22,6 @@ parent: MobCobraSpace categories: [ ForkFiltered ] components: - - type: CP14OutPVSDespawn - type: NpcFactionMember factions: - CP14HostileEveryone @@ -34,7 +31,6 @@ parent: MobPurpleSnake categories: [ ForkFiltered ] components: - - type: CP14OutPVSDespawn - type: NpcFactionMember factions: - CP14HostileEveryone @@ -44,7 +40,6 @@ parent: MobSmallPurpleSnake categories: [ ForkFiltered ] components: - - type: CP14OutPVSDespawn - type: NpcFactionMember factions: - CP14HostileEveryone @@ -54,7 +49,6 @@ parent: MobWatcherMagmawing categories: [ ForkFiltered ] components: - - type: CP14OutPVSDespawn - type: NpcFactionMember factions: - CP14HostileEveryone diff --git a/Resources/Prototypes/_CP14/Entities/Structures/Flora/rocks.yml b/Resources/Prototypes/_CP14/Entities/Structures/Flora/rocks.yml index de3b880a83..172e153cd5 100644 --- a/Resources/Prototypes/_CP14/Entities/Structures/Flora/rocks.yml +++ b/Resources/Prototypes/_CP14/Entities/Structures/Flora/rocks.yml @@ -7,6 +7,8 @@ placement: mode: SnapgridCenter components: + - type: Transform + anchored: True - type: Clickable - type: Sprite drawdepth: Mobs diff --git a/Resources/Prototypes/_CP14/Entities/subdimensionGenTEST.yml b/Resources/Prototypes/_CP14/Entities/subdimensionGenTEST.yml index 62bfc1a04a..e0071cf4e5 100644 --- a/Resources/Prototypes/_CP14/Entities/subdimensionGenTEST.yml +++ b/Resources/Prototypes/_CP14/Entities/subdimensionGenTEST.yml @@ -7,7 +7,6 @@ description: The core that connects the real world to the demiplane. Use it to open a temporary passage to the other world. components: - type: Sprite - drawdepth: Effects sprite: /Textures/_CP14/Structures/Dungeon/demiplan_rift_core.rsi layers: - state: core @@ -18,9 +17,9 @@ parent: CP14BaseSubdimensionalKey components: - type: CP14DemiplaneGeneratorData + rewardLimit: 1.25 + difficultyLimit: 0.75 - type: CP14DemiplaneRift - - type: Sprite - state: key1 - type: entity id: CP14DemiplanRiftCore diff --git a/Resources/Prototypes/_CP14/Procedural/Demiplane/T1_Caves/config.yml b/Resources/Prototypes/_CP14/Procedural/Demiplane/Locations/T1_Caves/config.yml similarity index 79% rename from Resources/Prototypes/_CP14/Procedural/Demiplane/T1_Caves/config.yml rename to Resources/Prototypes/_CP14/Procedural/Demiplane/Locations/T1_Caves/config.yml index b3d978904a..3978446deb 100644 --- a/Resources/Prototypes/_CP14/Procedural/Demiplane/T1_Caves/config.yml +++ b/Resources/Prototypes/_CP14/Procedural/Demiplane/Locations/T1_Caves/config.yml @@ -1,6 +1,9 @@ - type: cp14DemiplaneLocation id: T1Caves locationConfig: CP14ExpeditionCaves + tags: + - CP14DemiplanOre + - CP14DemiplanUnderground components: - type: CP14WeatherController entries: @@ -25,32 +28,6 @@ proto: CP14ExpeditionCavesFillAir - !type:PrototypeDunGen proto: CP14ExpeditionCavesFillCave - # Ore and resources - - !type:OreDunGen - replacement: CP14WallStone - entity: CP14WallStoneGoldOre - count: 10 - minGroupSize: 10 - maxGroupSize: 15 - - !type:OreDunGen - replacement: CP14WallStone - entity: CP14WallStoneIronOre - count: 10 - minGroupSize: 10 - maxGroupSize: 15 - - !type:OreDunGen - replacement: CP14WallStone - entity: CP14WallStoneCopperOre - count: 10 - minGroupSize: 10 - maxGroupSize: 15 - # Mobs - - !type:MobsDunGen - minCount: 5 - maxCount: 10 - groups: - - id: CP14SpawnMobUndeadZombie - amount: 1 # Enter and Exit - !type:MobsDunGen minCount: 1 @@ -64,12 +41,6 @@ groups: - id: CP14DemiplanePassway amount: 1 - # Loot - - !type:EntityTableDunGen - minCount: 10 - maxCount: 25 - table: !type:NestedSelector - tableId: CP14TableExpeditionLootCommon - type: dungeonConfig id: CP14ExpeditionCavesFloorMaskAir diff --git a/Resources/Prototypes/_CP14/Procedural/Demiplane/T1_Grassland_island/config.yml b/Resources/Prototypes/_CP14/Procedural/Demiplane/Locations/T1_Grassland_island/config.yml similarity index 82% rename from Resources/Prototypes/_CP14/Procedural/Demiplane/T1_Grassland_island/config.yml rename to Resources/Prototypes/_CP14/Procedural/Demiplane/Locations/T1_Grassland_island/config.yml index f557694711..1aa9e5d457 100644 --- a/Resources/Prototypes/_CP14/Procedural/Demiplane/T1_Grassland_island/config.yml +++ b/Resources/Prototypes/_CP14/Procedural/Demiplane/Locations/T1_Grassland_island/config.yml @@ -1,6 +1,10 @@ - type: cp14DemiplaneLocation id: T1GrasslandIsland locationConfig: CP14ExpeditionGrasslandIsland + tags: + - CP14DemiplanOre + - CP14DemiplanOpenSky + - CP14DemiplanGrass components: - type: MapLight ambientLightColor: "#BFEEFFFF" @@ -57,32 +61,6 @@ proto: CP14ExpeditionGrasslandIslandFillGrassland - !type:PrototypeDunGen proto: CP14ExpeditionGrasslandIslandFillCave - # Ore and resources - - !type:OreDunGen - replacement: CP14WallStone - entity: CP14WallStoneGoldOre - count: 10 - minGroupSize: 10 - maxGroupSize: 15 - - !type:OreDunGen - replacement: CP14WallStone - entity: CP14WallStoneIronOre - count: 10 - minGroupSize: 10 - maxGroupSize: 15 - - !type:OreDunGen - replacement: CP14WallStone - entity: CP14WallStoneCopperOre - count: 10 - minGroupSize: 10 - maxGroupSize: 15 - # Mobs - - !type:MobsDunGen - minCount: 3 - maxCount: 6 - groups: - - id: CP14SpawnMobDinoYumkaraptor - amount: 1 # Enter and Exit - !type:MobsDunGen minCount: 1 @@ -96,12 +74,6 @@ groups: - id: CP14DemiplanePassway amount: 1 - # Loot - - !type:EntityTableDunGen - minCount: 5 - maxCount: 20 - table: !type:NestedSelector - tableId: CP14TableExpeditionLootCommon - type: dungeonConfig id: CP14ExpeditionGrasslandIslandFloorMaskStone diff --git a/Resources/Prototypes/_CP14/Procedural/Demiplane/T1_Grassland_island/exterier.yml b/Resources/Prototypes/_CP14/Procedural/Demiplane/Locations/T1_Grassland_island/exterier.yml similarity index 100% rename from Resources/Prototypes/_CP14/Procedural/Demiplane/T1_Grassland_island/exterier.yml rename to Resources/Prototypes/_CP14/Procedural/Demiplane/Locations/T1_Grassland_island/exterier.yml diff --git a/Resources/Prototypes/_CP14/Procedural/Demiplane/Modifiers/test.yml b/Resources/Prototypes/_CP14/Procedural/Demiplane/Modifiers/test.yml new file mode 100644 index 0000000000..df24a81163 --- /dev/null +++ b/Resources/Prototypes/_CP14/Procedural/Demiplane/Modifiers/test.yml @@ -0,0 +1,227 @@ +- type: cp14DemiplaneModifier + id: GoldOre + unique: false + reward: 0.5 + requiredTags: + - CP14DemiplanOre + layers: + - !type:OreDunGen + entityMask: + - CP14WallStone + entity: CP14WallStoneGoldOre + count: 10 + minGroupSize: 10 + maxGroupSize: 15 + +- type: cp14DemiplaneModifier + id: IronOre + unique: false + reward: 0.4 + requiredTags: + - CP14DemiplanOre + layers: + - !type:OreDunGen + entityMask: + - CP14WallStone + entity: CP14WallStoneIronOre + count: 10 + minGroupSize: 10 + maxGroupSize: 15 + +- type: cp14DemiplaneModifier + id: QuartzCrystal + reward: 0.2 + requiredTags: + - CP14DemiplanOre + layers: + - !type:OreDunGen + tileMask: + - CP14FloorBase + entity: CP14QuartzCrystal + count: 10 + minGroupSize: 3 + maxGroupSize: 5 + +- type: cp14DemiplaneModifier + id: Dayflin + reward: 0.2 + requiredTags: + - CP14DemiplanGrass + - CP14DemiplanOpenSky + layers: + - !type:OreDunGen + tileMask: + - CP14FloorGrass + - CP14FloorGrassLight + - CP14FloorGrassTall + entity: CP14GatherableDayflin + count: 10 + minGroupSize: 3 + maxGroupSize: 5 + +- type: cp14DemiplaneModifier + id: BlueAmanita + reward: 0.2 + requiredTags: + - CP14DemiplanGrass + layers: + - !type:OreDunGen + tileMask: + - CP14FloorGrass + - CP14FloorGrassLight + - CP14FloorGrassTall + entity: CP14GatherableBlueAmanita + count: 10 + minGroupSize: 3 + maxGroupSize: 5 + +- type: cp14DemiplaneModifier + id: BloodFlower + reward: 0.2 + requiredTags: + - CP14DemiplanGrass + layers: + - !type:OreDunGen + tileMask: + - CP14FloorGrass + - CP14FloorGrassLight + - CP14FloorGrassTall + entity: CP14GatherableBloodFlower + count: 10 + minGroupSize: 3 + maxGroupSize: 5 + +- type: cp14DemiplaneModifier + id: WildSage + reward: 0.2 + requiredTags: + - CP14DemiplanGrass + - CP14DemiplanOpenSky + layers: + - !type:OreDunGen + tileMask: + - CP14FloorGrass + - CP14FloorGrassLight + - CP14FloorGrassTall + entity: CP14GatherableWildSage + count: 10 + minGroupSize: 3 + maxGroupSize: 5 + +- type: cp14DemiplaneModifier + id: LumiShroom + reward: 0.2 + requiredTags: + - CP14DemiplanUnderground + layers: + - !type:OreDunGen + tileMask: + - CP14FloorGrass + - CP14FloorGrassLight + - CP14FloorGrassTall + - CP14FloorBase + entity: CP14GatherableLumiMushroom + count: 10 + minGroupSize: 3 + maxGroupSize: 5 + +- type: cp14DemiplaneModifier + id: CopperOre + unique: false + reward: 0.3 + requiredTags: + - CP14DemiplanOre + layers: + - !type:OreDunGen + entityMask: + - CP14WallStone + entity: CP14WallStoneCopperOre + count: 10 + minGroupSize: 10 + maxGroupSize: 15 + +- type: cp14DemiplaneModifier + id: Explosive + difficulty: 0.4 + generationWeight: 0.25 + layers: + - !type:MobsDunGen + minCount: 25 + maxCount: 50 + groups: + - id: LandMineExplosive + amount: 1 + +- type: cp14DemiplaneModifier + id: CommonLoot + reward: 0.25 + generationWeight: 2 + layers: + - !type:EntityTableDunGen + minCount: 15 + maxCount: 30 + table: !type:NestedSelector + tableId: CP14TableExpeditionLootCommon + +- type: cp14DemiplaneModifier + id: EnemyXeno + difficulty: 0.5 + requiredTags: + - CP14DemiplanUnderground + layers: + - !type:EntityTableDunGen + minCount: 5 + maxCount: 10 + table: !type:GroupSelector + children: + - id: CP14MobXenoDrone + - id: CP14MobXeno + +- type: cp14DemiplaneModifier + id: EnemyZombie + difficulty: 0.4 + layers: + - !type:EntityTableDunGen + minCount: 5 + maxCount: 10 + table: !type:GroupSelector + children: + - id: CP14SpawnMobUndeadZombie + +- type: cp14DemiplaneModifier + id: EnemyDyno + difficulty: 0.5 + requiredTags: + - CP14DemiplanOpenSky + layers: + - !type:MobsDunGen + minCount: 3 + maxCount: 6 + groups: + - id: CP14SpawnMobDinoYumkaraptor + amount: 1 + +- type: cp14DemiplaneModifier + id: EnemySnakes + difficulty: 0.7 + layers: + - !type:EntityTableDunGen + minCount: 5 + maxCount: 10 + table: !type:GroupSelector + children: + - id: CP14MobPurpleSnake + - id: CP14MobSmallPurpleSnake + - id: CP14MobSpaceCobra + +- type: cp14DemiplaneModifier + id: EnemyMagmawind + difficulty: 0.3 + generationWeight: 0.4 + layers: + - !type:MobsDunGen + minCount: 3 + maxCount: 5 + groups: + - id: CP14MobWatcherMagmawing + amount: 1 \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/Procedural/Demiplane/tags.yml b/Resources/Prototypes/_CP14/Procedural/Demiplane/tags.yml new file mode 100644 index 0000000000..93fb543997 --- /dev/null +++ b/Resources/Prototypes/_CP14/Procedural/Demiplane/tags.yml @@ -0,0 +1,11 @@ +- type: Tag + id: CP14DemiplanOre + +- type: Tag + id: CP14DemiplanGrass + +- type: Tag + id: CP14DemiplanOpenSky + +- type: Tag + id: CP14DemiplanUnderground \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/Procedural/biome_template_caves.yml b/Resources/Prototypes/_CP14/Procedural/biome_template_caves.yml index fe77c0142d..70e34add2d 100644 --- a/Resources/Prototypes/_CP14/Procedural/biome_template_caves.yml +++ b/Resources/Prototypes/_CP14/Procedural/biome_template_caves.yml @@ -22,24 +22,6 @@ - CP14FloorBase entities: - CP14RockSmall - - CP14RockSmall - - CP14QuartzCrystal - - !type:BiomeEntityLayer # lumishroom sage - threshold: 0.8 - noise: - seed: 8 - noiseType: OpenSimplex2 - fractalType: Ridged - frequency: 0.045 - octaves: 3 - lacunarity: 1.8 - gain: 0.7 - domainWarpType: OpenSimplex2 - domainWarpAmp: 120 - allowedTiles: - - CP14FloorBase - entities: - - CP14GatherableLumiMushroom - type: biomeTemplate id: CP14CavesGeneric diff --git a/Resources/Prototypes/_CP14/Procedural/biome_template_grasslands.yml b/Resources/Prototypes/_CP14/Procedural/biome_template_grasslands.yml index cf9f6fee10..db912bf400 100644 --- a/Resources/Prototypes/_CP14/Procedural/biome_template_grasslands.yml +++ b/Resources/Prototypes/_CP14/Procedural/biome_template_grasslands.yml @@ -98,42 +98,6 @@ - CP14GrassBushes7 - CP14GrassBushes8 - CP14GrassBushes9 - - !type:BiomeEntityLayer # flowers - threshold: 0.7 - noise: - seed: 34 - noiseType: OpenSimplex2 - fractalType: Ridged - frequency: 0.035 - octaves: 3 - lacunarity: 1.8 - gain: 0.7 - domainWarpType: OpenSimplex2 - domainWarpAmp: 120 - allowedTiles: - - CP14FloorGrass - - CP14FloorGrassLight - - CP14FloorGrassTall - entities: - - CP14GatherableDayflin - - !type:BiomeEntityLayer # BLue amanita - threshold: 0.7 - noise: - seed: 67 - noiseType: OpenSimplex2 - fractalType: Ridged - frequency: 0.038 - octaves: 3 - lacunarity: 1.8 - gain: 0.7 - domainWarpType: OpenSimplex2 - domainWarpAmp: 120 - allowedTiles: - - CP14FloorGrass - - CP14FloorGrassLight - - CP14FloorGrassTall - entities: - - CP14GatherableBlueAmanita - !type:BiomeEntityLayer # Tall grass! threshold: 0.3 noise: @@ -174,40 +138,6 @@ - CP14FloraTreeLarge04 - CP14FloraTreeLarge05 - CP14FloraTreeLarge06 - - !type:BiomeEntityLayer # Rare Bloodflower - threshold: 0.7 - noise: - seed: 3 - noiseType: OpenSimplex2 - fractalType: Ridged - frequency: 0.015 - octaves: 3 - lacunarity: 1.8 - gain: 0.7 - domainWarpType: OpenSimplex2 - domainWarpAmp: 120 - allowedTiles: - - CP14FloorGrass - - CP14FloorGrassLight - - CP14FloorGrassTall - entities: - - CP14GatherableBloodFlower - - !type:BiomeEntityLayer # Rare Wild sage - threshold: 0.6 - noise: - seed: 8 - noiseType: OpenSimplex2 - fractalType: Ridged - frequency: 0.015 - octaves: 3 - lacunarity: 1.8 - gain: 0.7 - domainWarpType: OpenSimplex2 - domainWarpAmp: 120 - allowedTiles: - - CP14FloorGrass - entities: - - CP14GatherableWildSage - !type:BiomeEntityLayer # More Rocks threshold: 0.7 noise: