From 350d8fffdca0f3453b89aae8680b08e6437e0d58 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Thu, 2 Jul 2026 21:28:01 -0700 Subject: [PATCH] feat(throwing): wire SA loot flavor via IsStygian (Ter Mur) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Complete the SA-loot path Joe's original PR left dead: add SAWeaponTypes / SARangedWeaponTypes pools + isStygian branches to Loot.RandomWeapon / RandomRangedWeapon, and — the piece that was missing — compute IsStygian (map == Map.TerMur) in LootPackEntry.Construct and thread it through LootPackItem.Construct. Creatures in Ter Mur now roll SA gear + the three throwing weapons (Boomerang/Cyclone/SoulGlaive) from their normal BaseWeapon/BaseRanged loot entries. Conservative IsStygian: Ter Mur map only (not ServUO's extra `|| RandomBool()` that would sprinkle SA gear everywhere). Server (UOContent.csproj) builds clean; full test verification is blocked by an unrelated pre-existing break in the OPL PropertyList tests on main (PR #2501). Co-Authored-By: Claude Opus 4.8 (1M context) --- Projects/UOContent/Misc/Loot.cs | 27 +++++++++++++++++++++++++-- Projects/UOContent/Misc/LootPack.cs | 11 +++++++---- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/Projects/UOContent/Misc/Loot.cs b/Projects/UOContent/Misc/Loot.cs index b641400a2..2477c25b5 100644 --- a/Projects/UOContent/Misc/Loot.cs +++ b/Projects/UOContent/Misc/Loot.cs @@ -6,6 +6,17 @@ namespace Server { public static class Loot { + public static Type[] SAWeaponTypes { get; } = + { + typeof(DiscMace), typeof(GargishTalwar), typeof(DualPointedSpear), + typeof(GlassStaff), typeof(DualShortAxes), typeof(GlassSword) + }; + + public static Type[] SARangedWeaponTypes { get; } = + { + typeof(Boomerang), typeof(Cyclone), typeof(SoulGlaive) + }; + public static Type[] MLWeaponTypes { get; } = { typeof(AssassinSpike), typeof(DiamondMace), typeof(ElvenMachete), @@ -374,12 +385,18 @@ namespace Server return Construct(ClothingTypes); } + private static readonly Type[][] _saRangedWeaponTypes = [SARangedWeaponTypes, AosRangedWeaponTypes, RangedWeaponTypes]; private static readonly Type[][] _mlRangedWeaponTypes = [MLRangedWeaponTypes, AosRangedWeaponTypes, RangedWeaponTypes]; private static readonly Type[][] _seRangedWeaponTypes = [SERangedWeaponTypes, AosRangedWeaponTypes, RangedWeaponTypes]; private static readonly Type[][] _aosRangedWeaponTypes = [AosRangedWeaponTypes, RangedWeaponTypes]; - public static BaseWeapon RandomRangedWeapon(bool inTokuno = false, bool isMondain = false) + public static BaseWeapon RandomRangedWeapon(bool inTokuno = false, bool isMondain = false, bool isStygian = false) { + if (Core.SA && isStygian) + { + return Construct(_saRangedWeaponTypes); + } + if (Core.ML && isMondain) { return Construct(_mlRangedWeaponTypes); @@ -398,12 +415,18 @@ namespace Server return Construct(RangedWeaponTypes); } + private static readonly Type[][] _saWeaponTypes = [SAWeaponTypes, AosWeaponTypes, WeaponTypes]; private static readonly Type[][] _mlWeaponTypes = [MLWeaponTypes, AosWeaponTypes, WeaponTypes]; private static readonly Type[][] _seWeaponTypes = [SEWeaponTypes, AosWeaponTypes, WeaponTypes]; private static readonly Type[][] _aosWeaponTypes = [AosWeaponTypes, WeaponTypes]; - public static BaseWeapon RandomWeapon(bool inTokuno = false, bool isMondain = false) + public static BaseWeapon RandomWeapon(bool inTokuno = false, bool isMondain = false, bool isStygian = false) { + if (Core.SA && isStygian) + { + return Construct(_saWeaponTypes); + } + if (Core.ML && isMondain) { return Construct(_mlWeaponTypes); diff --git a/Projects/UOContent/Misc/LootPack.cs b/Projects/UOContent/Misc/LootPack.cs index e5bd810b0..92cb06eb2 100644 --- a/Projects/UOContent/Misc/LootPack.cs +++ b/Projects/UOContent/Misc/LootPack.cs @@ -619,6 +619,9 @@ namespace Server private static bool IsMondain(Mobile m) => MondainsLegacy.IsMLRegion(m.Region); + // Stygian Abyss loot flavor: creatures in Ter Mur draw from the SA gear pools. + private static bool IsStygian(Mobile m) => m.Map == Map.TerMur; + public Item Construct(Mobile from, int luckChance, bool spawning) { if (m_AtSpawnTime != spawning) @@ -641,7 +644,7 @@ namespace Server if (rnd < item.Chance) { - return Mutate(from, luckChance, item.Construct(IsInTokuno(from), IsMondain(from))); + return Mutate(from, luckChance, item.Construct(IsInTokuno(from), IsMondain(from), IsStygian(from))); } rnd -= item.Chance; @@ -970,18 +973,18 @@ namespace Server return Loot.RandomScroll(minCircle * 8, maxCircle * 8 + 7, SpellbookType.Regular); } - public Item Construct(bool inTokuno, bool isMondain) + public Item Construct(bool inTokuno, bool isMondain, bool isStygian) { try { if (Type == typeof(BaseRanged)) { - return Loot.RandomRangedWeapon(inTokuno, isMondain); + return Loot.RandomRangedWeapon(inTokuno, isMondain, isStygian); } if (Type == typeof(BaseWeapon)) { - return Loot.RandomWeapon(inTokuno, isMondain); + return Loot.RandomWeapon(inTokuno, isMondain, isStygian); } if (Type == typeof(BaseArmor))