feat(throwing): wire SA loot flavor + Valkyrie's Glaive stealable (#2512)
Phase 2 follow-up to #2510 — wires acquisition for the gargoyle Throwing content that Phase 1 deliberately left out. ## Changes - **SA loot flavor (`IsStygian`)** — completes the dead loot path from the original PR: adds `SAWeaponTypes`/`SARangedWeaponTypes` pools + `isStygian` branches to `Loot.RandomWeapon`/`RandomRangedWeapon`, **and** the missing piece — computes `IsStygian` (`map == Map.TerMur`) in `LootPackEntry.Construct` and threads it through `LootPackItem.Construct`. Ter Mur creatures now roll SA gear + the three throwing weapons (Boomerang/Cyclone/SoulGlaive) from their normal `BaseWeapon`/`BaseRanged` loot entries. Conservative `TerMur`-only (not ServUO's extra `|| RandomBool()`). - **Valkyrie's Glaive** — re-added as a self-contained Ter Mur stealable artifact at `(843, 665, 27)`, matching ServUO/OSI, with the previously-missing `ArtifactRarity => 5`. ## Deferred (documented) The 5 host-dependent artifacts (Raptor Claw, Stone Slith Claw, Storm Caller, Banshee's Call, Wind of Corruption) are intentionally NOT included — their OSI drop sources (Raptor, StoneSlith, and the renowned/boss creatures + a `BaseRenowned` artifact-list system) don't exist in ModernUO yet, so re-adding the items now would leave them `[add`-only. They'll follow a dedicated SA-creatures effort. ## Notes - No new tests: both changes are property/plumbing with RNG-driven output — no deterministic complex logic to assert (consistent with the repo's test-scope conventions). - Verified: server + test project compile; throwing suite 14/14.
This commit is contained in:
parent
e42a62b1d3
commit
8c6eab5fca
5 changed files with 66 additions and 7 deletions
|
|
@ -170,7 +170,10 @@ public class StealableArtifacts : GenericPersistence
|
|||
new(Map.Malas, new Point3D(157, 608, -1), 18432, 27648, typeof(SwordDisplay5WestArtifact)),
|
||||
new(Map.Malas, new Point3D(187, 643, 1), 18432, 27648, typeof(Painting6NorthArtifact)),
|
||||
new(Map.Malas, new Point3D(146, 623, 1), 18432, 27648, typeof(Painting6WestArtifact)),
|
||||
new(Map.Malas, new Point3D(178, 629, -1), 18432, 27648, typeof(ManStatuetteEastArtifact))
|
||||
new(Map.Malas, new Point3D(178, 629, -1), 18432, 27648, typeof(ManStatuetteEastArtifact)),
|
||||
|
||||
// Stygian Abyss (Ter Mur) - Artifact rarity 5
|
||||
new(Map.TerMur, new Point3D(843, 665, 27), 1152, 1728, typeof(ValkyriesGlaive))
|
||||
};
|
||||
|
||||
public static Type[] TypesOfEntries
|
||||
|
|
|
|||
26
Projects/UOContent/Items/Weapons/Throwing/ValkyriesGlaive.cs
Normal file
26
Projects/UOContent/Items/Weapons/Throwing/ValkyriesGlaive.cs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
using ModernUO.Serialization;
|
||||
|
||||
namespace Server.Items;
|
||||
|
||||
[SerializationGenerator(0)]
|
||||
public partial class ValkyriesGlaive : SoulGlaive
|
||||
{
|
||||
[Constructible]
|
||||
public ValkyriesGlaive()
|
||||
{
|
||||
Hue = 1651;
|
||||
Attributes.SpellChanneling = 1;
|
||||
Attributes.BonusStr = 5;
|
||||
Attributes.WeaponSpeed = 20;
|
||||
Attributes.WeaponDamage = 20;
|
||||
Slayer = SlayerName.Silver;
|
||||
WeaponAttributes.HitFireball = 40;
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1113531; // Valkyrie's Glaive
|
||||
|
||||
public override int ArtifactRarity => 5;
|
||||
|
||||
public override int InitMinHits => 255;
|
||||
public override int InitMaxHits => 255;
|
||||
}
|
||||
4
Projects/UOContent/Migrations/Server.Items.ValkyriesGlaive.v0.json
generated
Normal file
4
Projects/UOContent/Migrations/Server.Items.ValkyriesGlaive.v0.json
generated
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"version": 0,
|
||||
"type": "Server.Items.ValkyriesGlaive"
|
||||
}
|
||||
|
|
@ -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<BaseClothing>(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<BaseWeapon>(_saRangedWeaponTypes);
|
||||
}
|
||||
|
||||
if (Core.ML && isMondain)
|
||||
{
|
||||
return Construct<BaseWeapon>(_mlRangedWeaponTypes);
|
||||
|
|
@ -398,12 +415,18 @@ namespace Server
|
|||
return Construct<BaseWeapon>(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<BaseWeapon>(_saWeaponTypes);
|
||||
}
|
||||
|
||||
if (Core.ML && isMondain)
|
||||
{
|
||||
return Construct<BaseWeapon>(_mlWeaponTypes);
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue