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;
using System.Collections.Generic; using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Items; using Server.Items;
using Server.Utilities; 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, Visible = false;
InProgress, Movable = false;
Completed
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; get
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)
{ {
Visible = false; if (Creatures.Count == 0)
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) return false;
}
for (var i = 0; i < Creatures.Count; ++i)
{
var mob = Creatures[i];
if (!mob.Deleted)
{ {
return false; 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)] [SerializableProperty(7)]
public Rectangle2D RegionBounds { get; set; } [CommandProperty(AccessLevel.GameMaster)]
public GauntletSpawnerState State
[CommandProperty(AccessLevel.GameMaster)] {
public GauntletSpawnerState State get => _state;
set
{ {
get => m_State; if (_state != value)
set
{ {
if (m_State != value) _state = value;
{ Update();
m_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; } var hue = _state switch
private void Update(bool shouldSpawn = true)
{ {
var lockDoors = m_State == GauntletSpawnerState.InProgress; GauntletSpawnerState.InSequence => InSequenceItemHue,
GauntletSpawnerState.InProgress => InProgressItemHue,
GauntletSpawnerState.Completed => CompletedItemHue,
_ => 0
};
var hue = m_State switch if (Door != null)
{ {
GauntletSpawnerState.InSequence => InSequenceItemHue, Door.Hue = hue;
GauntletSpawnerState.InProgress => InProgressItemHue, Door.Locked = lockDoors;
GauntletSpawnerState.Completed => CompletedItemHue,
_ => 0
};
if (Door != null) if (lockDoors)
{ {
Door.Hue = hue; Door.KeyValue = Key.RandomValue();
Door.Locked = lockDoors; Door.Open = false;
}
if (Door.Link?.Deleted == false)
{
Door.Link.Hue = hue;
Door.Link.Locked = lockDoors;
if (lockDoors) if (lockDoors)
{ {
Door.KeyValue = Key.RandomValue(); Door.Link.KeyValue = Key.RandomValue();
Door.Open = false; 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"; if (Addon != null)
public virtual void CreateRegion()
{ {
if (Region != null) Addon.Hue = hue;
{
return;
}
var map = Map;
if (map == null || map == Map.Internal)
{
return;
}
Region = new GauntletRegion(this, map);
} }
public void Stop() if (_state == GauntletSpawnerState.InProgress)
{ {
ClearCreatures(); CreateRegion();
ClearTraps();
DestroyRegion();
_timerToken.Cancel(); if (shouldSpawn)
{
FullSpawn();
}
Timer.StartTimer(TimeSpan.FromSeconds(1.0), TimeSpan.FromSeconds(1.0), Slice, out _timerToken);
} }
else
public override void OnDelete()
{ {
base.OnDelete();
Stop(); 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 System;
using ModernUO.Serialization;
using Server.Mobiles; using Server.Mobiles;
using Server.Spells; 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; _controller = controller;
private Mobile m_Wanderer; ItemID = 0xe80;
Movable = false;
}
public LampRoomBox(LeverPuzzleController controller) : base(0xe80) public override void OnDoubleClick(Mobile m)
{
if (!m.InRange(GetWorldLocation(), 3))
{ {
m_Controller = controller; return;
ItemID = 0xe80;
Movable = false;
} }
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)) _wanderer = new WandererOfTheVoid();
{ _wanderer.MoveToWorld(LeverPuzzleController.lr_Enter, Map.Malas);
return; _wanderer.PublicOverheadMessage(MessageType.Regular, 0x3B2, 1060002); // I am the guardian of...
} Timer.StartTimer(TimeSpan.FromSeconds(5.0), CallBackMessage);
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>();
} }
} }
public class LeverPuzzleStatue : Item public void CallBackMessage()
{ {
private LeverPuzzleController m_Controller; PublicOverheadMessage(MessageType.Regular, 0x3B2, 1060003); // You try to pry the box open...
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>();
}
} }
public class LeverPuzzleLever : Item public override void OnAfterDelete()
{ {
private LeverPuzzleController m_Controller; if (_controller?.Deleted == false)
public LeverPuzzleLever(ushort code, LeverPuzzleController controller) : base(0x108E)
{ {
m_Controller = controller; _controller.Delete();
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();
} }
} }
} }
[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( base.Serialize(writer);
"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] writer.WriteEncodedInt(0); // version
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 override void Deserialize(IGenericReader reader)
{ {
public static readonly BookContent Content = new( base.Deserialize(reader);
"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] var version = reader.ReadEncodedInt();
public LysanderNotebook7() : base(Utility.Random(0xFF1, 2), false) }
{ }
}
public class LysanderNotebook2 : BaseBook
public LysanderNotebook7(Serial serial) : base(serial) {
{ public static readonly BookContent Content = new(
} "Lysander's Notebook",
"L. Gathenwale",
public override BookContent DefaultContent => Content; new BookPageInfo(
"Day Two:",
public override void Serialize(IGenericWriter writer) "",
{ "The woman, Tavara",
base.Serialize(writer); "Sewel, is unbearable.",
"Her entire demeanor",
writer.WriteEncodedInt(0); // version "sickens me. I would",
} "take her life for Thee",
"now, my Lord. But I"
public override void Deserialize(IGenericReader reader) ),
{ new BookPageInfo(
base.Deserialize(reader); "cannot alert the",
"others. Progress is",
var version = reader.ReadEncodedInt(); "made too slowly, I",
} "cannot stand this",
} "perpetual waiting.",
"Today I knelt down",
public class LysanderNotebook8 : BaseBook "with the workers,",
{ "tossing stones and dirt"
public static readonly BookContent Content = new( ),
"Lysander's Notebook", new BookPageInfo(
"L. Gathenwale", "aside with my very",
new BookPageInfo( "hands as they dug at",
"Day Eight - Day Ten :", "the last of the rubble",
"", "covering the entrance",
"Have you taken them,", "to Thy Sanctum. The",
"Master? They could", "Sewel woman was",
"not have found a way", "shocked at my",
"past the stones that", "demeanor, dirtying"
"block our path! The", ),
"three workers, My" new BookPageInfo(
), "my robes, on my",
new BookPageInfo( "knees in the muck as I",
"Master, where have", "clawed at the rocks.",
"they gone? Curses", "She thought I did this",
"upon them! I'll cut", "for those sickly",
"them all to pieces if", "scholars, or for her,",
"they show their faces", "or for what she",
"again, then burn the", "laughably calls 'The"
"rest alive upon a pyre,", ),
"for all to see, as a" new BookPageInfo(
), "Gift of Discovery', of",
new BookPageInfo( "learning. As if I did",
"warning of Thy", "not know what I went",
"Power. How could", "to find! I come for",
"they have gotten past", "Thee, Master. Soon",
"me? I sleep against", "shall I receive Thy",
"the very walls, to", "gifts, Thy blessings.",
"hear Thy Words, to", "Patience, eternal"
"feel Thy Breath. I", ),
"can find no egress" new BookPageInfo(
), "patience. I must take",
new BookPageInfo( "my lessons well. I",
"from the chambers", "have learned from",
"that the Sewel woman", "Thee, Master, I have."
"does not know of nor", )
"have men working at", );
"excavating. Where",
"have they gone,", [Constructible]
"Master? Have you", public LysanderNotebook2() : base(Utility.Random(0xFF1, 2), false)
"taken them, or do they" {
), }
new BookPageInfo(
"truly flee from Thy", public LysanderNotebook2(Serial serial) : base(serial)
"Presence? I will kill", {
"them if they show", }
"their faces again.",
"Give me Strength, my", public override BookContent DefaultContent => Content;
"Master, to let them",
"live a while longer,", public override void Serialize(IGenericWriter writer)
"until they have" {
), base.Serialize(writer);
new BookPageInfo(
"fulfilled their", writer.WriteEncodedInt(0); // version
"purpose and I kneel", }
"before Thee, covered",
"in their blood." public override void Deserialize(IGenericReader reader)
) {
); base.Deserialize(reader);
[Constructible] var version = reader.ReadEncodedInt();
public LysanderNotebook8() : base(Utility.Random(0xFF1, 2), false) }
{ }
}
public class LysanderNotebook3 : BaseBook
public LysanderNotebook8(Serial serial) : base(serial) {
{ public static readonly BookContent Content = new(
} "Lysander's Notebook",
"L. Gathenwale",
public override BookContent DefaultContent => Content; new BookPageInfo(
"Day Three - Day Six:",
public override void Serialize(IGenericWriter writer) "",
{ "What are these Beasts",
base.Serialize(writer); "that dare to defy our",
"presence here? Hast",
writer.WriteEncodedInt(0); // version "Thou sent them,",
} "Master? To tear",
"apart these foolish"
public override void Deserialize(IGenericReader reader) ),
{ new BookPageInfo(
base.Deserialize(reader); "ones that accompany",
"me? That repugnant",
var version = reader.ReadEncodedInt(); "pustule, Drummel, put",
} "forth his absurd little",
} "theories as to the",
"nature of the Beasts",
public class LysanderNotebook11 : BaseBook "that attacked our",
{ "camp, but I'll have"
public static readonly BookContent Content = new( ),
"Lysander's Notebook", new BookPageInfo(
"L. Gathenwale", "none of his words. He",
new BookPageInfo( "asks too many",
"Day Eleven - Day", "questions. He is a",
"Thirteen:", "taint upon the grounds",
"", "of Thy Sanctum,",
"I come for Thee, my", "Master - I will deal",
"Master. I come! The", "with him after the",
"way is clear, I have", "Sewel woman."
"found Thy path and", ),
"washed it in the blood" new BookPageInfo(
), "Speaking of Sewel, I",
new BookPageInfo( "have convinced that",
"of the two workers", "empty-headed harlot",
"that caught sight of", "that we should move",
"me. Ah, how sweet it", "our encampment",
"was to cut them open,", "within the",
"to see the blood pour", "antechamber. She",
"out in great torrents, to", "thinks I worry for"
"stand in it, to revel in", ),
"it. If only I had time" new BookPageInfo(
), "her safety. I come",
new BookPageInfo( "for thee, Master. I",
"for the Sewel woman.", "make my camp in Thy",
"But there will be time", "chambers. I sleep",
"enough for her. I", "under Thy roof. I can",
"have learned Thy", "feel Thine presence",
"Patience, Master. I", "even now. Soon,",
"come for Thee. I walk", "Master. Soon."
"Thy halls in penance,", )
"my last steps in this" );
),
new BookPageInfo( [Constructible]
"repulsive living", public LysanderNotebook3() : base(Utility.Random(0xFF1, 2), false)
"frame. I come for", {
"Thee and Thy Gifts,", }
"my Master. Glory",
"Unto Thee, Khal", public LysanderNotebook3(Serial serial) : base(serial)
"Ankur, Keeper of the", {
"Seventh Death,", }
"Master, Leader of the"
), public override BookContent DefaultContent => Content;
new BookPageInfo(
"Chosen, the Khaldun.", public override void Serialize(IGenericWriter writer)
"Praises in Thy", {
"Name, Master of Life", base.Serialize(writer);
"and Death, Lord of All.",
" Khal Ankur, Master,", writer.WriteEncodedInt(0); // version
"Prophet, I join Thy", }
"ranks this night, a",
"member of the" public override void Deserialize(IGenericReader reader)
), {
new BookPageInfo( base.Deserialize(reader);
"Khaldun at last!"
) var version = reader.ReadEncodedInt();
); }
}
[Constructible]
public LysanderNotebook11() : base(Utility.Random(0xFF1, 2), false) public class LysanderNotebook7 : BaseBook
{ {
} public static readonly BookContent Content = new(
"Lysander's Notebook",
public LysanderNotebook11(Serial serial) : base(serial) "L. Gathenwale",
{ new BookPageInfo(
} "Day Seven :",
"",
public override BookContent DefaultContent => Content; "The Sewel woman",
"pratters on endlessly.",
public override void Serialize(IGenericWriter writer) "And she dares to",
{ "speak Thy Name,",
base.Serialize(writer); "Master! I wish so",
"vehemently to take a"
writer.WriteEncodedInt(0); // version ),
} new BookPageInfo(
"knife to that little",
public override void Deserialize(IGenericReader reader) "neck of hers. She",
{ "struts around the",
base.Deserialize(reader); "chambers of Thy",
"Sanctum with her",
var version = reader.ReadEncodedInt(); "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; 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] var map = MapDest;
public KhaldunPitTeleporter(Point3D pointDest, Map mapDest) : base(0x053B)
{
Movable = false;
Hue = 1;
Active = true; if (map != null && map != Map.Internal && m.InRange(this, 3))
PointDest = pointDest; {
MapDest = mapDest; BaseCreature.TeleportPets(m, PointDest, MapDest);
m.MoveToWorld(PointDest, MapDest);
} }
else
public KhaldunPitTeleporter(Serial serial) : base(serial)
{ {
} m.SendLocalizedMessage(1019045); // I can't reach that.
[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();
} }
} }
public override void OnDoubleClickDead(Mobile m)
{
OnDoubleClick(m);
}
} }

View file

@ -1,122 +1,106 @@
using ModernUO.Serialization;
using Server.Items; 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] Title = "the Cursed";
public GrimmochDrummel() : base(AIType.AI_Archer)
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"; PackItem(new FireHorn());
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());
}
} }
public GrimmochDrummel(Serial serial) : base(serial) if (Utility.Random(3) < 1)
{ {
} 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;
}
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();
} }
} }
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; 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] Title = "the Cursed";
public LysanderGathenwale() : base(AIType.AI_Mage)
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"; return false;
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 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; Effects.SendLocationEffect(Location, Map, 0x376A, 10, 1);
public override bool ShowFameTitle => false; return true;
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();
}
} }
} }

