diff --git a/Projects/UOContent/Engines/Doom/GauntletSpawner.cs b/Projects/UOContent/Engines/Doom/GauntletSpawner.cs index 51abc207c..32f9e134b 100644 --- a/Projects/UOContent/Engines/Doom/GauntletSpawner.cs +++ b/Projects/UOContent/Engines/Doom/GauntletSpawner.cs @@ -1,461 +1,430 @@ using System; using System.Collections.Generic; +using ModernUO.Serialization; using Server.Items; using Server.Utilities; -namespace Server.Engines.Doom +namespace Server.Engines.Doom; + +public enum GauntletSpawnerState { - public enum GauntletSpawnerState + InSequence, + InProgress, + Completed +} + +[SerializationGenerator(2, false)] +public partial class GauntletSpawner : Item +{ + public const int PlayersPerSpawn = 5; + + public const int InSequenceItemHue = 0x000; + public const int InProgressItemHue = 0x676; + public const int CompletedItemHue = 0x455; + + [SerializableField(0)] + [SerializedCommandProperty(AccessLevel.GameMaster)] + private Rectangle2D _regionBounds; + + [SerializableField(1)] + [SerializedCommandProperty(AccessLevel.GameMaster)] + private List _traps; + + [SerializableField(2)] + [SerializedCommandProperty(AccessLevel.GameMaster)] + private List _creatures; + + [SerializableField(3)] + [SerializedCommandProperty(AccessLevel.GameMaster)] + private string _typeName; + + [SerializableField(4)] + [SerializedCommandProperty(AccessLevel.GameMaster)] + private BaseDoor _door; + + [SerializableField(5)] + [SerializedCommandProperty(AccessLevel.GameMaster)] + private BaseAddon _addon; + + [SerializableField(6)] + [SerializedCommandProperty(AccessLevel.GameMaster)] + private GauntletSpawner _sequence; + + private TimerExecutionToken _timerToken; + + [Constructible] + public GauntletSpawner(string typeName = null) : base(0x36FE) { - InSequence, - InProgress, - Completed + Visible = false; + Movable = false; + + TypeName = typeName; + Creatures = new List(); + Traps = new List(); } - public class GauntletSpawner : Item + [CommandProperty(AccessLevel.GameMaster)] + public bool HasCompleted { - public const int PlayersPerSpawn = 5; - - public const int InSequenceItemHue = 0x000; - public const int InProgressItemHue = 0x676; - public const int CompletedItemHue = 0x455; - - private GauntletSpawnerState m_State; - - private TimerExecutionToken _timerToken; - - [Constructible] - public GauntletSpawner(string typeName = null) : base(0x36FE) + get { - Visible = false; - Movable = false; - - TypeName = typeName; - Creatures = new List(); - Traps = new List(); - } - - public GauntletSpawner(Serial serial) : base(serial) - { - } - - [CommandProperty(AccessLevel.GameMaster)] - public string TypeName { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public BaseDoor Door { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public BaseAddon Addon { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public GauntletSpawner Sequence { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public bool HasCompleted - { - get + if (Creatures.Count == 0) { - if (Creatures.Count == 0) + return false; + } + + for (var i = 0; i < Creatures.Count; ++i) + { + var mob = Creatures[i]; + + if (!mob.Deleted) { return false; } - - for (var i = 0; i < Creatures.Count; ++i) - { - var mob = Creatures[i]; - - if (!mob.Deleted) - { - return false; - } - } - - return true; } + + return true; } + } - [CommandProperty(AccessLevel.GameMaster)] - public Rectangle2D RegionBounds { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public GauntletSpawnerState State + [SerializableProperty(7)] + [CommandProperty(AccessLevel.GameMaster)] + public GauntletSpawnerState State + { + get => _state; + set { - get => m_State; - set + if (_state != value) { - if (m_State != value) - { - m_State = value; - Update(); - } + _state = value; + Update(); } + + this.MarkDirty(); } + } - public List Creatures { get; set; } + public Region Region { get; set; } - public List Traps { get; set; } + private void Update(bool shouldSpawn = true) + { + var lockDoors = _state == GauntletSpawnerState.InProgress; - public Region Region { get; set; } - - private void Update(bool shouldSpawn = true) + var hue = _state switch { - var lockDoors = m_State == GauntletSpawnerState.InProgress; + GauntletSpawnerState.InSequence => InSequenceItemHue, + GauntletSpawnerState.InProgress => InProgressItemHue, + GauntletSpawnerState.Completed => CompletedItemHue, + _ => 0 + }; - var hue = m_State switch - { - GauntletSpawnerState.InSequence => InSequenceItemHue, - GauntletSpawnerState.InProgress => InProgressItemHue, - GauntletSpawnerState.Completed => CompletedItemHue, - _ => 0 - }; + if (Door != null) + { + Door.Hue = hue; + Door.Locked = lockDoors; - if (Door != null) + if (lockDoors) { - Door.Hue = hue; - Door.Locked = lockDoors; + Door.KeyValue = Key.RandomValue(); + Door.Open = false; + } + + if (Door.Link?.Deleted == false) + { + Door.Link.Hue = hue; + Door.Link.Locked = lockDoors; if (lockDoors) { - Door.KeyValue = Key.RandomValue(); + Door.Link.KeyValue = Key.RandomValue(); Door.Open = false; } - - if (Door.Link?.Deleted == false) - { - Door.Link.Hue = hue; - Door.Link.Locked = lockDoors; - - if (lockDoors) - { - Door.Link.KeyValue = Key.RandomValue(); - Door.Open = false; - } - } - } - - if (Addon != null) - { - Addon.Hue = hue; - } - - if (m_State == GauntletSpawnerState.InProgress) - { - CreateRegion(); - - if (shouldSpawn) - { - FullSpawn(); - } - - Timer.StartTimer(TimeSpan.FromSeconds(1.0), TimeSpan.FromSeconds(1.0), Slice, out _timerToken); - } - else - { - Stop(); } } - public override string DefaultName => "doom spawner"; - - public virtual void CreateRegion() + if (Addon != null) { - if (Region != null) - { - return; - } - - var map = Map; - - if (map == null || map == Map.Internal) - { - return; - } - - Region = new GauntletRegion(this, map); + Addon.Hue = hue; } - public void Stop() + if (_state == GauntletSpawnerState.InProgress) { - ClearCreatures(); - ClearTraps(); - DestroyRegion(); + CreateRegion(); - _timerToken.Cancel(); + if (shouldSpawn) + { + FullSpawn(); + } + + Timer.StartTimer(TimeSpan.FromSeconds(1.0), TimeSpan.FromSeconds(1.0), Slice, out _timerToken); } - - public override void OnDelete() + else { - base.OnDelete(); Stop(); - - Door?.Link?.Delete(); - Door?.Delete(); - Addon?.Delete(); - } - - public virtual void DestroyRegion() - { - Region?.Unregister(); - - Region = null; - } - - public virtual int ComputeTrapCount() - { - var area = RegionBounds.Width * RegionBounds.Height; - - return area / 100; - } - - public virtual void ClearTraps() - { - for (var i = 0; i < Traps.Count; ++i) - { - Traps[i].Delete(); - } - - Traps.Clear(); - } - - public virtual void SpawnTrap() - { - var map = Map; - - if (map == null) - { - return; - } - - var random = Utility.Random(100); - - BaseTrap trap = random switch - { - < 22 => new SawTrap(Utility.RandomBool() ? SawTrapType.WestFloor : SawTrapType.NorthFloor), - < 44 => new SpikeTrap(Utility.RandomBool() ? SpikeTrapType.WestFloor : SpikeTrapType.NorthFloor), - < 66 => new GasTrap(Utility.RandomBool() ? GasTrapType.NorthWall : GasTrapType.WestWall), - < 88 => new FireColumnTrap(), - _ => new MushroomTrap() - }; - - if (trap is FireColumnTrap or MushroomTrap) - { - trap.Hue = 0x451; - } - - // try 10 times to find a valid location - for (var i = 0; i < 10; ++i) - { - var x = Utility.Random(RegionBounds.X, RegionBounds.Width); - var y = Utility.Random(RegionBounds.Y, RegionBounds.Height); - var z = Z; - - if (!map.CanFit(x, y, z, 16, false, false)) - { - z = map.GetAverageZ(x, y); - } - - if (!map.CanFit(x, y, z, 16, false, false)) - { - continue; - } - - trap.MoveToWorld(new Point3D(x, y, z), map); - Traps.Add(trap); - - return; - } - - trap.Delete(); - } - - public virtual int ComputeSpawnCount() - { - var playerCount = 0; - - var map = Map; - - if (map != null) - { - var loc = GetWorldLocation(); - - var reg = Region.Find(loc, map).GetRegion("Doom Gauntlet"); - - if (reg != null) - { - playerCount = reg.GetPlayerCount(); - } - } - - if (playerCount == 0 && Region != null) - { - playerCount = Region.GetPlayerCount(); - } - - return Math.Max((playerCount + PlayersPerSpawn - 1) / PlayersPerSpawn, 1); - } - - public virtual void ClearCreatures() - { - for (var i = 0; i < Creatures.Count; ++i) - { - Creatures[i].Delete(); - } - - Creatures.Clear(); - } - - public virtual void FullSpawn() - { - ClearCreatures(); - - var count = ComputeSpawnCount(); - - for (var i = 0; i < count; ++i) - { - Spawn(); - } - - ClearTraps(); - - count = ComputeTrapCount(); - - for (var i = 0; i < count; ++i) - { - SpawnTrap(); - } - } - - public virtual void Spawn() - { - try - { - if (TypeName == null) - { - return; - } - - var type = AssemblyHandler.FindTypeByName(TypeName); - - if (type == null) - { - return; - } - - var mob = type.CreateEntityInstance(); - - if (mob != null) - { - mob.MoveToWorld(GetWorldLocation(), Map); - Creatures.Add(mob); - } - } - catch - { - // ignored - } - } - - public virtual void RecurseReset() - { - if (m_State != GauntletSpawnerState.InSequence) - { - State = GauntletSpawnerState.InSequence; - - if (Sequence?.Deleted == false) - { - Sequence.RecurseReset(); - } - } - } - - public virtual void Slice() - { - if (m_State != GauntletSpawnerState.InProgress) - { - return; - } - - var count = ComputeSpawnCount(); - - for (var i = Creatures.Count; i < count; ++i) - { - Spawn(); - } - - if (HasCompleted) - { - State = GauntletSpawnerState.Completed; - - if (Sequence?.Deleted == false) - { - if (Sequence.State == GauntletSpawnerState.Completed) - { - RecurseReset(); - } - - Sequence.State = GauntletSpawnerState.InProgress; - } - } - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(1); // version - - writer.Write(RegionBounds); - - writer.Write(Traps); - - writer.Write(Creatures); - - writer.Write(TypeName); - writer.Write(Door); - writer.Write(Addon); - writer.Write(Sequence); - - writer.Write((int)m_State); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - switch (version) - { - case 1: - { - RegionBounds = reader.ReadRect2D(); - Traps = reader.ReadEntityList(); - - goto case 0; - } - case 0: - { - if (version < 1) - { - Traps = new List(); - RegionBounds = new Rectangle2D(X - 40, Y - 40, 80, 80); - } - - Creatures = reader.ReadEntityList(); - - TypeName = reader.ReadString(); - Door = reader.ReadEntity(); - Addon = reader.ReadEntity(); - Sequence = reader.ReadEntity(); - - m_State = (GauntletSpawnerState)reader.ReadInt(); - - break; - } - } - - Timer.DelayCall(() => Update(false)); } } + + public override string DefaultName => "doom spawner"; + + public virtual void CreateRegion() + { + if (Region != null) + { + return; + } + + var map = Map; + + if (map == null || map == Map.Internal) + { + return; + } + + Region = new GauntletRegion(this, map); + } + + public void Stop() + { + ClearCreatures(); + ClearTraps(); + DestroyRegion(); + + _timerToken.Cancel(); + } + + public override void OnDelete() + { + base.OnDelete(); + Stop(); + + Door?.Link?.Delete(); + Door?.Delete(); + Addon?.Delete(); + } + + public virtual void DestroyRegion() + { + Region?.Unregister(); + + Region = null; + } + + public virtual int ComputeTrapCount() + { + var area = RegionBounds.Width * RegionBounds.Height; + + return area / 100; + } + + public virtual void ClearTraps() + { + for (var i = 0; i < Traps.Count; ++i) + { + Traps[i].Delete(); + } + + Traps.Clear(); + } + + public virtual void SpawnTrap() + { + var map = Map; + + if (map == null) + { + return; + } + + var random = Utility.Random(100); + + BaseTrap trap = random switch + { + < 22 => new SawTrap(Utility.RandomBool() ? SawTrapType.WestFloor : SawTrapType.NorthFloor), + < 44 => new SpikeTrap(Utility.RandomBool() ? SpikeTrapType.WestFloor : SpikeTrapType.NorthFloor), + < 66 => new GasTrap(Utility.RandomBool() ? GasTrapType.NorthWall : GasTrapType.WestWall), + < 88 => new FireColumnTrap(), + _ => new MushroomTrap() + }; + + if (trap is FireColumnTrap or MushroomTrap) + { + trap.Hue = 0x451; + } + + // try 10 times to find a valid location + for (var i = 0; i < 10; ++i) + { + var x = Utility.Random(RegionBounds.X, RegionBounds.Width); + var y = Utility.Random(RegionBounds.Y, RegionBounds.Height); + var z = Z; + + if (!map.CanFit(x, y, z, 16, false, false)) + { + z = map.GetAverageZ(x, y); + } + + if (!map.CanFit(x, y, z, 16, false, false)) + { + continue; + } + + trap.MoveToWorld(new Point3D(x, y, z), map); + Traps.Add(trap); + + return; + } + + trap.Delete(); + } + + public virtual int ComputeSpawnCount() + { + var playerCount = 0; + + var map = Map; + + if (map != null) + { + var loc = GetWorldLocation(); + + var reg = Region.Find(loc, map).GetRegion("Doom Gauntlet"); + + if (reg != null) + { + playerCount = reg.GetPlayerCount(); + } + } + + if (playerCount == 0 && Region != null) + { + playerCount = Region.GetPlayerCount(); + } + + return Math.Max((playerCount + PlayersPerSpawn - 1) / PlayersPerSpawn, 1); + } + + public virtual void ClearCreatures() + { + for (var i = 0; i < Creatures.Count; ++i) + { + Creatures[i].Delete(); + } + + Creatures.Clear(); + } + + public virtual void FullSpawn() + { + ClearCreatures(); + + var count = ComputeSpawnCount(); + + for (var i = 0; i < count; ++i) + { + Spawn(); + } + + ClearTraps(); + + count = ComputeTrapCount(); + + for (var i = 0; i < count; ++i) + { + SpawnTrap(); + } + } + + public virtual void Spawn() + { + try + { + if (TypeName == null) + { + return; + } + + var type = AssemblyHandler.FindTypeByName(TypeName); + + if (type == null) + { + return; + } + + var mob = type.CreateEntityInstance(); + + if (mob != null) + { + mob.MoveToWorld(GetWorldLocation(), Map); + Creatures.Add(mob); + } + } + catch + { + // ignored + } + } + + public virtual void RecurseReset() + { + if (_state != GauntletSpawnerState.InSequence) + { + State = GauntletSpawnerState.InSequence; + + if (Sequence?.Deleted == false) + { + Sequence.RecurseReset(); + } + } + } + + public virtual void Slice() + { + if (_state != GauntletSpawnerState.InProgress) + { + return; + } + + var count = ComputeSpawnCount(); + + for (var i = Creatures.Count; i < count; ++i) + { + Spawn(); + } + + if (HasCompleted) + { + State = GauntletSpawnerState.Completed; + + if (Sequence?.Deleted == false) + { + if (Sequence.State == GauntletSpawnerState.Completed) + { + RecurseReset(); + } + + Sequence.State = GauntletSpawnerState.InProgress; + } + } + } + + private void Deserialize(IGenericReader reader, int version) + { + RegionBounds = reader.ReadRect2D(); + Traps = reader.ReadEntityList(); + + Creatures = reader.ReadEntityList(); + + TypeName = reader.ReadString(); + Door = reader.ReadEntity(); + Addon = reader.ReadEntity(); + Sequence = reader.ReadEntity(); + + _state = (GauntletSpawnerState)reader.ReadInt(); + } + + [AfterDeserialization(false)] + private void AfterDeserialization() + { + Update(false); + } } diff --git a/Projects/UOContent/Engines/Doom/LeverPuzzle/LeverPuzzleController.cs b/Projects/UOContent/Engines/Doom/LeverPuzzle/LeverPuzzleController.cs index 5ca64e0cb..095ed7727 100644 --- a/Projects/UOContent/Engines/Doom/LeverPuzzle/LeverPuzzleController.cs +++ b/Projects/UOContent/Engines/Doom/LeverPuzzle/LeverPuzzleController.cs @@ -1,750 +1,734 @@ using System; using System.Collections.Generic; +using ModernUO.Serialization; using Server.Mobiles; using Server.Network; using Server.Spells; -namespace Server.Engines.Doom +namespace Server.Engines.Doom; + +[SerializationGenerator(0, false)] +public partial class LeverPuzzleController : Item { - public class LeverPuzzleController : Item + private static bool installed; + + public static string[] Msgs = { - private static bool installed; + "You are pinned down by the weight of the boulder!!!", // 0 + "A speeding rock hits you in the head!", // 1 + "OUCH!" // 2 + }; + /* font&hue for above msgs. index matches */ - public static string[] Msgs = + public static int[][] MsgParams = + { + new[] { 0x66d, 3 }, + new[] { 0x66d, 3 }, + new[] { 0x34, 3 } + }; + /* World data for items */ + + public static int[][] TA = + { + new[] { 316, 64, 5 }, /* 3D Coords for levers */ + new[] { 323, 58, 5 }, + new[] { 332, 63, 5 }, + new[] { 323, 71, 5 }, + + new[] { 324, 64 }, /* 2D Coords for standing regions */ + new[] { 316, 65 }, + new[] { 324, 58 }, + new[] { 332, 64 }, + new[] { 323, 72 }, + + new[] { 468, 92, -1 }, new[] { 0x181D, 0x482 }, /* 3D coord, itemid+hue for L.R. teles */ + new[] { 469, 92, -1 }, new[] { 0x1821, 0x3fd }, + new[] { 470, 92, -1 }, new[] { 0x1825, 0x66d }, + + new[] { 319, 70, 18 }, new[] { 0x12d8 }, /* 3D coord, itemid for statues */ + new[] { 329, 60, 18 }, new[] { 0x12d9 }, + + new[] { 469, 96, 6 } /* 3D Coords for Fake Box */ + }; + + /* CLILOC data for statue "correct souls" messages */ + + public static int[] Statue_Msg = { 1050009, 1050007, 1050008, 1050008 }; + + /* Exit & Enter locations for the lamp room */ + + public static Point3D lr_Exit = new(353, 172, -1); + public static Point3D lr_Enter = new(467, 96, -1); + + /* "Center" location in puzzle */ + + public static Point3D lp_Center = new(324, 64, -1); + + /* Lamp Room Area */ + + public static Rectangle2D lr_Rect = new(465, 92, 10, 10); + + /* Lamp Room area Poison message data */ + + public static int[][] PA = + { + new[] { 0, 0, 0xA6 }, + new[] { 1050001, 0x485, 0xAA }, + new[] { 1050003, 0x485, 0xAC }, + new[] { 1050056, 0x485, 0xA8 }, + new[] { 1050057, 0x485, 0xA4 }, + new[] { 1062091, 0x23F3, 0xAC } + }; + + public static Poison[] PA2 = + { + Poison.Lesser, + Poison.Regular, + Poison.Greater, + Poison.Deadly, + Poison.Lethal, + Poison.Lethal + }; + + /* SOUNDS */ + + private static readonly int[] fs = { 0x144, 0x154 }; + private static readonly int[] ms = { 0x144, 0x14B }; + private static readonly int[] fs2 = { 0x13F, 0x154 }; + private static readonly int[] ms2 = { 0x13F, 0x14B }; + private static readonly int[] cs1 = { 0x244 }; + private static readonly int[] exp = { 0x307 }; + private TimerExecutionToken _resetTimerToken; + private Region _lampRoom; + + [SerializableField(0, getter: "private", setter: "private")] + private List _levers; + + [SerializableField(1, getter: "private", setter: "private")] + private List _statues; + + [SerializableField(2, getter: "private", setter: "private")] + private List _teles; + + [SerializableField(3, getter: "private", setter: "private")] + private LampRoomBox _box; + + private List _tiles; + + private Timer m_Timer; + + public LeverPuzzleController() : base(0x1822) + { + Movable = false; + Hue = 0x4c; + installed = true; + var i = 0; + + _levers = new List(); /* codes are 0x1 shifted left x # of bits, easily handled here */ + for (; i < 4; i++) { - "You are pinned down by the weight of the boulder!!!", // 0 - "A speeding rock hits you in the head!", // 1 - "OUCH!" // 2 - }; - /* font&hue for above msgs. index matches */ - - public static int[][] MsgParams = - { - new[] { 0x66d, 3 }, - new[] { 0x66d, 3 }, - new[] { 0x34, 3 } - }; - /* World data for items */ - - public static int[][] TA = - { - new[] { 316, 64, 5 }, /* 3D Coords for levers */ - new[] { 323, 58, 5 }, - new[] { 332, 63, 5 }, - new[] { 323, 71, 5 }, - - new[] { 324, 64 }, /* 2D Coords for standing regions */ - new[] { 316, 65 }, - new[] { 324, 58 }, - new[] { 332, 64 }, - new[] { 323, 72 }, - - new[] { 468, 92, -1 }, new[] { 0x181D, 0x482 }, /* 3D coord, itemid+hue for L.R. teles */ - new[] { 469, 92, -1 }, new[] { 0x1821, 0x3fd }, - new[] { 470, 92, -1 }, new[] { 0x1825, 0x66d }, - - new[] { 319, 70, 18 }, new[] { 0x12d8 }, /* 3D coord, itemid for statues */ - new[] { 329, 60, 18 }, new[] { 0x12d9 }, - - new[] { 469, 96, 6 } /* 3D Coords for Fake Box */ - }; - - /* CLILOC data for statue "correct souls" messages */ - - public static int[] Statue_Msg = { 1050009, 1050007, 1050008, 1050008 }; - - /* Exit & Enter locations for the lamp room */ - - public static Point3D lr_Exit = new(353, 172, -1); - public static Point3D lr_Enter = new(467, 96, -1); - - /* "Center" location in puzzle */ - - public static Point3D lp_Center = new(324, 64, -1); - - /* Lamp Room Area */ - - public static Rectangle2D lr_Rect = new(465, 92, 10, 10); - - /* Lamp Room area Poison message data */ - - public static int[][] PA = - { - new[] { 0, 0, 0xA6 }, - new[] { 1050001, 0x485, 0xAA }, - new[] { 1050003, 0x485, 0xAC }, - new[] { 1050056, 0x485, 0xA8 }, - new[] { 1050057, 0x485, 0xA4 }, - new[] { 1062091, 0x23F3, 0xAC } - }; - - public static Poison[] PA2 = - { - Poison.Lesser, - Poison.Regular, - Poison.Greater, - Poison.Deadly, - Poison.Lethal, - Poison.Lethal - }; - - /* SOUNDS */ - - private static readonly int[] fs = { 0x144, 0x154 }; - private static readonly int[] ms = { 0x144, 0x14B }; - private static readonly int[] fs2 = { 0x13F, 0x154 }; - private static readonly int[] ms2 = { 0x13F, 0x14B }; - private static readonly int[] cs1 = { 0x244 }; - private static readonly int[] exp = { 0x307 }; - private TimerExecutionToken _resetTimerToken; - private LampRoomBox m_Box; - private Region m_LampRoom; - - private List m_Levers; - private List m_Statues; - private List m_Teles; - private List m_Tiles; - - private Timer m_Timer; - - public LeverPuzzleController() : base(0x1822) - { - Movable = false; - Hue = 0x4c; - installed = true; - var i = 0; - - m_Levers = new List(); /* codes are 0x1 shifted left x # of bits, easily handled here */ - for (; i < 4; i++) - { - m_Levers.Add(AddLeverPuzzlePart(TA[i], new LeverPuzzleLever((ushort)(1 << i), this))); - } - - m_Tiles = new List(); - for (; i < 9; i++) - { - m_Tiles.Add(new LeverPuzzleRegion(TA[i])); - } - - m_Teles = new List(); - for (; i < 15; i++) - { - m_Teles.Add(AddLeverPuzzlePart(TA[i], new LampRoomTeleporter(TA[++i]))); - } - - m_Statues = new List(); - for (; i < 19; i++) - { - m_Statues.Add(AddLeverPuzzlePart(TA[i], new LeverPuzzleStatue(TA[++i], this))); - } - - if (!installed) - { - Delete(); - } - else - { - Enabled = true; - } - - m_Box = (LampRoomBox)AddLeverPuzzlePart(TA[i], new LampRoomBox(this)); - m_LampRoom = new LampRoomRegion(this); - GenKey(); + _levers.Add(AddLeverPuzzlePart(TA[i], new LeverPuzzleLever((ushort)(1 << i), this))); } - public LeverPuzzleController(Serial serial) : base(serial) + _tiles = new List(); + for (; i < 9; i++) { + _tiles.Add(new LeverPuzzleRegion(TA[i])); } - [CommandProperty(AccessLevel.GameMaster)] - public ushort MyKey { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public ushort TheirKey { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public bool Enabled { get; set; } - - public Mobile Successful { get; private set; } - - public bool CircleComplete + _teles = new List(); + for (; i < 15; i++) { - get /* OSI: all 5 must be occupied */ + _teles.Add(AddLeverPuzzlePart(TA[i], new LampRoomTeleporter(TA[++i]))); + } + + _statues = new List(); + for (; i < 19; i++) + { + _statues.Add(AddLeverPuzzlePart(TA[i], new LeverPuzzleStatue(TA[++i], this))); + } + + if (!installed) + { + Delete(); + } + else + { + Enabled = true; + } + + _box = (LampRoomBox)AddLeverPuzzlePart(TA[i], new LampRoomBox(this)); + _lampRoom = new LampRoomRegion(this); + GenKey(); + } + + [CommandProperty(AccessLevel.GameMaster)] + public ushort MyKey { get; set; } + + [CommandProperty(AccessLevel.GameMaster)] + public ushort TheirKey { get; set; } + + [CommandProperty(AccessLevel.GameMaster)] + public bool Enabled { get; set; } + + public Mobile Successful { get; private set; } + + public bool CircleComplete + { + get /* OSI: all 5 must be occupied */ + { + for (var i = 0; i < 5; i++) { - for (var i = 0; i < 5; i++) + if (GetOccupant(i) == null) { - if (GetOccupant(i) == null) - { - return false; - } - } - - return true; - } - } - - public static void Initialize() - { - CommandSystem.Register("GenLeverPuzzle", AccessLevel.Administrator, GenLampPuzzle_OnCommand); - } - - [Usage("GenLeverPuzzle"), Description("Generates lamp room and lever puzzle in doom.")] - public static void GenLampPuzzle_OnCommand(CommandEventArgs e) - { - var eable = Map.Malas.GetItemsInRange(lp_Center, 0); - - foreach (var item in eable) - { - if (item is LeverPuzzleController) - { - eable.Free(); - e.Mobile.SendMessage("Lamp room puzzle already exists: please delete the existing controller first ..."); - return; + return false; } } - eable.Free(); - - e.Mobile.SendMessage("Generating Lamp Room puzzle..."); - - NetState.FlushAll(); - - new LeverPuzzleController().MoveToWorld(lp_Center, Map.Malas); - - e.Mobile.SendMessage( - !installed ? "There was a problem generating the puzzle." : "Lamp room puzzle successfully generated." - ); + return true; } + } - public static Item AddLeverPuzzlePart(int[] loc, Item newitem) + public static void Initialize() + { + CommandSystem.Register("GenLeverPuzzle", AccessLevel.Administrator, GenLampPuzzle_OnCommand); + } + + [Usage("GenLeverPuzzle"), Description("Generates lamp room and lever puzzle in doom.")] + public static void GenLampPuzzle_OnCommand(CommandEventArgs e) + { + var eable = Map.Malas.GetItemsInRange(lp_Center, 0); + + foreach (var item in eable) { - if (newitem?.Deleted != false) + if (item is LeverPuzzleController) { - installed = false; - } - else - { - newitem.MoveToWorld(new Point3D(loc[0], loc[1], loc[2]), Map.Malas); - } - - return newitem; - } - - public override void OnDelete() - { - KillTimers(); - base.OnDelete(); - } - - public override void OnAfterDelete() - { - NukeItemList(m_Teles); - NukeItemList(m_Statues); - NukeItemList(m_Levers); - - m_LampRoom?.Unregister(); - if (m_Tiles != null) - { - foreach (var region in m_Tiles) - { - region.Unregister(); - } - } - - if (m_Box?.Deleted == false) - { - m_Box.Delete(); - } - } - - public static void NukeItemList(List list) - { - if (list?.Count > 0) - { - foreach (var item in list) - { - if (item?.Deleted == false) - { - item.Delete(); - } - } - } - } - - public virtual PlayerMobile GetOccupant(int index) - { - var region = m_Tiles[index]; - - if (region?.Occupant?.Alive == true) - { - return (PlayerMobile)region.Occupant; - } - - return null; - } - - public virtual LeverPuzzleStatue GetStatue(int index) - { - var statue = (LeverPuzzleStatue)m_Statues[index]; - return statue?.Deleted == false ? statue : null; - } - - public virtual LeverPuzzleLever GetLever(int index) - { - var lever = (LeverPuzzleLever)m_Levers[index]; - - return lever?.Deleted == false ? lever : null; - } - - public virtual void PuzzleStatus(int message, string fstring = null) - { - for (var i = 0; i < 2; i++) - { - Item s; - if ((s = GetStatue(i)) != null) - { - s.PublicOverheadMessage(MessageType.Regular, 0x3B2, message, fstring); - } - } - } - - public virtual void ResetPuzzle() - { - PuzzleStatus(1062053); - ResetLevers(); - } - - public virtual void ResetLevers() - { - for (var i = 0; i < 4; i++) - { - Item l; - if ((l = GetLever(i)) != null) - { - l.ItemID = 0x108E; - Effects.PlaySound(l.Location, Map, 0x3E8); - } - } - - TheirKey ^= TheirKey; - } - - public virtual void KillTimers() - { - _resetTimerToken.Cancel(); - m_Timer?.Stop(); - } - - public virtual void RemoveSuccessful() - { - Successful = null; - } - - public virtual void LeverPulled(ushort code) - { - var correct = 0; - - KillTimers(); - - /* if one bit in each of the four nibbles is set, this is false */ - - if ((TheirKey = (ushort)(code | (TheirKey <<= 4))) < 0x0FFF) - { - Timer.StartTimer(TimeSpan.FromSeconds(30.0), ResetPuzzle, out _resetTimerToken); + eable.Free(); + e.Mobile.SendMessage("Lamp room puzzle already exists: please delete the existing controller first ..."); return; } + } - if (!CircleComplete) + eable.Free(); + + e.Mobile.SendMessage("Generating Lamp Room puzzle..."); + + NetState.FlushAll(); + + new LeverPuzzleController().MoveToWorld(lp_Center, Map.Malas); + + e.Mobile.SendMessage( + !installed ? "There was a problem generating the puzzle." : "Lamp room puzzle successfully generated." + ); + } + + public static Item AddLeverPuzzlePart(int[] loc, Item newitem) + { + if (newitem?.Deleted != false) + { + installed = false; + } + else + { + newitem.MoveToWorld(new Point3D(loc[0], loc[1], loc[2]), Map.Malas); + } + + return newitem; + } + + public override void OnDelete() + { + KillTimers(); + base.OnDelete(); + } + + public override void OnAfterDelete() + { + NukeItemList(_teles); + NukeItemList(_statues); + NukeItemList(_levers); + + _lampRoom?.Unregister(); + if (_tiles != null) + { + foreach (var region in _tiles) { - PuzzleStatus(1050004); // The circle is the key... + region.Unregister(); + } + } + + if (_box?.Deleted == false) + { + _box.Delete(); + } + } + + public static void NukeItemList(List list) + { + if (list?.Count > 0) + { + foreach (var item in list) + { + if (item?.Deleted == false) + { + item.Delete(); + } + } + } + } + + public virtual PlayerMobile GetOccupant(int index) + { + var region = _tiles[index]; + + if (region?.Occupant?.Alive == true) + { + return (PlayerMobile)region.Occupant; + } + + return null; + } + + public virtual LeverPuzzleStatue GetStatue(int index) + { + var statue = (LeverPuzzleStatue)_statues[index]; + return statue?.Deleted == false ? statue : null; + } + + public virtual LeverPuzzleLever GetLever(int index) + { + var lever = (LeverPuzzleLever)_levers[index]; + + return lever?.Deleted == false ? lever : null; + } + + public virtual void PuzzleStatus(int message, string fstring = null) + { + for (var i = 0; i < 2; i++) + { + Item s; + if ((s = GetStatue(i)) != null) + { + s.PublicOverheadMessage(MessageType.Regular, 0x3B2, message, fstring); + } + } + } + + public virtual void ResetPuzzle() + { + PuzzleStatus(1062053); + ResetLevers(); + } + + public virtual void ResetLevers() + { + for (var i = 0; i < 4; i++) + { + Item l; + if ((l = GetLever(i)) != null) + { + l.ItemID = 0x108E; + Effects.PlaySound(l.Location, Map, 0x3E8); + } + } + + TheirKey ^= TheirKey; + } + + public virtual void KillTimers() + { + _resetTimerToken.Cancel(); + m_Timer?.Stop(); + } + + public virtual void RemoveSuccessful() + { + Successful = null; + } + + public virtual void LeverPulled(ushort code) + { + var correct = 0; + + KillTimers(); + + /* if one bit in each of the four nibbles is set, this is false */ + + if ((TheirKey = (ushort)(code | (TheirKey <<= 4))) < 0x0FFF) + { + Timer.StartTimer(TimeSpan.FromSeconds(30.0), ResetPuzzle, out _resetTimerToken); + return; + } + + if (!CircleComplete) + { + PuzzleStatus(1050004); // The circle is the key... + } + else + { + Mobile player; + if (TheirKey == MyKey) + { + GenKey(); + if ((Successful = player = GetOccupant(0)) != null) + { + SendLocationEffect(lp_Center, 0x1153, 0, 60, 1); + PlaySounds(lp_Center, cs1); + + Effects.SendBoltEffect(player); + player.MoveToWorld(lr_Enter, Map.Malas); + + m_Timer = new LampRoomTimer(this); + m_Timer.Start(); + Enabled = false; + } } else { - Mobile player; - if (TheirKey == MyKey) + for (var i = 0; i < 16; i++) /* Count matching SET bits, ie correct codes */ { - GenKey(); - if ((Successful = player = GetOccupant(0)) != null) + if (((MyKey >> i) & 1) == 1 && ((TheirKey >> i) & 1) == 1) { - SendLocationEffect(lp_Center, 0x1153, 0, 60, 1); - PlaySounds(lp_Center, cs1); - - Effects.SendBoltEffect(player); - player.MoveToWorld(lr_Enter, Map.Malas); - - m_Timer = new LampRoomTimer(this); - m_Timer.Start(); - Enabled = false; + correct++; } } - else + + PuzzleStatus(Statue_Msg[correct], correct > 0 ? correct.ToString() : null); + + for (var i = 0; i < 5; i++) { - for (var i = 0; i < 16; i++) /* Count matching SET bits, ie correct codes */ + if ((player = GetOccupant(i)) != null) { - if (((MyKey >> i) & 1) == 1 && ((TheirKey >> i) & 1) == 1) - { - correct++; - } - } - - PuzzleStatus(Statue_Msg[correct], correct > 0 ? correct.ToString() : null); - - for (var i = 0; i < 5; i++) - { - if ((player = GetOccupant(i)) != null) - { - new RockTimer(player).Start(); - } + new RockTimer(player).Start(); } } } - - ResetLevers(); } - public virtual void GenKey() + ResetLevers(); + } + + public virtual void GenKey() + { + Span ca = stackalloc ushort[] { 1, 2, 4, 8 }; + ca.Shuffle(); + + for (var i = 0; i < 4; i++) { - Span ca = stackalloc ushort[] { 1, 2, 4, 8 }; - ca.Shuffle(); - - for (var i = 0; i < 4; i++) - { - MyKey = (ushort)(ca[i] | (MyKey <<= 4)); - } + MyKey = (ushort)(ca[i] | (MyKey <<= 4)); } + } - private static bool IsValidDamagable(Mobile m) => - m?.Deleted == false && - (m.Player && m.Alive || - m is BaseCreature bc && (bc.Controlled || bc.Summoned) && !bc.IsDeadBondedPet); + private static bool IsValidDamagable(Mobile m) => + m?.Deleted == false && + (m.Player && m.Alive || + m is BaseCreature bc && (bc.Controlled || bc.Summoned) && !bc.IsDeadBondedPet); - public static void MoveMobileOut(Mobile m) + public static void MoveMobileOut(Mobile m) + { + if (m != null) { - if (m != null) + if (m is PlayerMobile && !m.Alive && m.Corpse?.Deleted == false) { - if (m is PlayerMobile && !m.Alive && m.Corpse?.Deleted == false) - { - m.Corpse.MoveToWorld(lr_Exit, Map.Malas); - } - - BaseCreature.TeleportPets(m, lr_Exit, Map.Malas); - m.Location = lr_Exit; - m.ProcessDelta(); + m.Corpse.MoveToWorld(lr_Exit, Map.Malas); } + + BaseCreature.TeleportPets(m, lr_Exit, Map.Malas); + m.Location = lr_Exit; + m.ProcessDelta(); } + } - public static bool AniSafe(Mobile m) => - m?.BodyMod == 0 && m.Alive && !TransformationSpellHelper.UnderTransformation(m); + public static bool AniSafe(Mobile m) => + m?.BodyMod == 0 && m.Alive && !TransformationSpellHelper.UnderTransformation(m); - public static IEntity ZAdjustedIEFromMobile(Mobile m, int zDelta) => new Entity( - Serial.Zero, - new Point3D(m.X, m.Y, m.Z + zDelta), - m.Map + public static IEntity ZAdjustedIEFromMobile(Mobile m, int zDelta) => new Entity( + Serial.Zero, + new Point3D(m.X, m.Y, m.Z + zDelta), + m.Map + ); + + public static void DoDamage(Mobile m, int min, int max, bool poison) + { + if (m?.Deleted == false && m.Alive) + { + var damage = Utility.Random(min, max); + AOS.Damage(m, damage, poison ? 0 : 100, 0, 0, poison ? 100 : 0, 0); + } + } + + public static Point3D RandomPointIn(Point3D point, int range) => RandomPointIn( + point.X - range, + point.Y - range, + range * 2, + range * 2, + point.Z + ); + + public static Point3D RandomPointIn(Rectangle2D rect, int z) => + RandomPointIn(rect.X, rect.Y, rect.Height, rect.Width, z); + + public static Point3D RandomPointIn(int x, int y, int x2, int y2, int z) => + new(Utility.Random(x, x2), Utility.Random(y, y2), z); + + public static void PlaySounds(Point3D location, int[] sounds) + { + foreach (var soundid in sounds) + { + Effects.PlaySound(location, Map.Malas, soundid); + } + } + + private static void PlayEffect(IEntity from, IEntity to, int itemid, int speed, bool explodes) + { + Effects.SendMovingParticles(from, to, itemid, speed, 0, true, explodes, 2, 0, 0); + } + + private static void SendLocationEffect(Point3D p, int itemID, int speed, int duration, int hue) + { + Effects.SendLocationEffect(p, Map.Malas, itemID, speed, duration, hue); + } + + public static void PlayerSendASCII(Mobile player, int index) + { + player.NetState.SendMessage( + Serial.MinusOne, + 0xFFFF, + MessageType.Label, + MsgParams[index][0], + MsgParams[index][1], + true, + null, + null, + Msgs[index] ); + } - public static void DoDamage(Mobile m, int min, int max, bool poison) + /* I cant find any better way to send "speech" using fonts other than default */ + public static void POHMessage(Mobile from, int index) + { + Span buffer = stackalloc byte[OutgoingMessagePackets.GetMaxMessageLength(Msgs[index])].InitializePacket(); + + var eable = from.Map.GetClientsInRange(from.Location); + + foreach (var state in eable) { - if (m?.Deleted == false && m.Alive) - { - var damage = Utility.Random(min, max); - AOS.Damage(m, damage, poison ? 0 : 100, 0, 0, poison ? 100 : 0, 0); - } - } - - public static Point3D RandomPointIn(Point3D point, int range) => RandomPointIn( - point.X - range, - point.Y - range, - range * 2, - range * 2, - point.Z - ); - - public static Point3D RandomPointIn(Rectangle2D rect, int z) => - RandomPointIn(rect.X, rect.Y, rect.Height, rect.Width, z); - - public static Point3D RandomPointIn(int x, int y, int x2, int y2, int z) => - new(Utility.Random(x, x2), Utility.Random(y, y2), z); - - public static void PlaySounds(Point3D location, int[] sounds) - { - foreach (var soundid in sounds) - { - Effects.PlaySound(location, Map.Malas, soundid); - } - } - - private static void PlayEffect(IEntity from, IEntity to, int itemid, int speed, bool explodes) - { - Effects.SendMovingParticles(from, to, itemid, speed, 0, true, explodes, 2, 0, 0); - } - - private static void SendLocationEffect(Point3D p, int itemID, int speed, int duration, int hue) - { - Effects.SendLocationEffect(p, Map.Malas, itemID, speed, duration, hue); - } - - public static void PlayerSendASCII(Mobile player, int index) - { - player.NetState.SendMessage( - Serial.MinusOne, - 0xFFFF, - MessageType.Label, + var length = OutgoingMessagePackets.CreateMessage( + buffer, + from.Serial, + from.Body, + MessageType.Regular, MsgParams[index][0], MsgParams[index][1], true, null, - null, + from.Name, Msgs[index] ); + + if (length != buffer.Length) + { + buffer = buffer[..length]; // Adjust to the actual size + } + + state.Send(buffer); } - /* I cant find any better way to send "speech" using fonts other than default */ - public static void POHMessage(Mobile from, int index) + eable.Free(); + } + + private void Deserialize(IGenericReader reader, int version) + { + _levers = reader.ReadEntityList(); + _statues = reader.ReadEntityList(); + _teles = reader.ReadEntityList(); + _box = reader.ReadEntity(); + } + + [AfterDeserialization] + private void AfterDeserialization() + { + _tiles = new List(); + for (var i = 4; i < 9; i++) { - Span buffer = stackalloc byte[OutgoingMessagePackets.GetMaxMessageLength(Msgs[index])].InitializePacket(); + _tiles.Add(new LeverPuzzleRegion(TA[i])); + } - var eable = from.Map.GetClientsInRange(from.Location); + _lampRoom = new LampRoomRegion(this); + Enabled = true; + TheirKey = 0; + MyKey = 0; + GenKey(); + } - foreach (var state in eable) + public class RockTimer : Timer + { + private readonly Mobile m_Player; + private int Count; + + public RockTimer(Mobile player) : base(TimeSpan.Zero, TimeSpan.FromSeconds(.25)) + { + Count = 0; + m_Player = player; + } + + private int Rock() => 0x1363 + Utility.Random(0, 11); + + protected override void OnTick() + { + if (m_Player == null || m_Player.Map != Map.Malas) { - var length = OutgoingMessagePackets.CreateMessage( - buffer, - from.Serial, - from.Body, - MessageType.Regular, - MsgParams[index][0], - MsgParams[index][1], - true, - null, - from.Name, - Msgs[index] - ); - - if (length != buffer.Length) + Stop(); + } + else + { + Count++; + if (Count == 1) /* TODO consolidate */ { - buffer = buffer[..length]; // Adjust to the actual size + m_Player.Paralyze(TimeSpan.FromSeconds(2)); + Effects.SendTargetEffect(m_Player, 0x11B7, 20, 10); + PlayerSendASCII(m_Player, 0); // You are pinned down ... + + PlaySounds(m_Player.Location, !m_Player.Female ? fs : ms); + PlayEffect(ZAdjustedIEFromMobile(m_Player, 50), m_Player, 0x11B7, 20, false); } + else if (Count == 2) + { + DoDamage(m_Player, 80, 90, false); + Effects.SendTargetEffect(m_Player, 0x36BD, 20, 10); + PlaySounds(m_Player.Location, exp); + PlayerSendASCII(m_Player, 1); // A speeding rock ... - state.Send(buffer); - } - - eable.Free(); - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); // version - - m_Levers.Tidy(); - writer.Write(m_Levers); - - m_Statues.Tidy(); - writer.Write(m_Statues); - - m_Teles.Tidy(); - writer.Write(m_Teles); - - writer.Write(m_Box); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - m_Levers = reader.ReadEntityList(); - m_Statues = reader.ReadEntityList(); - m_Teles = reader.ReadEntityList(); - - m_Box = reader.ReadEntity(); - - m_Tiles = new List(); - for (var i = 4; i < 9; i++) - { - m_Tiles.Add(new LeverPuzzleRegion(TA[i])); - } - - m_LampRoom = new LampRoomRegion(this); - Enabled = true; - TheirKey = 0; - MyKey = 0; - GenKey(); - } - - public class RockTimer : Timer - { - private readonly Mobile m_Player; - private int Count; - - public RockTimer(Mobile player) - : base(TimeSpan.Zero, TimeSpan.FromSeconds(.25)) - { - Count = 0; - m_Player = player; - } - - private int Rock() => 0x1363 + Utility.Random(0, 11); - - protected override void OnTick() - { - if (m_Player == null || m_Player.Map != Map.Malas) + if (AniSafe(m_Player)) + { + m_Player.Animate(21, 10, 1, true, true, 0); + } + } + else if (Count == 3) { Stop(); - } - else - { - Count++; - if (Count == 1) /* TODO consolidate */ - { - m_Player.Paralyze(TimeSpan.FromSeconds(2)); - Effects.SendTargetEffect(m_Player, 0x11B7, 20, 10); - PlayerSendASCII(m_Player, 0); // You are pinned down ... - PlaySounds(m_Player.Location, !m_Player.Female ? fs : ms); - PlayEffect(ZAdjustedIEFromMobile(m_Player, 50), m_Player, 0x11B7, 20, false); - } - else if (Count == 2) - { - DoDamage(m_Player, 80, 90, false); - Effects.SendTargetEffect(m_Player, 0x36BD, 20, 10); - PlaySounds(m_Player.Location, exp); - PlayerSendASCII(m_Player, 1); // A speeding rock ... + Effects.SendTargetEffect(m_Player, 0x36B0, 20, 10); + PlayerSendASCII(m_Player, 1); // A speeding rock ... + PlaySounds(m_Player.Location, !m_Player.Female ? fs2 : ms2); - if (AniSafe(m_Player)) + var j = Utility.Random(6, 10); + for (var i = 0; i < j; i++) + { + IEntity m_IEntity = new Entity(Serial.Zero, RandomPointIn(m_Player.Location, 10), m_Player.Map); + + var eable = m_IEntity.Map.GetMobilesInRange(m_IEntity.Location, 2); + var mobiles = new List(); + mobiles.AddRange(eable); + eable.Free(); + + for (var k = 0; k < mobiles.Count; k++) { - m_Player.Animate(21, 10, 1, true, true, 0); - } - } - else if (Count == 3) - { - Stop(); - - Effects.SendTargetEffect(m_Player, 0x36B0, 20, 10); - PlayerSendASCII(m_Player, 1); // A speeding rock ... - PlaySounds(m_Player.Location, !m_Player.Female ? fs2 : ms2); - - var j = Utility.Random(6, 10); - for (var i = 0; i < j; i++) - { - IEntity m_IEntity = new Entity(Serial.Zero, RandomPointIn(m_Player.Location, 10), m_Player.Map); - - var eable = m_IEntity.Map.GetMobilesInRange(m_IEntity.Location, 2); - var mobiles = new List(); - mobiles.AddRange(eable); - eable.Free(); - - for (var k = 0; k < mobiles.Count; k++) + if (IsValidDamagable(mobiles[k]) && mobiles[k] != m_Player) { - if (IsValidDamagable(mobiles[k]) && mobiles[k] != m_Player) - { - PlayEffect(m_Player, mobiles[k], Rock(), 8, true); - DoDamage(mobiles[k], 25, 30, false); + PlayEffect(m_Player, mobiles[k], Rock(), 8, true); + DoDamage(mobiles[k], 25, 30, false); - if (mobiles[k].Player) - { - POHMessage(mobiles[k], 2); // OUCH! - } + if (mobiles[k].Player) + { + POHMessage(mobiles[k], 2); // OUCH! } } - - PlayEffect(m_Player, m_IEntity, Rock(), 8, false); } - } - } - } - } - public class LampRoomKickTimer : Timer - { - private readonly Mobile m; - - public LampRoomKickTimer(Mobile player) - : base(TimeSpan.FromSeconds(.25)) => - m = player; - - protected override void OnTick() - { - MoveMobileOut(m); - } - } - - public class LampRoomTimer : Timer - { - public int level; - public LeverPuzzleController m_Controller; - public int ticks; - - public LampRoomTimer(LeverPuzzleController controller) - : base(TimeSpan.FromSeconds(5.0), TimeSpan.FromSeconds(5.0)) - { - level = 0; - ticks = 0; - m_Controller = controller; - } - - protected override void OnTick() - { - ticks++; - var mobiles = m_Controller.m_LampRoom.GetMobiles(); - - if (ticks >= 71 || m_Controller.m_LampRoom.GetPlayerCount() == 0) - { - foreach (var mobile in mobiles) - { - if (mobile?.Deleted == false && !mobile.IsDeadBondedPet) - { - mobile.Kill(); - } - } - - m_Controller.Enabled = true; - Stop(); - } - else - { - if (ticks % 12 == 0) - { - level++; - } - - foreach (var mobile in mobiles) - { - if (IsValidDamagable(mobile)) - { - if (ticks % 2 == 0 && level == 5) - { - if (mobile.Player) - { - mobile.Say(1062092); - if (AniSafe(mobile)) - { - mobile.Animate(32, 5, 1, true, false, 0); - } - } - - DoDamage(mobile, 15, 20, true); - } - - if (Utility.Random((int)(level & ~0xfffffffc), 3) == 3) - { - mobile.ApplyPoison(mobile, PA2[level]); - } - - if (ticks % 12 == 0 && level > 0 && mobile.Player) - { - mobile.SendLocalizedMessage(PA[level][0], null, PA[level][1]); - } - } - } - - for (var i = 0; i <= level; i++) - { - SendLocationEffect(RandomPointIn(lr_Rect, -1), 0x36B0, Utility.Random(150, 200), 0, PA[level][2]); + PlayEffect(m_Player, m_IEntity, Rock(), 8, false); } } } } } + + public class LampRoomKickTimer : Timer + { + private readonly Mobile m; + + public LampRoomKickTimer(Mobile player) : base(TimeSpan.FromSeconds(.25)) => m = player; + + protected override void OnTick() + { + MoveMobileOut(m); + } + } + + public class LampRoomTimer : Timer + { + public int level; + public LeverPuzzleController m_Controller; + public int ticks; + + public LampRoomTimer(LeverPuzzleController controller) + : base(TimeSpan.FromSeconds(5.0), TimeSpan.FromSeconds(5.0)) + { + level = 0; + ticks = 0; + m_Controller = controller; + } + + protected override void OnTick() + { + ticks++; + var mobiles = m_Controller._lampRoom.GetMobiles(); + + if (ticks >= 71 || m_Controller._lampRoom.GetPlayerCount() == 0) + { + foreach (var mobile in mobiles) + { + if (mobile?.Deleted == false && !mobile.IsDeadBondedPet) + { + mobile.Kill(); + } + } + + m_Controller.Enabled = true; + Stop(); + } + else + { + if (ticks % 12 == 0) + { + level++; + } + + foreach (var mobile in mobiles) + { + if (IsValidDamagable(mobile)) + { + if (ticks % 2 == 0 && level == 5) + { + if (mobile.Player) + { + mobile.Say(1062092); + if (AniSafe(mobile)) + { + mobile.Animate(32, 5, 1, true, false, 0); + } + } + + DoDamage(mobile, 15, 20, true); + } + + if (Utility.Random((int)(level & ~0xfffffffc), 3) == 3) + { + mobile.ApplyPoison(mobile, PA2[level]); + } + + if (ticks % 12 == 0 && level > 0 && mobile.Player) + { + mobile.SendLocalizedMessage(PA[level][0], null, PA[level][1]); + } + } + } + + for (var i = 0; i <= level; i++) + { + SendLocationEffect(RandomPointIn(lr_Rect, -1), 0x36B0, Utility.Random(150, 200), 0, PA[level][2]); + } + } + } + } } diff --git a/Projects/UOContent/Engines/Doom/LeverPuzzle/LeverPuzzleItems.cs b/Projects/UOContent/Engines/Doom/LeverPuzzle/LeverPuzzleItems.cs index fa6445359..7c8362c5e 100644 --- a/Projects/UOContent/Engines/Doom/LeverPuzzle/LeverPuzzleItems.cs +++ b/Projects/UOContent/Engines/Doom/LeverPuzzle/LeverPuzzleItems.cs @@ -1,215 +1,149 @@ using System; +using ModernUO.Serialization; using Server.Mobiles; using Server.Spells; -namespace Server.Engines.Doom +namespace Server.Engines.Doom; + +[SerializationGenerator(0, false)] +public partial class LampRoomBox : Item { - public class LampRoomBox : Item + [SerializableField(0)] + private LeverPuzzleController _controller; + private Mobile _wanderer; + + public LampRoomBox(LeverPuzzleController controller) : base(0xe80) { - private LeverPuzzleController m_Controller; - private Mobile m_Wanderer; + _controller = controller; + ItemID = 0xe80; + Movable = false; + } - public LampRoomBox(LeverPuzzleController controller) : base(0xe80) + public override void OnDoubleClick(Mobile m) + { + if (!m.InRange(GetWorldLocation(), 3)) { - m_Controller = controller; - ItemID = 0xe80; - Movable = false; + return; } - public LampRoomBox(Serial serial) : base(serial) + if (_controller.Enabled) { + return; } - public override void OnDoubleClick(Mobile m) + if (_wanderer?.Alive != true) { - if (!m.InRange(GetWorldLocation(), 3)) - { - return; - } - - if (m_Controller.Enabled) - { - return; - } - - if (m_Wanderer?.Alive != true) - { - m_Wanderer = new WandererOfTheVoid(); - m_Wanderer.MoveToWorld(LeverPuzzleController.lr_Enter, Map.Malas); - m_Wanderer.PublicOverheadMessage(MessageType.Regular, 0x3B2, 1060002); // I am the guardian of... - Timer.StartTimer(TimeSpan.FromSeconds(5.0), CallBackMessage); - } - } - - public void CallBackMessage() - { - PublicOverheadMessage(MessageType.Regular, 0x3B2, 1060003); // You try to pry the box open... - } - - public override void OnAfterDelete() - { - if (m_Controller?.Deleted == false) - { - m_Controller.Delete(); - } - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); // version - writer.Write(m_Controller); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - m_Controller = reader.ReadEntity(); + _wanderer = new WandererOfTheVoid(); + _wanderer.MoveToWorld(LeverPuzzleController.lr_Enter, Map.Malas); + _wanderer.PublicOverheadMessage(MessageType.Regular, 0x3B2, 1060002); // I am the guardian of... + Timer.StartTimer(TimeSpan.FromSeconds(5.0), CallBackMessage); } } - public class LeverPuzzleStatue : Item + public void CallBackMessage() { - private LeverPuzzleController m_Controller; - - public LeverPuzzleStatue(int[] dat, LeverPuzzleController controller) : base(dat[0]) - { - m_Controller = controller; - Hue = 0x44E; - Movable = false; - } - - public LeverPuzzleStatue(Serial serial) : base(serial) - { - } - - public override void OnAfterDelete() - { - if (m_Controller?.Deleted == false) - { - m_Controller.Delete(); - } - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); // version - writer.Write(m_Controller); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - m_Controller = reader.ReadEntity(); - } + PublicOverheadMessage(MessageType.Regular, 0x3B2, 1060003); // You try to pry the box open... } - public class LeverPuzzleLever : Item + public override void OnAfterDelete() { - private LeverPuzzleController m_Controller; - - public LeverPuzzleLever(ushort code, LeverPuzzleController controller) : base(0x108E) + if (_controller?.Deleted == false) { - m_Controller = controller; - Code = code; - Hue = 0x66D; - Movable = false; - } - - public LeverPuzzleLever(Serial serial) : base(serial) - { - } - - [CommandProperty(AccessLevel.GameMaster)] - public ushort Code { get; private set; } - - public override void OnDoubleClick(Mobile m) - { - if (m != null && m_Controller.Enabled) - { - ItemID ^= 2; - Effects.PlaySound(Location, Map, 0x3E8); - m_Controller.LeverPulled(Code); - } - else - { - m?.SendLocalizedMessage(1060001); // You throw the switch, but the mechanism cannot be engaged again so soon. - } - } - - public override void OnAfterDelete() - { - if (m_Controller?.Deleted == false) - { - m_Controller.Delete(); - } - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); // version - writer.Write(Code); - writer.Write(m_Controller); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); - Code = reader.ReadUShort(); - m_Controller = reader.ReadEntity(); - } - } - - [TypeAlias("Server.Engines.Doom.LampRoomTelePorter")] - public class LampRoomTeleporter : Item - { - public LampRoomTeleporter(int[] dat) - { - Hue = dat[1]; - ItemID = dat[0]; - Movable = false; - } - - public LampRoomTeleporter(Serial serial) : base(serial) - { - } - - public override bool HandlesOnMovement => true; - - public override bool OnMoveOver(Mobile m) - { - if (m is PlayerMobile) - { - if (SpellHelper.CheckCombat(m)) - { - m.SendLocalizedMessage(1005564, "", 0x22); // Wouldst thou flee during the heat of battle?? - } - else - { - BaseCreature.TeleportPets(m, LeverPuzzleController.lr_Exit, Map.Malas); - m.MoveToWorld(LeverPuzzleController.lr_Exit, Map.Malas); - return false; - } - } - - return true; - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - var version = reader.ReadInt(); + _controller.Delete(); } } } + +[SerializationGenerator(0, false)] +public partial class LeverPuzzleStatue : Item +{ + private LeverPuzzleController _controller; + + public LeverPuzzleStatue(int[] dat, LeverPuzzleController controller) : base(dat[0]) + { + _controller = controller; + Hue = 0x44E; + Movable = false; + } + + public override void OnAfterDelete() + { + if (_controller?.Deleted == false) + { + _controller.Delete(); + } + } +} + +[SerializationGenerator(0, false)] +public partial class LeverPuzzleLever : Item +{ + [SerializableField(0, setter: "private")] + private ushort _code; + + [SerializableField(1)] + private LeverPuzzleController _controller; + + public LeverPuzzleLever(ushort code, LeverPuzzleController controller) : base(0x108E) + { + _controller = controller; + _code = code; + Hue = 0x66D; + Movable = false; + } + + public override void OnDoubleClick(Mobile m) + { + if (m != null && _controller.Enabled) + { + ItemID ^= 2; + Effects.PlaySound(Location, Map, 0x3E8); + _controller.LeverPulled(Code); + } + else + { + m?.SendLocalizedMessage(1060001); // You throw the switch, but the mechanism cannot be engaged again so soon. + } + } + + public override void OnAfterDelete() + { + if (_controller?.Deleted == false) + { + _controller.Delete(); + } + } +} + +[TypeAlias("Server.Engines.Doom.LampRoomTelePorter")] +[SerializationGenerator(0, false)] +public partial class LampRoomTeleporter : Item +{ + public LampRoomTeleporter(int[] dat) + { + Hue = dat[1]; + ItemID = dat[0]; + Movable = false; + } + + public override bool HandlesOnMovement => true; + + public override bool OnMoveOver(Mobile m) + { + if (m is PlayerMobile) + { + if (SpellHelper.CheckCombat(m)) + { + m.SendLocalizedMessage(1005564, "", 0x22); // Wouldst thou flee during the heat of battle?? + } + else + { + BaseCreature.TeleportPets(m, LeverPuzzleController.lr_Exit, Map.Malas); + m.MoveToWorld(LeverPuzzleController.lr_Exit, Map.Malas); + return false; + } + } + + return true; + } +} diff --git a/Projects/UOContent/Engines/Khaldun/Books/GrimmochJournal.cs b/Projects/UOContent/Engines/Khaldun/Books/GrimmochJournal.cs index 3ce08eeb2..83ae8f30f 100644 --- a/Projects/UOContent/Engines/Khaldun/Books/GrimmochJournal.cs +++ b/Projects/UOContent/Engines/Khaldun/Books/GrimmochJournal.cs @@ -1,730 +1,578 @@ -namespace Server.Items +using ModernUO.Serialization; + +namespace Server.Items; + +[SerializationGenerator(0)] +public partial class GrimmochJournal1 : BaseBook { - public class GrimmochJournal1 : BaseBook + public static readonly BookContent Content = new( + "The daily journal of Grimmoch Drummel", + "Grimmoch", + new BookPageInfo( + "Day One :", + "", + "'Tis a grand sight, this", + "primeval tomb, I agree", + "with Tavara on that.", + "And we've a good crew", + "here, they've strong", + "backs and a good" + ), + new BookPageInfo( + "attitude. I'm a bit", + "concerned by those", + "that worked as guides", + "for us, however. All", + "seemed well enough", + "until we revealed the", + "immense stone doors", + "of the tomb structure" + ), + new BookPageInfo( + "itself. Seemed to send", + "a shiver up their", + "spines and get them all", + "stirred up with", + "whispering. I'll", + "watch the lot of them", + "with a close eye, but", + "I'm confident we won't" + ), + new BookPageInfo( + "have any real", + "problems on the dig.", + "I'm especially proud to", + "see Thomas standing", + "out - he was a good", + "hire, despite the", + "warnings from his", + "previous employers." + ), + new BookPageInfo( + "He's drummed up the", + "workers into a", + "furious pace - we've", + "nearly halved the", + "estimate on the", + "timeline for", + "excavating the Tomb's", + "entrance." + ) + ); + + [Constructible] + public GrimmochJournal1() : base(Utility.Random(0xFF1, 2), false) { - public static readonly BookContent Content = new( - "The daily journal of Grimmoch Drummel", - "Grimmoch", - new BookPageInfo( - "Day One :", - "", - "'Tis a grand sight, this", - "primeval tomb, I agree", - "with Tavara on that.", - "And we've a good crew", - "here, they've strong", - "backs and a good" - ), - new BookPageInfo( - "attitude. I'm a bit", - "concerned by those", - "that worked as guides", - "for us, however. All", - "seemed well enough", - "until we revealed the", - "immense stone doors", - "of the tomb structure" - ), - new BookPageInfo( - "itself. Seemed to send", - "a shiver up their", - "spines and get them all", - "stirred up with", - "whispering. I'll", - "watch the lot of them", - "with a close eye, but", - "I'm confident we won't" - ), - new BookPageInfo( - "have any real", - "problems on the dig.", - "I'm especially proud to", - "see Thomas standing", - "out - he was a good", - "hire, despite the", - "warnings from his", - "previous employers." - ), - new BookPageInfo( - "He's drummed up the", - "workers into a", - "furious pace - we've", - "nearly halved the", - "estimate on the", - "timeline for", - "excavating the Tomb's", - "entrance." - ) - ); - - [Constructible] - public GrimmochJournal1() : base(Utility.Random(0xFF1, 2), false) - { - } - - public GrimmochJournal1(Serial serial) : base(serial) - { - } - - public override BookContent DefaultContent => Content; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class GrimmochJournal2 : BaseBook - { - public static readonly BookContent Content = new( - "The daily journal of Grimmoch Drummel", - "Grimmoch", - new BookPageInfo( - "Day Two :", - "", - "We managed to dig out", - "the last of the", - "remaining rubble", - "today, revealing the", - "entirety of the giant", - "stone doors that sealed" - ), - new BookPageInfo( - "ol' Khal Ankur and", - "his folk up ages ago.", - "Actually getting them", - "open was another", - "matter altogether,", - "however. As the", - "workers set to the", - "task with picks and" - ), - new BookPageInfo( - "crowbars, I could have", - "sworn I saw Lysander", - "Gathenwale fiddling", - "with something in that", - "musty old tome of his.", - " I've no great", - "knowledge of things", - "magical, but the way" - ), - new BookPageInfo( - "his hand moved over", - "that book, and the look", - "of concentration on his", - "face as he whispered", - "something to himself", - "looked like every", - "description of an", - "incantation I've ever" - ), - new BookPageInfo( - "heard. The strange", - "thing is, this set of", - "doors that an entire", - "crew of excavators", - "was laboring over for", - "hours, right when", - "Gathenwale finishes", - "with his mumbling..." - ), - new BookPageInfo( - "well, I swore the doors", - "just gave open at the", - "exact moment he", - "spoke his last bit of", - "whisper and shut the", - "tome tight in his", - "hands. When he", - "looked up, it was" - ), - new BookPageInfo( - "almost as if he was", - "expecting the doors to", - "be open, rather than", - "shocked that they'd", - "finally given way." - ) - ); - - [Constructible] - public GrimmochJournal2() : base(Utility.Random(0xFF1, 2), false) - { - } - - public GrimmochJournal2(Serial serial) : base(serial) - { - } - - public override BookContent DefaultContent => Content; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class GrimmochJournal3 : BaseBook - { - public static readonly BookContent Content = new( - "The daily journal of Grimmoch Drummel", - "Grimmoch", - new BookPageInfo( - "Day Three - Day Five:", - "", - "I might have", - "written too hastily in", - "my first entry - this", - "place doesn't seem too", - "bent on giving up any", - "secrets. Though the" - ), - new BookPageInfo( - "main antechamber is", - "open to us, the main", - "exit hall is blocked by", - "yet another pile of", - "rubble. Doesn't look a", - "bit like anything", - "caused by a quake or", - "instability in the" - ), - new BookPageInfo( - "stonework... I swear it", - "looks as if someone", - "actually piled the", - "stones up themselves,", - "some time after the", - "tomb was built. The", - "stones aren't of the", - "same set nor quality" - ), - new BookPageInfo( - "of the carved work", - "that surrounds them", - "- if anything, they", - "resemble the grade of", - "common rock we saw", - "in great quantities on", - "the trip here. Which", - "makes it feel all the" - ), - new BookPageInfo( - "more like someone", - "hauled them in and", - "deliberately covered", - "this passage. But then", - "why not decorate them", - "in the same ornate", - "manner as the rest of", - "the stone in this" - ), - new BookPageInfo( - "place? Lysander", - "wouldn't hear a word", - "of what I had to say -", - "to him, it was a quake", - "some time in the", - "history of the tomb,", - "and that was it, shut", - "up and move on. So I" - ), - new BookPageInfo( - "shut up, and got back", - "to work." - ) - ); - - [Constructible] - public GrimmochJournal3() : base(Utility.Random(0xFF1, 2), false) - { - } - - public GrimmochJournal3(Serial serial) : base(serial) - { - } - - public override BookContent DefaultContent => Content; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class GrimmochJournal6 : BaseBook - { - public static readonly BookContent Content = new( - "The daily journal of Grimmoch Drummel", - "Grimmoch", - new BookPageInfo( - "Day Six :", - "", - "The camp was", - "attacked last night by", - "a pack of, well, I don't", - "have a clue. I've never", - "seen the like of these", - "beasts anywhere." - ), - new BookPageInfo( - "Huge things, with", - "fangs the size of your", - "forefinger, covered in", - "hair and with the", - "strangest arched back", - "I've ever seen. And so", - "many of them. We", - "were forced back into" - ), - new BookPageInfo( - "the Tomb for the", - "night, just to keep our", - "hides on us. And", - "today Gathenwale", - "practically orders us", - "all to move the entire", - "exterior camp into the", - "Tomb. Now, I don't" - ), - new BookPageInfo( - "disagree that we'd be", - "well off to use the", - "place as a point of", - "fortification... but I", - "don't like it one bit, in", - "any case. I don't like", - "the look of this place,", - "nor the sound of it." - ), - new BookPageInfo( - "The way the wind", - "gets into the", - "passageways,", - "whistling up the", - "strangest noises.", - "Deep, sustained echoes", - "of the wind, not so", - "much flute-like as..." - ), - new BookPageInfo( - "well, it sounds", - "ridiculous. In any", - "case, we've set to work", - "moving the bulk of the", - "exterior camp into the", - "main antechamber, so", - "there's no use moaning", - "about it now." - ) - ); - - [Constructible] - public GrimmochJournal6() : base(Utility.Random(0xFF1, 2), false) - { - } - - public GrimmochJournal6(Serial serial) : base(serial) - { - } - - public override BookContent DefaultContent => Content; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class GrimmochJournal7 : BaseBook - { - public static readonly BookContent Content = new( - "The daily journal of Grimmoch Drummel", - "Grimmoch", - new BookPageInfo( - "Day Seven - Day Ten:", - "", - "I cannot stand this", - "place, I cannot bear it.", - "I've got to get out.", - "Something evil lurks", - "in this ancient place,", - "something best left" - ), - new BookPageInfo( - "alone. I hear them,", - "yet none of the others", - "do. And yet they", - "must. Hands, claws,", - "scratching at stone,", - "the awful scratching", - "and the piteous cries", - "that sound almost like" - ), - new BookPageInfo( - "laughter. I can hear", - "them above even the", - "cracks of the", - "workmen's picks, and", - "at night they are all I", - "can hear. And yet the", - "others hear nothing.", - "We must leave this" - ), - new BookPageInfo( - "place, we must.", - "Three workers have", - "gone missing - Tavara", - "expects they've", - "abandoned us - and I", - "count them lucky if", - "they have. I don't care", - "what the others say," - ), - new BookPageInfo( - "we must leave this", - "place. We must do as", - "those before and pile", - "up the stones, block all", - "access to this primeval", - "crypt, seal it up again", - "for all eternity." - ) - ); - - [Constructible] - public GrimmochJournal7() : base(Utility.Random(0xFF1, 2), false) - { - } - - public GrimmochJournal7(Serial serial) : base(serial) - { - } - - public override BookContent DefaultContent => Content; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class GrimmochJournal11 : BaseBook - { - public static readonly BookContent Content = new( - "The daily journal of Grimmoch Drummel", - "Grimmoch", - new BookPageInfo( - "Day Eleven - Day", - "Thirteen :", - "", - "Lysander is gone, and", - "two more workers", - "with him. Good", - "riddance to the first.", - "He knows something." - ), - new BookPageInfo( - "He heard them too, I", - "know he did - and yet", - "he scowled at me", - "when I mentioned", - "them. I cannot stop", - "the noise in my head,", - "the scratching, the", - "clawing tears at my" - ), - new BookPageInfo( - "senses. What is it?", - "What does Lysander", - "seek that I can only", - "turn from? Where", - "has he gone? The", - "only answer to my", - "questions comes as", - "laughter from behind" - ), - new BookPageInfo( - "the stones." - ) - ); - - [Constructible] - public GrimmochJournal11() : base(Utility.Random(0xFF1, 2), false) - { - } - - public GrimmochJournal11(Serial serial) : base(serial) - { - } - - public override BookContent DefaultContent => Content; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class GrimmochJournal14 : BaseBook - { - public static readonly BookContent Content = new( - "The daily journal of Grimmoch Drummel", - "Grimmoch", - new BookPageInfo( - "Day Fourteen - Day", - "Sixteen :", - "", - "We are lost... we are", - "lost... all is lost. The", - "dead are piled up at", - "my feet. Bergen and I", - "somehow managed in" - ), - new BookPageInfo( - "the madness to piece", - "together a barricade,", - "barring access to the", - "camp antechamber.", - "He knows as well as I", - "that we cannot hold it", - "forever. The dead", - "come. They took" - ), - new BookPageInfo( - "Lysander before our", - "eyes. I pity the soul", - "of even such a", - "madman - no one", - "should die in such a", - "manner. And yet so", - "many have. We're", - "trapped here in this" - ), - new BookPageInfo( - "horror. So many have", - "died, and for what?", - "What curse have we", - "stumbled upon? I", - "cannot bear it, the", - "moaning, wailing cries", - "of the dead. Poor", - "Thomas, cut to pieces" - ), - new BookPageInfo( - "by their blades. We", - "had only an hour to", - "properly bury those", - "we could, before the", - "undead legions struck", - "again. I cannot go on...", - "I cannot go on." - ) - ); - - [Constructible] - public GrimmochJournal14() : base(Utility.Random(0xFF1, 2), false) - { - } - - public GrimmochJournal14(Serial serial) : base(serial) - { - } - - public override BookContent DefaultContent => Content; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class GrimmochJournal17 : BaseBook - { - public static readonly BookContent Content = new( - "The daily journal of Grimmoch Drummel", - "Grimmoch", - new BookPageInfo( - "Day Seventeen - Day", - "Twenty-Two :", - "", - "The fighting never", - "ceases... the blood", - "never stops flowing,", - "like a river through", - "the bloated corpses of" - ), - new BookPageInfo( - "the dead. And yet", - "there are still more.", - "Always more, with", - "the red fire gleaming", - "in their eyes. My", - "arm aches, I've taken", - "to the sword as my", - "bow seems to do little" - ), - new BookPageInfo( - "good... the dull ache in", - "my arm... so many", - "swings, cleaving a", - "mountain of decaying", - "flesh. And Thomas...", - "he was there, in the", - "thick of it... Thomas", - "was beside me..." - ), - new BookPageInfo( - "his face cleaved in", - "twain - and yet beside", - "me, fighting with us", - "against the horde until", - "he was cut down once", - "again. And I swear I", - "see him even now,", - "there in the dark" - ), - new BookPageInfo( - "corner of the", - "antechamber, his eyes", - "flickering in the last", - "dying embers of the", - "fire... and he stares at", - "me, and a scream fills", - "the vault - whether", - "his or mine, I can no" - ), - new BookPageInfo( - "longer tell." - ) - ); - - [Constructible] - public GrimmochJournal17() : base(Utility.Random(0xFF1, 2), false) - { - } - - public GrimmochJournal17(Serial serial) : base(serial) - { - } - - public override BookContent DefaultContent => Content; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class GrimmochJournal23 : BaseBook - { - public static readonly BookContent Content = new( - "The daily journal of Grimmoch Drummel", - "Grimmoch", - new BookPageInfo( - "Day Twenty-Three :", - "", - "We no longer bury the", - "dead." - ) - ); - - [Constructible] - public GrimmochJournal23() : base(Utility.Random(0xFF1, 2), false) - { - } - - public GrimmochJournal23(Serial serial) : base(serial) - { - } - - public override BookContent DefaultContent => Content; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } + public override BookContent DefaultContent => Content; +} + +[SerializationGenerator(0)] +public partial class GrimmochJournal2 : BaseBook +{ + public static readonly BookContent Content = new( + "The daily journal of Grimmoch Drummel", + "Grimmoch", + new BookPageInfo( + "Day Two :", + "", + "We managed to dig out", + "the last of the", + "remaining rubble", + "today, revealing the", + "entirety of the giant", + "stone doors that sealed" + ), + new BookPageInfo( + "ol' Khal Ankur and", + "his folk up ages ago.", + "Actually getting them", + "open was another", + "matter altogether,", + "however. As the", + "workers set to the", + "task with picks and" + ), + new BookPageInfo( + "crowbars, I could have", + "sworn I saw Lysander", + "Gathenwale fiddling", + "with something in that", + "musty old tome of his.", + " I've no great", + "knowledge of things", + "magical, but the way" + ), + new BookPageInfo( + "his hand moved over", + "that book, and the look", + "of concentration on his", + "face as he whispered", + "something to himself", + "looked like every", + "description of an", + "incantation I've ever" + ), + new BookPageInfo( + "heard. The strange", + "thing is, this set of", + "doors that an entire", + "crew of excavators", + "was laboring over for", + "hours, right when", + "Gathenwale finishes", + "with his mumbling..." + ), + new BookPageInfo( + "well, I swore the doors", + "just gave open at the", + "exact moment he", + "spoke his last bit of", + "whisper and shut the", + "tome tight in his", + "hands. When he", + "looked up, it was" + ), + new BookPageInfo( + "almost as if he was", + "expecting the doors to", + "be open, rather than", + "shocked that they'd", + "finally given way." + ) + ); + + [Constructible] + public GrimmochJournal2() : base(Utility.Random(0xFF1, 2), false) + { + } + + public override BookContent DefaultContent => Content; +} + +[SerializationGenerator(0)] +public partial class GrimmochJournal3 : BaseBook +{ + public static readonly BookContent Content = new( + "The daily journal of Grimmoch Drummel", + "Grimmoch", + new BookPageInfo( + "Day Three - Day Five:", + "", + "I might have", + "written too hastily in", + "my first entry - this", + "place doesn't seem too", + "bent on giving up any", + "secrets. Though the" + ), + new BookPageInfo( + "main antechamber is", + "open to us, the main", + "exit hall is blocked by", + "yet another pile of", + "rubble. Doesn't look a", + "bit like anything", + "caused by a quake or", + "instability in the" + ), + new BookPageInfo( + "stonework... I swear it", + "looks as if someone", + "actually piled the", + "stones up themselves,", + "some time after the", + "tomb was built. The", + "stones aren't of the", + "same set nor quality" + ), + new BookPageInfo( + "of the carved work", + "that surrounds them", + "- if anything, they", + "resemble the grade of", + "common rock we saw", + "in great quantities on", + "the trip here. Which", + "makes it feel all the" + ), + new BookPageInfo( + "more like someone", + "hauled them in and", + "deliberately covered", + "this passage. But then", + "why not decorate them", + "in the same ornate", + "manner as the rest of", + "the stone in this" + ), + new BookPageInfo( + "place? Lysander", + "wouldn't hear a word", + "of what I had to say -", + "to him, it was a quake", + "some time in the", + "history of the tomb,", + "and that was it, shut", + "up and move on. So I" + ), + new BookPageInfo( + "shut up, and got back", + "to work." + ) + ); + + [Constructible] + public GrimmochJournal3() : base(Utility.Random(0xFF1, 2), false) + { + } + + public override BookContent DefaultContent => Content; +} + +[SerializationGenerator(0)] +public partial class GrimmochJournal6 : BaseBook +{ + public static readonly BookContent Content = new( + "The daily journal of Grimmoch Drummel", + "Grimmoch", + new BookPageInfo( + "Day Six :", + "", + "The camp was", + "attacked last night by", + "a pack of, well, I don't", + "have a clue. I've never", + "seen the like of these", + "beasts anywhere." + ), + new BookPageInfo( + "Huge things, with", + "fangs the size of your", + "forefinger, covered in", + "hair and with the", + "strangest arched back", + "I've ever seen. And so", + "many of them. We", + "were forced back into" + ), + new BookPageInfo( + "the Tomb for the", + "night, just to keep our", + "hides on us. And", + "today Gathenwale", + "practically orders us", + "all to move the entire", + "exterior camp into the", + "Tomb. Now, I don't" + ), + new BookPageInfo( + "disagree that we'd be", + "well off to use the", + "place as a point of", + "fortification... but I", + "don't like it one bit, in", + "any case. I don't like", + "the look of this place,", + "nor the sound of it." + ), + new BookPageInfo( + "The way the wind", + "gets into the", + "passageways,", + "whistling up the", + "strangest noises.", + "Deep, sustained echoes", + "of the wind, not so", + "much flute-like as..." + ), + new BookPageInfo( + "well, it sounds", + "ridiculous. In any", + "case, we've set to work", + "moving the bulk of the", + "exterior camp into the", + "main antechamber, so", + "there's no use moaning", + "about it now." + ) + ); + + [Constructible] + public GrimmochJournal6() : base(Utility.Random(0xFF1, 2), false) + { + } + + public override BookContent DefaultContent => Content; +} + +[SerializationGenerator(0)] +public partial class GrimmochJournal7 : BaseBook +{ + public static readonly BookContent Content = new( + "The daily journal of Grimmoch Drummel", + "Grimmoch", + new BookPageInfo( + "Day Seven - Day Ten:", + "", + "I cannot stand this", + "place, I cannot bear it.", + "I've got to get out.", + "Something evil lurks", + "in this ancient place,", + "something best left" + ), + new BookPageInfo( + "alone. I hear them,", + "yet none of the others", + "do. And yet they", + "must. Hands, claws,", + "scratching at stone,", + "the awful scratching", + "and the piteous cries", + "that sound almost like" + ), + new BookPageInfo( + "laughter. I can hear", + "them above even the", + "cracks of the", + "workmen's picks, and", + "at night they are all I", + "can hear. And yet the", + "others hear nothing.", + "We must leave this" + ), + new BookPageInfo( + "place, we must.", + "Three workers have", + "gone missing - Tavara", + "expects they've", + "abandoned us - and I", + "count them lucky if", + "they have. I don't care", + "what the others say," + ), + new BookPageInfo( + "we must leave this", + "place. We must do as", + "those before and pile", + "up the stones, block all", + "access to this primeval", + "crypt, seal it up again", + "for all eternity." + ) + ); + + [Constructible] + public GrimmochJournal7() : base(Utility.Random(0xFF1, 2), false) + { + } + + public override BookContent DefaultContent => Content; +} + +[SerializationGenerator(0)] +public partial class GrimmochJournal11 : BaseBook +{ + public static readonly BookContent Content = new( + "The daily journal of Grimmoch Drummel", + "Grimmoch", + new BookPageInfo( + "Day Eleven - Day", + "Thirteen :", + "", + "Lysander is gone, and", + "two more workers", + "with him. Good", + "riddance to the first.", + "He knows something." + ), + new BookPageInfo( + "He heard them too, I", + "know he did - and yet", + "he scowled at me", + "when I mentioned", + "them. I cannot stop", + "the noise in my head,", + "the scratching, the", + "clawing tears at my" + ), + new BookPageInfo( + "senses. What is it?", + "What does Lysander", + "seek that I can only", + "turn from? Where", + "has he gone? The", + "only answer to my", + "questions comes as", + "laughter from behind" + ), + new BookPageInfo( + "the stones." + ) + ); + + [Constructible] + public GrimmochJournal11() : base(Utility.Random(0xFF1, 2), false) + { + } + + public override BookContent DefaultContent => Content; +} + +[SerializationGenerator(0)] +public partial class GrimmochJournal14 : BaseBook +{ + public static readonly BookContent Content = new( + "The daily journal of Grimmoch Drummel", + "Grimmoch", + new BookPageInfo( + "Day Fourteen - Day", + "Sixteen :", + "", + "We are lost... we are", + "lost... all is lost. The", + "dead are piled up at", + "my feet. Bergen and I", + "somehow managed in" + ), + new BookPageInfo( + "the madness to piece", + "together a barricade,", + "barring access to the", + "camp antechamber.", + "He knows as well as I", + "that we cannot hold it", + "forever. The dead", + "come. They took" + ), + new BookPageInfo( + "Lysander before our", + "eyes. I pity the soul", + "of even such a", + "madman - no one", + "should die in such a", + "manner. And yet so", + "many have. We're", + "trapped here in this" + ), + new BookPageInfo( + "horror. So many have", + "died, and for what?", + "What curse have we", + "stumbled upon? I", + "cannot bear it, the", + "moaning, wailing cries", + "of the dead. Poor", + "Thomas, cut to pieces" + ), + new BookPageInfo( + "by their blades. We", + "had only an hour to", + "properly bury those", + "we could, before the", + "undead legions struck", + "again. I cannot go on...", + "I cannot go on." + ) + ); + + [Constructible] + public GrimmochJournal14() : base(Utility.Random(0xFF1, 2), false) + { + } + + public override BookContent DefaultContent => Content; +} + +[SerializationGenerator(0)] +public partial class GrimmochJournal17 : BaseBook +{ + public static readonly BookContent Content = new( + "The daily journal of Grimmoch Drummel", + "Grimmoch", + new BookPageInfo( + "Day Seventeen - Day", + "Twenty-Two :", + "", + "The fighting never", + "ceases... the blood", + "never stops flowing,", + "like a river through", + "the bloated corpses of" + ), + new BookPageInfo( + "the dead. And yet", + "there are still more.", + "Always more, with", + "the red fire gleaming", + "in their eyes. My", + "arm aches, I've taken", + "to the sword as my", + "bow seems to do little" + ), + new BookPageInfo( + "good... the dull ache in", + "my arm... so many", + "swings, cleaving a", + "mountain of decaying", + "flesh. And Thomas...", + "he was there, in the", + "thick of it... Thomas", + "was beside me..." + ), + new BookPageInfo( + "his face cleaved in", + "twain - and yet beside", + "me, fighting with us", + "against the horde until", + "he was cut down once", + "again. And I swear I", + "see him even now,", + "there in the dark" + ), + new BookPageInfo( + "corner of the", + "antechamber, his eyes", + "flickering in the last", + "dying embers of the", + "fire... and he stares at", + "me, and a scream fills", + "the vault - whether", + "his or mine, I can no" + ), + new BookPageInfo( + "longer tell." + ) + ); + + [Constructible] + public GrimmochJournal17() : base(Utility.Random(0xFF1, 2), false) + { + } + + public override BookContent DefaultContent => Content; +} + +[SerializationGenerator(0)] +public partial class GrimmochJournal23 : BaseBook +{ + public static readonly BookContent Content = new( + "The daily journal of Grimmoch Drummel", + "Grimmoch", + new BookPageInfo( + "Day Twenty-Three :", + "", + "We no longer bury the", + "dead." + ) + ); + + [Constructible] + public GrimmochJournal23() : base(Utility.Random(0xFF1, 2), false) + { + } + + public override BookContent DefaultContent => Content; } diff --git a/Projects/UOContent/Engines/Khaldun/Books/LysanderNotebook.cs b/Projects/UOContent/Engines/Khaldun/Books/LysanderNotebook.cs index 1a51a9461..8bbb685d5 100644 --- a/Projects/UOContent/Engines/Khaldun/Books/LysanderNotebook.cs +++ b/Projects/UOContent/Engines/Khaldun/Books/LysanderNotebook.cs @@ -1,503 +1,502 @@ -namespace Server.Items +namespace Server.Items; + +public class LysanderNotebook1 : BaseBook { - public class LysanderNotebook1 : BaseBook + public static readonly BookContent Content = new( + "Lysander's Notebook", + "L. Gathenwale", + new BookPageInfo( + "Day One :", + "", + "At last, it stands", + "before me. The doors", + "of Thy Sanctum will", + "open to me now, after", + "all these years of", + "searching. I give" + ), + new BookPageInfo( + "myself unto Thee,", + "Khal Ankur, I have", + "come for Thy secrets", + "and I will kneel", + "prostrate before Thee.", + " Blessed are the", + "Keepers, praise unto", + "Thee, a thousand" + ), + new BookPageInfo( + "fortunes in the night." + ) + ); + + [Constructible] + public LysanderNotebook1() : base(Utility.Random(0xFF1, 2), false) { - public static readonly BookContent Content = new( - "Lysander's Notebook", - "L. Gathenwale", - new BookPageInfo( - "Day One :", - "", - "At last, it stands", - "before me. The doors", - "of Thy Sanctum will", - "open to me now, after", - "all these years of", - "searching. I give" - ), - new BookPageInfo( - "myself unto Thee,", - "Khal Ankur, I have", - "come for Thy secrets", - "and I will kneel", - "prostrate before Thee.", - " Blessed are the", - "Keepers, praise unto", - "Thee, a thousand" - ), - new BookPageInfo( - "fortunes in the night." - ) - ); - - [Constructible] - public LysanderNotebook1() : base(Utility.Random(0xFF1, 2), false) - { - } - - public LysanderNotebook1(Serial serial) : base(serial) - { - } - - public override BookContent DefaultContent => Content; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class LysanderNotebook2 : BaseBook + public LysanderNotebook1(Serial serial) : base(serial) { - public static readonly BookContent Content = new( - "Lysander's Notebook", - "L. Gathenwale", - new BookPageInfo( - "Day Two:", - "", - "The woman, Tavara", - "Sewel, is unbearable.", - "Her entire demeanor", - "sickens me. I would", - "take her life for Thee", - "now, my Lord. But I" - ), - new BookPageInfo( - "cannot alert the", - "others. Progress is", - "made too slowly, I", - "cannot stand this", - "perpetual waiting.", - "Today I knelt down", - "with the workers,", - "tossing stones and dirt" - ), - new BookPageInfo( - "aside with my very", - "hands as they dug at", - "the last of the rubble", - "covering the entrance", - "to Thy Sanctum. The", - "Sewel woman was", - "shocked at my", - "demeanor, dirtying" - ), - new BookPageInfo( - "my robes, on my", - "knees in the muck as I", - "clawed at the rocks.", - "She thought I did this", - "for those sickly", - "scholars, or for her,", - "or for what she", - "laughably calls 'The" - ), - new BookPageInfo( - "Gift of Discovery', of", - "learning. As if I did", - "not know what I went", - "to find! I come for", - "Thee, Master. Soon", - "shall I receive Thy", - "gifts, Thy blessings.", - "Patience, eternal" - ), - new BookPageInfo( - "patience. I must take", - "my lessons well. I", - "have learned from", - "Thee, Master, I have." - ) - ); - - [Constructible] - public LysanderNotebook2() : base(Utility.Random(0xFF1, 2), false) - { - } - - public LysanderNotebook2(Serial serial) : base(serial) - { - } - - public override BookContent DefaultContent => Content; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class LysanderNotebook3 : BaseBook + public override BookContent DefaultContent => Content; + + public override void Serialize(IGenericWriter writer) { - public static readonly BookContent Content = new( - "Lysander's Notebook", - "L. Gathenwale", - new BookPageInfo( - "Day Three - Day Six:", - "", - "What are these Beasts", - "that dare to defy our", - "presence here? Hast", - "Thou sent them,", - "Master? To tear", - "apart these foolish" - ), - new BookPageInfo( - "ones that accompany", - "me? That repugnant", - "pustule, Drummel, put", - "forth his absurd little", - "theories as to the", - "nature of the Beasts", - "that attacked our", - "camp, but I'll have" - ), - new BookPageInfo( - "none of his words. He", - "asks too many", - "questions. He is a", - "taint upon the grounds", - "of Thy Sanctum,", - "Master - I will deal", - "with him after the", - "Sewel woman." - ), - new BookPageInfo( - "Speaking of Sewel, I", - "have convinced that", - "empty-headed harlot", - "that we should move", - "our encampment", - "within the", - "antechamber. She", - "thinks I worry for" - ), - new BookPageInfo( - "her safety. I come", - "for thee, Master. I", - "make my camp in Thy", - "chambers. I sleep", - "under Thy roof. I can", - "feel Thine presence", - "even now. Soon,", - "Master. Soon." - ) - ); + base.Serialize(writer); - [Constructible] - public LysanderNotebook3() : base(Utility.Random(0xFF1, 2), false) - { - } - - public LysanderNotebook3(Serial serial) : base(serial) - { - } - - public override BookContent DefaultContent => Content; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } + writer.WriteEncodedInt(0); // version } - public class LysanderNotebook7 : BaseBook + public override void Deserialize(IGenericReader reader) { - public static readonly BookContent Content = new( - "Lysander's Notebook", - "L. Gathenwale", - new BookPageInfo( - "Day Seven :", - "", - "The Sewel woman", - "pratters on endlessly.", - "And she dares to", - "speak Thy Name,", - "Master! I wish so", - "vehemently to take a" - ), - new BookPageInfo( - "knife to that little", - "neck of hers. She", - "struts around the", - "chambers of Thy", - "Sanctum with her", - "repugnant airs, her", - "scholarly conjecture", - "on this or that. That I" - ), - new BookPageInfo( - "could peel the skin", - "from her face and", - "show her how vile and", - "ugly she truly is, how", - "unworthy of entrance", - "to Thy Sanctum. I", - "must take her,", - "Master. I must rend" - ), - new BookPageInfo( - "that little wench to", - "pieces. I ask this gift", - "of Thee, that I might", - "cleanse Thy Sanctum", - "of her presence. Give", - "me the Sewel woman", - "and I shall show you", - "my mastery of Death," - ), - new BookPageInfo( - "Master. I shall cut", - "her to bits and scatter", - "them before the", - "others as a warning.", - "I cannot stand her", - "presence, I cannot", - "abide it. And", - "Drummel! He is a" - ), - new BookPageInfo( - "pustule that must be", - "lanced, a sickness that", - "I must cure by blade", - "and fire. Not a trace", - "of him will be left", - "when I'm done with", - "him. Praises to Thee,", - "Master. I shall honor" - ), - new BookPageInfo( - "Thee with many", - "sacrifices, soon", - "enough." - ) - ); + base.Deserialize(reader); - [Constructible] - public LysanderNotebook7() : base(Utility.Random(0xFF1, 2), false) - { - } - - public LysanderNotebook7(Serial serial) : base(serial) - { - } - - public override BookContent DefaultContent => Content; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class LysanderNotebook8 : BaseBook - { - public static readonly BookContent Content = new( - "Lysander's Notebook", - "L. Gathenwale", - new BookPageInfo( - "Day Eight - Day Ten :", - "", - "Have you taken them,", - "Master? They could", - "not have found a way", - "past the stones that", - "block our path! The", - "three workers, My" - ), - new BookPageInfo( - "Master, where have", - "they gone? Curses", - "upon them! I'll cut", - "them all to pieces if", - "they show their faces", - "again, then burn the", - "rest alive upon a pyre,", - "for all to see, as a" - ), - new BookPageInfo( - "warning of Thy", - "Power. How could", - "they have gotten past", - "me? I sleep against", - "the very walls, to", - "hear Thy Words, to", - "feel Thy Breath. I", - "can find no egress" - ), - new BookPageInfo( - "from the chambers", - "that the Sewel woman", - "does not know of nor", - "have men working at", - "excavating. Where", - "have they gone,", - "Master? Have you", - "taken them, or do they" - ), - new BookPageInfo( - "truly flee from Thy", - "Presence? I will kill", - "them if they show", - "their faces again.", - "Give me Strength, my", - "Master, to let them", - "live a while longer,", - "until they have" - ), - new BookPageInfo( - "fulfilled their", - "purpose and I kneel", - "before Thee, covered", - "in their blood." - ) - ); - - [Constructible] - public LysanderNotebook8() : base(Utility.Random(0xFF1, 2), false) - { - } - - public LysanderNotebook8(Serial serial) : base(serial) - { - } - - public override BookContent DefaultContent => Content; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class LysanderNotebook11 : BaseBook - { - public static readonly BookContent Content = new( - "Lysander's Notebook", - "L. Gathenwale", - new BookPageInfo( - "Day Eleven - Day", - "Thirteen:", - "", - "I come for Thee, my", - "Master. I come! The", - "way is clear, I have", - "found Thy path and", - "washed it in the blood" - ), - new BookPageInfo( - "of the two workers", - "that caught sight of", - "me. Ah, how sweet it", - "was to cut them open,", - "to see the blood pour", - "out in great torrents, to", - "stand in it, to revel in", - "it. If only I had time" - ), - new BookPageInfo( - "for the Sewel woman.", - "But there will be time", - "enough for her. I", - "have learned Thy", - "Patience, Master. I", - "come for Thee. I walk", - "Thy halls in penance,", - "my last steps in this" - ), - new BookPageInfo( - "repulsive living", - "frame. I come for", - "Thee and Thy Gifts,", - "my Master. Glory", - "Unto Thee, Khal", - "Ankur, Keeper of the", - "Seventh Death,", - "Master, Leader of the" - ), - new BookPageInfo( - "Chosen, the Khaldun.", - "Praises in Thy", - "Name, Master of Life", - "and Death, Lord of All.", - " Khal Ankur, Master,", - "Prophet, I join Thy", - "ranks this night, a", - "member of the" - ), - new BookPageInfo( - "Khaldun at last!" - ) - ); - - [Constructible] - public LysanderNotebook11() : base(Utility.Random(0xFF1, 2), false) - { - } - - public LysanderNotebook11(Serial serial) : base(serial) - { - } - - public override BookContent DefaultContent => Content; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } + var version = reader.ReadEncodedInt(); } } + +public class LysanderNotebook2 : BaseBook +{ + public static readonly BookContent Content = new( + "Lysander's Notebook", + "L. Gathenwale", + new BookPageInfo( + "Day Two:", + "", + "The woman, Tavara", + "Sewel, is unbearable.", + "Her entire demeanor", + "sickens me. I would", + "take her life for Thee", + "now, my Lord. But I" + ), + new BookPageInfo( + "cannot alert the", + "others. Progress is", + "made too slowly, I", + "cannot stand this", + "perpetual waiting.", + "Today I knelt down", + "with the workers,", + "tossing stones and dirt" + ), + new BookPageInfo( + "aside with my very", + "hands as they dug at", + "the last of the rubble", + "covering the entrance", + "to Thy Sanctum. The", + "Sewel woman was", + "shocked at my", + "demeanor, dirtying" + ), + new BookPageInfo( + "my robes, on my", + "knees in the muck as I", + "clawed at the rocks.", + "She thought I did this", + "for those sickly", + "scholars, or for her,", + "or for what she", + "laughably calls 'The" + ), + new BookPageInfo( + "Gift of Discovery', of", + "learning. As if I did", + "not know what I went", + "to find! I come for", + "Thee, Master. Soon", + "shall I receive Thy", + "gifts, Thy blessings.", + "Patience, eternal" + ), + new BookPageInfo( + "patience. I must take", + "my lessons well. I", + "have learned from", + "Thee, Master, I have." + ) + ); + + [Constructible] + public LysanderNotebook2() : base(Utility.Random(0xFF1, 2), false) + { + } + + public LysanderNotebook2(Serial serial) : base(serial) + { + } + + public override BookContent DefaultContent => Content; + + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + + writer.WriteEncodedInt(0); // version + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + + var version = reader.ReadEncodedInt(); + } +} + +public class LysanderNotebook3 : BaseBook +{ + public static readonly BookContent Content = new( + "Lysander's Notebook", + "L. Gathenwale", + new BookPageInfo( + "Day Three - Day Six:", + "", + "What are these Beasts", + "that dare to defy our", + "presence here? Hast", + "Thou sent them,", + "Master? To tear", + "apart these foolish" + ), + new BookPageInfo( + "ones that accompany", + "me? That repugnant", + "pustule, Drummel, put", + "forth his absurd little", + "theories as to the", + "nature of the Beasts", + "that attacked our", + "camp, but I'll have" + ), + new BookPageInfo( + "none of his words. He", + "asks too many", + "questions. He is a", + "taint upon the grounds", + "of Thy Sanctum,", + "Master - I will deal", + "with him after the", + "Sewel woman." + ), + new BookPageInfo( + "Speaking of Sewel, I", + "have convinced that", + "empty-headed harlot", + "that we should move", + "our encampment", + "within the", + "antechamber. She", + "thinks I worry for" + ), + new BookPageInfo( + "her safety. I come", + "for thee, Master. I", + "make my camp in Thy", + "chambers. I sleep", + "under Thy roof. I can", + "feel Thine presence", + "even now. Soon,", + "Master. Soon." + ) + ); + + [Constructible] + public LysanderNotebook3() : base(Utility.Random(0xFF1, 2), false) + { + } + + public LysanderNotebook3(Serial serial) : base(serial) + { + } + + public override BookContent DefaultContent => Content; + + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + + writer.WriteEncodedInt(0); // version + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + + var version = reader.ReadEncodedInt(); + } +} + +public class LysanderNotebook7 : BaseBook +{ + public static readonly BookContent Content = new( + "Lysander's Notebook", + "L. Gathenwale", + new BookPageInfo( + "Day Seven :", + "", + "The Sewel woman", + "pratters on endlessly.", + "And she dares to", + "speak Thy Name,", + "Master! I wish so", + "vehemently to take a" + ), + new BookPageInfo( + "knife to that little", + "neck of hers. She", + "struts around the", + "chambers of Thy", + "Sanctum with her", + "repugnant airs, her", + "scholarly conjecture", + "on this or that. That I" + ), + new BookPageInfo( + "could peel the skin", + "from her face and", + "show her how vile and", + "ugly she truly is, how", + "unworthy of entrance", + "to Thy Sanctum. I", + "must take her,", + "Master. I must rend" + ), + new BookPageInfo( + "that little wench to", + "pieces. I ask this gift", + "of Thee, that I might", + "cleanse Thy Sanctum", + "of her presence. Give", + "me the Sewel woman", + "and I shall show you", + "my mastery of Death," + ), + new BookPageInfo( + "Master. I shall cut", + "her to bits and scatter", + "them before the", + "others as a warning.", + "I cannot stand her", + "presence, I cannot", + "abide it. And", + "Drummel! He is a" + ), + new BookPageInfo( + "pustule that must be", + "lanced, a sickness that", + "I must cure by blade", + "and fire. Not a trace", + "of him will be left", + "when I'm done with", + "him. Praises to Thee,", + "Master. I shall honor" + ), + new BookPageInfo( + "Thee with many", + "sacrifices, soon", + "enough." + ) + ); + + [Constructible] + public LysanderNotebook7() : base(Utility.Random(0xFF1, 2), false) + { + } + + public LysanderNotebook7(Serial serial) : base(serial) + { + } + + public override BookContent DefaultContent => Content; + + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + + writer.WriteEncodedInt(0); // version + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + + var version = reader.ReadEncodedInt(); + } +} + +public class LysanderNotebook8 : BaseBook +{ + public static readonly BookContent Content = new( + "Lysander's Notebook", + "L. Gathenwale", + new BookPageInfo( + "Day Eight - Day Ten :", + "", + "Have you taken them,", + "Master? They could", + "not have found a way", + "past the stones that", + "block our path! The", + "three workers, My" + ), + new BookPageInfo( + "Master, where have", + "they gone? Curses", + "upon them! I'll cut", + "them all to pieces if", + "they show their faces", + "again, then burn the", + "rest alive upon a pyre,", + "for all to see, as a" + ), + new BookPageInfo( + "warning of Thy", + "Power. How could", + "they have gotten past", + "me? I sleep against", + "the very walls, to", + "hear Thy Words, to", + "feel Thy Breath. I", + "can find no egress" + ), + new BookPageInfo( + "from the chambers", + "that the Sewel woman", + "does not know of nor", + "have men working at", + "excavating. Where", + "have they gone,", + "Master? Have you", + "taken them, or do they" + ), + new BookPageInfo( + "truly flee from Thy", + "Presence? I will kill", + "them if they show", + "their faces again.", + "Give me Strength, my", + "Master, to let them", + "live a while longer,", + "until they have" + ), + new BookPageInfo( + "fulfilled their", + "purpose and I kneel", + "before Thee, covered", + "in their blood." + ) + ); + + [Constructible] + public LysanderNotebook8() : base(Utility.Random(0xFF1, 2), false) + { + } + + public LysanderNotebook8(Serial serial) : base(serial) + { + } + + public override BookContent DefaultContent => Content; + + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + + writer.WriteEncodedInt(0); // version + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + + var version = reader.ReadEncodedInt(); + } +} + +public class LysanderNotebook11 : BaseBook +{ + public static readonly BookContent Content = new( + "Lysander's Notebook", + "L. Gathenwale", + new BookPageInfo( + "Day Eleven - Day", + "Thirteen:", + "", + "I come for Thee, my", + "Master. I come! The", + "way is clear, I have", + "found Thy path and", + "washed it in the blood" + ), + new BookPageInfo( + "of the two workers", + "that caught sight of", + "me. Ah, how sweet it", + "was to cut them open,", + "to see the blood pour", + "out in great torrents, to", + "stand in it, to revel in", + "it. If only I had time" + ), + new BookPageInfo( + "for the Sewel woman.", + "But there will be time", + "enough for her. I", + "have learned Thy", + "Patience, Master. I", + "come for Thee. I walk", + "Thy halls in penance,", + "my last steps in this" + ), + new BookPageInfo( + "repulsive living", + "frame. I come for", + "Thee and Thy Gifts,", + "my Master. Glory", + "Unto Thee, Khal", + "Ankur, Keeper of the", + "Seventh Death,", + "Master, Leader of the" + ), + new BookPageInfo( + "Chosen, the Khaldun.", + "Praises in Thy", + "Name, Master of Life", + "and Death, Lord of All.", + " Khal Ankur, Master,", + "Prophet, I join Thy", + "ranks this night, a", + "member of the" + ), + new BookPageInfo( + "Khaldun at last!" + ) + ); + + [Constructible] + public LysanderNotebook11() : base(Utility.Random(0xFF1, 2), false) + { + } + + public LysanderNotebook11(Serial serial) : base(serial) + { + } + + public override BookContent DefaultContent => Content; + + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + + writer.WriteEncodedInt(0); // version + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + + var version = reader.ReadEncodedInt(); + } +} \ No newline at end of file diff --git a/Projects/UOContent/Engines/Khaldun/Books/TavarasJournal.cs b/Projects/UOContent/Engines/Khaldun/Books/TavarasJournal.cs index cc69a2df4..8ae117fd0 100644 --- a/Projects/UOContent/Engines/Khaldun/Books/TavarasJournal.cs +++ b/Projects/UOContent/Engines/Khaldun/Books/TavarasJournal.cs @@ -1,1245 +1,1244 @@ -namespace Server.Items +namespace Server.Items; + +public class TavarasJournal1 : BaseBook { - public class TavarasJournal1 : BaseBook + public static readonly BookContent Content = new( + "Journal: Discovery of the Tomb", + "Tavara Sewel", + new BookPageInfo( + "Day One:", + "", + "The workers continue", + "tirelessly in their", + "efforts to unload our", + "supplies even as light", + "fades. I feel I should", + "lend a hand in the" + ), + new BookPageInfo( + "effort, and yet I", + "cannot bear to take my", + "attention away from", + "the magnificent stone", + "doors of the tomb.", + "Every inch of their", + "massive frame is", + "covered with" + ), + new BookPageInfo( + "intricately carved", + "design work - 'tis", + "truly a sight to see.", + "I've spent the day", + "sketching and", + "cataloging what I can", + "of them while my", + "companions set up our" + ), + new BookPageInfo( + "camp and make", + "preparations for", + "tomorrow's work.", + "Though the stonework", + "symbols inspire me to", + "new flights of fancy,", + "some of the workers", + "seem strangely" + ), + new BookPageInfo( + "fearful of them. I", + "cannot wait 'til the", + "morrow when those", + "ancient works of stone", + "shall swing open and", + "deliver unto me", + "everything I have", + "dreamed of for the" + ), + new BookPageInfo( + "last ten years of my", + "life." + ) + ); + + [Constructible] + public TavarasJournal1() : base(Utility.Random(0xFF1, 2), false) { - public static readonly BookContent Content = new( - "Journal: Discovery of the Tomb", - "Tavara Sewel", - new BookPageInfo( - "Day One:", - "", - "The workers continue", - "tirelessly in their", - "efforts to unload our", - "supplies even as light", - "fades. I feel I should", - "lend a hand in the" - ), - new BookPageInfo( - "effort, and yet I", - "cannot bear to take my", - "attention away from", - "the magnificent stone", - "doors of the tomb.", - "Every inch of their", - "massive frame is", - "covered with" - ), - new BookPageInfo( - "intricately carved", - "design work - 'tis", - "truly a sight to see.", - "I've spent the day", - "sketching and", - "cataloging what I can", - "of them while my", - "companions set up our" - ), - new BookPageInfo( - "camp and make", - "preparations for", - "tomorrow's work.", - "Though the stonework", - "symbols inspire me to", - "new flights of fancy,", - "some of the workers", - "seem strangely" - ), - new BookPageInfo( - "fearful of them. I", - "cannot wait 'til the", - "morrow when those", - "ancient works of stone", - "shall swing open and", - "deliver unto me", - "everything I have", - "dreamed of for the" - ), - new BookPageInfo( - "last ten years of my", - "life." - ) - ); - - [Constructible] - public TavarasJournal1() : base(Utility.Random(0xFF1, 2), false) - { - } - - public TavarasJournal1(Serial serial) : base(serial) - { - } - - public override BookContent DefaultContent => Content; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class TavarasJournal2 : BaseBook + public TavarasJournal1(Serial serial) : base(serial) { - public static readonly BookContent Content = new( - "Journal: Discovery of the Tomb", - "Tavara Sewel", - new BookPageInfo( - "Day Two:", - "", - "Everything we'd", - "heard and read of the", - "tomb has proved", - "correct - and yet,", - "nothing could prepare", - "me for the sight of it" - ), - new BookPageInfo( - "with my own eyes.", - "The Tomb of Khal", - "Ankur has given up", - "its secrets at last! The", - "intricate stonework", - "that covered the tomb", - "doors seems to", - "continue throughout" - ), - new BookPageInfo( - "the entirety of the", - "catacombs, each", - "hallway and room", - "yielding a seemingly", - "endless amount of", - "information for my", - "companions and I to", - "record. It will take" - ), - new BookPageInfo( - "years to catalogue the", - "entirety of the Tomb,", - "if those legends of its", - "massive size prove", - "true. Sadly, a good", - "deal of the Tomb's", - "interior has been", - "damaged or utterly" - ), - new BookPageInfo( - "destroyed, whether", - "by seismic activity in", - "the surrounding", - "mountainside or", - "merely the slow", - "efforts of Time", - "itself, I do not know.", - "A good deal of the" - ), - new BookPageInfo( - "stonework has been", - "cracked or collapsed", - "entirely, especially", - "near the entrance", - "supports of the main", - "hall. Our passage has", - "indeed already been", - "entirely blocked in the" - ), - new BookPageInfo( - "first major room", - "we've discovered, a", - "massive pile of", - "boulders and stones", - "blocking any exit", - "from the", - "antechamber. What", - "could have caused" - ), - new BookPageInfo( - "such a localized", - "disruption of the", - "support structures,", - "one can only guess -", - "but it will surely take", - "an entire afternoon's", - "effort to remove even", - "a fraction of it. I look" - ), - new BookPageInfo( - "forward to more", - "progress tomorrow", - "once the workers have", - "set to excavating the", - "hall." - ) - ); - - [Constructible] - public TavarasJournal2() : base(Utility.Random(0xFF1, 2), false) - { - } - - public TavarasJournal2(Serial serial) : base(serial) - { - } - - public override BookContent DefaultContent => Content; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } } - public class TavarasJournal3 : BaseBook + public override BookContent DefaultContent => Content; + + public override void Serialize(IGenericWriter writer) { - public static readonly BookContent Content = new( - "Journal: Discovery of the Tomb", - "Tavara Sewel", - new BookPageInfo( - "Day Three - Day Five:", - "", - "I do not understand", - "this place... not as I", - "once thought I did.", - "Something palatable", - "seems to hinder our", - "every attempt to" - ), - new BookPageInfo( - "investigate this", - "ancient site.", - "Excavation work on", - "the first major", - "hallway finished only", - "yesterday - the", - "amount of stone and", - "rubble blocking the" - ), - new BookPageInfo( - "egress was", - "astounding, it stands", - "in immense piles", - "outside the Tomb's", - "entrance, as if we", - "were digging the", - "tunnels of this", - "abhorred place" - ), - new BookPageInfo( - "ourselves! The", - "satisfaction of", - "completing our efforts", - "was quickly thwarted,", - "however, as we", - "discovered the end of", - "the hallway we had", - "just revealed was" - ), - new BookPageInfo( - "blocked by yet another", - "colossal pile of stone.", - "I've had a few of the", - "workers set up", - "primitive scaffolding", - "in the main", - "antechamber so that I", - "can spend my time" - ), - new BookPageInfo( - "pouring over the detail", - "work on the stone", - "carvings while the", - "rest of our crew", - "continue excavating", - "the inner halls." - ) - ); + base.Serialize(writer); - [Constructible] - public TavarasJournal3() : base(Utility.Random(0xFF1, 2), false) - { - } - - public TavarasJournal3(Serial serial) : base(serial) - { - } - - public override BookContent DefaultContent => Content; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } + writer.WriteEncodedInt(0); // version } - public class TavarasJournal6 : BaseBook + public override void Deserialize(IGenericReader reader) { - public static readonly BookContent Content = new( - "Journal: Discovery of the Tomb", - "Tavara Sewel", - new BookPageInfo( - "Day Six:", - "", - "Late last night our", - "camp was set upon by", - "a pack of wild beasts", - "- behemoth creatures", - "with a speed and", - "viciousness I'd n'ere" - ), - new BookPageInfo( - "before seen. Even", - "Grimmoch, well", - "versed in all manner", - "of wildlife, was", - "unsure as to their", - "nature - though I lay", - "blame upon the", - "darkness covering" - ), - new BookPageInfo( - "their movements", - "rather than on his", - "skill as a huntsman.", - "The attacks did not let", - "up the entire night,", - "and we were", - "eventually forced to", - "flee into the Tomb" - ), - new BookPageInfo( - "itself to take refuge", - "from the ravenous", - "creatures - e'en", - "Lysander's spells", - "could not keep the foul", - "things from attacking", - "in great numbers.", - "The Tomb performed" - ), - new BookPageInfo( - "well as an impromptu", - "fortress, and we", - "managed to spend the", - "night unscathed.", - "Morning's light", - "seemed to have", - "scattered the beasts,", - "as not a single one of" - ), - new BookPageInfo( - "them was to be seen as", - "we exited the Tomb -", - "not even a carcass of", - "the few that were", - "slain a'fore we fled.", - "Lysander set the crew", - "to work, moving our", - "supplies and gear into" - ), - new BookPageInfo( - "the Tomb, in case the", - "creatures did opt to", - "return. Such savage", - "fury had the beasts -", - "and not a single one", - "ever turned to run,", - "even in the face of", - "certain death." - ) - ); + base.Deserialize(reader); - [Constructible] - public TavarasJournal6() : base(Utility.Random(0xFF1, 2), false) - { - } - - public TavarasJournal6(Serial serial) : base(serial) - { - } - - public override BookContent DefaultContent => Content; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class TavarasJournal7 : BaseBook - { - public static readonly BookContent Content = new( - "Journal: Discovery of the Tomb", - "Tavara Sewel", - new BookPageInfo( - "Day Seven:", - "", - "T'was written that,", - "upon his death, Khal", - "Ankur's followers,", - "those known as the", - "Keepers of the", - "Seventh Death, sealed" - ), - new BookPageInfo( - "themselves within the", - "Sanctum they had", - "carved from the", - "mountains in his", - "honor. The Zealots of", - "his order entombed", - "the lesser followers", - "alive, then, when all" - ), - new BookPageInfo( - "but two remained, slit", - "their throats and", - "joined Khal Ankur in", - "death. Surely this is", - "not surprising for a", - "Cult that worshipped", - "death and sacrifice so", - "vehemently as it is" - ), - new BookPageInfo( - "said that the Keepers", - "did - and yet, to be in", - "this Tomb, to know", - "that somewhere in its", - "depths hundreds upon", - "hundreds of bodies", - "lay, sealed alive at", - "their own behest..." - ), - new BookPageInfo( - "I must confess that", - "the very thought of it", - "troubles my dreams at", - "night. I've asked", - "Lysander if we might", - "reestablish the camp", - "outside the Tomb,", - "setting up night" - ), - new BookPageInfo( - "watches and some sort", - "of fortification, but", - "he'll have none of it. I", - "did not press the", - "issue, as I suddenly", - "felt foolish even at", - "my askance." - ) - ); - - [Constructible] - public TavarasJournal7() : base(Utility.Random(0xFF1, 2), false) - { - } - - public TavarasJournal7(Serial serial) : base(serial) - { - } - - public override BookContent DefaultContent => Content; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class TavarasJournal8 : BaseBook - { - public static readonly BookContent Content = new( - "Journal: Discovery of the Tomb", - "Tavara Sewel", - new BookPageInfo( - "Day Eight :", - "", - "Astounding progress", - "was made today, and", - "my very head spins", - "with the excitement", - "of it. Upon full", - "excavation of the far" - ), - new BookPageInfo( - "western hall, another", - "large antechamber", - "was revealed. By the", - "larger, mosaic style of", - "the wall carvings and", - "their framing, as well", - "as the numerous", - "vellum scrolls and" - ), - new BookPageInfo( - "tomes held within, the", - "room appears to have", - "been a great museum", - "or library of sorts.", - "The sheer amount of", - "written information", - "encased within this", - "room would surely" - ), - new BookPageInfo( - "take me decades to", - "study e'en if I could", - "immediately decipher", - "the strange text with", - "which it was written.", - "My sheer joy at the", - "discovery was quickly", - "noted by the brute" - ), - new BookPageInfo( - "known as Morg", - "Bergen, who, even in", - "his simple way,", - "seemed just as", - "delighted as I that", - "some progress had", - "been made. I must", - "confess, upon his" - ), - new BookPageInfo( - "inclusion in our party", - "at the beginning of", - "this journey I was", - "somewhat suspect of", - "his nature, but he has", - "a startlingly quick wit", - "about him for such a", - "massive, calloused" - ), - new BookPageInfo( - "warrior. While", - "Lysander and e'en", - "Grimmoch always", - "seem to investigate the", - "tomb with a scowling", - "determination, Bergen", - "seems to feel the same", - "thrill of discovery as" - ), - new BookPageInfo( - "I. I am proud to now", - "count him as a friend,", - "and am thankful for", - "his laughter as well", - "as his strength." - ) - ); - - [Constructible] - public TavarasJournal8() : base(Utility.Random(0xFF1, 2), false) - { - } - - public TavarasJournal8(Serial serial) : base(serial) - { - } - - public override BookContent DefaultContent => Content; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class TavarasJournal9 : BaseBook - { - public static readonly BookContent Content = new( - "Journal: Discovery of the Tomb", - "Tavara Sewel", - new BookPageInfo( - "Day Nine - Day Ten:", - "", - "The excavation of the", - "next set of tunnels", - "has ceased, as three", - "of the workers have", - "gone missing in the", - "night. Bergen voiced" - ), - new BookPageInfo( - "the opinion that they", - "had most likely", - "abandoned our group", - "altogether and headed", - "back, as they were of", - "the number that", - "seemed especially", - "disturbed by the" - ), - new BookPageInfo( - "Tomb. Lysander had", - "other ideas, however.", - "In the middle of our", - "discussion on the", - "matter, he went into a", - "wild tirade on the", - "possibility that they", - "had somehow" - ), - new BookPageInfo( - "infiltrated the tomb's", - "interior without us.", - "The pure, hateful", - "venom in his voice", - "when he spoke of the", - "workers shocked me,", - "as I had always", - "thought him to be a" - ), - new BookPageInfo( - "levelheaded man of", - "great learning. As we", - "are still at work", - "digging out the rubble", - "that blocks all access", - "to the inner chambers,", - "I cannot help but", - "believe the workers" - ), - new BookPageInfo( - "must have fled the", - "site altogether, as", - "Bergen said." - ) - ); - - [Constructible] - public TavarasJournal9() : base(Utility.Random(0xFF1, 2), false) - { - } - - public TavarasJournal9(Serial serial) : base(serial) - { - } - - public override BookContent DefaultContent => Content; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class TavarasJournal11 : BaseBook - { - public static readonly BookContent Content = new( - "Journal: Discovery of the Tomb", - "Tavara Sewel", - new BookPageInfo( - "Day Eleven - Day", - "Thirteen:", - "", - "Two more workers", - "have gone missing.", - "Even more disturbing", - "is the fact that", - "Lysander has joined" - ), - new BookPageInfo( - "them. Late last night", - "the workers finished", - "excavating the next", - "main hall, and we", - "retired to the main", - "antechamber and our", - "camp to rest up for", - "exploration on the" - ), - new BookPageInfo( - "'morrow. In the", - "middle of the night we", - "woke to a strange", - "howling sound, and as", - "the men prepared", - "themselves for", - "another onslaught of", - "the beasts that had" - ), - new BookPageInfo( - "troubled our outer", - "camp, it was noticed", - "that Lysander was", - "nowhere in our", - "number. I cannot", - "fathom where he has", - "gone - the newly", - "revealed chamber" - ), - new BookPageInfo( - "holds no immediate", - "egress, blocked again", - "by piles of stone and", - "rubble, and I cannot", - "believe that Lysander,", - "of all people, would", - "have fled this site -", - "indeed, he had lately" - ), - new BookPageInfo( - "grown almost fanatical", - "in his work to", - "discover more of the", - "secrets barred to us", - "by the consistently", - "slow progress of", - "excavating each new", - "hallway. The men are" - ), - new BookPageInfo( - "at work even now, and", - "as the ceaseless", - "thumps and cracks of", - "their picks", - "reverberate", - "throughout the", - "entirety of the tomb,", - "the dust continues to" - ), - new BookPageInfo( - "pour down from the", - "ancient stonework", - "above us like some", - "horrible, eldritch", - "curse upon us all." - ) - ); - - [Constructible] - public TavarasJournal11() : base(Utility.Random(0xFF1, 2), false) - { - } - - public TavarasJournal11(Serial serial) : base(serial) - { - } - - public override BookContent DefaultContent => Content; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class TavarasJournal14 : BaseBook - { - public static readonly BookContent Content = new( - "Journal: Discovery of the Tomb", - "Tavara Sewel", - new BookPageInfo( - "Day Fourteen - Day", - "Fifteen:", - "", - "Lysander has", - "returned... and yet,", - "how can I describe the", - "horror of it? He", - "stands across the" - ), - new BookPageInfo( - "chamber from me", - "even now, a changed", - "man. His hair hangs", - "in grimy knots across", - "his face, his clothes", - "filthy and torn in", - "places... and the blood", - "- covered in blood, his" - ), - new BookPageInfo( - "skin shining in", - "scarlet reflections of", - "the torchlight. He", - "will let no one", - "approach; a thick,", - "rusted dagger in his", - "hand warding off any", - "attempts to overcome" - ), - new BookPageInfo( - "him. And the blood,", - "which runs down in", - "great rivulets from", - "his arms and hands -", - "it is not his own, and", - "this is enough to keep", - "us at a wary distance.", - "Morg Bergen wishes" - ), - new BookPageInfo( - "to subdue him", - "quickly, but there is", - "something in", - "Lysander's eyes - and", - "I remember the power", - "of his spells, even as", - "he swings the jagged", - "dagger back and forth" - ), - new BookPageInfo( - "in a wide swath", - "before him.", - "Something about the", - "sight of it makes my", - "stomach churn.", - "Something has", - "happened, something", - "that changes" - ), - new BookPageInfo( - "everything. Lysander", - "has lost his sanity to", - "this tomb... or to", - "something within it.", - "Do we dare approach?", - "We must make a", - "decision soon." - ) - ); - - [Constructible] - public TavarasJournal14() : base(Utility.Random(0xFF1, 2), false) - { - } - - public TavarasJournal14(Serial serial) : base(serial) - { - } - - public override BookContent DefaultContent => Content; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class TavarasJournal16 : BaseBook - { - public static readonly BookContent Content = new( - "Journal: Discovery of the Tomb", - "Tavara Sewel", - new BookPageInfo( - "Day Sixteen:", - "", - "Why do I write? I", - "must... not so much", - "because there must be", - "some record of", - "this... what's", - "happened here... as" - ), - new BookPageInfo( - "for my own sanity.", - "The act of putting pen", - "to paper calms me,", - "focuses me, even in", - "this madness.", - "Lysander is dead. So", - "many are dead. And", - "we're trapped here," - ), - new BookPageInfo( - "trapped forever in", - "this nightmare. He", - "would not let us pass,", - "wild in his psychosis,", - "furious, spitting,", - "covered in blood, he", - "swung the ancient", - "dagger at any who" - ), - new BookPageInfo( - "approached. He", - "babbled incoherently,", - "cursed at us, the most", - "hateful curses,", - "prophecy, doom upon", - "us. Bergen would", - "have none of it.", - "Finally, he leapt at" - ), - new BookPageInfo( - "Lysander, his", - "massive axe at his", - "side. But he would not", - "be the end of the mad", - "mage... no... they", - "were... those hands,", - "covered in the dirt of", - "the grave, maggots," - ), - new BookPageInfo( - "filth. They rose up", - "behind Lysander.", - "That look of curiosity", - "on the mage's face as", - "Bergen skidded to a", - "halt... t'was almost a", - "moment of sanity for", - "him, surely, to" - ), - new BookPageInfo( - "attempt to comprehend", - "what could have", - "stopped the warrior in", - "his tracks. And then", - "they were upon him.", - "Skeletal hands, arms", - "and faces with loose,", - "corrupted flesh" - ), - new BookPageInfo( - "hanging from yellow", - "bone. Inhuman, yet", - "once human,", - "staggering towards us", - "as their companions", - "tore at Lysander,", - "coming towards us in", - "droves." - ) - ); - - [Constructible] - public TavarasJournal16() : base(Utility.Random(0xFF1, 2), false) - { - } - - public TavarasJournal16(Serial serial) : base(serial) - { - } - - public override BookContent DefaultContent => Content; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class TavarasJournal16b : BaseBook - { - public static readonly BookContent Content = new( - "Journal: Discovery of the Tomb", - "Tavara Sewel", - new BookPageInfo( - "Day Sixteen, Later :", - "", - "We ran. What could", - "we do? We ran back", - "towards the entrance,", - "cutting at them when", - "we could. T'was a", - "nightmare, and yet" - ), - new BookPageInfo( - "nothing to prepare us", - "for what would come.", - "We were almost there,", - "the entrance to this", - "abhorred crypt in", - "sight. Then the earth", - "shook with such a", - "force that we were" - ), - new BookPageInfo( - "dropped to our hands", - "and knees, stumbling", - "in the darkness with", - "those... those things", - "surely behind us.", - "The noise of falling", - "rock and crumbling", - "stone drowned out our" - ), - new BookPageInfo( - "piteous cries. No sign", - "of the entrance", - "remained.", - "We owe our lives to", - "Bergen, whose wits", - "returned quickly.", - "That he could make us", - "hurry back into the" - ), - new BookPageInfo( - "main antechamber...", - "actually run back", - "towards those eldritch", - "dead that stalked us.", - "But we did, the", - "strength of his", - "convictions enough for", - "us in the moment." - ), - new BookPageInfo( - "And at our campsite", - "we erected our last", - "defense, a pitiable", - "wall of wood and", - "stone, anything at", - "hand that might block", - "the tide of those", - "nightmare creatures." - ), - new BookPageInfo( - "And I sit against it", - "even now. I can hear", - "their moans, their", - "wailing cries in the", - "distance - they'll be", - "here soon, even at the", - "unhurried pace of the", - "shuffling dead." - ) - ); - - [Constructible] - public TavarasJournal16b() : base(Utility.Random(0xFF1, 2), false) - { - } - - public TavarasJournal16b(Serial serial) : base(serial) - { - } - - public override BookContent DefaultContent => Content; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class TavarasJournal17 : BaseBook - { - public static readonly BookContent Content = new( - "Journal: Discovery of the Tomb", - "Tavara Sewel", - new BookPageInfo( - "Day Seventeen - Day", - "Eighteen :", - "", - "I cannot go on much", - "longer. I know now", - "t'was no work of the", - "earth that trapped us", - "here - I can feel His" - ), - new BookPageInfo( - "force in it. It was His", - "will, His power that", - "has sealed us here in", - "this nightmare. The", - "barricade will not be", - "enough. So many of", - "them. They come like", - "unto the ocean's waves" - ), - new BookPageInfo( - "- ceaseless,", - "neverending. For", - "every five we strike", - "down, another ten rise", - "up against us. And", - "like the sands we", - "cannot help but be", - "brought down, wasted" - ), - new BookPageInfo( - "away in this ocean of", - "blood." - ) - ); - - [Constructible] - public TavarasJournal17() : base(Utility.Random(0xFF1, 2), false) - { - } - - public TavarasJournal17(Serial serial) : base(serial) - { - } - - public override BookContent DefaultContent => Content; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } - } - - public class TavarasJournal19 : BaseBook - { - public static readonly BookContent Content = new( - "Journal: Discovery of the Tomb", - "Tavara Sewel", - new BookPageInfo( - "Day Nineteen - Day", - "Twenty-One :", - "", - "The barricade won't", - "hold - never, and", - "they'll come, they", - "come even now. I", - "would tear the last of" - ), - new BookPageInfo( - "it down, let them in to", - "devour us all, if only", - "to stop the screaming", - "- the awful, wailing", - "cries that fill the tomb", - "with their presence.", - "May my ancestors", - "forgive me, but it" - ), - new BookPageInfo( - "must be done. I must", - "end this." - ) - ); - - [Constructible] - public TavarasJournal19() : base(Utility.Random(0xFF1, 2), false) - { - } - - public TavarasJournal19(Serial serial) : base(serial) - { - } - - public override BookContent DefaultContent => Content; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - } + var version = reader.ReadEncodedInt(); } } + +public class TavarasJournal2 : BaseBook +{ + public static readonly BookContent Content = new( + "Journal: Discovery of the Tomb", + "Tavara Sewel", + new BookPageInfo( + "Day Two:", + "", + "Everything we'd", + "heard and read of the", + "tomb has proved", + "correct - and yet,", + "nothing could prepare", + "me for the sight of it" + ), + new BookPageInfo( + "with my own eyes.", + "The Tomb of Khal", + "Ankur has given up", + "its secrets at last! The", + "intricate stonework", + "that covered the tomb", + "doors seems to", + "continue throughout" + ), + new BookPageInfo( + "the entirety of the", + "catacombs, each", + "hallway and room", + "yielding a seemingly", + "endless amount of", + "information for my", + "companions and I to", + "record. It will take" + ), + new BookPageInfo( + "years to catalogue the", + "entirety of the Tomb,", + "if those legends of its", + "massive size prove", + "true. Sadly, a good", + "deal of the Tomb's", + "interior has been", + "damaged or utterly" + ), + new BookPageInfo( + "destroyed, whether", + "by seismic activity in", + "the surrounding", + "mountainside or", + "merely the slow", + "efforts of Time", + "itself, I do not know.", + "A good deal of the" + ), + new BookPageInfo( + "stonework has been", + "cracked or collapsed", + "entirely, especially", + "near the entrance", + "supports of the main", + "hall. Our passage has", + "indeed already been", + "entirely blocked in the" + ), + new BookPageInfo( + "first major room", + "we've discovered, a", + "massive pile of", + "boulders and stones", + "blocking any exit", + "from the", + "antechamber. What", + "could have caused" + ), + new BookPageInfo( + "such a localized", + "disruption of the", + "support structures,", + "one can only guess -", + "but it will surely take", + "an entire afternoon's", + "effort to remove even", + "a fraction of it. I look" + ), + new BookPageInfo( + "forward to more", + "progress tomorrow", + "once the workers have", + "set to excavating the", + "hall." + ) + ); + + [Constructible] + public TavarasJournal2() : base(Utility.Random(0xFF1, 2), false) + { + } + + public TavarasJournal2(Serial serial) : base(serial) + { + } + + public override BookContent DefaultContent => Content; + + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + + writer.WriteEncodedInt(0); // version + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + + var version = reader.ReadEncodedInt(); + } +} + +public class TavarasJournal3 : BaseBook +{ + public static readonly BookContent Content = new( + "Journal: Discovery of the Tomb", + "Tavara Sewel", + new BookPageInfo( + "Day Three - Day Five:", + "", + "I do not understand", + "this place... not as I", + "once thought I did.", + "Something palatable", + "seems to hinder our", + "every attempt to" + ), + new BookPageInfo( + "investigate this", + "ancient site.", + "Excavation work on", + "the first major", + "hallway finished only", + "yesterday - the", + "amount of stone and", + "rubble blocking the" + ), + new BookPageInfo( + "egress was", + "astounding, it stands", + "in immense piles", + "outside the Tomb's", + "entrance, as if we", + "were digging the", + "tunnels of this", + "abhorred place" + ), + new BookPageInfo( + "ourselves! The", + "satisfaction of", + "completing our efforts", + "was quickly thwarted,", + "however, as we", + "discovered the end of", + "the hallway we had", + "just revealed was" + ), + new BookPageInfo( + "blocked by yet another", + "colossal pile of stone.", + "I've had a few of the", + "workers set up", + "primitive scaffolding", + "in the main", + "antechamber so that I", + "can spend my time" + ), + new BookPageInfo( + "pouring over the detail", + "work on the stone", + "carvings while the", + "rest of our crew", + "continue excavating", + "the inner halls." + ) + ); + + [Constructible] + public TavarasJournal3() : base(Utility.Random(0xFF1, 2), false) + { + } + + public TavarasJournal3(Serial serial) : base(serial) + { + } + + public override BookContent DefaultContent => Content; + + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + + writer.WriteEncodedInt(0); // version + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + + var version = reader.ReadEncodedInt(); + } +} + +public class TavarasJournal6 : BaseBook +{ + public static readonly BookContent Content = new( + "Journal: Discovery of the Tomb", + "Tavara Sewel", + new BookPageInfo( + "Day Six:", + "", + "Late last night our", + "camp was set upon by", + "a pack of wild beasts", + "- behemoth creatures", + "with a speed and", + "viciousness I'd n'ere" + ), + new BookPageInfo( + "before seen. Even", + "Grimmoch, well", + "versed in all manner", + "of wildlife, was", + "unsure as to their", + "nature - though I lay", + "blame upon the", + "darkness covering" + ), + new BookPageInfo( + "their movements", + "rather than on his", + "skill as a huntsman.", + "The attacks did not let", + "up the entire night,", + "and we were", + "eventually forced to", + "flee into the Tomb" + ), + new BookPageInfo( + "itself to take refuge", + "from the ravenous", + "creatures - e'en", + "Lysander's spells", + "could not keep the foul", + "things from attacking", + "in great numbers.", + "The Tomb performed" + ), + new BookPageInfo( + "well as an impromptu", + "fortress, and we", + "managed to spend the", + "night unscathed.", + "Morning's light", + "seemed to have", + "scattered the beasts,", + "as not a single one of" + ), + new BookPageInfo( + "them was to be seen as", + "we exited the Tomb -", + "not even a carcass of", + "the few that were", + "slain a'fore we fled.", + "Lysander set the crew", + "to work, moving our", + "supplies and gear into" + ), + new BookPageInfo( + "the Tomb, in case the", + "creatures did opt to", + "return. Such savage", + "fury had the beasts -", + "and not a single one", + "ever turned to run,", + "even in the face of", + "certain death." + ) + ); + + [Constructible] + public TavarasJournal6() : base(Utility.Random(0xFF1, 2), false) + { + } + + public TavarasJournal6(Serial serial) : base(serial) + { + } + + public override BookContent DefaultContent => Content; + + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + + writer.WriteEncodedInt(0); // version + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + + var version = reader.ReadEncodedInt(); + } +} + +public class TavarasJournal7 : BaseBook +{ + public static readonly BookContent Content = new( + "Journal: Discovery of the Tomb", + "Tavara Sewel", + new BookPageInfo( + "Day Seven:", + "", + "T'was written that,", + "upon his death, Khal", + "Ankur's followers,", + "those known as the", + "Keepers of the", + "Seventh Death, sealed" + ), + new BookPageInfo( + "themselves within the", + "Sanctum they had", + "carved from the", + "mountains in his", + "honor. The Zealots of", + "his order entombed", + "the lesser followers", + "alive, then, when all" + ), + new BookPageInfo( + "but two remained, slit", + "their throats and", + "joined Khal Ankur in", + "death. Surely this is", + "not surprising for a", + "Cult that worshipped", + "death and sacrifice so", + "vehemently as it is" + ), + new BookPageInfo( + "said that the Keepers", + "did - and yet, to be in", + "this Tomb, to know", + "that somewhere in its", + "depths hundreds upon", + "hundreds of bodies", + "lay, sealed alive at", + "their own behest..." + ), + new BookPageInfo( + "I must confess that", + "the very thought of it", + "troubles my dreams at", + "night. I've asked", + "Lysander if we might", + "reestablish the camp", + "outside the Tomb,", + "setting up night" + ), + new BookPageInfo( + "watches and some sort", + "of fortification, but", + "he'll have none of it. I", + "did not press the", + "issue, as I suddenly", + "felt foolish even at", + "my askance." + ) + ); + + [Constructible] + public TavarasJournal7() : base(Utility.Random(0xFF1, 2), false) + { + } + + public TavarasJournal7(Serial serial) : base(serial) + { + } + + public override BookContent DefaultContent => Content; + + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + + writer.WriteEncodedInt(0); // version + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + + var version = reader.ReadEncodedInt(); + } +} + +public class TavarasJournal8 : BaseBook +{ + public static readonly BookContent Content = new( + "Journal: Discovery of the Tomb", + "Tavara Sewel", + new BookPageInfo( + "Day Eight :", + "", + "Astounding progress", + "was made today, and", + "my very head spins", + "with the excitement", + "of it. Upon full", + "excavation of the far" + ), + new BookPageInfo( + "western hall, another", + "large antechamber", + "was revealed. By the", + "larger, mosaic style of", + "the wall carvings and", + "their framing, as well", + "as the numerous", + "vellum scrolls and" + ), + new BookPageInfo( + "tomes held within, the", + "room appears to have", + "been a great museum", + "or library of sorts.", + "The sheer amount of", + "written information", + "encased within this", + "room would surely" + ), + new BookPageInfo( + "take me decades to", + "study e'en if I could", + "immediately decipher", + "the strange text with", + "which it was written.", + "My sheer joy at the", + "discovery was quickly", + "noted by the brute" + ), + new BookPageInfo( + "known as Morg", + "Bergen, who, even in", + "his simple way,", + "seemed just as", + "delighted as I that", + "some progress had", + "been made. I must", + "confess, upon his" + ), + new BookPageInfo( + "inclusion in our party", + "at the beginning of", + "this journey I was", + "somewhat suspect of", + "his nature, but he has", + "a startlingly quick wit", + "about him for such a", + "massive, calloused" + ), + new BookPageInfo( + "warrior. While", + "Lysander and e'en", + "Grimmoch always", + "seem to investigate the", + "tomb with a scowling", + "determination, Bergen", + "seems to feel the same", + "thrill of discovery as" + ), + new BookPageInfo( + "I. I am proud to now", + "count him as a friend,", + "and am thankful for", + "his laughter as well", + "as his strength." + ) + ); + + [Constructible] + public TavarasJournal8() : base(Utility.Random(0xFF1, 2), false) + { + } + + public TavarasJournal8(Serial serial) : base(serial) + { + } + + public override BookContent DefaultContent => Content; + + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + + writer.WriteEncodedInt(0); // version + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + + var version = reader.ReadEncodedInt(); + } +} + +public class TavarasJournal9 : BaseBook +{ + public static readonly BookContent Content = new( + "Journal: Discovery of the Tomb", + "Tavara Sewel", + new BookPageInfo( + "Day Nine - Day Ten:", + "", + "The excavation of the", + "next set of tunnels", + "has ceased, as three", + "of the workers have", + "gone missing in the", + "night. Bergen voiced" + ), + new BookPageInfo( + "the opinion that they", + "had most likely", + "abandoned our group", + "altogether and headed", + "back, as they were of", + "the number that", + "seemed especially", + "disturbed by the" + ), + new BookPageInfo( + "Tomb. Lysander had", + "other ideas, however.", + "In the middle of our", + "discussion on the", + "matter, he went into a", + "wild tirade on the", + "possibility that they", + "had somehow" + ), + new BookPageInfo( + "infiltrated the tomb's", + "interior without us.", + "The pure, hateful", + "venom in his voice", + "when he spoke of the", + "workers shocked me,", + "as I had always", + "thought him to be a" + ), + new BookPageInfo( + "levelheaded man of", + "great learning. As we", + "are still at work", + "digging out the rubble", + "that blocks all access", + "to the inner chambers,", + "I cannot help but", + "believe the workers" + ), + new BookPageInfo( + "must have fled the", + "site altogether, as", + "Bergen said." + ) + ); + + [Constructible] + public TavarasJournal9() : base(Utility.Random(0xFF1, 2), false) + { + } + + public TavarasJournal9(Serial serial) : base(serial) + { + } + + public override BookContent DefaultContent => Content; + + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + + writer.WriteEncodedInt(0); // version + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + + var version = reader.ReadEncodedInt(); + } +} + +public class TavarasJournal11 : BaseBook +{ + public static readonly BookContent Content = new( + "Journal: Discovery of the Tomb", + "Tavara Sewel", + new BookPageInfo( + "Day Eleven - Day", + "Thirteen:", + "", + "Two more workers", + "have gone missing.", + "Even more disturbing", + "is the fact that", + "Lysander has joined" + ), + new BookPageInfo( + "them. Late last night", + "the workers finished", + "excavating the next", + "main hall, and we", + "retired to the main", + "antechamber and our", + "camp to rest up for", + "exploration on the" + ), + new BookPageInfo( + "'morrow. In the", + "middle of the night we", + "woke to a strange", + "howling sound, and as", + "the men prepared", + "themselves for", + "another onslaught of", + "the beasts that had" + ), + new BookPageInfo( + "troubled our outer", + "camp, it was noticed", + "that Lysander was", + "nowhere in our", + "number. I cannot", + "fathom where he has", + "gone - the newly", + "revealed chamber" + ), + new BookPageInfo( + "holds no immediate", + "egress, blocked again", + "by piles of stone and", + "rubble, and I cannot", + "believe that Lysander,", + "of all people, would", + "have fled this site -", + "indeed, he had lately" + ), + new BookPageInfo( + "grown almost fanatical", + "in his work to", + "discover more of the", + "secrets barred to us", + "by the consistently", + "slow progress of", + "excavating each new", + "hallway. The men are" + ), + new BookPageInfo( + "at work even now, and", + "as the ceaseless", + "thumps and cracks of", + "their picks", + "reverberate", + "throughout the", + "entirety of the tomb,", + "the dust continues to" + ), + new BookPageInfo( + "pour down from the", + "ancient stonework", + "above us like some", + "horrible, eldritch", + "curse upon us all." + ) + ); + + [Constructible] + public TavarasJournal11() : base(Utility.Random(0xFF1, 2), false) + { + } + + public TavarasJournal11(Serial serial) : base(serial) + { + } + + public override BookContent DefaultContent => Content; + + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + + writer.WriteEncodedInt(0); // version + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + + var version = reader.ReadEncodedInt(); + } +} + +public class TavarasJournal14 : BaseBook +{ + public static readonly BookContent Content = new( + "Journal: Discovery of the Tomb", + "Tavara Sewel", + new BookPageInfo( + "Day Fourteen - Day", + "Fifteen:", + "", + "Lysander has", + "returned... and yet,", + "how can I describe the", + "horror of it? He", + "stands across the" + ), + new BookPageInfo( + "chamber from me", + "even now, a changed", + "man. His hair hangs", + "in grimy knots across", + "his face, his clothes", + "filthy and torn in", + "places... and the blood", + "- covered in blood, his" + ), + new BookPageInfo( + "skin shining in", + "scarlet reflections of", + "the torchlight. He", + "will let no one", + "approach; a thick,", + "rusted dagger in his", + "hand warding off any", + "attempts to overcome" + ), + new BookPageInfo( + "him. And the blood,", + "which runs down in", + "great rivulets from", + "his arms and hands -", + "it is not his own, and", + "this is enough to keep", + "us at a wary distance.", + "Morg Bergen wishes" + ), + new BookPageInfo( + "to subdue him", + "quickly, but there is", + "something in", + "Lysander's eyes - and", + "I remember the power", + "of his spells, even as", + "he swings the jagged", + "dagger back and forth" + ), + new BookPageInfo( + "in a wide swath", + "before him.", + "Something about the", + "sight of it makes my", + "stomach churn.", + "Something has", + "happened, something", + "that changes" + ), + new BookPageInfo( + "everything. Lysander", + "has lost his sanity to", + "this tomb... or to", + "something within it.", + "Do we dare approach?", + "We must make a", + "decision soon." + ) + ); + + [Constructible] + public TavarasJournal14() : base(Utility.Random(0xFF1, 2), false) + { + } + + public TavarasJournal14(Serial serial) : base(serial) + { + } + + public override BookContent DefaultContent => Content; + + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + + writer.WriteEncodedInt(0); // version + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + + var version = reader.ReadEncodedInt(); + } +} + +public class TavarasJournal16 : BaseBook +{ + public static readonly BookContent Content = new( + "Journal: Discovery of the Tomb", + "Tavara Sewel", + new BookPageInfo( + "Day Sixteen:", + "", + "Why do I write? I", + "must... not so much", + "because there must be", + "some record of", + "this... what's", + "happened here... as" + ), + new BookPageInfo( + "for my own sanity.", + "The act of putting pen", + "to paper calms me,", + "focuses me, even in", + "this madness.", + "Lysander is dead. So", + "many are dead. And", + "we're trapped here," + ), + new BookPageInfo( + "trapped forever in", + "this nightmare. He", + "would not let us pass,", + "wild in his psychosis,", + "furious, spitting,", + "covered in blood, he", + "swung the ancient", + "dagger at any who" + ), + new BookPageInfo( + "approached. He", + "babbled incoherently,", + "cursed at us, the most", + "hateful curses,", + "prophecy, doom upon", + "us. Bergen would", + "have none of it.", + "Finally, he leapt at" + ), + new BookPageInfo( + "Lysander, his", + "massive axe at his", + "side. But he would not", + "be the end of the mad", + "mage... no... they", + "were... those hands,", + "covered in the dirt of", + "the grave, maggots," + ), + new BookPageInfo( + "filth. They rose up", + "behind Lysander.", + "That look of curiosity", + "on the mage's face as", + "Bergen skidded to a", + "halt... t'was almost a", + "moment of sanity for", + "him, surely, to" + ), + new BookPageInfo( + "attempt to comprehend", + "what could have", + "stopped the warrior in", + "his tracks. And then", + "they were upon him.", + "Skeletal hands, arms", + "and faces with loose,", + "corrupted flesh" + ), + new BookPageInfo( + "hanging from yellow", + "bone. Inhuman, yet", + "once human,", + "staggering towards us", + "as their companions", + "tore at Lysander,", + "coming towards us in", + "droves." + ) + ); + + [Constructible] + public TavarasJournal16() : base(Utility.Random(0xFF1, 2), false) + { + } + + public TavarasJournal16(Serial serial) : base(serial) + { + } + + public override BookContent DefaultContent => Content; + + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + + writer.WriteEncodedInt(0); // version + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + + var version = reader.ReadEncodedInt(); + } +} + +public class TavarasJournal16b : BaseBook +{ + public static readonly BookContent Content = new( + "Journal: Discovery of the Tomb", + "Tavara Sewel", + new BookPageInfo( + "Day Sixteen, Later :", + "", + "We ran. What could", + "we do? We ran back", + "towards the entrance,", + "cutting at them when", + "we could. T'was a", + "nightmare, and yet" + ), + new BookPageInfo( + "nothing to prepare us", + "for what would come.", + "We were almost there,", + "the entrance to this", + "abhorred crypt in", + "sight. Then the earth", + "shook with such a", + "force that we were" + ), + new BookPageInfo( + "dropped to our hands", + "and knees, stumbling", + "in the darkness with", + "those... those things", + "surely behind us.", + "The noise of falling", + "rock and crumbling", + "stone drowned out our" + ), + new BookPageInfo( + "piteous cries. No sign", + "of the entrance", + "remained.", + "We owe our lives to", + "Bergen, whose wits", + "returned quickly.", + "That he could make us", + "hurry back into the" + ), + new BookPageInfo( + "main antechamber...", + "actually run back", + "towards those eldritch", + "dead that stalked us.", + "But we did, the", + "strength of his", + "convictions enough for", + "us in the moment." + ), + new BookPageInfo( + "And at our campsite", + "we erected our last", + "defense, a pitiable", + "wall of wood and", + "stone, anything at", + "hand that might block", + "the tide of those", + "nightmare creatures." + ), + new BookPageInfo( + "And I sit against it", + "even now. I can hear", + "their moans, their", + "wailing cries in the", + "distance - they'll be", + "here soon, even at the", + "unhurried pace of the", + "shuffling dead." + ) + ); + + [Constructible] + public TavarasJournal16b() : base(Utility.Random(0xFF1, 2), false) + { + } + + public TavarasJournal16b(Serial serial) : base(serial) + { + } + + public override BookContent DefaultContent => Content; + + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + + writer.WriteEncodedInt(0); // version + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + + var version = reader.ReadEncodedInt(); + } +} + +public class TavarasJournal17 : BaseBook +{ + public static readonly BookContent Content = new( + "Journal: Discovery of the Tomb", + "Tavara Sewel", + new BookPageInfo( + "Day Seventeen - Day", + "Eighteen :", + "", + "I cannot go on much", + "longer. I know now", + "t'was no work of the", + "earth that trapped us", + "here - I can feel His" + ), + new BookPageInfo( + "force in it. It was His", + "will, His power that", + "has sealed us here in", + "this nightmare. The", + "barricade will not be", + "enough. So many of", + "them. They come like", + "unto the ocean's waves" + ), + new BookPageInfo( + "- ceaseless,", + "neverending. For", + "every five we strike", + "down, another ten rise", + "up against us. And", + "like the sands we", + "cannot help but be", + "brought down, wasted" + ), + new BookPageInfo( + "away in this ocean of", + "blood." + ) + ); + + [Constructible] + public TavarasJournal17() : base(Utility.Random(0xFF1, 2), false) + { + } + + public TavarasJournal17(Serial serial) : base(serial) + { + } + + public override BookContent DefaultContent => Content; + + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + + writer.WriteEncodedInt(0); // version + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + + var version = reader.ReadEncodedInt(); + } +} + +public class TavarasJournal19 : BaseBook +{ + public static readonly BookContent Content = new( + "Journal: Discovery of the Tomb", + "Tavara Sewel", + new BookPageInfo( + "Day Nineteen - Day", + "Twenty-One :", + "", + "The barricade won't", + "hold - never, and", + "they'll come, they", + "come even now. I", + "would tear the last of" + ), + new BookPageInfo( + "it down, let them in to", + "devour us all, if only", + "to stop the screaming", + "- the awful, wailing", + "cries that fill the tomb", + "with their presence.", + "May my ancestors", + "forgive me, but it" + ), + new BookPageInfo( + "must be done. I must", + "end this." + ) + ); + + [Constructible] + public TavarasJournal19() : base(Utility.Random(0xFF1, 2), false) + { + } + + public TavarasJournal19(Serial serial) : base(serial) + { + } + + public override BookContent DefaultContent => Content; + + public override void Serialize(IGenericWriter writer) + { + base.Serialize(writer); + + writer.WriteEncodedInt(0); // version + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + + var version = reader.ReadEncodedInt(); + } +} \ No newline at end of file diff --git a/Projects/UOContent/Engines/Khaldun/KhaldunPitTeleporter.cs b/Projects/UOContent/Engines/Khaldun/KhaldunPitTeleporter.cs index 66e910959..b1b5c6d52 100644 --- a/Projects/UOContent/Engines/Khaldun/KhaldunPitTeleporter.cs +++ b/Projects/UOContent/Engines/Khaldun/KhaldunPitTeleporter.cs @@ -1,86 +1,64 @@ +using ModernUO.Serialization; using Server.Mobiles; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(0, false)] +public partial class KhaldunPitTeleporter : Item { - public class KhaldunPitTeleporter : Item + [SerializableField(0)] + [SerializedCommandProperty(AccessLevel.GameMaster)] + private bool _active; + + [SerializableField(1)] + [SerializedCommandProperty(AccessLevel.GameMaster)] + private Point3D _pointDest; + + [SerializableField(2)] + [SerializedCommandProperty(AccessLevel.GameMaster)] + private Map _mapDest; + + [Constructible] + public KhaldunPitTeleporter() : this(new Point3D(5451, 1374, 0), Map.Felucca) { - [Constructible] - public KhaldunPitTeleporter() : this(new Point3D(5451, 1374, 0), Map.Felucca) + } + + [Constructible] + public KhaldunPitTeleporter(Point3D pointDest, Map mapDest) : base(0x053B) + { + Movable = false; + Hue = 1; + + _active = true; + _pointDest = pointDest; + _mapDest = mapDest; + } + + // the floor of the cavern seems to have collapsed here - a faint light is visible at the bottom of the pit + public override int LabelNumber => 1016511; + + public override void OnDoubleClick(Mobile m) + { + if (!Active) { + return; } - [Constructible] - public KhaldunPitTeleporter(Point3D pointDest, Map mapDest) : base(0x053B) - { - Movable = false; - Hue = 1; + var map = MapDest; - Active = true; - PointDest = pointDest; - MapDest = mapDest; + if (map != null && map != Map.Internal && m.InRange(this, 3)) + { + BaseCreature.TeleportPets(m, PointDest, MapDest); + m.MoveToWorld(PointDest, MapDest); } - - public KhaldunPitTeleporter(Serial serial) : base(serial) + else { - } - - [CommandProperty(AccessLevel.GameMaster)] - public bool Active { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public Point3D PointDest { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public Map MapDest { get; set; } - - // the floor of the cavern seems to have collapsed here - a faint light is visible at the bottom of the pit - public override int LabelNumber => 1016511; - - public override void OnDoubleClick(Mobile m) - { - if (!Active) - { - return; - } - - var map = MapDest; - - if (map != null && map != Map.Internal && m.InRange(this, 3)) - { - BaseCreature.TeleportPets(m, PointDest, MapDest); - m.MoveToWorld(PointDest, MapDest); - } - else - { - m.SendLocalizedMessage(1019045); // I can't reach that. - } - } - - public override void OnDoubleClickDead(Mobile m) - { - OnDoubleClick(m); - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); // version - - writer.Write(Active); - writer.Write(PointDest); - writer.Write(MapDest); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - Active = reader.ReadBool(); - PointDest = reader.ReadPoint3D(); - MapDest = reader.ReadMap(); + m.SendLocalizedMessage(1019045); // I can't reach that. } } + + public override void OnDoubleClickDead(Mobile m) + { + OnDoubleClick(m); + } } diff --git a/Projects/UOContent/Engines/Khaldun/Mobiles/GrimmochDrummel.cs b/Projects/UOContent/Engines/Khaldun/Mobiles/GrimmochDrummel.cs index d18e54dc8..5bb348cbe 100644 --- a/Projects/UOContent/Engines/Khaldun/Mobiles/GrimmochDrummel.cs +++ b/Projects/UOContent/Engines/Khaldun/Mobiles/GrimmochDrummel.cs @@ -1,122 +1,106 @@ +using ModernUO.Serialization; using Server.Items; -namespace Server.Mobiles +namespace Server.Mobiles; + +[SerializationGenerator(0, false)] +public partial class GrimmochDrummel : BaseCreature { - public class GrimmochDrummel : BaseCreature + [Constructible] + public GrimmochDrummel() : base(AIType.AI_Archer) { - [Constructible] - public GrimmochDrummel() : base(AIType.AI_Archer) + Title = "the Cursed"; + + Hue = 0x8596; + Body = 0x190; + + HairItemID = 0x204A; // Krisna + + var bow = new Bow(); + bow.Movable = false; + AddItem(bow); + + AddItem(new Boots(0x8A4)); + AddItem(new BodySash(0x8A4)); + + var backpack = new Backpack(); + backpack.Movable = false; + AddItem(backpack); + + var gloves = new LeatherGloves(); + var chest = new LeatherChest(); + gloves.Hue = 0x96F; + chest.Hue = 0x96F; + + AddItem(gloves); + AddItem(chest); + + SetStr(111, 120); + SetDex(151, 160); + SetInt(41, 50); + + SetHits(180, 207); + SetMana(0); + + SetDamage(13, 16); + + SetResistance(ResistanceType.Physical, 35, 45); + SetResistance(ResistanceType.Fire, 25, 30); + SetResistance(ResistanceType.Cold, 45, 55); + SetResistance(ResistanceType.Poison, 30, 40); + SetResistance(ResistanceType.Energy, 20, 25); + + SetSkill(SkillName.Archery, 90.1, 110.0); + SetSkill(SkillName.Swords, 60.1, 70.0); + SetSkill(SkillName.Tactics, 90.1, 100.0); + SetSkill(SkillName.MagicResist, 60.1, 70.0); + SetSkill(SkillName.Anatomy, 90.1, 100.0); + + Fame = 5000; + Karma = -1000; + + PackItem(new Arrow(40)); + + if (Utility.Random(100) < 3) { - Title = "the Cursed"; - - Hue = 0x8596; - Body = 0x190; - - HairItemID = 0x204A; // Krisna - - var bow = new Bow(); - bow.Movable = false; - AddItem(bow); - - AddItem(new Boots(0x8A4)); - AddItem(new BodySash(0x8A4)); - - var backpack = new Backpack(); - backpack.Movable = false; - AddItem(backpack); - - var gloves = new LeatherGloves(); - var chest = new LeatherChest(); - gloves.Hue = 0x96F; - chest.Hue = 0x96F; - - AddItem(gloves); - AddItem(chest); - - SetStr(111, 120); - SetDex(151, 160); - SetInt(41, 50); - - SetHits(180, 207); - SetMana(0); - - SetDamage(13, 16); - - SetResistance(ResistanceType.Physical, 35, 45); - SetResistance(ResistanceType.Fire, 25, 30); - SetResistance(ResistanceType.Cold, 45, 55); - SetResistance(ResistanceType.Poison, 30, 40); - SetResistance(ResistanceType.Energy, 20, 25); - - SetSkill(SkillName.Archery, 90.1, 110.0); - SetSkill(SkillName.Swords, 60.1, 70.0); - SetSkill(SkillName.Tactics, 90.1, 100.0); - SetSkill(SkillName.MagicResist, 60.1, 70.0); - SetSkill(SkillName.Anatomy, 90.1, 100.0); - - Fame = 5000; - Karma = -1000; - - PackItem(new Arrow(40)); - - if (Utility.Random(100) < 3) - { - PackItem(new FireHorn()); - } - - if (Utility.Random(3) < 1) - { - PackItem(Loot.RandomGrimmochJournal()); - } + PackItem(new FireHorn()); } - public GrimmochDrummel(Serial serial) : base(serial) + if (Utility.Random(3) < 1) { - } - - public override bool ClickTitle => false; - public override bool ShowFameTitle => false; - public override bool DeleteCorpseOnDeath => true; - public override string DefaultName => "Grimmoch Drummel"; - - public override bool AlwaysMurderer => true; - - public override int GetIdleSound() => 0x178; - - public override int GetAngerSound() => 0x1AC; - - public override int GetDeathSound() => 0x27E; - - public override int GetHurtSound() => 0x177; - - public override bool OnBeforeDeath() - { - var gold = new Gold(Utility.RandomMinMax(190, 230)); - gold.MoveToWorld(Location, Map); - - var pack = Backpack; - if (pack != null) - { - pack.Movable = true; - pack.MoveToWorld(Location, Map); - } - - Effects.SendLocationEffect(Location, Map, 0x376A, 10, 1); - return true; - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); + PackItem(Loot.RandomGrimmochJournal()); } } + + public override bool ClickTitle => false; + public override bool ShowFameTitle => false; + public override bool DeleteCorpseOnDeath => true; + public override string DefaultName => "Grimmoch Drummel"; + + public override bool AlwaysMurderer => true; + + public override int GetIdleSound() => 0x178; + + public override int GetAngerSound() => 0x1AC; + + public override int GetDeathSound() => 0x27E; + + public override int GetHurtSound() => 0x177; + + public override bool OnBeforeDeath() + { + var gold = new Gold(Utility.RandomMinMax(190, 230)); + gold.MoveToWorld(Location, Map); + + var pack = Backpack; + if (pack != null) + { + pack.Movable = true; + pack.MoveToWorld(Location, Map); + } + + Effects.SendLocationEffect(Location, Map, 0x376A, 10, 1); + return true; + } + } diff --git a/Projects/UOContent/Engines/Khaldun/Mobiles/LysanderGathenwale.cs b/Projects/UOContent/Engines/Khaldun/Mobiles/LysanderGathenwale.cs index 8d7f2cb3d..f3870261a 100644 --- a/Projects/UOContent/Engines/Khaldun/Mobiles/LysanderGathenwale.cs +++ b/Projects/UOContent/Engines/Khaldun/Mobiles/LysanderGathenwale.cs @@ -1,120 +1,103 @@ +using ModernUO.Serialization; using Server.Items; -namespace Server.Mobiles +namespace Server.Mobiles; + +[SerializationGenerator(0, false)] +public partial class LysanderGathenwale : BaseCreature { - public class LysanderGathenwale : BaseCreature + [Constructible] + public LysanderGathenwale() : base(AIType.AI_Mage) { - [Constructible] - public LysanderGathenwale() : base(AIType.AI_Mage) + Title = "the Cursed"; + + Hue = 0x8838; + Body = 0x190; + + AddItem(new Boots(0x599)); + AddItem(new Cloak(0x96F)); + + var spellbook = new Spellbook(); + var gloves = new RingmailGloves(); + var chest = new StuddedChest(); + var arms = new PlateArms(); + + spellbook.Hue = 0x599; + gloves.Hue = 0x599; + chest.Hue = 0x96F; + arms.Hue = 0x599; + + AddItem(spellbook); + AddItem(gloves); + AddItem(chest); + AddItem(arms); + + SetStr(111, 120); + SetDex(71, 80); + SetInt(121, 130); + + SetHits(180, 207); + SetMana(227, 265); + + SetDamage(5, 13); + + SetResistance(ResistanceType.Physical, 35, 45); + SetResistance(ResistanceType.Fire, 25, 30); + SetResistance(ResistanceType.Cold, 50, 60); + SetResistance(ResistanceType.Poison, 25, 35); + SetResistance(ResistanceType.Energy, 25, 35); + + SetSkill(SkillName.Wrestling, 80.1, 90.0); + SetSkill(SkillName.Tactics, 90.1, 100.0); + SetSkill(SkillName.MagicResist, 80.1, 90.0); + SetSkill(SkillName.Magery, 90.1, 100.0); + SetSkill(SkillName.EvalInt, 95.1, 100.0); + SetSkill(SkillName.Meditation, 90.1, 100.0); + + Fame = 5000; + Karma = -10000; + + var reags = Loot.RandomReagent(); + reags.Amount = 30; + PackItem(reags); + } + + public override bool ClickTitle => false; + public override bool ShowFameTitle => false; + public override bool DeleteCorpseOnDeath => true; + public override string DefaultName => "Lysander Gatherwale"; + + public override bool AlwaysMurderer => true; + + public override int GetIdleSound() => 0x1CE; + + public override int GetAngerSound() => 0x1AC; + + public override int GetDeathSound() => 0x182; + + public override int GetHurtSound() => 0x28D; + + public override void GenerateLoot() + { + AddLoot(LootPack.MedScrolls, 2); + } + + public override bool OnBeforeDeath() + { + if (!base.OnBeforeDeath()) { - Title = "the Cursed"; - - Hue = 0x8838; - Body = 0x190; - - AddItem(new Boots(0x599)); - AddItem(new Cloak(0x96F)); - - var spellbook = new Spellbook(); - var gloves = new RingmailGloves(); - var chest = new StuddedChest(); - var arms = new PlateArms(); - - spellbook.Hue = 0x599; - gloves.Hue = 0x599; - chest.Hue = 0x96F; - arms.Hue = 0x599; - - AddItem(spellbook); - AddItem(gloves); - AddItem(chest); - AddItem(arms); - - SetStr(111, 120); - SetDex(71, 80); - SetInt(121, 130); - - SetHits(180, 207); - SetMana(227, 265); - - SetDamage(5, 13); - - SetResistance(ResistanceType.Physical, 35, 45); - SetResistance(ResistanceType.Fire, 25, 30); - SetResistance(ResistanceType.Cold, 50, 60); - SetResistance(ResistanceType.Poison, 25, 35); - SetResistance(ResistanceType.Energy, 25, 35); - - SetSkill(SkillName.Wrestling, 80.1, 90.0); - SetSkill(SkillName.Tactics, 90.1, 100.0); - SetSkill(SkillName.MagicResist, 80.1, 90.0); - SetSkill(SkillName.Magery, 90.1, 100.0); - SetSkill(SkillName.EvalInt, 95.1, 100.0); - SetSkill(SkillName.Meditation, 90.1, 100.0); - - Fame = 5000; - Karma = -10000; - - var reags = Loot.RandomReagent(); - reags.Amount = 30; - PackItem(reags); + return false; } - public LysanderGathenwale(Serial serial) : base(serial) + Backpack?.Destroy(); + + if (Utility.Random(3) == 0) { + var notebook = Loot.RandomLysanderNotebook(); + notebook.MoveToWorld(Location, Map); } - public override bool ClickTitle => false; - public override bool ShowFameTitle => false; - public override bool DeleteCorpseOnDeath => true; - public override string DefaultName => "Lysander Gatherwale"; - - public override bool AlwaysMurderer => true; - - public override int GetIdleSound() => 0x1CE; - - public override int GetAngerSound() => 0x1AC; - - public override int GetDeathSound() => 0x182; - - public override int GetHurtSound() => 0x28D; - - public override void GenerateLoot() - { - AddLoot(LootPack.MedScrolls, 2); - } - - public override bool OnBeforeDeath() - { - if (!base.OnBeforeDeath()) - { - return false; - } - - Backpack?.Destroy(); - - if (Utility.Random(3) == 0) - { - var notebook = Loot.RandomLysanderNotebook(); - notebook.MoveToWorld(Location, Map); - } - - Effects.SendLocationEffect(Location, Map, 0x376A, 10, 1); - return true; - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } + Effects.SendLocationEffect(Location, Map, 0x376A, 10, 1); + return true; } } diff --git a/Projects/UOContent/Engines/Khaldun/Mobiles/MorgBergen.cs b/Projects/UOContent/Engines/Khaldun/Mobiles/MorgBergen.cs index fa1a61a20..5c9bb495c 100644 --- a/Projects/UOContent/Engines/Khaldun/Mobiles/MorgBergen.cs +++ b/Projects/UOContent/Engines/Khaldun/Mobiles/MorgBergen.cs @@ -1,98 +1,81 @@ +using ModernUO.Serialization; using Server.Items; -namespace Server.Mobiles +namespace Server.Mobiles; + +[SerializationGenerator(0, false)] +public partial class MorgBergen : BaseCreature { - public class MorgBergen : BaseCreature + [Constructible] + public MorgBergen() : base(AIType.AI_Melee) { - [Constructible] - public MorgBergen() : base(AIType.AI_Melee) - { - Title = "the Cursed"; + Title = "the Cursed"; - Hue = 0x8596; - Body = 0x190; + Hue = 0x8596; + Body = 0x190; - AddItem(new ShortPants(0x59C)); + AddItem(new ShortPants(0x59C)); - var bardiche = new Bardiche(); - var gloves = new LeatherGloves(); - var arms = new LeatherArms(); + var bardiche = new Bardiche(); + var gloves = new LeatherGloves(); + var arms = new LeatherArms(); - bardiche.Hue = 0x96F; - bardiche.Movable = false; - gloves.Hue = 0x96F; - arms.Hue = 0x96F; + bardiche.Hue = 0x96F; + bardiche.Movable = false; + gloves.Hue = 0x96F; + arms.Hue = 0x96F; - AddItem(bardiche); - AddItem(gloves); - AddItem(arms); + AddItem(bardiche); + AddItem(gloves); + AddItem(arms); - SetStr(111, 120); - SetDex(111, 120); - SetInt(51, 60); + SetStr(111, 120); + SetDex(111, 120); + SetInt(51, 60); - SetHits(180, 207); - SetMana(0); + SetHits(180, 207); + SetMana(0); - SetDamage(9, 17); + SetDamage(9, 17); - SetDamageType(ResistanceType.Physical, 40); - SetDamageType(ResistanceType.Cold, 60); + SetDamageType(ResistanceType.Physical, 40); + SetDamageType(ResistanceType.Cold, 60); - SetResistance(ResistanceType.Physical, 35, 45); - SetResistance(ResistanceType.Fire, 25, 30); - SetResistance(ResistanceType.Cold, 50, 60); - SetResistance(ResistanceType.Poison, 25, 35); - SetResistance(ResistanceType.Energy, 25, 35); + SetResistance(ResistanceType.Physical, 35, 45); + SetResistance(ResistanceType.Fire, 25, 30); + SetResistance(ResistanceType.Cold, 50, 60); + SetResistance(ResistanceType.Poison, 25, 35); + SetResistance(ResistanceType.Energy, 25, 35); - SetSkill(SkillName.Swords, 90.1, 100.0); - SetSkill(SkillName.Tactics, 90.1, 100.0); - SetSkill(SkillName.MagicResist, 80.1, 90.0); - SetSkill(SkillName.Anatomy, 90.1, 100.0); + SetSkill(SkillName.Swords, 90.1, 100.0); + SetSkill(SkillName.Tactics, 90.1, 100.0); + SetSkill(SkillName.MagicResist, 80.1, 90.0); + SetSkill(SkillName.Anatomy, 90.1, 100.0); - Fame = 5000; - Karma = -1000; - } + Fame = 5000; + Karma = -1000; + } - public MorgBergen(Serial serial) : base(serial) - { - } + public override bool ShowFameTitle => false; + public override bool DeleteCorpseOnDeath => true; + public override string DefaultName => "Morg Bergen"; - public override bool ShowFameTitle => false; - public override bool DeleteCorpseOnDeath => true; - public override string DefaultName => "Morg Bergen"; + public override bool AlwaysMurderer => true; - public override bool AlwaysMurderer => true; + public override int GetIdleSound() => 0x1CE; - public override int GetIdleSound() => 0x1CE; + public override int GetAngerSound() => 0x263; - public override int GetAngerSound() => 0x263; + public override int GetDeathSound() => 0x1D1; - public override int GetDeathSound() => 0x1D1; + public override int GetHurtSound() => 0x25E; - public override int GetHurtSound() => 0x25E; + public override bool OnBeforeDeath() + { + var gold = new Gold(Utility.RandomMinMax(190, 230)); + gold.MoveToWorld(Location, Map); - public override bool OnBeforeDeath() - { - var gold = new Gold(Utility.RandomMinMax(190, 230)); - gold.MoveToWorld(Location, Map); - - Effects.SendLocationEffect(Location, Map, 0x376A, 10, 1); - return true; - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } + Effects.SendLocationEffect(Location, Map, 0x376A, 10, 1); + return true; } } diff --git a/Projects/UOContent/Engines/Khaldun/Mobiles/TavaraSewel.cs b/Projects/UOContent/Engines/Khaldun/Mobiles/TavaraSewel.cs index 4e01e38b8..c9711faff 100644 --- a/Projects/UOContent/Engines/Khaldun/Mobiles/TavaraSewel.cs +++ b/Projects/UOContent/Engines/Khaldun/Mobiles/TavaraSewel.cs @@ -1,108 +1,91 @@ +using ModernUO.Serialization; using Server.Items; -namespace Server.Mobiles +namespace Server.Mobiles; + +[SerializationGenerator(0, false)] +public partial class TavaraSewel : BaseCreature { - public class TavaraSewel : BaseCreature + [Constructible] + public TavaraSewel() : base(AIType.AI_Melee) { - [Constructible] - public TavaraSewel() : base(AIType.AI_Melee) + Title = "the Cursed"; + + Hue = 0x8838; + Female = true; + Body = 0x191; + + AddItem(new Kilt(0x59C)); + AddItem(new Sandals(0x599)); + + var kryss = new Kryss(); + var buckler = new Buckler(); + var gloves = new RingmailGloves(); + var chest = new FemalePlateChest(); + + kryss.Hue = 0x96F; + kryss.Movable = false; + buckler.Hue = 0x96F; + buckler.Movable = false; + gloves.Hue = 0x599; + chest.Hue = 0x96F; + + AddItem(kryss); + AddItem(buckler); + AddItem(gloves); + AddItem(chest); + + SetStr(111, 120); + SetDex(111, 120); + SetInt(111, 120); + + SetHits(180, 207); + SetStam(126, 150); + SetMana(0); + + SetDamage(13, 16); + + SetResistance(ResistanceType.Physical, 25, 30); + SetResistance(ResistanceType.Fire, 25, 30); + SetResistance(ResistanceType.Cold, 50, 60); + SetResistance(ResistanceType.Poison, 25, 35); + SetResistance(ResistanceType.Energy, 25, 35); + + SetSkill(SkillName.Fencing, 90.1, 100.0); + SetSkill(SkillName.Tactics, 90.1, 100.0); + SetSkill(SkillName.MagicResist, 80.1, 90.0); + SetSkill(SkillName.Anatomy, 90.1, 100.0); + + Fame = 5000; + Karma = -1000; + } + + public override bool ShowFameTitle => false; + public override bool DeleteCorpseOnDeath => true; + public override string DefaultName => "Tavara Sewel"; + + public override bool AlwaysMurderer => true; + + public override int GetIdleSound() => 0x27F; + + public override int GetAngerSound() => 0x258; + + public override int GetDeathSound() => 0x25B; + + public override int GetHurtSound() => 0x257; + + public override bool OnBeforeDeath() + { + var gold = new Gold(Utility.RandomMinMax(190, 230)); + gold.MoveToWorld(Location, Map); + + if (Utility.Random(3) == 0) { - Title = "the Cursed"; - - Hue = 0x8838; - Female = true; - Body = 0x191; - - AddItem(new Kilt(0x59C)); - AddItem(new Sandals(0x599)); - - var kryss = new Kryss(); - var buckler = new Buckler(); - var gloves = new RingmailGloves(); - var chest = new FemalePlateChest(); - - kryss.Hue = 0x96F; - kryss.Movable = false; - buckler.Hue = 0x96F; - buckler.Movable = false; - gloves.Hue = 0x599; - chest.Hue = 0x96F; - - AddItem(kryss); - AddItem(buckler); - AddItem(gloves); - AddItem(chest); - - SetStr(111, 120); - SetDex(111, 120); - SetInt(111, 120); - - SetHits(180, 207); - SetStam(126, 150); - SetMana(0); - - SetDamage(13, 16); - - SetResistance(ResistanceType.Physical, 25, 30); - SetResistance(ResistanceType.Fire, 25, 30); - SetResistance(ResistanceType.Cold, 50, 60); - SetResistance(ResistanceType.Poison, 25, 35); - SetResistance(ResistanceType.Energy, 25, 35); - - SetSkill(SkillName.Fencing, 90.1, 100.0); - SetSkill(SkillName.Tactics, 90.1, 100.0); - SetSkill(SkillName.MagicResist, 80.1, 90.0); - SetSkill(SkillName.Anatomy, 90.1, 100.0); - - Fame = 5000; - Karma = -1000; + var journal = Loot.RandomTavarasJournal(); + journal.MoveToWorld(Location, Map); } - public TavaraSewel(Serial serial) : base(serial) - { - } - - public override bool ShowFameTitle => false; - public override bool DeleteCorpseOnDeath => true; - public override string DefaultName => "Tavara Sewel"; - - public override bool AlwaysMurderer => true; - - public override int GetIdleSound() => 0x27F; - - public override int GetAngerSound() => 0x258; - - public override int GetDeathSound() => 0x25B; - - public override int GetHurtSound() => 0x257; - - public override bool OnBeforeDeath() - { - var gold = new Gold(Utility.RandomMinMax(190, 230)); - gold.MoveToWorld(Location, Map); - - if (Utility.Random(3) == 0) - { - var journal = Loot.RandomTavarasJournal(); - journal.MoveToWorld(Location, Map); - } - - Effects.SendLocationEffect(Location, Map, 0x376A, 10, 1); - return true; - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - } + Effects.SendLocationEffect(Location, Map, 0x376A, 10, 1); + return true; } } diff --git a/Projects/UOContent/Engines/Khaldun/RaisableItem.cs b/Projects/UOContent/Engines/Khaldun/RaisableItem.cs index c27326b28..59b4fd580 100644 --- a/Projects/UOContent/Engines/Khaldun/RaisableItem.cs +++ b/Projects/UOContent/Engines/Khaldun/RaisableItem.cs @@ -1,187 +1,164 @@ using System; +using ModernUO.Serialization; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(0)] +public partial class RaisableItem : Item { - public class RaisableItem : Item + [SerializableField(1)] + [SerializedCommandProperty(AccessLevel.GameMaster)] + private int _moveSound; + + [SerializableField(2)] + [SerializedCommandProperty(AccessLevel.GameMaster)] + private int _stopSound; + + [SerializableField(3)] + [SerializedCommandProperty(AccessLevel.GameMaster)] + private TimeSpan _closeDelay; + + [SerializableField(4, setter: "private")] + [SerializedCommandProperty(AccessLevel.GameMaster)] + private int _elevation; + + private RaiseTimer _raiseTimer; + + [Constructible] + public RaisableItem(int itemID) : this(itemID, 20, -1, -1, TimeSpan.FromMinutes(1.0)) { - private int m_Elevation; - private int m_MaxElevation; - private RaiseTimer m_RaiseTimer; + } - [Constructible] - public RaisableItem(int itemID) : this(itemID, 20, -1, -1, TimeSpan.FromMinutes(1.0)) + [Constructible] + public RaisableItem(int itemID, int maxElevation, TimeSpan closeDelay) : this( + itemID, + maxElevation, + -1, + -1, + closeDelay + ) + { + } + + [Constructible] + public RaisableItem(int itemID, int maxElevation, int moveSound, int stopSound, TimeSpan closeDelay) : base(itemID) + { + Movable = false; + + _maxElevation = maxElevation; + MoveSound = moveSound; + StopSound = stopSound; + CloseDelay = closeDelay; + } + + [EncodedInt] + [SerializableProperty(0)] + [CommandProperty(AccessLevel.GameMaster)] + public int MaxElevation + { + get => _maxElevation; + set { - } - - [Constructible] - public RaisableItem(int itemID, int maxElevation, TimeSpan closeDelay) : this( - itemID, - maxElevation, - -1, - -1, - closeDelay - ) - { - } - - [Constructible] - public RaisableItem(int itemID, int maxElevation, int moveSound, int stopSound, TimeSpan closeDelay) : base(itemID) - { - Movable = false; - - m_MaxElevation = maxElevation; - MoveSound = moveSound; - StopSound = stopSound; - CloseDelay = closeDelay; - } - - public RaisableItem(Serial serial) : base(serial) - { - } - - [CommandProperty(AccessLevel.GameMaster)] - public int MaxElevation - { - get => m_MaxElevation; - set + _maxElevation = value switch { - if (value <= 0) - { - m_MaxElevation = 0; - } - else if (value >= 60) - { - m_MaxElevation = 60; - } - else - { - m_MaxElevation = value; - } - } + <= 0 => 0, + >= 60 => 60, + _ => value + }; + + this.MarkDirty(); + } + } + + public bool IsRaisable => _raiseTimer == null; + + public void Raise() + { + if (!IsRaisable) + { + return; } - [CommandProperty(AccessLevel.GameMaster)] - public int MoveSound { get; set; } + _raiseTimer = new RaiseTimer(this); + _raiseTimer.Start(); + } - [CommandProperty(AccessLevel.GameMaster)] - public int StopSound { get; set; } + [AfterDeserialization] + private void AfterDeserialization() + { + Z -= _elevation; + } - [CommandProperty(AccessLevel.GameMaster)] - public TimeSpan CloseDelay { get; set; } + private class RaiseTimer : Timer + { + private readonly DateTime _closeTime; + private readonly RaisableItem _item; + private int _step; + private bool _up; - public bool IsRaisable => m_RaiseTimer == null; - - public void Raise() + public RaiseTimer(RaisableItem item) : base(TimeSpan.Zero, TimeSpan.FromSeconds(0.5)) { - if (!IsRaisable) + _item = item; + _closeTime = Core.Now + item.CloseDelay; + _up = true; + } + + protected override void OnTick() + { + if (_item.Deleted) { + Stop(); return; } - m_RaiseTimer = new RaiseTimer(this); - m_RaiseTimer.Start(); - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - - writer.WriteEncodedInt(m_MaxElevation); - writer.WriteEncodedInt(MoveSound); - writer.WriteEncodedInt(StopSound); - writer.Write(CloseDelay); - - writer.WriteEncodedInt(m_Elevation); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - - m_MaxElevation = reader.ReadEncodedInt(); - MoveSound = reader.ReadEncodedInt(); - StopSound = reader.ReadEncodedInt(); - CloseDelay = reader.ReadTimeSpan(); - - var elevation = reader.ReadEncodedInt(); - Z -= elevation; - } - - private class RaiseTimer : Timer - { - private readonly DateTime m_CloseTime; - private readonly RaisableItem m_Item; - private int m_Step; - private bool m_Up; - - public RaiseTimer(RaisableItem item) : base(TimeSpan.Zero, TimeSpan.FromSeconds(0.5)) + if (_step++ % 3 == 0) { - m_Item = item; - m_CloseTime = Core.Now + item.CloseDelay; - m_Up = true; + if (_up) + { + _item.Z++; + + if (++_item._elevation >= _item.MaxElevation) + { + Stop(); + + if (_item.StopSound >= 0) + { + Effects.PlaySound(_item.Location, _item.Map, _item.StopSound); + } + + _up = false; + _step = 0; + + var delay = _closeTime - Core.Now; + + StartTimer(delay, () => Start()); + + return; + } + } + else + { + _item.Z--; + + if (--_item._elevation <= 0) + { + Stop(); + + if (_item.StopSound >= 0) + { + Effects.PlaySound(_item.Location, _item.Map, _item.StopSound); + } + + _item._raiseTimer = null; + + return; + } + } } - protected override void OnTick() + if (_item.MoveSound >= 0) { - if (m_Item.Deleted) - { - Stop(); - return; - } - - if (m_Step++ % 3 == 0) - { - if (m_Up) - { - m_Item.Z++; - - if (++m_Item.m_Elevation >= m_Item.MaxElevation) - { - Stop(); - - if (m_Item.StopSound >= 0) - { - Effects.PlaySound(m_Item.Location, m_Item.Map, m_Item.StopSound); - } - - m_Up = false; - m_Step = 0; - - var delay = m_CloseTime - Core.Now; - - StartTimer(delay, () => Start()); - - return; - } - } - else - { - m_Item.Z--; - - if (--m_Item.m_Elevation <= 0) - { - Stop(); - - if (m_Item.StopSound >= 0) - { - Effects.PlaySound(m_Item.Location, m_Item.Map, m_Item.StopSound); - } - - m_Item.m_RaiseTimer = null; - - return; - } - } - } - - if (m_Item.MoveSound >= 0) - { - Effects.PlaySound(m_Item.Location, m_Item.Map, m_Item.MoveSound); - } + Effects.PlaySound(_item.Location, _item.Map, _item.MoveSound); } } } diff --git a/Projects/UOContent/Engines/Khaldun/RaiseSwitch.cs b/Projects/UOContent/Engines/Khaldun/RaiseSwitch.cs index 7815fee84..f967f9ce8 100644 --- a/Projects/UOContent/Engines/Khaldun/RaiseSwitch.cs +++ b/Projects/UOContent/Engines/Khaldun/RaiseSwitch.cs @@ -1,228 +1,212 @@ using System; +using ModernUO.Serialization; -namespace Server.Items +namespace Server.Items; + +[SerializationGenerator(0)] +public partial class RaiseSwitch : Item { - public class RaiseSwitch : Item + [SerializableField(0)] + [SerializedCommandProperty(AccessLevel.GameMaster)] + private RaisableItem _raisableItem; + + private ResetTimer _resetTimer; + + [Constructible] + public RaiseSwitch(int itemID = 0x1093) : base(itemID) => Movable = false; + + public override void OnDoubleClick(Mobile m) { - private ResetTimer m_ResetTimer; - - [Constructible] - public RaiseSwitch(int itemID = 0x1093) : base(itemID) => Movable = false; - - public RaiseSwitch(Serial serial) : base(serial) + if (!m.InRange(this, 2)) { + m.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that. + return; } - [CommandProperty(AccessLevel.GameMaster)] - public RaisableItem RaisableItem { get; set; } - - public override void OnDoubleClick(Mobile m) + if (RaisableItem?.Deleted == true) { - if (!m.InRange(this, 2)) - { - m.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that. - return; - } - - if (RaisableItem?.Deleted == true) - { - RaisableItem = null; - } - - Flip(); - - if (RaisableItem == null) - { - return; - } - - if (RaisableItem.IsRaisable) - { - RaisableItem.Raise(); - m.LocalOverheadMessage( - MessageType.Regular, - 0x5A, - true, - "You hear a grinding noise echoing in the distance." - ); - } - else - { - m.LocalOverheadMessage( - MessageType.Regular, - 0x5A, - true, - "You flip the switch again, but nothing happens." - ); - } + RaisableItem = null; } - protected virtual void Flip() + Flip(); + + if (RaisableItem == null) { - if (ItemID != 0x1093) - { - ItemID = 0x1093; - - StopResetTimer(); - } - else - { - ItemID = 0x1095; - - StartResetTimer( - RaisableItem?.CloseDelay >= TimeSpan.Zero ? RaisableItem.CloseDelay : TimeSpan.FromMinutes(2.0) - ); - } - - Effects.PlaySound(Location, Map, 0x3E8); + return; } - protected void StartResetTimer(TimeSpan delay) + if (RaisableItem.IsRaisable) { - StopResetTimer(); - - m_ResetTimer = new ResetTimer(this, delay); - m_ResetTimer.Start(); + RaisableItem.Raise(); + m.LocalOverheadMessage( + MessageType.Regular, + 0x5A, + true, + "You hear a grinding noise echoing in the distance." + ); } - - protected void StopResetTimer() + else { - if (m_ResetTimer != null) - { - m_ResetTimer.Stop(); - m_ResetTimer = null; - } - } - - protected virtual void Reset() - { - if (ItemID != 0x1093) - { - Flip(); - } - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.WriteEncodedInt(0); // version - - writer.Write(RaisableItem); - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - - RaisableItem = (RaisableItem)reader.ReadEntity(); - - Reset(); - } - - private class ResetTimer : Timer - { - private readonly RaiseSwitch m_RaiseSwitch; - - public ResetTimer(RaiseSwitch raiseSwitch, TimeSpan delay) : base(delay) - { - m_RaiseSwitch = raiseSwitch; - } - - protected override void OnTick() - { - if (m_RaiseSwitch.Deleted) - { - return; - } - - m_RaiseSwitch.m_ResetTimer = null; - - m_RaiseSwitch.Reset(); - } + m.LocalOverheadMessage( + MessageType.Regular, + 0x5A, + true, + "You flip the switch again, but nothing happens." + ); } } - public class DisappearingRaiseSwitch : RaiseSwitch + protected virtual void Flip() { - [Constructible] - public DisappearingRaiseSwitch() : base(0x108F) + if (ItemID != 0x1093) { + ItemID = 0x1093; + + StopResetTimer(); + } + else + { + ItemID = 0x1095; + + StartResetTimer( + RaisableItem?.CloseDelay >= TimeSpan.Zero ? RaisableItem.CloseDelay : TimeSpan.FromMinutes(2.0) + ); } - public DisappearingRaiseSwitch(Serial serial) : base(serial) + Effects.PlaySound(Location, Map, 0x3E8); + } + + protected void StartResetTimer(TimeSpan delay) + { + StopResetTimer(); + + _resetTimer = new ResetTimer(this, delay); + _resetTimer.Start(); + } + + protected void StopResetTimer() + { + if (_resetTimer != null) { + _resetTimer.Stop(); + _resetTimer = null; + } + } + + protected virtual void Reset() + { + if (ItemID != 0x1093) + { + Flip(); + } + } + + [AfterDeserialization] + private void AfterDeserialization() + { + Reset(); + } + + private class ResetTimer : Timer + { + private readonly RaiseSwitch m_RaiseSwitch; + + public ResetTimer(RaiseSwitch raiseSwitch, TimeSpan delay) : base(delay) + { + m_RaiseSwitch = raiseSwitch; } - public int CurrentRange => Visible ? 3 : 2; - - public override bool HandlesOnMovement => true; - - protected override void Flip() + protected override void OnTick() { - } - - protected override void Reset() - { - } - - public override void OnMovement(Mobile m, Point3D oldLocation) - { - if (Utility.InRange(m.Location, Location, CurrentRange) || Utility.InRange(oldLocation, Location, CurrentRange)) + if (m_RaiseSwitch.Deleted) { - Refresh(); - } - } - - public override void OnMapChange() - { - if (!Deleted) - { - Refresh(); - } - } - - public override void OnLocationChange(Point3D oldLoc) - { - if (!Deleted) - { - Refresh(); - } - } - - public void Refresh() - { - foreach (var mob in GetMobilesInRange(CurrentRange)) - { - if (!mob.Hidden || mob.AccessLevel <= AccessLevel.Player) - { - Visible = true; - break; - } - } - } - - public override void Serialize(IGenericWriter writer) - { - if (RaisableItem?.Deleted == true) - { - RaisableItem = null; + return; } - base.Serialize(writer); + m_RaiseSwitch._resetTimer = null; - writer.WriteEncodedInt(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadEncodedInt(); - - Timer.StartTimer(Refresh); + m_RaiseSwitch.Reset(); } } } + +public class DisappearingRaiseSwitch : RaiseSwitch +{ + [Constructible] + public DisappearingRaiseSwitch() : base(0x108F) + { + } + + public DisappearingRaiseSwitch(Serial serial) : base(serial) + { + } + + public int CurrentRange => Visible ? 3 : 2; + + public override bool HandlesOnMovement => true; + + protected override void Flip() + { + } + + protected override void Reset() + { + } + + public override void OnMovement(Mobile m, Point3D oldLocation) + { + if (Utility.InRange(m.Location, Location, CurrentRange) || Utility.InRange(oldLocation, Location, CurrentRange)) + { + Refresh(); + } + } + + public override void OnMapChange() + { + if (!Deleted) + { + Refresh(); + } + } + + public override void OnLocationChange(Point3D oldLoc) + { + if (!Deleted) + { + Refresh(); + } + } + + public void Refresh() + { + foreach (var mob in GetMobilesInRange(CurrentRange)) + { + if (!mob.Hidden || mob.AccessLevel <= AccessLevel.Player) + { + Visible = true; + break; + } + } + } + + public override void Serialize(IGenericWriter writer) + { + if (RaisableItem?.Deleted == true) + { + RaisableItem = null; + } + + base.Serialize(writer); + + writer.WriteEncodedInt(0); // version + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + + var version = reader.ReadEncodedInt(); + + Timer.StartTimer(Refresh); + } +} diff --git a/Projects/UOContent/Migrations/Server.Engines.Doom.GauntletSpawner.v2.json b/Projects/UOContent/Migrations/Server.Engines.Doom.GauntletSpawner.v2.json new file mode 100644 index 000000000..317898c7c --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Engines.Doom.GauntletSpawner.v2.json @@ -0,0 +1,60 @@ +{ + "version": 2, + "type": "Server.Engines.Doom.GauntletSpawner", + "properties": [ + { + "name": "RegionBounds", + "type": "Server.Rectangle2D", + "rule": "PrimitiveUOTypeMigrationRule", + "ruleArguments": [ + "Rect2D" + ] + }, + { + "name": "Traps", + "type": "System.Collections.Generic.List\u003CServer.Items.BaseTrap\u003E", + "rule": "ListMigrationRule", + "ruleArguments": [ + "Server.Items.BaseTrap", + "SerializableInterfaceMigrationRule" + ] + }, + { + "name": "Creatures", + "type": "System.Collections.Generic.List\u003CServer.Mobile\u003E", + "rule": "ListMigrationRule", + "ruleArguments": [ + "Server.Mobile", + "SerializableInterfaceMigrationRule" + ] + }, + { + "name": "TypeName", + "type": "string", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "Door", + "type": "Server.Items.BaseDoor", + "rule": "SerializableInterfaceMigrationRule" + }, + { + "name": "Addon", + "type": "Server.Items.BaseAddon", + "rule": "SerializableInterfaceMigrationRule" + }, + { + "name": "Sequence", + "type": "Server.Engines.Doom.GauntletSpawner", + "rule": "SerializableInterfaceMigrationRule" + }, + { + "name": "State", + "type": "Server.Engines.Doom.GauntletSpawnerState", + "rule": "EnumMigrationRule" + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Engines.Doom.LampRoomBox.v0.json b/Projects/UOContent/Migrations/Server.Engines.Doom.LampRoomBox.v0.json new file mode 100644 index 000000000..0a03f2d79 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Engines.Doom.LampRoomBox.v0.json @@ -0,0 +1,11 @@ +{ + "version": 0, + "type": "Server.Engines.Doom.LampRoomBox", + "properties": [ + { + "name": "Controller", + "type": "Server.Engines.Doom.LeverPuzzleController", + "rule": "SerializableInterfaceMigrationRule" + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Engines.Doom.LampRoomTeleporter.v0.json b/Projects/UOContent/Migrations/Server.Engines.Doom.LampRoomTeleporter.v0.json new file mode 100644 index 000000000..1e95dd0a5 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Engines.Doom.LampRoomTeleporter.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Engines.Doom.LampRoomTeleporter" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Engines.Doom.LeverPuzzleController.v0.json b/Projects/UOContent/Migrations/Server.Engines.Doom.LeverPuzzleController.v0.json new file mode 100644 index 000000000..093f1753e --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Engines.Doom.LeverPuzzleController.v0.json @@ -0,0 +1,38 @@ +{ + "version": 0, + "type": "Server.Engines.Doom.LeverPuzzleController", + "properties": [ + { + "name": "Levers", + "type": "System.Collections.Generic.List\u003CServer.Item\u003E", + "rule": "ListMigrationRule", + "ruleArguments": [ + "Server.Item", + "SerializableInterfaceMigrationRule" + ] + }, + { + "name": "Statues", + "type": "System.Collections.Generic.List\u003CServer.Item\u003E", + "rule": "ListMigrationRule", + "ruleArguments": [ + "Server.Item", + "SerializableInterfaceMigrationRule" + ] + }, + { + "name": "Teles", + "type": "System.Collections.Generic.List\u003CServer.Item\u003E", + "rule": "ListMigrationRule", + "ruleArguments": [ + "Server.Item", + "SerializableInterfaceMigrationRule" + ] + }, + { + "name": "Box", + "type": "Server.Engines.Doom.LampRoomBox", + "rule": "SerializableInterfaceMigrationRule" + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Engines.Doom.LeverPuzzleLever.v0.json b/Projects/UOContent/Migrations/Server.Engines.Doom.LeverPuzzleLever.v0.json new file mode 100644 index 000000000..317bad67d --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Engines.Doom.LeverPuzzleLever.v0.json @@ -0,0 +1,19 @@ +{ + "version": 0, + "type": "Server.Engines.Doom.LeverPuzzleLever", + "properties": [ + { + "name": "Code", + "type": "ushort", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "Controller", + "type": "Server.Engines.Doom.LeverPuzzleController", + "rule": "SerializableInterfaceMigrationRule" + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Engines.Doom.LeverPuzzleStatue.v0.json b/Projects/UOContent/Migrations/Server.Engines.Doom.LeverPuzzleStatue.v0.json new file mode 100644 index 000000000..1072ecafc --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Engines.Doom.LeverPuzzleStatue.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Engines.Doom.LeverPuzzleStatue" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.GrimmochJournal1.v0.json b/Projects/UOContent/Migrations/Server.Items.GrimmochJournal1.v0.json new file mode 100644 index 000000000..f3ea3459d --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.GrimmochJournal1.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.GrimmochJournal1" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.GrimmochJournal11.v0.json b/Projects/UOContent/Migrations/Server.Items.GrimmochJournal11.v0.json new file mode 100644 index 000000000..98755b693 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.GrimmochJournal11.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.GrimmochJournal11" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.GrimmochJournal14.v0.json b/Projects/UOContent/Migrations/Server.Items.GrimmochJournal14.v0.json new file mode 100644 index 000000000..7adb7bb42 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.GrimmochJournal14.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.GrimmochJournal14" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.GrimmochJournal17.v0.json b/Projects/UOContent/Migrations/Server.Items.GrimmochJournal17.v0.json new file mode 100644 index 000000000..faf8ab349 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.GrimmochJournal17.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.GrimmochJournal17" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.GrimmochJournal2.v0.json b/Projects/UOContent/Migrations/Server.Items.GrimmochJournal2.v0.json new file mode 100644 index 000000000..016d5cbe0 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.GrimmochJournal2.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.GrimmochJournal2" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.GrimmochJournal23.v0.json b/Projects/UOContent/Migrations/Server.Items.GrimmochJournal23.v0.json new file mode 100644 index 000000000..f6d765c3a --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.GrimmochJournal23.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.GrimmochJournal23" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.GrimmochJournal3.v0.json b/Projects/UOContent/Migrations/Server.Items.GrimmochJournal3.v0.json new file mode 100644 index 000000000..c24d782bb --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.GrimmochJournal3.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.GrimmochJournal3" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.GrimmochJournal6.v0.json b/Projects/UOContent/Migrations/Server.Items.GrimmochJournal6.v0.json new file mode 100644 index 000000000..ea88476fb --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.GrimmochJournal6.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.GrimmochJournal6" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.GrimmochJournal7.v0.json b/Projects/UOContent/Migrations/Server.Items.GrimmochJournal7.v0.json new file mode 100644 index 000000000..017332253 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.GrimmochJournal7.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Items.GrimmochJournal7" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.KhaldunPitTeleporter.v0.json b/Projects/UOContent/Migrations/Server.Items.KhaldunPitTeleporter.v0.json new file mode 100644 index 000000000..09895d0e2 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.KhaldunPitTeleporter.v0.json @@ -0,0 +1,30 @@ +{ + "version": 0, + "type": "Server.Items.KhaldunPitTeleporter", + "properties": [ + { + "name": "Active", + "type": "bool", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "PointDest", + "type": "Server.Point3D", + "rule": "PrimitiveUOTypeMigrationRule", + "ruleArguments": [ + "Point3D" + ] + }, + { + "name": "MapDest", + "type": "Server.Map", + "rule": "PrimitiveUOTypeMigrationRule", + "ruleArguments": [ + "Map" + ] + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.RaisableItem.v0.json b/Projects/UOContent/Migrations/Server.Items.RaisableItem.v0.json new file mode 100644 index 000000000..6e37f9204 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.RaisableItem.v0.json @@ -0,0 +1,43 @@ +{ + "version": 0, + "type": "Server.Items.RaisableItem", + "properties": [ + { + "name": "MaxElevation", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "EncodedInt" + ] + }, + { + "name": "MoveSound", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "StopSound", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "CloseDelay", + "type": "System.TimeSpan", + "rule": "PrimitiveTypeMigrationRule" + }, + { + "name": "Elevation", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Items.RaiseSwitch.v0.json b/Projects/UOContent/Migrations/Server.Items.RaiseSwitch.v0.json new file mode 100644 index 000000000..13d7ba7d6 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Items.RaiseSwitch.v0.json @@ -0,0 +1,11 @@ +{ + "version": 0, + "type": "Server.Items.RaiseSwitch", + "properties": [ + { + "name": "RaisableItem", + "type": "Server.Items.RaisableItem", + "rule": "SerializableInterfaceMigrationRule" + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Mobiles.GrimmochDrummel.v0.json b/Projects/UOContent/Migrations/Server.Mobiles.GrimmochDrummel.v0.json new file mode 100644 index 000000000..9c091216e --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Mobiles.GrimmochDrummel.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Mobiles.GrimmochDrummel" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Mobiles.LysanderGathenwale.v0.json b/Projects/UOContent/Migrations/Server.Mobiles.LysanderGathenwale.v0.json new file mode 100644 index 000000000..db2b5b906 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Mobiles.LysanderGathenwale.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Mobiles.LysanderGathenwale" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Mobiles.MorgBergen.v0.json b/Projects/UOContent/Migrations/Server.Mobiles.MorgBergen.v0.json new file mode 100644 index 000000000..5371dbf9c --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Mobiles.MorgBergen.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Mobiles.MorgBergen" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Mobiles.TavaraSewel.v0.json b/Projects/UOContent/Migrations/Server.Mobiles.TavaraSewel.v0.json new file mode 100644 index 000000000..6de27b3c9 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Mobiles.TavaraSewel.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Mobiles.TavaraSewel" +} \ No newline at end of file