From 51f4ec84d514aa2623e0f23c6456b6340b2ade12 Mon Sep 17 00:00:00 2001 From: Ed <96445749+TheShuEd@users.noreply.github.com> Date: Sat, 2 Nov 2024 17:46:19 +0300 Subject: [PATCH] Demiplan polishing v3 (#529) * Wizden PR copy * sync * Update DungeonJob.PostGenBiome.cs * Update DungeonJob.PostGenBiome.cs * some rebalance * required exits and enters! * room fill fix * snakes nerf * enable En-US localization for playtest * guidebook update * hotfix!!! --- .../DungeonJob/DungeonJob.PostGenBiome.cs | 25 +++-- .../Procedural/DungeonSystem.Rooms.cs | 55 +++++---- .../CP14DemiplanSystem.Generation.cs | 2 +- .../Jobs/CP14SpawnRandomDemiplaneJob.cs | 24 +++- .../ContentLocalizationManager.cs | 8 +- .../Procedural/PostGeneration/BiomeDunGen.cs | 7 ++ .../Locale/en-US/_CP14/guidebook/guides.ftl | 7 -- .../Locale/ru-RU/_CP14/guidebook/guides.ftl | 7 -- .../Actions/Spells/sphere_of_light.yml | 4 +- .../Markers/Spawners/Random/Loot/spawners.yml | 1 + .../_CP14/Entities/Mobs/NPC/xeno_test.yml | 30 +++++ .../Structures/Flora/Gatherable/wild.yml | 18 ++- .../_CP14/Entities/Structures/Flora/trees.yml | 2 + .../Structures/Furniture/lamppost.yml | 6 + .../_CP14/Entities/subdimensionGenTEST.yml | 39 ++++++- .../_CP14/Guidebook/Eng/alchemy.yml | 13 ++- .../Prototypes/_CP14/Guidebook/Ru/alchemy.yml | 13 ++- .../Prototypes/_CP14/Guidebook/entry.yml | 8 +- .../Demiplane/Locations/t1_caves.yml | 53 ++------- .../Demiplane/Locations/t1_grass_geode.yml | 40 ++----- .../Locations/t1_grassland_island.yml | 59 ++-------- .../Procedural/Demiplane/Modifiers/test.yml | 104 ++++++++++-------- .../Procedural/Demiplane/required_layers.yml | 15 +++ .../_CP14/Guidebook_EN/Demiplanes.xml | 61 ++++++++++ .../_CP14/Guidebook_RU/Demiplanes.xml | 61 ++++++++++ 25 files changed, 421 insertions(+), 241 deletions(-) create mode 100644 Resources/Prototypes/_CP14/Procedural/Demiplane/required_layers.yml create mode 100644 Resources/ServerInfo/_CP14/Guidebook_EN/Demiplanes.xml create mode 100644 Resources/ServerInfo/_CP14/Guidebook_RU/Demiplanes.xml diff --git a/Content.Server/Procedural/DungeonJob/DungeonJob.PostGenBiome.cs b/Content.Server/Procedural/DungeonJob/DungeonJob.PostGenBiome.cs index 65f6d2d14f..63905cfd66 100644 --- a/Content.Server/Procedural/DungeonJob/DungeonJob.PostGenBiome.cs +++ b/Content.Server/Procedural/DungeonJob/DungeonJob.PostGenBiome.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using Content.Server.Parallax; +using Content.Shared.Maps; using Content.Shared.Parallax.Biomes; using Content.Shared.Procedural; using Content.Shared.Procedural.PostGeneration; @@ -15,27 +16,35 @@ public sealed partial class DungeonJob /// private async Task PostGen(BiomeDunGen dunGen, DungeonData data, Dungeon dungeon, HashSet reservedTiles, Random random) { - if (_entManager.TryGetComponent(_gridUid, out BiomeComponent? biomeComp)) + if (!_prototype.TryIndex(dunGen.BiomeTemplate, out var indexedBiome)) return; - biomeComp = _entManager.AddComponent(_gridUid); var biomeSystem = _entManager.System(); - biomeSystem.SetTemplate(_gridUid, biomeComp, _prototype.Index(dunGen.BiomeTemplate)); + var seed = random.Next(); var xformQuery = _entManager.GetEntityQuery(); - foreach (var node in dungeon.RoomTiles) + var tiles = _maps.GetAllTilesEnumerator(_gridUid, _grid); + while (tiles.MoveNext(out var tileRef)) { + var node = tileRef.Value.GridIndices; + if (reservedTiles.Contains(node)) continue; + if (dunGen.TileMask is not null) + { + if (!dunGen.TileMask.Contains(((ContentTileDefinition) _tileDefManager[tileRef.Value.Tile.TypeId]).ID)) + continue; + } + // Need to set per-tile to override data. - if (biomeSystem.TryGetTile(node, biomeComp.Layers, seed, _grid, out var tile)) + if (biomeSystem.TryGetTile(node, indexedBiome.Layers, seed, _grid, out var tile)) { _maps.SetTile(_gridUid, _grid, node, tile.Value); } - if (biomeSystem.TryGetDecals(node, biomeComp.Layers, seed, _grid, out var decals)) + if (biomeSystem.TryGetDecals(node, indexedBiome.Layers, seed, _grid, out var decals)) { foreach (var decal in decals) { @@ -43,7 +52,7 @@ public sealed partial class DungeonJob } } - if (biomeSystem.TryGetEntity(node, biomeComp, _grid, out var entityProto)) + if (tile is not null && biomeSystem.TryGetEntity(node, indexedBiome.Layers, tile.Value, seed, _grid, out var entityProto)) { var ent = _entManager.SpawnEntity(entityProto, new EntityCoordinates(_gridUid, node + _grid.TileSizeHalfVector)); var xform = xformQuery.Get(ent); @@ -61,7 +70,5 @@ public sealed partial class DungeonJob if (!ValidateResume()) return; } - - biomeComp.Enabled = false; } } diff --git a/Content.Server/Procedural/DungeonSystem.Rooms.cs b/Content.Server/Procedural/DungeonSystem.Rooms.cs index 011cc4ad54..a990edd715 100644 --- a/Content.Server/Procedural/DungeonSystem.Rooms.cs +++ b/Content.Server/Procedural/DungeonSystem.Rooms.cs @@ -115,28 +115,30 @@ public sealed partial class DungeonSystem var finalRoomRotation = roomTransform.Rotation(); + //CP14 bandage it - int dont work // go BRRNNTTT on existing stuff - if (clearExisting) - { - var gridBounds = new Box2(Vector2.Transform(-room.Size/2, roomTransform), Vector2.Transform(room.Size/2, roomTransform)); - _entitySet.Clear(); - // Polygon skin moment - gridBounds = gridBounds.Enlarged(-0.05f); - _lookup.GetLocalEntitiesIntersecting(gridUid, gridBounds, _entitySet, LookupFlags.Uncontained); - - foreach (var templateEnt in _entitySet) - { - Del(templateEnt); - } - - if (TryComp(gridUid, out DecalGridComponent? decalGrid)) - { - foreach (var decal in _decals.GetDecalsIntersecting(gridUid, gridBounds, decalGrid)) - { - _decals.RemoveDecal(gridUid, decal.Index, decalGrid); - } - } - } + //if (clearExisting) + //{ + // var gridBounds = new Box2(Vector2.Transform(-room.Size/2, roomTransform), Vector2.Transform(room.Size/2, roomTransform)); + // _entitySet.Clear(); + // // Polygon skin moment + // gridBounds = gridBounds.Enlarged(-0.05f); + // _lookup.GetLocalEntitiesIntersecting(gridUid, gridBounds, _entitySet, LookupFlags.Uncontained); +// + // foreach (var templateEnt in _entitySet) + // { + // Del(templateEnt); + // } +// + // if (TryComp(gridUid, out DecalGridComponent? decalGrid)) + // { + // foreach (var decal in _decals.GetDecalsIntersecting(gridUid, gridBounds, decalGrid)) + // { + // _decals.RemoveDecal(gridUid, decal.Index, decalGrid); + // } + // } + //} + //CP14 end var roomCenter = (room.Offset + room.Size / 2f) * grid.TileSize; var tileOffset = -roomCenter + grid.TileSizeHalfVector; @@ -163,6 +165,17 @@ public sealed partial class DungeonSystem } _tiles.Add((rounded, tileRef.Tile)); + + //CP14 clearExisting variant + if (clearExisting) + { + var anchored = _maps.GetAnchoredEntities((gridUid, grid), rounded); + foreach (var ent in anchored) + { + QueueDel(ent); + } + } + //CP14 clearExisting variant end } } diff --git a/Content.Server/_CP14/Demiplane/CP14DemiplanSystem.Generation.cs b/Content.Server/_CP14/Demiplane/CP14DemiplanSystem.Generation.cs index a942bc176d..6dc9c12a0b 100644 --- a/Content.Server/_CP14/Demiplane/CP14DemiplanSystem.Generation.cs +++ b/Content.Server/_CP14/Demiplane/CP14DemiplanSystem.Generation.cs @@ -99,7 +99,7 @@ public sealed partial class CP14DemiplaneSystem AddDemiplanRandomExitPoint(demiplane, (tempRift2, connection2)); #if !DEBUG - QueueDel(generator); //wtf its crash debug build? + QueueDel(generator); //wtf its crash debug build! #endif } diff --git a/Content.Server/_CP14/Demiplane/Jobs/CP14SpawnRandomDemiplaneJob.cs b/Content.Server/_CP14/Demiplane/Jobs/CP14SpawnRandomDemiplaneJob.cs index 4744f342be..46d910bfde 100644 --- a/Content.Server/_CP14/Demiplane/Jobs/CP14SpawnRandomDemiplaneJob.cs +++ b/Content.Server/_CP14/Demiplane/Jobs/CP14SpawnRandomDemiplaneJob.cs @@ -5,6 +5,8 @@ using Content.Server.Procedural; using Content.Shared._CP14.Demiplane.Prototypes; using Content.Shared.Atmos; using Content.Shared.Gravity; +using Content.Shared.Procedural; +using Content.Shared.Procedural.DungeonGenerators; using Robust.Shared.CPUJob.JobQueues; using Robust.Shared.Map; using Robust.Shared.Prototypes; @@ -69,6 +71,7 @@ public sealed class CP14SpawnRandomDemiplaneJob : Job var grid = _mapManager.CreateGridEntity(DemiplaneMapUid); MetaDataComponent? metadata = null; + DungeonConfigPrototype dungeonConfig = new(); _metaData.SetEntityName(DemiplaneMapUid, "TODO: MAP Expedition name generation"); _metaData.SetEntityName(grid, "TODO: GRID Expedition name generation"); @@ -77,28 +80,36 @@ public sealed class CP14SpawnRandomDemiplaneJob : Job var expeditionConfig = _prototypeManager.Index(_config); var indexedLocation = _prototypeManager.Index(expeditionConfig.LocationConfig); + dungeonConfig.Data = indexedLocation.Data; + dungeonConfig.Layers.AddRange(indexedLocation.Layers); + dungeonConfig.ReserveTiles = indexedLocation.ReserveTiles; + //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); + dungeonConfig.Layers.AddRange(indexedModifier.Layers); _entManager.AddComponents(DemiplaneMapUid, indexedModifier.Components); } - _mapManager.DoMapInitialize(_demiplaneMapId); - _mapManager.SetMapPaused(_demiplaneMapId, false); + //Enter and exits + if (_prototypeManager.TryIndex("DemiplaneConnections", out var indexedConnections)) + { + dungeonConfig.Layers.AddRange(indexedConnections.Layers); + } //Spawn modified config - _dungeon.GenerateDungeon(indexedLocation, + _dungeon.GenerateDungeon(dungeonConfig, grid, grid, Vector2i.Zero, - _seed); //Not async, because dont work with biomespawner boilerplate + _seed); //Setup gravity var gravity = _entManager.EnsureComponent(DemiplaneMapUid); @@ -112,6 +123,9 @@ 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); + return true; } } diff --git a/Content.Shared/Localizations/ContentLocalizationManager.cs b/Content.Shared/Localizations/ContentLocalizationManager.cs index 12380d53f8..24d692499e 100644 --- a/Content.Shared/Localizations/ContentLocalizationManager.cs +++ b/Content.Shared/Localizations/ContentLocalizationManager.cs @@ -10,7 +10,7 @@ namespace Content.Shared.Localizations [Dependency] private readonly ILocalizationManager _loc = default!; // If you want to change your codebase's language, do it here. - public const string Culture = "ru-RU"; // CrystallPunk-Localization. "ru-RU" or "en-US" + public const string Culture = "en-US"; // CrystallPunk-Localization. "ru-RU" or "en-US" /// /// Custom format strings used for parsing and displaying minutes:seconds timespans. @@ -28,9 +28,9 @@ namespace Content.Shared.Localizations var culture = new CultureInfo(Culture); _loc.LoadCulture(culture); // Uncomment for Ru localization - var fallbackCulture = new CultureInfo("en-US"); - _loc.LoadCulture(fallbackCulture); - _loc.SetFallbackCluture(fallbackCulture); + //var fallbackCulture = new CultureInfo("en-US"); + //_loc.LoadCulture(fallbackCulture); + //_loc.SetFallbackCluture(fallbackCulture); // _loc.AddFunction(culture, "PRESSURE", FormatPressure); diff --git a/Content.Shared/Procedural/PostGeneration/BiomeDunGen.cs b/Content.Shared/Procedural/PostGeneration/BiomeDunGen.cs index 833cf2dec7..e21e582211 100644 --- a/Content.Shared/Procedural/PostGeneration/BiomeDunGen.cs +++ b/Content.Shared/Procedural/PostGeneration/BiomeDunGen.cs @@ -1,3 +1,4 @@ +using Content.Shared.Maps; using Content.Shared.Parallax.Biomes; using Robust.Shared.Prototypes; @@ -11,4 +12,10 @@ public sealed partial class BiomeDunGen : IDunGenLayer { [DataField(required: true)] public ProtoId BiomeTemplate; + + /// + /// creates a biome only on the specified tiles + /// + [DataField] + public HashSet>? TileMask; } diff --git a/Resources/Locale/en-US/_CP14/guidebook/guides.ftl b/Resources/Locale/en-US/_CP14/guidebook/guides.ftl index dd15db927f..a022217836 100644 --- a/Resources/Locale/en-US/_CP14/guidebook/guides.ftl +++ b/Resources/Locale/en-US/_CP14/guidebook/guides.ftl @@ -1,8 +1 @@ -cp14-guide-entry-russian = Russian guidebook -cp14-guide-entry-english = English guidebook - -cp14-guide-entry-alchemy = Alchemy -cp14-guide-entry-basic-alchemy = Basic alchemical reagents -cp14-guide-entry-biological = Biological - cp14-guidebook-random-variations-title = Random products diff --git a/Resources/Locale/ru-RU/_CP14/guidebook/guides.ftl b/Resources/Locale/ru-RU/_CP14/guidebook/guides.ftl index c41bea4b66..771eae61d2 100644 --- a/Resources/Locale/ru-RU/_CP14/guidebook/guides.ftl +++ b/Resources/Locale/ru-RU/_CP14/guidebook/guides.ftl @@ -1,8 +1 @@ -cp14-guide-entry-russian = Русское руководство -cp14-guide-entry-english = Английское руководство - -cp14-guide-entry-alchemy = Алхимия -cp14-guide-entry-basic-alchemy = Базовые алхимические элементы -cp14-guide-entry-biological = Биологические вещества - cp14-guidebook-random-variations-title = Случайные продукты diff --git a/Resources/Prototypes/_CP14/Entities/Actions/Spells/sphere_of_light.yml b/Resources/Prototypes/_CP14/Entities/Actions/Spells/sphere_of_light.yml index 0f76e01342..e8fbac597f 100644 --- a/Resources/Prototypes/_CP14/Entities/Actions/Spells/sphere_of_light.yml +++ b/Resources/Prototypes/_CP14/Entities/Actions/Spells/sphere_of_light.yml @@ -89,8 +89,8 @@ - type: LandAtCursor - type: MovementIgnoreGravity - type: PointLight - radius: 5.0 - energy: 6 + radius: 6.0 + energy: 2 color: "#efedff" - type: Damageable - type: EmitSoundOnLand diff --git a/Resources/Prototypes/_CP14/Entities/Markers/Spawners/Random/Loot/spawners.yml b/Resources/Prototypes/_CP14/Entities/Markers/Spawners/Random/Loot/spawners.yml index aa173f9cfe..597f948d32 100644 --- a/Resources/Prototypes/_CP14/Entities/Markers/Spawners/Random/Loot/spawners.yml +++ b/Resources/Prototypes/_CP14/Entities/Markers/Spawners/Random/Loot/spawners.yml @@ -86,6 +86,7 @@ - id: CP14SilverCoin5 - id: CP14GoldBar1 - id: CP14EnergyCrystalMedium + - id: CP14DemiplanKey - type: entityTable id: CP14TableBureaucracy diff --git a/Resources/Prototypes/_CP14/Entities/Mobs/NPC/xeno_test.yml b/Resources/Prototypes/_CP14/Entities/Mobs/NPC/xeno_test.yml index 81aa17926a..0f321b32bb 100644 --- a/Resources/Prototypes/_CP14/Entities/Mobs/NPC/xeno_test.yml +++ b/Resources/Prototypes/_CP14/Entities/Mobs/NPC/xeno_test.yml @@ -25,6 +25,18 @@ - type: NpcFactionMember factions: - CP14HostileEveryone + - type: MeleeChemicalInjector + transferAmount: 2 + - type: MeleeWeapon + hidden: true + soundHit: + path: /Audio/Effects/bite.ogg + angle: 0 + animation: WeaponArcBite + damage: + types: + Piercing: 2 + Poison: 2 - type: entity id: CP14MobPurpleSnake @@ -34,6 +46,14 @@ - type: NpcFactionMember factions: - CP14HostileEveryone + - type: MeleeWeapon + angle: 0 + animation: WeaponArcBite + damage: + types: + Piercing: 1 + - type: MeleeChemicalInjector + transferAmount: 3 - type: entity id: CP14MobSmallPurpleSnake @@ -43,6 +63,16 @@ - type: NpcFactionMember factions: - CP14HostileEveryone + - type: SolutionTransfer + maxTransferAmount: 0.2 + - type: MeleeWeapon + angle: 0 + animation: WeaponArcBite + damage: + types: + Piercing: 0.5 + - type: MeleeChemicalInjector + transferAmount: 2 - type: entity id: CP14MobWatcherMagmawing diff --git a/Resources/Prototypes/_CP14/Entities/Structures/Flora/Gatherable/wild.yml b/Resources/Prototypes/_CP14/Entities/Structures/Flora/Gatherable/wild.yml index 9af138fc57..33beec46d3 100644 --- a/Resources/Prototypes/_CP14/Entities/Structures/Flora/Gatherable/wild.yml +++ b/Resources/Prototypes/_CP14/Entities/Structures/Flora/Gatherable/wild.yml @@ -172,12 +172,14 @@ All: CP14GatherLumiMushroom - type: entity - parent: CP14BaseRock + parent: BaseRock id: CP14QuartzCrystal name: quartz description: Quartz is an essential mineral capable of interacting with magical energy. It is highly sought after by alchemists for extracting beneficial properties from liquids - categories: [ HideSpawnMenu ] + categories: [ ForkFiltered ] components: + - type: Transform + anchored: true - type: Sprite drawdepth: Mobs sprite: _CP14/Structures/crystal.rsi @@ -227,11 +229,15 @@ fix1: shape: !type:PhysShapeCircle - radius: 0.4 - density: 500 + radius: 0.30 + density: 60 + mask: + - MachineMask layer: - - HalfWallLayer - - Opaque + - MidImpassable + - LowImpassable + - BulletImpassable + - Opaque # Blue amanita diff --git a/Resources/Prototypes/_CP14/Entities/Structures/Flora/trees.yml b/Resources/Prototypes/_CP14/Entities/Structures/Flora/trees.yml index aa352bf4aa..8a27ab2d70 100644 --- a/Resources/Prototypes/_CP14/Entities/Structures/Flora/trees.yml +++ b/Resources/Prototypes/_CP14/Entities/Structures/Flora/trees.yml @@ -6,6 +6,8 @@ name: tree description: Decades of life and growth, saturating the surrounding nature with fresh air. components: + - type: Transform + anchored: true - type: CP14WaveShader speed: 1 dis: 5 diff --git a/Resources/Prototypes/_CP14/Entities/Structures/Furniture/lamppost.yml b/Resources/Prototypes/_CP14/Entities/Structures/Furniture/lamppost.yml index a0bface339..3b6da32677 100644 --- a/Resources/Prototypes/_CP14/Entities/Structures/Furniture/lamppost.yml +++ b/Resources/Prototypes/_CP14/Entities/Structures/Furniture/lamppost.yml @@ -2,7 +2,13 @@ id: CP14BaseLamppost categories: [ ForkFiltered ] abstract: true + placement: + mode: SnapgridCenter + snap: + - Wall components: + - type: Transform + anchored: true - type: SpriteFade - type: Clickable - type: Physics diff --git a/Resources/Prototypes/_CP14/Entities/subdimensionGenTEST.yml b/Resources/Prototypes/_CP14/Entities/subdimensionGenTEST.yml index e0071cf4e5..b2aacf45cb 100644 --- a/Resources/Prototypes/_CP14/Entities/subdimensionGenTEST.yml +++ b/Resources/Prototypes/_CP14/Entities/subdimensionGenTEST.yml @@ -11,15 +11,40 @@ layers: - state: core shader: unshaded + - type: GuideHelp + guides: + - CP14_RU_Demiplanes + - CP14_EN_Demiplanes - type: entity id: CP14DemiplanKey parent: CP14BaseSubdimensionalKey + name: demiplan key components: - type: CP14DemiplaneGeneratorData rewardLimit: 1.25 difficultyLimit: 0.75 - - type: CP14DemiplaneRift + maxModifiers: 6 + +- type: entity + id: CP14DemiplanKeyHard + parent: CP14BaseSubdimensionalKey + name: hard demiplan key - hard + components: + - type: CP14DemiplaneGeneratorData + rewardLimit: 2.25 + difficultyLimit: 1.75 + maxModifiers: 10 + +- type: entity + id: CP14DemiplanKeyHardcore + parent: CP14BaseSubdimensionalKey + name: demiplan key - HARDCORE + components: + - type: CP14DemiplaneGeneratorData + rewardLimit: 4.25 + difficultyLimit: 2.75 + maxModifiers: 15 - type: entity id: CP14DemiplanRiftCore @@ -47,6 +72,10 @@ energy: 2 color: "#371c5c" netsync: false + - type: GuideHelp + guides: + - CP14_RU_Demiplanes + - CP14_EN_Demiplanes - type: entity id: CP14DemiplaneTimedRadiusPassway @@ -75,6 +104,10 @@ range: 7 sound: path: /Audio/Ambience/Objects/gravity_gen_hum.ogg + - type: GuideHelp + guides: + - CP14_RU_Demiplanes + - CP14_EN_Demiplanes - type: entity id: CP14DemiplanePassway @@ -99,6 +132,10 @@ range: 7 sound: path: /Audio/Ambience/Objects/gravity_gen_hum.ogg + - type: GuideHelp + guides: + - CP14_RU_Demiplanes + - CP14_EN_Demiplanes - type: entity parent: MarkerBase diff --git a/Resources/Prototypes/_CP14/Guidebook/Eng/alchemy.yml b/Resources/Prototypes/_CP14/Guidebook/Eng/alchemy.yml index f8cdaff635..1fccf92e8b 100644 --- a/Resources/Prototypes/_CP14/Guidebook/Eng/alchemy.yml +++ b/Resources/Prototypes/_CP14/Guidebook/Eng/alchemy.yml @@ -1,7 +1,7 @@ - type: guideEntry crystallPunkAllowed: true id: CP14_EN_Alchemy - name: cp14-guide-entry-alchemy + name: Alchemy text: "/ServerInfo/_CP14/Guidebook_EN/Alchemy.xml" children: - CP14_EN_BasicAlchemy @@ -11,13 +11,20 @@ - type: guideEntry crystallPunkAllowed: true id: CP14_EN_BasicAlchemy - name: cp14-guide-entry-basic-alchemy + name: Basic effects solutions text: "/ServerInfo/_CP14/Guidebook_EN/AlchemyTabs/BasicAlchemy.xml" filterEnabled: True - type: guideEntry crystallPunkAllowed: true id: CP14_EN_Biological - name: cp14-guide-entry-biological + name: Biological solutions text: "/ServerInfo/_CP14/Guidebook_EN/AlchemyTabs/Biological.xml" + filterEnabled: True + +- type: guideEntry + crystallPunkAllowed: true + id: CP14_EN_Demiplanes + name: Demiplanes exploration + text: "/ServerInfo/_CP14/Guidebook_EN/Demiplanes.xml" filterEnabled: True \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/Guidebook/Ru/alchemy.yml b/Resources/Prototypes/_CP14/Guidebook/Ru/alchemy.yml index 30229923c4..5e8ad91832 100644 --- a/Resources/Prototypes/_CP14/Guidebook/Ru/alchemy.yml +++ b/Resources/Prototypes/_CP14/Guidebook/Ru/alchemy.yml @@ -1,7 +1,7 @@ - type: guideEntry crystallPunkAllowed: true id: CP14_RU_Alchemy - name: cp14-guide-entry-alchemy + name: Алхимия text: "/ServerInfo/_CP14/Guidebook_RU/Alchemy.xml" children: - CP14_RU_BasicAlchemy @@ -11,13 +11,20 @@ - type: guideEntry crystallPunkAllowed: true id: CP14_RU_BasicAlchemy - name: cp14-guide-entry-basic-alchemy + name: Базовые алхимические растворы text: "/ServerInfo/_CP14/Guidebook_RU/AlchemyTabs/BasicAlchemy.xml" filterEnabled: True - type: guideEntry crystallPunkAllowed: true id: CP14_RU_Biological - name: cp14-guide-entry-biological + name: Биологические растворы text: "/ServerInfo/_CP14/Guidebook_RU/AlchemyTabs/Biological.xml" + filterEnabled: True + +- type: guideEntry + crystallPunkAllowed: true + id: CP14_RU_Demiplanes + name: Исследование демипланов + text: "/ServerInfo/_CP14/Guidebook_RU/Demiplanes.xml" filterEnabled: True \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/Guidebook/entry.yml b/Resources/Prototypes/_CP14/Guidebook/entry.yml index 2532ca91a6..d3d7d93c16 100644 --- a/Resources/Prototypes/_CP14/Guidebook/entry.yml +++ b/Resources/Prototypes/_CP14/Guidebook/entry.yml @@ -2,16 +2,18 @@ crystallPunkAllowed: true locFilter: "en-US" id: CP14_EN - name: cp14-guide-entry-english + name: Welcome to CrystallPunk text: "/ServerInfo/_CP14/Guidebook_EN/Welcome.xml" children: - CP14_EN_Alchemy + - CP14_EN_Demiplanes - type: guideEntry crystallPunkAllowed: true locFilter: "ru-RU" id: CP14_RU - name: cp14-guide-entry-russian + name: Добро пожаловать в CrystallPunk text: "/ServerInfo/_CP14/Guidebook_RU/Welcome.xml" children: - - CP14_RU_Alchemy \ No newline at end of file + - CP14_RU_Alchemy + - CP14_RU_Demiplanes \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/Procedural/Demiplane/Locations/t1_caves.yml b/Resources/Prototypes/_CP14/Procedural/Demiplane/Locations/t1_caves.yml index 596d92db64..1b7daa7868 100644 --- a/Resources/Prototypes/_CP14/Procedural/Demiplane/Locations/t1_caves.yml +++ b/Resources/Prototypes/_CP14/Procedural/Demiplane/Locations/t1_caves.yml @@ -12,35 +12,24 @@ - type: dungeonConfig id: CP14ExpeditionCaves layers: - # Masks (from center to border!) + # Masks - !type:PrototypeDunGen proto: CP14ExpeditionCavesFloorMaskBorder - !type:PrototypeDunGen proto: CP14ExpeditionCavesFloorMaskStone - !type:PrototypeDunGen proto: CP14ExpeditionCavesFloorMaskAir - # Exterior rooms - # Enter and Exit - - !type:MobsDunGen - minCount: 1 - maxCount: 1 - groups: - - id: CP14DemiplanEnterRoomMarker - amount: 1 - #here - # Biome Spawner fills (from border to center!) order is very important! For inexplicable reasons, only a certain sequence works! + # Biomes - !type:PrototypeDunGen proto: CP14ExpeditionCavesFillBorder - - !type:PrototypeDunGen - proto: CP14ExpeditionCavesFillAir - - !type:PrototypeDunGen - proto: CP14ExpeditionCavesFillCave - - !type:MobsDunGen - minCount: 2 - maxCount: 2 - groups: - - id: CP14DemiplanePassway - amount: 1 + - !type:BiomeDunGen + biomeTemplate: CP14CavesGeneric + tileMask: + - CP14FloorSand + - !type:BiomeDunGen + biomeTemplate: CP14CavesFloor + tileMask: + - CP14FloorGrass - type: dungeonConfig id: CP14ExpeditionCavesFloorMaskAir @@ -96,28 +85,6 @@ lacunarity: 2 gain: 0.5 -- type: dungeonConfig - id: CP14ExpeditionCavesFillAir - reserveTiles: true - data: - entities: - Fill: CP14BiomeSpawnerCaveEmpty - layers: - - !type:FillGridDunGen - allowedTiles: - - CP14FloorGrass - -- type: dungeonConfig - id: CP14ExpeditionCavesFillCave - reserveTiles: true - data: - entities: - Fill: CP14BiomeSpawnerCave - layers: - - !type:FillGridDunGen - allowedTiles: - - CP14FloorSand - - type: dungeonConfig id: CP14ExpeditionCavesFillBorder reserveTiles: true diff --git a/Resources/Prototypes/_CP14/Procedural/Demiplane/Locations/t1_grass_geode.yml b/Resources/Prototypes/_CP14/Procedural/Demiplane/Locations/t1_grass_geode.yml index c5df0efbf1..1d60442742 100644 --- a/Resources/Prototypes/_CP14/Procedural/Demiplane/Locations/t1_grass_geode.yml +++ b/Resources/Prototypes/_CP14/Procedural/Demiplane/Locations/t1_grass_geode.yml @@ -15,7 +15,7 @@ - type: dungeonConfig id: CP14DemiplaneGrassGeode layers: - # Masks (from center to border!) + # Masks - !type:PrototypeDunGen proto: CP14DemiplaneGrassGeodeFloorMaskBorder - !type:PrototypeDunGen @@ -24,28 +24,19 @@ proto: CP14DemiplaneGrassGeodeFloorMaskAir - !type:PrototypeDunGen proto: CP14DemiplaneGrassGeodeFloorMaskWater - # Enter and Exit - - !type:MobsDunGen - minCount: 1 - maxCount: 1 - groups: - - id: CP14DemiplanEnterRoomMarker - amount: 1 - # Biome Spawner fills (from border to center!) order is very important! For inexplicable reasons, only a certain sequence works! + # Biomes - !type:PrototypeDunGen proto: CP14ExpeditionCavesFillBorder - - !type:PrototypeDunGen - proto: CP14DemiplaneGrassGeodeFillGrass - - !type:PrototypeDunGen - proto: CP14ExpeditionCavesFillCave + - !type:BiomeDunGen + biomeTemplate: CP14GrasslandTestResult + tileMask: + - CP14FloorGrass + - !type:BiomeDunGen + biomeTemplate: CP14CavesGeneric + tileMask: + - CP14FloorSand - !type:PrototypeDunGen proto: CP14DemiplaneGrassGeodeFillWater - - !type:MobsDunGen - minCount: 2 - maxCount: 2 - groups: - - id: CP14DemiplanePassway - amount: 1 - type: dungeonConfig id: CP14DemiplaneGrassGeodeFloorMaskWater @@ -119,17 +110,6 @@ lacunarity: 2 gain: 0.5 -- type: dungeonConfig - id: CP14DemiplaneGrassGeodeFillGrass - reserveTiles: true - data: - entities: - Fill: CP14BiomeSpawnerGrassland - layers: - - !type:FillGridDunGen - allowedTiles: - - CP14FloorGrass - - type: dungeonConfig id: CP14DemiplaneGrassGeodeFillWater reserveTiles: true diff --git a/Resources/Prototypes/_CP14/Procedural/Demiplane/Locations/t1_grassland_island.yml b/Resources/Prototypes/_CP14/Procedural/Demiplane/Locations/t1_grassland_island.yml index d66cc39b44..408095fd5c 100644 --- a/Resources/Prototypes/_CP14/Procedural/Demiplane/Locations/t1_grassland_island.yml +++ b/Resources/Prototypes/_CP14/Procedural/Demiplane/Locations/t1_grassland_island.yml @@ -43,37 +43,22 @@ - type: dungeonConfig id: CP14ExpeditionGrasslandIsland layers: - # Masks (from center to border!) + # Masks - !type:PrototypeDunGen proto: CP14ExpeditionGrasslandIslandFloorMaskSand - !type:PrototypeDunGen proto: CP14ExpeditionGrasslandIslandFloorMaskGrass - !type:PrototypeDunGen proto: CP14ExpeditionGrasslandIslandFloorMaskStone - # Exterior rooms - #- !type:EntityTableDunGen - # minCount: 1 - # maxCount: 2 - # table: - # id: CP14GrasslandIslandExteriorRoomSpawner - # Enter and Exit - - !type:MobsDunGen - minCount: 1 - maxCount: 1 - groups: - - id: CP14DemiplanEnterRoomMarker - amount: 1 - # Biome Spawner fills (from border to center!) order is very important! For inexplicable reasons, only a certain sequence works! - - !type:PrototypeDunGen - proto: CP14ExpeditionGrasslandIslandFillGrassland - - !type:PrototypeDunGen - proto: CP14ExpeditionGrasslandIslandFillCave - - !type:MobsDunGen - minCount: 2 - maxCount: 2 - groups: - - id: CP14DemiplanePassway - amount: 1 + # Biomes + - !type:BiomeDunGen + biomeTemplate: CP14CavesGeneric + tileMask: + - CP14FloorBase + - !type:BiomeDunGen + biomeTemplate: CP14GrasslandTestResult + tileMask: + - CP14FloorGrass - type: dungeonConfig id: CP14ExpeditionGrasslandIslandFloorMaskStone @@ -127,26 +112,4 @@ fractalType: FBm octaves: 5 lacunarity: 2 - gain: 0.5 - -- type: dungeonConfig - id: CP14ExpeditionGrasslandIslandFillGrassland - reserveTiles: true - data: - entities: - Fill: CP14BiomeSpawnerGrassland - layers: - - !type:FillGridDunGen - allowedTiles: - - CP14FloorGrass - -- type: dungeonConfig - id: CP14ExpeditionGrasslandIslandFillCave - reserveTiles: true - data: - entities: - Fill: CP14BiomeSpawnerCave - layers: - - !type:FillGridDunGen - allowedTiles: - - CP14FloorBase \ No newline at end of file + gain: 0.5 \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/Procedural/Demiplane/Modifiers/test.yml b/Resources/Prototypes/_CP14/Procedural/Demiplane/Modifiers/test.yml index 021f40c016..0bf2611246 100644 --- a/Resources/Prototypes/_CP14/Procedural/Demiplane/Modifiers/test.yml +++ b/Resources/Prototypes/_CP14/Procedural/Demiplane/Modifiers/test.yml @@ -30,7 +30,7 @@ - type: cp14DemiplaneModifier id: QuartzCrystal - reward: 0.2 + reward: 0.1 requiredTags: - CP14DemiplanOre layers: @@ -39,13 +39,13 @@ - CP14FloorBase entity: CP14QuartzCrystal count: 10 - minGroupSize: 3 - maxGroupSize: 5 + minGroupSize: 1 + maxGroupSize: 4 - type: cp14DemiplaneModifier id: QuartzCrystalRubies reward: 0.2 - generationWeight: 0.2 + generationWeight: 0.1 requiredTags: - CP14DemiplanOre - CP14DemiplanUnderground @@ -54,62 +54,66 @@ tileMask: - CP14FloorBase entity: CP14CrystalRubiesMedium - count: 10 - minGroupSize: 3 - maxGroupSize: 5 + count: 30 + minGroupSize: 1 + maxGroupSize: 4 - type: cp14DemiplaneModifier id: QuartzCrystalTopazes reward: 0.2 - generationWeight: 0.2 + generationWeight: 0.1 requiredTags: - CP14DemiplanOre - - CP14DemiplanUnderground layers: - !type:OreDunGen tileMask: - CP14FloorBase + - CP14FloorSand entity: CP14CrystalTopazesMedium - count: 10 - minGroupSize: 3 - maxGroupSize: 5 + count: 30 + minGroupSize: 1 + maxGroupSize: 4 - type: cp14DemiplaneModifier id: QuartzCrystalEmeralds reward: 0.2 - generationWeight: 0.2 + generationWeight: 0.1 requiredTags: - CP14DemiplanOre - - CP14DemiplanUnderground layers: - !type:OreDunGen tileMask: - CP14FloorBase + - CP14FloorGrass + - CP14FloorGrassLight + - CP14FloorGrassTall entity: CP14CrystalEmeraldsMedium - count: 10 - minGroupSize: 3 - maxGroupSize: 5 + count: 30 + minGroupSize: 1 + maxGroupSize: 4 - type: cp14DemiplaneModifier id: QuartzCrystalSapphires reward: 0.2 - generationWeight: 0.2 + generationWeight: 0.1 requiredTags: - CP14DemiplanOre - - CP14DemiplanUnderground layers: - !type:OreDunGen tileMask: - CP14FloorBase + - CP14FloorGrass + - CP14FloorGrassLight + - CP14FloorGrassTall entity: CP14CrystalSapphiresMedium - count: 10 - minGroupSize: 3 - maxGroupSize: 5 + count: 30 + minGroupSize: 1 + maxGroupSize: 4 - type: cp14DemiplaneModifier id: QuartzCrystalAmethysts reward: 0.2 - generationWeight: 0.2 + generationWeight: 0.1 requiredTags: - CP14DemiplanOre - CP14DemiplanUnderground @@ -118,14 +122,14 @@ tileMask: - CP14FloorBase entity: CP14CrystalAmethystsMedium - count: 10 - minGroupSize: 3 - maxGroupSize: 5 + count: 30 + minGroupSize: 1 + maxGroupSize: 4 - type: cp14DemiplaneModifier id: QuartzCrystalDiamonds reward: 0.2 - generationWeight: 0.2 + generationWeight: 0.1 requiredTags: - CP14DemiplanOre - CP14DemiplanUnderground @@ -133,10 +137,11 @@ - !type:OreDunGen tileMask: - CP14FloorBase + - CP14FloorSand entity: CP14CrystalDiamondsMedium - count: 10 - minGroupSize: 3 - maxGroupSize: 5 + count: 30 + minGroupSize: 1 + maxGroupSize: 4 - type: cp14DemiplaneModifier id: Dayflin @@ -265,24 +270,25 @@ requiredTags: - CP14DemiplanUnderground layers: - - !type:EntityTableDunGen + - !type:MobsDunGen minCount: 5 - maxCount: 10 - table: !type:GroupSelector - children: - - id: CP14MobXenoDrone - - id: CP14MobXeno + maxCount: 8 + groups: + - id: CP14MobXenoDrone + amount: 1 + - id: CP14MobXeno + amount: 1 - type: cp14DemiplaneModifier id: EnemyZombie difficulty: 0.4 layers: - - !type:EntityTableDunGen - minCount: 5 - maxCount: 10 - table: !type:GroupSelector - children: - - id: CP14SpawnMobUndeadZombie + - !type:MobsDunGen + minCount: 3 + maxCount: 6 + groups: + - id: CP14SpawnMobUndeadZombie + amount: 1 - type: cp14DemiplaneModifier id: EnemyDyno @@ -301,14 +307,16 @@ id: EnemySnakes difficulty: 0.7 layers: - - !type:EntityTableDunGen + - !type:MobsDunGen minCount: 3 maxCount: 6 - table: !type:GroupSelector - children: - - id: CP14MobPurpleSnake - - id: CP14MobSmallPurpleSnake - - id: CP14MobSpaceCobra + groups: + - id: CP14MobPurpleSnake + amount: 1 + - id: CP14MobSmallPurpleSnake + amount: 1 + - id: CP14MobSpaceCobra + amount: 1 - type: cp14DemiplaneModifier id: EnemyMagmawind diff --git a/Resources/Prototypes/_CP14/Procedural/Demiplane/required_layers.yml b/Resources/Prototypes/_CP14/Procedural/Demiplane/required_layers.yml new file mode 100644 index 0000000000..0f39196c65 --- /dev/null +++ b/Resources/Prototypes/_CP14/Procedural/Demiplane/required_layers.yml @@ -0,0 +1,15 @@ +- type: dungeonConfig + id: DemiplaneConnections + layers: + - !type:EntityTableDunGen + minCount: 1 + maxCount: 1 + table: !type:GroupSelector + children: + - id: CP14DemiplanEnterRoomMarker + - !type:EntityTableDunGen + minCount: 2 + maxCount: 2 + table: !type:GroupSelector + children: + - id: CP14DemiplanePassway \ No newline at end of file diff --git a/Resources/ServerInfo/_CP14/Guidebook_EN/Demiplanes.xml b/Resources/ServerInfo/_CP14/Guidebook_EN/Demiplanes.xml new file mode 100644 index 0000000000..9e8a4e215e --- /dev/null +++ b/Resources/ServerInfo/_CP14/Guidebook_EN/Demiplanes.xml @@ -0,0 +1,61 @@ + + +# Demiplanes exploring +Demiplanes are one of the main ways for adventurers and the city as a whole to obtain resources. + +The main goal of exploration is for adventurers to obtain resources (ore, loot, etc.) and successfully return them back to their world. + +As an adventurer, you can sell resources from the demiplane to artisans and other players at your own prices. + +## What research and preparation looks like. + +There are "keys" in the game world that allow you to temporarily activate a portal to move into a procedurally generated demiplane with enemies and resources. Within the location there will be generated exits from the demiplane that you will have to find on your own. + + + + +. + +When you activate the "key" (via the "Z" key or by clicking on the key), a portal is formed, which will teleport up to 4 players and what they are pulling behind them to the demiplane. +Be aware that you may be immediately attacked by opponents who are near you. + + + + + +After activation, an active gap remains in the real world, which cannot be moved or destroyed, and its animation shows that players are currently in the demiplane. + +Once transported, you have unlimited time to explore the demiplane and gather resources. However, lingering without a reason is not recommended. + +When you decide to leave the demiplane after finding the portal, you must touch the portal with your free hand to start the transfer. At this point, you may have time to take the object in your hand again or start dragging it to be carried along with you. If there are no living players left in the demiplane, the demiplane and all gaps leading into it are destroyed. + + + + + + + + + +## Preparing +To prepare for an expedition to the demiplane, you may need the following items: +- Weapons for all members of the group. +- Vials of healing potions or poison for weapons. +- Sharpening stones to sharpen your weapons on the spot. +- Armor for group members. +- Magical items and/or crossbows (with ammunition) for dealing damage remotely. +- A "key" to open the demiplane. +- Extra bags or crates for collecting loot. +- Belt lanterns or magical lighting. +- A supply of water and food for a short break from exploring. + +## Cooperation tips +The entire Demiplane is designed for adventurers to (and should) work as a team. Define the basic concepts amongst yourselves: +- who will engage in melee and ranged combat? +- who will be responsible for healing and/or storing medicine vials? +- Who will carry the team's cargo (crates or extra bags) to gather resources? +- How will you divide the items you receive amongst yourselves later on? +- who will be your team leader during critical situations? +- What will you do with dead and injured team members? + + \ No newline at end of file diff --git a/Resources/ServerInfo/_CP14/Guidebook_RU/Demiplanes.xml b/Resources/ServerInfo/_CP14/Guidebook_RU/Demiplanes.xml new file mode 100644 index 0000000000..b0377b72c2 --- /dev/null +++ b/Resources/ServerInfo/_CP14/Guidebook_RU/Demiplanes.xml @@ -0,0 +1,61 @@ + + +# Исследование демипланов +Демипланы - один из основных способов получение ресурсов авантюристами и города в целом. + +Основная задача при исследовании - добыча ресурсов (руды, лут, и прочее) авантюристами и удачный возврат обратно в свой мир. + +Как авантюрист, вы можете продавать ресурсы с демиплана ремесленникам и иным игрокам по собственным ценам. + +## Как выглядит исследование и подготовка к ней. + +В мире игры существуют «ключи», позволяющие временно активировать портал для перехода в процедурно сгенерированный демиплан с противниками и ресурсами. Внутри локации будут сгенерированы выходы с демиплана которые вам предстоит найти самим. + + + + + + +При активации "ключа" (через клавишу "Z" или кликнув по ключу) образуется портал, который через время в области от себя телепортирует в демиплан до 4 игроков и то, что они тянут за собой. +Учтите что при переносе на вас могут сразу же набросится противники, оказавшиеся рядом с вами. + + + + + +После активации в настоящем мире остаётся активный разрыв, который невозможно сдвинуть или уничтожить, и его анимация показывает, что в демиплане на данный момент находятся игроки. + +После переноса у вас неограниченное время для исследования демиплана и сбора ресурсов. Однако задерживаться без причины не рекомендуется. + +Когда вы решитесь покинуть демиплан отыскав портал, вам необходимо свободной рукой коснутся портала для начала переноса. В этот момент вы можете успеть снова взять предмет в руку или начать тащить что б его перенесло вместе с вами. Если в демиплане не остается живых игроков, демиплан и все разрывы ведущие в него, уничтожаются. + + + + + + + + + +## Подготовка +Для подготовки к экспедиции в демиплан вам могут пригодится следующие вещи: +- Оружие для всех участников группы. +- Флаконы с зельями лечения или ядом для оружия. +- Точильные камни для заточки вашего оружия на месте. +- Броня для участников группы. +- Магические предметы и/или арбалеты (с амуницией) для дистанционного нанесения урона. +- "Ключ" для открытия демиплана. +- Дополнительные сумки или ящики для сбора добычи. +- Поясные фонари или магическое освещение. +- Запас воды и еды для непродолжительного перерыва в исследовании. + +## Советы по кооперации +Весь Демиплан рассчитан на то что авантюристы будут (и должны) работать в команде. Определите между собой основные понятия: +- кто будет вступать в ближний и дальний бой? +- кто ответственен за лечение и/или хранение флаконов с лекарством? +- кто будет нести груз команды (ящики или дополнительные сумки) для сбора ресурсов? +- как вы будете делить полученные вещи между собой в дальнейшем? +- кто будет лидером вашей группы во время критических ситуаций? +- что делать с убитыми и раненными членами группы? + + \ No newline at end of file