diff --git a/Content.Server/_CP14/UniqueLoot/CP14UniqueLootSpawnerComponent.cs b/Content.Server/_CP14/UniqueLoot/CP14UniqueLootSpawnerComponent.cs index 8607f09051..c8fc042dc1 100644 --- a/Content.Server/_CP14/UniqueLoot/CP14UniqueLootSpawnerComponent.cs +++ b/Content.Server/_CP14/UniqueLoot/CP14UniqueLootSpawnerComponent.cs @@ -9,6 +9,6 @@ public sealed partial class CP14UniqueLootSpawnerComponent : Component /// /// Used to filter which types of unique loot can be generated. You can leave null to disable filtering. /// - [DataField] + [DataField(required: true)] public ProtoId? Tag; } diff --git a/Content.Server/_CP14/UniqueLoot/CP14UniqueLootSystem.cs b/Content.Server/_CP14/UniqueLoot/CP14UniqueLootSystem.cs index ee85bc7cd8..4558fe4619 100644 --- a/Content.Server/_CP14/UniqueLoot/CP14UniqueLootSystem.cs +++ b/Content.Server/_CP14/UniqueLoot/CP14UniqueLootSystem.cs @@ -1,6 +1,8 @@ +using System.Linq; using Content.Server.GameTicking.Events; using Content.Shared._CP14.UniqueLoot; using Content.Shared.GameTicking; +using Content.Shared.Tag; using Robust.Shared.Prototypes; using Robust.Shared.Random; @@ -11,7 +13,7 @@ public sealed partial class CP14UniqueLootSystem : EntitySystem [Dependency] private readonly IPrototypeManager _proto = default!; [Dependency] private readonly IRobustRandom _random = default!; - private Dictionary, int> _uniqueLootCount = new(); + private readonly Dictionary _uniqueLootCount = new(); public override void Initialize() { @@ -25,7 +27,7 @@ public sealed partial class CP14UniqueLootSystem : EntitySystem private void OnMapInit(Entity ent, ref MapInitEvent args) { - var loot = GetNextUniqueLoot(); + var loot = GetNextUniqueLoot(ent.Comp.Tag); if (loot == null) return; @@ -53,27 +55,43 @@ public sealed partial class CP14UniqueLootSystem : EntitySystem foreach (var loot in _proto.EnumeratePrototypes()) { - _uniqueLootCount[loot.ID] = loot.Count; + _uniqueLootCount[loot] = loot.Count; } } - public EntProtoId? GetNextUniqueLoot() + public EntProtoId? GetNextUniqueLoot(ProtoId? withTag = null) { if (_uniqueLootCount.Count == 0) return null; - var selectedLoot = _random.Pick(_uniqueLootCount); + var possibleLoot = _uniqueLootCount.Keys.ToList(); - //TODO: Tag filtering + CP14UniqueLootPrototype? selectedLoot = null; - if (selectedLoot.Value > 1) - _uniqueLootCount[selectedLoot.Key] -= 1; + while (selectedLoot is null) + { + if (possibleLoot.Count == 0) + return null; + + var tryLoot = _random.Pick(possibleLoot); + + if (withTag != null && !tryLoot.Tags.Contains(withTag.Value)) + { + possibleLoot.Remove(tryLoot); + continue; + } + + selectedLoot = tryLoot; + break; + } + + + + if (_uniqueLootCount[selectedLoot] > 1) + _uniqueLootCount[selectedLoot] -= 1; else - _uniqueLootCount.Remove(selectedLoot.Key); + _uniqueLootCount.Remove(selectedLoot); - if (!_proto.TryIndex(selectedLoot.Key, out var indexedLoot)) - return null; - - return indexedLoot.Entity; + return selectedLoot.Entity; } } diff --git a/Content.Shared/_CP14/UniqueLoot/CP14UniqueLootPrototype.cs b/Content.Shared/_CP14/UniqueLoot/CP14UniqueLootPrototype.cs index 06d1ff2d3d..1927a19799 100644 --- a/Content.Shared/_CP14/UniqueLoot/CP14UniqueLootPrototype.cs +++ b/Content.Shared/_CP14/UniqueLoot/CP14UniqueLootPrototype.cs @@ -6,7 +6,7 @@ namespace Content.Shared._CP14.UniqueLoot; /// /// Defines a unique loot that can only be generated a specified number of times per round. /// -[Prototype("uniqueLoot")] +[Prototype("uniqueSpawn")] public sealed partial class CP14UniqueLootPrototype : IPrototype { [IdDataField] diff --git a/Resources/Prototypes/_CP14/Entities/Markers/Spawners/unique_loot.yml b/Resources/Prototypes/_CP14/Entities/Markers/Spawners/unique_loot.yml index f4e3572ac2..e083e188f7 100644 --- a/Resources/Prototypes/_CP14/Entities/Markers/Spawners/unique_loot.yml +++ b/Resources/Prototypes/_CP14/Entities/Markers/Spawners/unique_loot.yml @@ -5,9 +5,25 @@ categories: [ ForkFiltered, DoNotMap ] components: - type: CP14UniqueLootSpawner + tag: CP14UniqueSpawnDemiplanetLoot - type: Sprite layers: - sprite: Markers/cross.rsi state: green - sprite: _CP14/Clothing/Shoes/flightboots.rsi + state: icon + +- type: entity + name: random tradepost spawner + id: CP14SpawnUniqueTradepost + parent: MarkerBase + categories: [ ForkFiltered ] + components: + - type: CP14UniqueLootSpawner + tag: CP14UniqueSpawnTradepost + - type: Sprite + layers: + - sprite: Markers/cross.rsi + state: green + - sprite: _CP14/Structures/Specific/Economy/trade_portal.rsi state: icon \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/UniqueLoot/demiplane_loot.yml b/Resources/Prototypes/_CP14/UniqueLoot/demiplane_loot.yml new file mode 100644 index 0000000000..b4a944785b --- /dev/null +++ b/Resources/Prototypes/_CP14/UniqueLoot/demiplane_loot.yml @@ -0,0 +1,38 @@ +- type: Tag + id: CP14UniqueSpawnDemiplanetLoot + +- type: uniqueSpawn + id: CP14ClothingShoesArtifactSpeedboots + entity: CP14ClothingShoesArtifactSpeedboots + tags: + - CP14UniqueSpawnDemiplanetLoot + +- type: uniqueSpawn + id: CP14ClothingShoesArtifactFlightboots + entity: CP14ClothingShoesArtifactFlightboots + tags: + - CP14UniqueSpawnDemiplanetLoot + +- type: uniqueSpawn + id: CP14ClothingRingFireball + entity: CP14ClothingRingFireball + tags: + - CP14UniqueSpawnDemiplanetLoot + +- type: uniqueSpawn + id: CP14MagicHealingStaff + entity: CP14MagicHealingStaff + tags: + - CP14UniqueSpawnDemiplanetLoot + +- type: uniqueSpawn + id: CP14MagicShadowStaff + entity: CP14MagicShadowStaff + tags: + - CP14UniqueSpawnDemiplanetLoot + +- type: uniqueSpawn + id: CP14CrayonRainbow + entity: CP14CrayonRainbow + tags: + - CP14UniqueSpawnDemiplanetLoot \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/UniqueLoot/loot.yml b/Resources/Prototypes/_CP14/UniqueLoot/loot.yml deleted file mode 100644 index db1a4c3022..0000000000 --- a/Resources/Prototypes/_CP14/UniqueLoot/loot.yml +++ /dev/null @@ -1,23 +0,0 @@ -- type: uniqueLoot - id: CP14ClothingShoesArtifactSpeedboots - entity: CP14ClothingShoesArtifactSpeedboots - -- type: uniqueLoot - id: CP14ClothingShoesArtifactFlightboots - entity: CP14ClothingShoesArtifactFlightboots - -- type: uniqueLoot - id: CP14ClothingRingFireball - entity: CP14ClothingRingFireball - -- type: uniqueLoot - id: CP14MagicHealingStaff - entity: CP14MagicHealingStaff - -- type: uniqueLoot - id: CP14MagicShadowStaff - entity: CP14MagicShadowStaff - -- type: uniqueLoot - id: CP14CrayonRainbow - entity: CP14CrayonRainbow \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/UniqueLoot/tradepost.yml b/Resources/Prototypes/_CP14/UniqueLoot/tradepost.yml new file mode 100644 index 0000000000..74681e099b --- /dev/null +++ b/Resources/Prototypes/_CP14/UniqueLoot/tradepost.yml @@ -0,0 +1,26 @@ +- type: Tag + id: CP14UniqueSpawnTradepost + +- type: uniqueSpawn + id: CP14TradingPortalSylphoria + entity: CP14TradingPortalSylphoria + tags: + - CP14UniqueSpawnTradepost + +- type: uniqueSpawn + id: CP14TradingPortalHelmirWeapon + entity: CP14TradingPortalHelmirWeapon + tags: + - CP14UniqueSpawnTradepost + +- type: uniqueSpawn + id: CP14TradingPortalBradFamily + entity: CP14TradingPortalBradFamily + tags: + - CP14UniqueSpawnTradepost + +- type: uniqueSpawn + id: CP14TradingPortalSpiceStream + entity: CP14TradingPortalSpiceStream + tags: + - CP14UniqueSpawnTradepost \ No newline at end of file