View file

@ -1,98 +1,81 @@
using ModernUO.Serialization;
using Server.Items; 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] Title = "the Cursed";
public MorgBergen() : base(AIType.AI_Melee)
{
Title = "the Cursed";
Hue = 0x8596; Hue = 0x8596;
Body = 0x190; Body = 0x190;
AddItem(new ShortPants(0x59C)); AddItem(new ShortPants(0x59C));
var bardiche = new Bardiche(); var bardiche = new Bardiche();
var gloves = new LeatherGloves(); var gloves = new LeatherGloves();
var arms = new LeatherArms(); var arms = new LeatherArms();
bardiche.Hue = 0x96F; bardiche.Hue = 0x96F;
bardiche.Movable = false; bardiche.Movable = false;
gloves.Hue = 0x96F; gloves.Hue = 0x96F;
arms.Hue = 0x96F; arms.Hue = 0x96F;
AddItem(bardiche); AddItem(bardiche);
AddItem(gloves); AddItem(gloves);
AddItem(arms); AddItem(arms);
SetStr(111, 120); SetStr(111, 120);
SetDex(111, 120); SetDex(111, 120);
SetInt(51, 60); SetInt(51, 60);
SetHits(180, 207); SetHits(180, 207);
SetMana(0); SetMana(0);
SetDamage(9, 17); SetDamage(9, 17);
SetDamageType(ResistanceType.Physical, 40); SetDamageType(ResistanceType.Physical, 40);
SetDamageType(ResistanceType.Cold, 60); SetDamageType(ResistanceType.Cold, 60);
SetResistance(ResistanceType.Physical, 35, 45); SetResistance(ResistanceType.Physical, 35, 45);
SetResistance(ResistanceType.Fire, 25, 30); SetResistance(ResistanceType.Fire, 25, 30);
SetResistance(ResistanceType.Cold, 50, 60); SetResistance(ResistanceType.Cold, 50, 60);
SetResistance(ResistanceType.Poison, 25, 35); SetResistance(ResistanceType.Poison, 25, 35);
SetResistance(ResistanceType.Energy, 25, 35); SetResistance(ResistanceType.Energy, 25, 35);
SetSkill(SkillName.Swords, 90.1, 100.0); SetSkill(SkillName.Swords, 90.1, 100.0);
SetSkill(SkillName.Tactics, 90.1, 100.0); SetSkill(SkillName.Tactics, 90.1, 100.0);
SetSkill(SkillName.MagicResist, 80.1, 90.0); SetSkill(SkillName.MagicResist, 80.1, 90.0);
SetSkill(SkillName.Anatomy, 90.1, 100.0); SetSkill(SkillName.Anatomy, 90.1, 100.0);
Fame = 5000; Fame = 5000;
Karma = -1000; 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 AlwaysMurderer => true;
public override bool DeleteCorpseOnDeath => true;
public override string DefaultName => "Morg Bergen";
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() Effects.SendLocationEffect(Location, Map, 0x376A, 10, 1);
{ return true;
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();
}
} }
} }

View file

@ -1,108 +1,91 @@
using ModernUO.Serialization;
using Server.Items; 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] Title = "the Cursed";
public TavaraSewel() : base(AIType.AI_Melee)
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"; var journal = Loot.RandomTavarasJournal();
journal.MoveToWorld(Location, Map);
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 TavaraSewel(Serial serial) : base(serial) Effects.SendLocationEffect(Location, Map, 0x376A, 10, 1);
{ return true;
}
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();
}
} }
} }

View file

@ -1,187 +1,164 @@
using System; 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] [Constructible]
public RaisableItem(int itemID) : this(itemID, 20, -1, -1, TimeSpan.FromMinutes(1.0)) 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
{ {
} _maxElevation = value switch
[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
{ {
if (value <= 0) <= 0 => 0,
{ >= 60 => 60,
m_MaxElevation = 0; _ => value
} };
else if (value >= 60)
{ this.MarkDirty();
m_MaxElevation = 60; }
} }
else
{ public bool IsRaisable => _raiseTimer == null;
m_MaxElevation = value;
} public void Raise()
} {
if (!IsRaisable)
{
return;
} }
[CommandProperty(AccessLevel.GameMaster)] _raiseTimer = new RaiseTimer(this);
public int MoveSound { get; set; } _raiseTimer.Start();
}
[CommandProperty(AccessLevel.GameMaster)] [AfterDeserialization]
public int StopSound { get; set; } private void AfterDeserialization()
{
Z -= _elevation;
}
[CommandProperty(AccessLevel.GameMaster)] private class RaiseTimer : Timer
public TimeSpan CloseDelay { get; set; } {
private readonly DateTime _closeTime;
private readonly RaisableItem _item;
private int _step;
private bool _up;
public bool IsRaisable => m_RaiseTimer == null; public RaiseTimer(RaisableItem item) : base(TimeSpan.Zero, TimeSpan.FromSeconds(0.5))
public void Raise()
{ {
if (!IsRaisable) _item = item;
_closeTime = Core.Now + item.CloseDelay;
_up = true;
}
protected override void OnTick()
{
if (_item.Deleted)
{ {
Stop();
return; return;
} }
m_RaiseTimer = new RaiseTimer(this); if (_step++ % 3 == 0)
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))
{ {
m_Item = item; if (_up)
m_CloseTime = Core.Now + item.CloseDelay; {
m_Up = true; _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) Effects.PlaySound(_item.Location, _item.Map, _item.MoveSound);
{
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);
}
} }
} }
} }

View file

@ -1,228 +1,212 @@
using System; 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; if (!m.InRange(this, 2))
[Constructible]
public RaiseSwitch(int itemID = 0x1093) : base(itemID) => Movable = false;
public RaiseSwitch(Serial serial) : base(serial)
{ {
m.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
return;
} }
[CommandProperty(AccessLevel.GameMaster)] if (RaisableItem?.Deleted == true)
public RaisableItem RaisableItem { get; set; }
public override void OnDoubleClick(Mobile m)
{ {
if (!m.InRange(this, 2)) RaisableItem = null;
{
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."
);
}
} }
protected virtual void Flip() Flip();
if (RaisableItem == null)
{ {
if (ItemID != 0x1093) return;
{
ItemID = 0x1093;
StopResetTimer();
}
else
{
ItemID = 0x1095;
StartResetTimer(
RaisableItem?.CloseDelay >= TimeSpan.Zero ? RaisableItem.CloseDelay : TimeSpan.FromMinutes(2.0)
);
}
Effects.PlaySound(Location, Map, 0x3E8);
} }
protected void StartResetTimer(TimeSpan delay) if (RaisableItem.IsRaisable)
{ {
StopResetTimer(); RaisableItem.Raise();
m.LocalOverheadMessage(
m_ResetTimer = new ResetTimer(this, delay); MessageType.Regular,
m_ResetTimer.Start(); 0x5A,
true,
"You hear a grinding noise echoing in the distance."
);
} }
else
protected void StopResetTimer()
{ {
if (m_ResetTimer != null) m.LocalOverheadMessage(
{ MessageType.Regular,
m_ResetTimer.Stop(); 0x5A,
m_ResetTimer = null; true,
} "You flip the switch again, but nothing happens."
} );
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();
}
} }
} }
public class DisappearingRaiseSwitch : RaiseSwitch protected virtual void Flip()
{ {
[Constructible] if (ItemID != 0x1093)
public DisappearingRaiseSwitch() : base(0x108F)
{ {
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; protected override void OnTick()
public override bool HandlesOnMovement => true;
protected override void Flip()
{ {
} if (m_RaiseSwitch.Deleted)
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(); return;
}
}
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); m_RaiseSwitch._resetTimer = null;
writer.WriteEncodedInt(0); // version m_RaiseSwitch.Reset();
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
Timer.StartTimer(Refresh);
} }
} }
} }
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"
}