From 2f6a0fad3a2468dd435f62dc05fb5162e15fb7ee Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 26 Mar 2022 21:15:15 -0700 Subject: [PATCH] fix: Codegens trappable containers (#973) Splits out trappable container so the logic is easier to expand. Changes trappable containers to be code genned. --- .../TrappableContainer.ExecuteTrap.cs | 146 +++++++++ .../Items/Containers/TrappableContainer.cs | 285 ++++-------------- .../Migrations/Server.Items.Talwar.v0.json | 4 - .../Server.Items.TrappableContainer.v3.json | 27 ++ 4 files changed, 234 insertions(+), 228 deletions(-) create mode 100644 Projects/UOContent/Items/Containers/TrappableContainer.ExecuteTrap.cs delete mode 100644 Projects/UOContent/Migrations/Server.Items.Talwar.v0.json create mode 100644 Projects/UOContent/Migrations/Server.Items.TrappableContainer.v3.json diff --git a/Projects/UOContent/Items/Containers/TrappableContainer.ExecuteTrap.cs b/Projects/UOContent/Items/Containers/TrappableContainer.ExecuteTrap.cs new file mode 100644 index 000000000..b4fef21d9 --- /dev/null +++ b/Projects/UOContent/Items/Containers/TrappableContainer.ExecuteTrap.cs @@ -0,0 +1,146 @@ +using System; +using System.Runtime.CompilerServices; +using Server.Network; + +namespace Server.Items; + +public partial class TrappableContainer +{ + public virtual bool ExecuteTrap(Mobile from) + { + if (_trapType == TrapType.None) + { + return false; + } + + if (from.AccessLevel >= AccessLevel.GameMaster) + { + SendMessageTo(from, "That is trapped, but you open it with your godly powers.", 0x3B2); + return false; + } + + SendMessageTo(from, 502999, 0x3B2); // You set off a trap! + + var loc = GetWorldLocation(); + + switch (_trapType) + { + case TrapType.ExplosionTrap: + { + ExecuteExplosionTrap(from, loc); + break; + } + case TrapType.MagicTrap: + { + ExecuteMagicTrap(from, loc); + break; + } + case TrapType.DartTrap: + { + ExecuteDartTrap(from, loc); + break; + } + case TrapType.PoisonTrap: + { + ExecutePoisonTrap(from, loc); + break; + } + } + + TrapType = TrapType.None; + TrapPower = 0; + TrapLevel = 0; + return true; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ExecuteExplosionTrap(Mobile from, Point3D loc) + { + var facet = Map; + if (from.InRange(loc, 3)) + { + int damage; + + if (_trapLevel > 0) + { + damage = Utility.RandomMinMax(10, 30) * _trapLevel; + } + else + { + damage = _trapPower; + } + + AOS.Damage(from, damage, 0, 100, 0, 0, 0); + + // Your skin blisters from the heat! + from.LocalOverheadMessage(MessageType.Regular, 0x2A, 503000); + } + + Effects.SendLocationEffect(loc, facet, 0x36BD, 15); + Effects.PlaySound(loc, facet, 0x307); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ExecuteMagicTrap(Mobile from, Point3D loc) + { + var facet = Map; + if (from.InRange(loc, 1)) + { + from.Damage(_trapPower); + } + + Effects.PlaySound(loc, facet, 0x307); + + Effects.SendLocationEffect(new Point3D(loc.X - 1, loc.Y, loc.Z), facet, 0x36BD, 15); + Effects.SendLocationEffect(new Point3D(loc.X + 1, loc.Y, loc.Z), facet, 0x36BD, 15); + + Effects.SendLocationEffect(new Point3D(loc.X, loc.Y - 1, loc.Z), facet, 0x36BD, 15); + Effects.SendLocationEffect(new Point3D(loc.X, loc.Y + 1, loc.Z), facet, 0x36BD, 15); + + Effects.SendLocationEffect(new Point3D(loc.X + 1, loc.Y + 1, loc.Z + 11), facet, 0x36BD, 15); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ExecuteDartTrap(Mobile from, Point3D loc) + { + if (from.InRange(loc, 3)) + { + var damage = _trapLevel > 0 ? Utility.RandomMinMax(5, 15) * _trapLevel : _trapPower; + + AOS.Damage(from, damage, 100, 0, 0, 0, 0); + + // A dart embeds itself in your flesh! + from.LocalOverheadMessage(MessageType.Regular, 0x62, 502998); + } + + Effects.PlaySound(loc, Map, 0x223); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ExecutePoisonTrap(Mobile from, Point3D loc) + { + var facet = Map; + if (from.InRange(loc, 3)) + { + Poison poison; + + if (_trapLevel > 0) + { + poison = Poison.GetPoison(Math.Max(0, Math.Min(4, _trapLevel - 1))); + } + else + { + AOS.Damage(from, _trapPower, 0, 0, 0, 100, 0); + poison = Poison.Greater; + } + + from.ApplyPoison(from, poison); + + // You are enveloped in a noxious green cloud! + from.LocalOverheadMessage(MessageType.Regular, 0x44, 503004); + } + + Effects.SendLocationEffect(loc, facet, 0x113A, 10, 20); + Effects.PlaySound(loc, facet, 0x231); + } +} diff --git a/Projects/UOContent/Items/Containers/TrappableContainer.cs b/Projects/UOContent/Items/Containers/TrappableContainer.cs index ac9398ae9..f4b4f51f7 100644 --- a/Projects/UOContent/Items/Containers/TrappableContainer.cs +++ b/Projects/UOContent/Items/Containers/TrappableContainer.cs @@ -1,243 +1,80 @@ -using System; using Server.Network; -namespace Server.Items +namespace Server.Items; + +public enum TrapType { - public enum TrapType + None, + MagicTrap, + ExplosionTrap, + DartTrap, + PoisonTrap +} + +[Serializable(3, false)] +public abstract partial class TrappableContainer : BaseContainer, ITelekinesisable +{ + [SerializableField(0)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private int _trapLevel; + + [SerializableField(1)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private int _trapPower; + + [SerializableField(2)] + [SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")] + private TrapType _trapType; + + public TrappableContainer(int itemID) : base(itemID) { - None, - MagicTrap, - ExplosionTrap, - DartTrap, - PoisonTrap } - public abstract class TrappableContainer : BaseContainer, ITelekinesisable + public virtual bool TrapOnOpen => true; + + public virtual void OnTelekinesis(Mobile from) { - public TrappableContainer(int itemID) : base(itemID) + Effects.SendLocationParticles(EffectItem.Create(Location, Map, EffectItem.DefaultDuration), 0x376A, 9, 32, 5022); + Effects.PlaySound(Location, Map, 0x1F5); + + if (TrapOnOpen) { + ExecuteTrap(from); + } + } + + private void SendMessageTo(Mobile to, int number, int hue) + { + if (Deleted || !to.CanSee(this)) + { + return; } - public TrappableContainer(Serial serial) : base(serial) + to.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Regular, hue, 3, number); + } + + private void SendMessageTo(Mobile to, string text, int hue) + { + if (Deleted || !to.CanSee(this)) { + return; } - [CommandProperty(AccessLevel.GameMaster)] - public TrapType TrapType { get; set; } + to.NetState.SendMessage(Serial, ItemID, MessageType.Regular, hue, 3, false, "ENU", "", text); + } - [CommandProperty(AccessLevel.GameMaster)] - public int TrapPower { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public int TrapLevel { get; set; } - - public virtual bool TrapOnOpen => true; - - public virtual void OnTelekinesis(Mobile from) + public override void Open(Mobile from) + { + if (!TrapOnOpen || !ExecuteTrap(from)) { - Effects.SendLocationParticles(EffectItem.Create(Location, Map, EffectItem.DefaultDuration), 0x376A, 9, 32, 5022); - Effects.PlaySound(Location, Map, 0x1F5); - - if (TrapOnOpen) - { - ExecuteTrap(from); - } + base.Open(from); } + } - private void SendMessageTo(Mobile to, int number, int hue) - { - if (Deleted || !to.CanSee(this)) - { - return; - } - - to.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Regular, hue, 3, number); - } - - private void SendMessageTo(Mobile to, string text, int hue) - { - if (Deleted || !to.CanSee(this)) - { - return; - } - - to.NetState.SendMessage(Serial, ItemID, MessageType.Regular, hue, 3, false, "ENU", "", text); - } - - public virtual bool ExecuteTrap(Mobile from) - { - if (TrapType != TrapType.None) - { - var loc = GetWorldLocation(); - var facet = Map; - - if (from.AccessLevel >= AccessLevel.GameMaster) - { - SendMessageTo(from, "That is trapped, but you open it with your godly powers.", 0x3B2); - return false; - } - - switch (TrapType) - { - case TrapType.ExplosionTrap: - { - SendMessageTo(from, 502999, 0x3B2); // You set off a trap! - - if (from.InRange(loc, 3)) - { - int damage; - - if (TrapLevel > 0) - { - damage = Utility.RandomMinMax(10, 30) * TrapLevel; - } - else - { - damage = TrapPower; - } - - AOS.Damage(from, damage, 0, 100, 0, 0, 0); - - // Your skin blisters from the heat! - from.LocalOverheadMessage(MessageType.Regular, 0x2A, 503000); - } - - Effects.SendLocationEffect(loc, facet, 0x36BD, 15); - Effects.PlaySound(loc, facet, 0x307); - - break; - } - case TrapType.MagicTrap: - { - if (from.InRange(loc, 1)) - { - from.Damage(TrapPower); - } - // AOS.Damage( from, m_TrapPower, 0, 100, 0, 0, 0 ); - - Effects.PlaySound(loc, Map, 0x307); - - Effects.SendLocationEffect(new Point3D(loc.X - 1, loc.Y, loc.Z), Map, 0x36BD, 15); - Effects.SendLocationEffect(new Point3D(loc.X + 1, loc.Y, loc.Z), Map, 0x36BD, 15); - - Effects.SendLocationEffect(new Point3D(loc.X, loc.Y - 1, loc.Z), Map, 0x36BD, 15); - Effects.SendLocationEffect(new Point3D(loc.X, loc.Y + 1, loc.Z), Map, 0x36BD, 15); - - Effects.SendLocationEffect(new Point3D(loc.X + 1, loc.Y + 1, loc.Z + 11), Map, 0x36BD, 15); - - break; - } - case TrapType.DartTrap: - { - SendMessageTo(from, 502999, 0x3B2); // You set off a trap! - - if (from.InRange(loc, 3)) - { - int damage; - - if (TrapLevel > 0) - { - damage = Utility.RandomMinMax(5, 15) * TrapLevel; - } - else - { - damage = TrapPower; - } - - AOS.Damage(from, damage, 100, 0, 0, 0, 0); - - // A dart imbeds itself in your flesh! - from.LocalOverheadMessage(MessageType.Regular, 0x62, 502998); - } - - Effects.PlaySound(loc, facet, 0x223); - - break; - } - case TrapType.PoisonTrap: - { - SendMessageTo(from, 502999, 0x3B2); // You set off a trap! - - if (from.InRange(loc, 3)) - { - Poison poison; - - if (TrapLevel > 0) - { - poison = Poison.GetPoison(Math.Max(0, Math.Min(4, TrapLevel - 1))); - } - else - { - AOS.Damage(from, TrapPower, 0, 0, 0, 100, 0); - poison = Poison.Greater; - } - - from.ApplyPoison(from, poison); - - // You are enveloped in a noxious green cloud! - from.LocalOverheadMessage(MessageType.Regular, 0x44, 503004); - } - - Effects.SendLocationEffect(loc, facet, 0x113A, 10, 20); - Effects.PlaySound(loc, facet, 0x231); - - break; - } - } - - TrapType = TrapType.None; - TrapPower = 0; - TrapLevel = 0; - return true; - } - - return false; - } - - public override void Open(Mobile from) - { - if (!TrapOnOpen || !ExecuteTrap(from)) - { - base.Open(from); - } - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(2); // version - - writer.Write(TrapLevel); - - writer.Write(TrapPower); - writer.Write((int)TrapType); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - switch (version) - { - case 2: - { - TrapLevel = reader.ReadInt(); - goto case 1; - } - case 1: - { - TrapPower = reader.ReadInt(); - goto case 0; - } - case 0: - { - TrapType = (TrapType)reader.ReadInt(); - break; - } - } - } + private void Deserialize(IGenericReader reader, int version) + { + _trapLevel = reader.ReadInt(); + _trapPower = reader.ReadInt(); + _trapType = (TrapType)reader.ReadInt(); } } diff --git a/Projects/UOContent/Migrations/Server.Items.Talwar.v0.json b/Projects/UOContent/Migrations/Server.Items.Talwar.v0.json deleted file mode 100644 index d69b5f76b..000000000 --- a/Projects/UOContent/Migrations/Server.Items.Talwar.v0.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "version": 0, - "type": "Server.Items.Talwar" -} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.TrappableContainer.v3.json b/Projects/UOContent/Migrations/Server.Items.TrappableContainer.v3.json new file mode 100644 index 000000000..83ddf011a --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.TrappableContainer.v3.json @@ -0,0 +1,27 @@ +{ + "version": 3, + "type": "Server.Items.TrappableContainer", + "properties": [ + { + "name": "TrapLevel", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "TrapPower", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "TrapType", + "type": "Server.Items.TrapType", + "rule": "EnumMigrationRule" + } + ] +} \ No newline at end of file