fix: Codegens Khaldun and Doom (#1521)

This commit is contained in:
Kamron Batman 2023-09-30 00:27:06 -07:00 committed by GitHub
parent 5dc2d09392
commit 145c93ccf7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
35 changed files with 4405 additions and 4528 deletions

View file

@ -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<BaseTrap> _traps;
[SerializableField(2)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private List<Mobile> _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<Mobile>();
Traps = new List<BaseTrap>();
}
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<Mobile>();
Traps = new List<BaseTrap>();
}
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<Mobile> Creatures { get; set; }
public Region Region { get; set; }
public List<BaseTrap> 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<Mobile>();
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<BaseTrap>();
goto case 0;
}
case 0:
{
if (version < 1)
{
Traps = new List<BaseTrap>();
RegionBounds = new Rectangle2D(X - 40, Y - 40, 80, 80);
}
Creatures = reader.ReadEntityList<Mobile>();
TypeName = reader.ReadString();
Door = reader.ReadEntity<BaseDoor>();
Addon = reader.ReadEntity<BaseAddon>();
Sequence = reader.ReadEntity<GauntletSpawner>();
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<Mobile>();
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<BaseTrap>();
Creatures = reader.ReadEntityList<Mobile>();
TypeName = reader.ReadString();
Door = reader.ReadEntity<BaseDoor>();
Addon = reader.ReadEntity<BaseAddon>();
Sequence = reader.ReadEntity<GauntletSpawner>();
_state = (GauntletSpawnerState)reader.ReadInt();
}
[AfterDeserialization(false)]
private void AfterDeserialization()
{
Update(false);
}
}

View file

@ -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<LeverPuzzleController>();
_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<LeverPuzzleController>();
}
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<LeverPuzzleController>();
}
}
[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;
}
}

File diff suppressed because it is too large Load diff

View file

@ -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();
}
}

File diff suppressed because it is too large Load diff

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}
}

View file

@ -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<Item>();
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);
}
}

View file

@ -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"
}
]
}

View file

@ -0,0 +1,11 @@
{
"version": 0,
"type": "Server.Engines.Doom.LampRoomBox",
"properties": [
{
"name": "Controller",
"type": "Server.Engines.Doom.LeverPuzzleController",
"rule": "SerializableInterfaceMigrationRule"
}
]
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Engines.Doom.LampRoomTeleporter"
}

View file

@ -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"
}
]
}

View file

@ -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"
}
]
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Engines.Doom.LeverPuzzleStatue"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Items.GrimmochJournal1"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Items.GrimmochJournal11"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Items.GrimmochJournal14"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Items.GrimmochJournal17"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Items.GrimmochJournal2"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Items.GrimmochJournal23"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Items.GrimmochJournal3"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Items.GrimmochJournal6"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Items.GrimmochJournal7"
}

View file

@ -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"
]
}
]
}

View file

@ -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": [
""
]
}
]
}

View file

@ -0,0 +1,11 @@
{
"version": 0,
"type": "Server.Items.RaiseSwitch",
"properties": [
{
"name": "RaisableItem",
"type": "Server.Items.RaisableItem",
"rule": "SerializableInterfaceMigrationRule"
}
]
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Mobiles.GrimmochDrummel"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Mobiles.LysanderGathenwale"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Mobiles.MorgBergen"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Mobiles.TavaraSewel"
}