Formats UO Content (#201)

This commit is contained in:
Kamron Batman 2020-08-27 18:30:38 -07:00 • committed by GitHub
parent 86b7b3aed1
commit ad3775c4d7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3249 changed files with 431083 additions and 440981 deletions

View file

@ -2,54 +2,54 @@ using Server.Engines.Craft;
namespace Server.Items
{
[Flippable(0xFAF, 0xFB0)]
[Anvil]
public class Anvil : Item
{
[Constructible]
public Anvil() : base(0xFAF) => Movable = false;
public Anvil(Serial serial) : base(serial)
[Flippable(0xFAF, 0xFB0)]
[Anvil]
public class Anvil : Item
{
[Constructible]
public Anvil() : base(0xFAF) => Movable = false;
public Anvil(Serial serial) : base(serial)
{
}
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 void Serialize(IGenericWriter writer)
[Forge]
public class Forge : Item
{
base.Serialize(writer);
[Constructible]
public Forge() : base(0xFB1) => Movable = false;
writer.Write(0); // version
public Forge(Serial serial) : base(serial)
{
}
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 void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
[Forge]
public class Forge : Item
{
[Constructible]
public Forge() : base(0xFB1) => Movable = false;
public Forge(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
}

View file

@ -2,347 +2,347 @@ using Server.Engines.Craft;
namespace Server.Items
{
[Forge]
public class LargeForgeWest : Item
{
private InternalItem m_Item;
private InternalItem2 m_Item2;
[Constructible]
public LargeForgeWest() : base(0x199A)
[Forge]
public class LargeForgeWest : Item
{
Movable = false;
private InternalItem m_Item;
private InternalItem2 m_Item2;
m_Item = new InternalItem(this);
m_Item2 = new InternalItem2(this);
}
[Constructible]
public LargeForgeWest() : base(0x199A)
{
Movable = false;
public LargeForgeWest(Serial serial) : base(serial)
{
}
m_Item = new InternalItem(this);
m_Item2 = new InternalItem2(this);
}
public override void OnLocationChange(Point3D oldLocation)
{
if (m_Item != null)
m_Item.Location = new Point3D(X, Y + 1, Z);
if (m_Item2 != null)
m_Item2.Location = new Point3D(X, Y + 2, Z);
}
public LargeForgeWest(Serial serial) : base(serial)
{
}
public override void OnMapChange()
{
if (m_Item != null)
m_Item.Map = Map;
if (m_Item2 != null)
m_Item2.Map = Map;
}
public override void OnLocationChange(Point3D oldLocation)
{
if (m_Item != null)
m_Item.Location = new Point3D(X, Y + 1, Z);
if (m_Item2 != null)
m_Item2.Location = new Point3D(X, Y + 2, Z);
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
public override void OnMapChange()
{
if (m_Item != null)
m_Item.Map = Map;
if (m_Item2 != null)
m_Item2.Map = Map;
}
m_Item?.Delete();
m_Item2?.Delete();
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
m_Item?.Delete();
m_Item2?.Delete();
}
writer.Write(0); // version
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(m_Item);
writer.Write(m_Item2);
}
writer.Write(0); // version
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
writer.Write(m_Item);
writer.Write(m_Item2);
}
int version = reader.ReadInt();
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
m_Item = reader.ReadItem() as InternalItem;
m_Item2 = reader.ReadItem() as InternalItem2;
var version = reader.ReadInt();
m_Item = reader.ReadItem() as InternalItem;
m_Item2 = reader.ReadItem() as InternalItem2;
}
[Forge]
private class InternalItem : Item
{
private LargeForgeWest m_Item;
public InternalItem(LargeForgeWest item) : base(0x1996)
{
Movable = false;
m_Item = item;
}
public InternalItem(Serial serial) : base(serial)
{
}
public override void OnLocationChange(Point3D oldLocation)
{
if (m_Item != null)
m_Item.Location = new Point3D(X, Y - 1, Z);
}
public override void OnMapChange()
{
if (m_Item != null)
m_Item.Map = Map;
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
m_Item?.Delete();
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
writer.Write(m_Item);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
m_Item = reader.ReadItem() as LargeForgeWest;
}
}
[Forge]
private class InternalItem2 : Item
{
private LargeForgeWest m_Item;
public InternalItem2(LargeForgeWest item) : base(0x1992)
{
Movable = false;
m_Item = item;
}
public InternalItem2(Serial serial) : base(serial)
{
}
public override void OnLocationChange(Point3D oldLocation)
{
if (m_Item != null)
m_Item.Location = new Point3D(X, Y - 2, Z);
}
public override void OnMapChange()
{
if (m_Item != null)
m_Item.Map = Map;
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
m_Item?.Delete();
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
writer.Write(m_Item);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
m_Item = reader.ReadItem() as LargeForgeWest;
}
}
}
[Forge]
private class InternalItem : Item
public class LargeForgeEast : Item
{
private LargeForgeWest m_Item;
private InternalItem m_Item;
private InternalItem2 m_Item2;
public InternalItem(LargeForgeWest item) : base(0x1996)
{
Movable = false;
[Constructible]
public LargeForgeEast() : base(0x197A)
{
Movable = false;
m_Item = item;
}
m_Item = new InternalItem(this);
m_Item2 = new InternalItem2(this);
}
public InternalItem(Serial serial) : base(serial)
{
}
public LargeForgeEast(Serial serial) : base(serial)
{
}
public override void OnLocationChange(Point3D oldLocation)
{
if (m_Item != null)
m_Item.Location = new Point3D(X, Y - 1, Z);
}
public override void OnLocationChange(Point3D oldLocation)
{
if (m_Item != null)
m_Item.Location = new Point3D(X + 1, Y, Z);
if (m_Item2 != null)
m_Item2.Location = new Point3D(X + 2, Y, Z);
}
public override void OnMapChange()
{
if (m_Item != null)
m_Item.Map = Map;
}
public override void OnMapChange()
{
if (m_Item != null)
m_Item.Map = Map;
if (m_Item2 != null)
m_Item2.Map = Map;
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
public override void OnAfterDelete()
{
base.OnAfterDelete();
m_Item?.Delete();
}
m_Item?.Delete();
m_Item2?.Delete();
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
writer.Write(0); // version
writer.Write(m_Item);
}
writer.Write(m_Item);
writer.Write(m_Item2);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
var version = reader.ReadInt();
m_Item = reader.ReadItem() as LargeForgeWest;
}
m_Item = reader.ReadItem() as InternalItem;
m_Item2 = reader.ReadItem() as InternalItem2;
}
[Forge]
private class InternalItem : Item
{
private LargeForgeEast m_Item;
public InternalItem(LargeForgeEast item) : base(0x197E)
{
Movable = false;
m_Item = item;
}
public InternalItem(Serial serial) : base(serial)
{
}
public override void OnLocationChange(Point3D oldLocation)
{
if (m_Item != null)
m_Item.Location = new Point3D(X - 1, Y, Z);
}
public override void OnMapChange()
{
if (m_Item != null)
m_Item.Map = Map;
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
m_Item?.Delete();
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
writer.Write(m_Item);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
m_Item = reader.ReadItem() as LargeForgeEast;
}
}
[Forge]
private class InternalItem2 : Item
{
private LargeForgeEast m_Item;
public InternalItem2(LargeForgeEast item) : base(0x1982)
{
Movable = false;
m_Item = item;
}
public InternalItem2(Serial serial) : base(serial)
{
}
public override void OnLocationChange(Point3D oldLocation)
{
if (m_Item != null)
m_Item.Location = new Point3D(X - 2, Y, Z);
}
public override void OnMapChange()
{
if (m_Item != null)
m_Item.Map = Map;
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
m_Item?.Delete();
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
writer.Write(m_Item);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
m_Item = reader.ReadItem() as LargeForgeEast;
}
}
}
[Forge]
private class InternalItem2 : Item
{
private LargeForgeWest m_Item;
public InternalItem2(LargeForgeWest item) : base(0x1992)
{
Movable = false;
m_Item = item;
}
public InternalItem2(Serial serial) : base(serial)
{
}
public override void OnLocationChange(Point3D oldLocation)
{
if (m_Item != null)
m_Item.Location = new Point3D(X, Y - 2, Z);
}
public override void OnMapChange()
{
if (m_Item != null)
m_Item.Map = Map;
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
m_Item?.Delete();
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
writer.Write(m_Item);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
m_Item = reader.ReadItem() as LargeForgeWest;
}
}
}
[Forge]
public class LargeForgeEast : Item
{
private InternalItem m_Item;
private InternalItem2 m_Item2;
[Constructible]
public LargeForgeEast() : base(0x197A)
{
Movable = false;
m_Item = new InternalItem(this);
m_Item2 = new InternalItem2(this);
}
public LargeForgeEast(Serial serial) : base(serial)
{
}
public override void OnLocationChange(Point3D oldLocation)
{
if (m_Item != null)
m_Item.Location = new Point3D(X + 1, Y, Z);
if (m_Item2 != null)
m_Item2.Location = new Point3D(X + 2, Y, Z);
}
public override void OnMapChange()
{
if (m_Item != null)
m_Item.Map = Map;
if (m_Item2 != null)
m_Item2.Map = Map;
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
m_Item?.Delete();
m_Item2?.Delete();
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
writer.Write(m_Item);
writer.Write(m_Item2);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
m_Item = reader.ReadItem() as InternalItem;
m_Item2 = reader.ReadItem() as InternalItem2;
}
[Forge]
private class InternalItem : Item
{
private LargeForgeEast m_Item;
public InternalItem(LargeForgeEast item) : base(0x197E)
{
Movable = false;
m_Item = item;
}
public InternalItem(Serial serial) : base(serial)
{
}
public override void OnLocationChange(Point3D oldLocation)
{
if (m_Item != null)
m_Item.Location = new Point3D(X - 1, Y, Z);
}
public override void OnMapChange()
{
if (m_Item != null)
m_Item.Map = Map;
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
m_Item?.Delete();
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
writer.Write(m_Item);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
m_Item = reader.ReadItem() as LargeForgeEast;
}
}
[Forge]
private class InternalItem2 : Item
{
private LargeForgeEast m_Item;
public InternalItem2(LargeForgeEast item) : base(0x1982)
{
Movable = false;
m_Item = item;
}
public InternalItem2(Serial serial) : base(serial)
{
}
public override void OnLocationChange(Point3D oldLocation)
{
if (m_Item != null)
m_Item.Location = new Point3D(X - 2, Y, Z);
}
public override void OnMapChange()
{
if (m_Item != null)
m_Item.Map = Map;
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
m_Item?.Delete();
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
writer.Write(m_Item);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
m_Item = reader.ReadItem() as LargeForgeEast;
}
}
}
}
}

View file

@ -5,123 +5,123 @@ using Server.Network;
namespace Server.Items
{
[Flippable(0xA57, 0xA58, 0xA59)]
public class Bedroll : Item
{
[Constructible]
public Bedroll() : base(0xA57) => Weight = 5.0;
public Bedroll(Serial serial) : base(serial)
[Flippable(0xA57, 0xA58, 0xA59)]
public class Bedroll : Item
{
}
[Constructible]
public Bedroll() : base(0xA57) => Weight = 5.0;
public override void OnDoubleClick(Mobile from)
{
if (Parent != null || !VerifyMove(from))
return;
if (!from.InRange(this, 2))
{
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
return;
}
if (ItemID == 0xA57) // rolled
{
Direction dir = PlayerMobile.GetDirection4(from.Location, Location);
if (dir == Direction.North || dir == Direction.South)
ItemID = 0xA55;
else
ItemID = 0xA56;
}
else // unrolled
{
ItemID = 0xA57;
if (!from.HasGump<LogoutGump>())
public Bedroll(Serial serial) : base(serial)
{
CampfireEntry entry = Campfire.GetEntry(from);
if (entry?.Safe == true)
from.SendGump(new LogoutGump(entry, this));
}
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadEncodedInt();
}
private class LogoutGump : Gump
{
private readonly Bedroll m_Bedroll;
private readonly Timer m_CloseTimer;
private readonly CampfireEntry m_Entry;
public LogoutGump(CampfireEntry entry, Bedroll bedroll) : base(100, 0)
{
m_Entry = entry;
m_Bedroll = bedroll;
m_CloseTimer = Timer.DelayCall(TimeSpan.FromSeconds(10.0), CloseGump);
AddBackground(0, 0, 400, 350, 0xA28);
AddHtmlLocalized(100, 20, 200, 35, 1011015); // <center>Logging out via camping</center>
/* Using a bedroll in the safety of a camp will log you out of the game safely.
* If this is what you wish to do choose CONTINUE and you will be logged out.
* Otherwise, select the CANCEL button to avoid logging out at this time.
* The camp will remain secure for 10 seconds at which time this window will close
* and you not be logged out.
*/
AddHtmlLocalized(50, 55, 300, 140, 1011016, true, true);
AddButton(45, 298, 0xFA5, 0xFA7, 1);
AddHtmlLocalized(80, 300, 110, 35, 1011011); // CONTINUE
AddButton(200, 298, 0xFA5, 0xFA7, 0);
AddHtmlLocalized(235, 300, 110, 35, 1011012); // CANCEL
}
public override void OnResponse(NetState sender, RelayInfo info)
{
PlayerMobile pm = m_Entry.Player;
m_CloseTimer.Stop();
if (Campfire.GetEntry(pm) != m_Entry)
return;
if (info.ButtonID == 1 && m_Entry.Safe && m_Bedroll.Parent == null && m_Bedroll.IsAccessibleTo(pm)
&& m_Bedroll.VerifyMove(pm) && m_Bedroll.Map == pm.Map && pm.InRange(m_Bedroll, 2))
{
pm.PlaceInBackpack(m_Bedroll);
pm.BedrollLogout = true;
sender.Dispose();
}
Campfire.RemoveEntry(m_Entry);
}
public override void OnDoubleClick(Mobile from)
{
if (Parent != null || !VerifyMove(from))
return;
private void CloseGump()
{
Campfire.RemoveEntry(m_Entry);
m_Entry.Player.CloseGump<LogoutGump>();
}
if (!from.InRange(this, 2))
{
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
return;
}
if (ItemID == 0xA57) // rolled
{
var dir = PlayerMobile.GetDirection4(from.Location, Location);
if (dir == Direction.North || dir == Direction.South)
ItemID = 0xA55;
else
ItemID = 0xA56;
}
else // unrolled
{
ItemID = 0xA57;
if (!from.HasGump<LogoutGump>())
{
var entry = Campfire.GetEntry(from);
if (entry?.Safe == true)
from.SendGump(new LogoutGump(entry, this));
}
}
}
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();
}
private class LogoutGump : Gump
{
private readonly Bedroll m_Bedroll;
private readonly Timer m_CloseTimer;
private readonly CampfireEntry m_Entry;
public LogoutGump(CampfireEntry entry, Bedroll bedroll) : base(100, 0)
{
m_Entry = entry;
m_Bedroll = bedroll;
m_CloseTimer = Timer.DelayCall(TimeSpan.FromSeconds(10.0), CloseGump);
AddBackground(0, 0, 400, 350, 0xA28);
AddHtmlLocalized(100, 20, 200, 35, 1011015); // <center>Logging out via camping</center>
/* Using a bedroll in the safety of a camp will log you out of the game safely.
* If this is what you wish to do choose CONTINUE and you will be logged out.
* Otherwise, select the CANCEL button to avoid logging out at this time.
* The camp will remain secure for 10 seconds at which time this window will close
* and you not be logged out.
*/
AddHtmlLocalized(50, 55, 300, 140, 1011016, true, true);
AddButton(45, 298, 0xFA5, 0xFA7, 1);
AddHtmlLocalized(80, 300, 110, 35, 1011011); // CONTINUE
AddButton(200, 298, 0xFA5, 0xFA7, 0);
AddHtmlLocalized(235, 300, 110, 35, 1011012); // CANCEL
}
public override void OnResponse(NetState sender, RelayInfo info)
{
var pm = m_Entry.Player;
m_CloseTimer.Stop();
if (Campfire.GetEntry(pm) != m_Entry)
return;
if (info.ButtonID == 1 && m_Entry.Safe && m_Bedroll.Parent == null && m_Bedroll.IsAccessibleTo(pm)
&& m_Bedroll.VerifyMove(pm) && m_Bedroll.Map == pm.Map && pm.InRange(m_Bedroll, 2))
{
pm.PlaceInBackpack(m_Bedroll);
pm.BedrollLogout = true;
sender.Dispose();
}
Campfire.RemoveEntry(m_Entry);
}
private void CloseGump()
{
Campfire.RemoveEntry(m_Entry);
m_Entry.Player.CloseGump<LogoutGump>();
}
}
}
}
}

View file

@ -2,193 +2,194 @@ using System;
using System.Collections.Generic;
using System.Linq;
using Server.Mobiles;
using Server.Network;
namespace Server.Items
{
public enum CampfireStatus
{
Burning,
Extinguishing,
Off
}
public class Campfire : Item
{
public static readonly int SecureRange = 7;
private static readonly Dictionary<Mobile, CampfireEntry> m_Table = new Dictionary<Mobile, CampfireEntry>();
private readonly List<CampfireEntry> m_Entries;
private readonly Timer m_Timer;
public Campfire() : base(0xDE3)
public enum CampfireStatus
{
Movable = false;
Light = LightType.Circle300;
m_Entries = new List<CampfireEntry>();
Created = DateTime.UtcNow;
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(1.0), TimeSpan.FromSeconds(1.0), OnTick);
Burning,
Extinguishing,
Off
}
public Campfire(Serial serial) : base(serial)
public class Campfire : Item
{
}
public static readonly int SecureRange = 7;
[CommandProperty(AccessLevel.GameMaster)]
public DateTime Created { get; }
private static readonly Dictionary<Mobile, CampfireEntry> m_Table = new Dictionary<Mobile, CampfireEntry>();
[CommandProperty(AccessLevel.GameMaster)]
public CampfireStatus Status
{
get
{
return ItemID switch
private readonly List<CampfireEntry> m_Entries;
private readonly Timer m_Timer;
public Campfire() : base(0xDE3)
{
0xDE3 => CampfireStatus.Burning,
0xDE9 => CampfireStatus.Extinguishing,
_ => CampfireStatus.Off
};
}
set
{
if (Status == value)
return;
switch (value)
{
case CampfireStatus.Burning:
ItemID = 0xDE3;
Movable = false;
Light = LightType.Circle300;
break;
case CampfireStatus.Extinguishing:
ItemID = 0xDE9;
Light = LightType.Circle150;
break;
m_Entries = new List<CampfireEntry>();
Created = DateTime.UtcNow;
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(1.0), TimeSpan.FromSeconds(1.0), OnTick);
}
public Campfire(Serial serial) : base(serial)
{
}
[CommandProperty(AccessLevel.GameMaster)]
public DateTime Created { get; }
[CommandProperty(AccessLevel.GameMaster)]
public CampfireStatus Status
{
get
{
return ItemID switch
{
0xDE3 => CampfireStatus.Burning,
0xDE9 => CampfireStatus.Extinguishing,
_ => CampfireStatus.Off
};
}
set
{
if (Status == value)
return;
switch (value)
{
case CampfireStatus.Burning:
ItemID = 0xDE3;
Light = LightType.Circle300;
break;
case CampfireStatus.Extinguishing:
ItemID = 0xDE9;
Light = LightType.Circle150;
break;
default:
ItemID = 0xDEA;
Light = LightType.ArchedWindowEast;
ClearEntries();
break;
}
}
}
public static CampfireEntry GetEntry(Mobile player)
{
m_Table.TryGetValue(player, out var value);
return value;
}
public static void RemoveEntry(CampfireEntry entry)
{
m_Table.Remove(entry.Player);
entry.Fire.m_Entries.Remove(entry);
}
private void OnTick()
{
var now = DateTime.UtcNow;
var age = now - Created;
if (age >= TimeSpan.FromSeconds(100.0))
Delete();
else if (age >= TimeSpan.FromSeconds(90.0))
Status = CampfireStatus.Off;
else if (age >= TimeSpan.FromSeconds(60.0))
Status = CampfireStatus.Extinguishing;
if (Status == CampfireStatus.Off || Deleted)
return;
foreach (var entry in m_Entries.ToList())
if (!entry.Valid || entry.Player.NetState == null)
{
RemoveEntry(entry);
}
else if (!entry.Safe && now - entry.Start >= TimeSpan.FromSeconds(30.0))
{
entry.Safe = true;
entry.Player.SendLocalizedMessage(500621); // The camp is now secure.
}
var eable = GetClientsInRange(SecureRange);
foreach (var state in eable)
if (state.Mobile is PlayerMobile pm && GetEntry(pm) == null)
{
var entry = new CampfireEntry(pm, this);
m_Table[pm] = entry;
m_Entries.Add(entry);
pm.SendLocalizedMessage(500620); // You feel it would take a few moments to secure your camp.
}
eable.Free();
}
private void ClearEntries()
{
if (m_Entries == null)
return;
foreach (var entry in m_Entries.ToList())
RemoveEntry(entry);
}
public override void OnAfterDelete()
{
m_Timer?.Stop();
default:
ItemID = 0xDEA;
Light = LightType.ArchedWindowEast;
ClearEntries();
break;
}
}
}
public static CampfireEntry GetEntry(Mobile player)
{
m_Table.TryGetValue(player, out CampfireEntry value);
return value;
}
public static void RemoveEntry(CampfireEntry entry)
{
m_Table.Remove(entry.Player);
entry.Fire.m_Entries.Remove(entry);
}
private void OnTick()
{
DateTime now = DateTime.UtcNow;
TimeSpan age = now - Created;
if (age >= TimeSpan.FromSeconds(100.0))
Delete();
else if (age >= TimeSpan.FromSeconds(90.0))
Status = CampfireStatus.Off;
else if (age >= TimeSpan.FromSeconds(60.0))
Status = CampfireStatus.Extinguishing;
if (Status == CampfireStatus.Off || Deleted)
return;
foreach (CampfireEntry entry in m_Entries.ToList())
if (!entry.Valid || entry.Player.NetState == null)
RemoveEntry(entry);
else if (!entry.Safe && now - entry.Start >= TimeSpan.FromSeconds(30.0))
public override void Serialize(IGenericWriter writer)
{
entry.Safe = true;
entry.Player.SendLocalizedMessage(500621); // The camp is now secure.
base.Serialize(writer);
writer.Write(0); // version
}
IPooledEnumerable<NetState> eable = GetClientsInRange(SecureRange);
foreach (NetState state in eable)
if (state.Mobile is PlayerMobile pm && GetEntry(pm) == null)
public override void Deserialize(IGenericReader reader)
{
CampfireEntry entry = new CampfireEntry(pm, this);
base.Deserialize(reader);
m_Table[pm] = entry;
m_Entries.Add(entry);
var version = reader.ReadInt();
pm.SendLocalizedMessage(500620); // You feel it would take a few moments to secure your camp.
Delete();
}
}
public class CampfireEntry
{
private bool m_Safe;
public CampfireEntry(PlayerMobile player, Campfire fire)
{
Player = player;
Fire = fire;
Start = DateTime.UtcNow;
m_Safe = false;
}
eable.Free();
public PlayerMobile Player { get; }
public Campfire Fire { get; }
public DateTime Start { get; }
public bool Valid => !Fire.Deleted && Fire.Status != CampfireStatus.Off && Player.Map == Fire.Map &&
Player.InRange(Fire, Campfire.SecureRange);
public bool Safe
{
get => Valid && m_Safe;
set => m_Safe = value;
}
}
private void ClearEntries()
{
if (m_Entries == null)
return;
foreach (CampfireEntry entry in m_Entries.ToList())
RemoveEntry(entry);
}
public override void OnAfterDelete()
{
m_Timer?.Stop();
ClearEntries();
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
Delete();
}
}
public class CampfireEntry
{
private bool m_Safe;
public CampfireEntry(PlayerMobile player, Campfire fire)
{
Player = player;
Fire = fire;
Start = DateTime.UtcNow;
m_Safe = false;
}
public PlayerMobile Player { get; }
public Campfire Fire { get; }
public DateTime Start { get; }
public bool Valid => !Fire.Deleted && Fire.Status != CampfireStatus.Off && Player.Map == Fire.Map &&
Player.InRange(Fire, Campfire.SecureRange);
public bool Safe
{
get => Valid && m_Safe;
set => m_Safe = value;
}
}
}

View file

@ -4,107 +4,107 @@ using Server.Regions;
namespace Server.Items
{
public class Kindling : Item
{
[Constructible]
public Kindling(int amount = 1) : base(0xDE1)
public class Kindling : Item
{
Stackable = true;
Weight = 5.0;
Amount = amount;
[Constructible]
public Kindling(int amount = 1) : base(0xDE1)
{
Stackable = true;
Weight = 5.0;
Amount = amount;
}
public Kindling(Serial serial) : base(serial)
{
}
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 void OnDoubleClick(Mobile from)
{
if (!VerifyMove(from))
return;
if (!from.InRange(GetWorldLocation(), 2))
{
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
return;
}
var fireLocation = GetFireLocation(from);
if (fireLocation == Point3D.Zero)
{
from.SendLocalizedMessage(501695); // There is not a spot nearby to place your campfire.
}
else if (!from.CheckSkill(SkillName.Camping, 0.0, 100.0))
{
from.SendLocalizedMessage(501696); // You fail to ignite the campfire.
}
else
{
Consume();
if (!Deleted && Parent == null)
from.PlaceInBackpack(this);
new Campfire().MoveToWorld(fireLocation, from.Map);
}
}
private Point3D GetFireLocation(Mobile from)
{
if (from.Region.IsPartOf<DungeonRegion>())
return Point3D.Zero;
if (Parent == null)
return Location;
var list = new List<Point3D>(4);
AddOffsetLocation(from, 0, -1, list);
AddOffsetLocation(from, -1, 0, list);
AddOffsetLocation(from, 0, 1, list);
AddOffsetLocation(from, 1, 0, list);
if (list.Count == 0)
return Point3D.Zero;
return list.RandomElement();
}
private void AddOffsetLocation(Mobile from, int offsetX, int offsetY, List<Point3D> list)
{
var map = from.Map;
var x = from.X + offsetX;
var y = from.Y + offsetY;
var loc = new Point3D(x, y, from.Z);
if (map.CanFit(loc, 1) && from.InLOS(loc))
{
list.Add(loc);
}
else
{
loc = new Point3D(x, y, map.GetAverageZ(x, y));
if (map.CanFit(loc, 1) && from.InLOS(loc))
list.Add(loc);
}
}
}
public Kindling(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
public override void OnDoubleClick(Mobile from)
{
if (!VerifyMove(from))
return;
if (!from.InRange(GetWorldLocation(), 2))
{
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
return;
}
Point3D fireLocation = GetFireLocation(from);
if (fireLocation == Point3D.Zero)
{
from.SendLocalizedMessage(501695); // There is not a spot nearby to place your campfire.
}
else if (!from.CheckSkill(SkillName.Camping, 0.0, 100.0))
{
from.SendLocalizedMessage(501696); // You fail to ignite the campfire.
}
else
{
Consume();
if (!Deleted && Parent == null)
from.PlaceInBackpack(this);
new Campfire().MoveToWorld(fireLocation, from.Map);
}
}
private Point3D GetFireLocation(Mobile from)
{
if (from.Region.IsPartOf<DungeonRegion>())
return Point3D.Zero;
if (Parent == null)
return Location;
List<Point3D> list = new List<Point3D>(4);
AddOffsetLocation(from, 0, -1, list);
AddOffsetLocation(from, -1, 0, list);
AddOffsetLocation(from, 0, 1, list);
AddOffsetLocation(from, 1, 0, list);
if (list.Count == 0)
return Point3D.Zero;
return list.RandomElement();
}
private void AddOffsetLocation(Mobile from, int offsetX, int offsetY, List<Point3D> list)
{
Map map = from.Map;
int x = from.X + offsetX;
int y = from.Y + offsetY;
Point3D loc = new Point3D(x, y, from.Z);
if (map.CanFit(loc, 1) && from.InLOS(loc))
{
list.Add(loc);
}
else
{
loc = new Point3D(x, y, map.GetAverageZ(x, y));
if (map.CanFit(loc, 1) && from.InLOS(loc))
list.Add(loc);
}
}
}
}

View file

@ -1,275 +1,275 @@
namespace Server.Items
{
[Flippable(0x1BD7, 0x1BDA)]
public class Board : Item, ICommodity
{
private CraftResource m_Resource;
[Constructible]
public Board(int amount = 1)
: this(CraftResource.RegularWood, amount)
[Flippable(0x1BD7, 0x1BDA)]
public class Board : Item, ICommodity
{
}
private CraftResource m_Resource;
public Board(Serial serial)
: base(serial)
{
}
[Constructible]
public Board(CraftResource resource, int amount = 1)
: base(0x1BD7)
{
Stackable = true;
Amount = amount;
m_Resource = resource;
Hue = CraftResources.GetHue(resource);
}
[CommandProperty(AccessLevel.GameMaster)]
public CraftResource Resource
{
get => m_Resource;
set
{
m_Resource = value;
InvalidateProperties();
}
}
int ICommodity.DescriptionNumber
{
get
{
if (m_Resource >= CraftResource.OakWood && m_Resource <= CraftResource.YewWood)
return 1075052 + ((int)m_Resource - (int)CraftResource.OakWood);
return m_Resource switch
[Constructible]
public Board(int amount = 1)
: this(CraftResource.RegularWood, amount)
{
CraftResource.Bloodwood => 1075055,
CraftResource.Frostwood => 1075056,
CraftResource.Heartwood => 1075062, // WHY Osi. Why?
_ => LabelNumber
};
}
}
public Board(Serial serial)
: base(serial)
{
}
[Constructible]
public Board(CraftResource resource, int amount = 1)
: base(0x1BD7)
{
Stackable = true;
Amount = amount;
m_Resource = resource;
Hue = CraftResources.GetHue(resource);
}
[CommandProperty(AccessLevel.GameMaster)]
public CraftResource Resource
{
get => m_Resource;
set
{
m_Resource = value;
InvalidateProperties();
}
}
int ICommodity.DescriptionNumber
{
get
{
if (m_Resource >= CraftResource.OakWood && m_Resource <= CraftResource.YewWood)
return 1075052 + ((int)m_Resource - (int)CraftResource.OakWood);
return m_Resource switch
{
CraftResource.Bloodwood => 1075055,
CraftResource.Frostwood => 1075056,
CraftResource.Heartwood => 1075062, // WHY Osi. Why?
_ => LabelNumber
};
}
}
bool ICommodity.IsDeedable => true;
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
if (!CraftResources.IsStandard(m_Resource))
{
var num = CraftResources.GetLocalizationNumber(m_Resource);
if (num > 0)
list.Add(num);
else
list.Add(CraftResources.GetName(m_Resource));
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(3);
writer.Write((int)m_Resource);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
switch (version)
{
case 3:
case 2:
{
m_Resource = (CraftResource)reader.ReadInt();
break;
}
}
if (version == 0 && Weight == 0.1 || version <= 2 && Weight == 2)
Weight = -1;
if (version <= 1)
m_Resource = CraftResource.RegularWood;
}
}
bool ICommodity.IsDeedable => true;
public override void GetProperties(ObjectPropertyList list)
public class HeartwoodBoard : Board
{
base.GetProperties(list);
[Constructible]
public HeartwoodBoard(int amount = 1)
: base(CraftResource.Heartwood, amount)
{
}
if (!CraftResources.IsStandard(m_Resource))
{
int num = CraftResources.GetLocalizationNumber(m_Resource);
public HeartwoodBoard(Serial serial)
: base(serial)
{
}
if (num > 0)
list.Add(num);
else
list.Add(CraftResources.GetName(m_Resource));
}
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 void Serialize(IGenericWriter writer)
public class BloodwoodBoard : Board
{
base.Serialize(writer);
[Constructible]
public BloodwoodBoard(int amount = 1)
: base(CraftResource.Bloodwood, amount)
{
}
writer.Write(3);
public BloodwoodBoard(Serial serial)
: base(serial)
{
}
writer.Write((int)m_Resource);
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 void Deserialize(IGenericReader reader)
public class FrostwoodBoard : Board
{
base.Deserialize(reader);
[Constructible]
public FrostwoodBoard(int amount = 1)
: base(CraftResource.Frostwood, amount)
{
}
int version = reader.ReadInt();
public FrostwoodBoard(Serial serial)
: base(serial)
{
}
switch (version)
{
case 3:
case 2:
{
m_Resource = (CraftResource)reader.ReadInt();
break;
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
if ((version == 0 && Weight == 0.1) || (version <= 2 && Weight == 2))
Weight = -1;
writer.Write(0); // version
}
if (version <= 1)
m_Resource = CraftResource.RegularWood;
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}
public class HeartwoodBoard : Board
{
[Constructible]
public HeartwoodBoard(int amount = 1)
: base(CraftResource.Heartwood, amount)
public class OakBoard : Board
{
[Constructible]
public OakBoard(int amount = 1)
: base(CraftResource.OakWood, amount)
{
}
public OakBoard(Serial serial)
: base(serial)
{
}
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 HeartwoodBoard(Serial serial)
: base(serial)
public class AshBoard : Board
{
[Constructible]
public AshBoard(int amount = 1)
: base(CraftResource.AshWood, amount)
{
}
public AshBoard(Serial serial)
: base(serial)
{
}
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 void Serialize(IGenericWriter writer)
public class YewBoard : Board
{
base.Serialize(writer);
[Constructible]
public YewBoard(int amount = 1)
: base(CraftResource.YewWood, amount)
{
}
writer.Write(0); // version
public YewBoard(Serial serial)
: base(serial)
{
}
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 void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class BloodwoodBoard : Board
{
[Constructible]
public BloodwoodBoard(int amount = 1)
: base(CraftResource.Bloodwood, amount)
{
}
public BloodwoodBoard(Serial serial)
: base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class FrostwoodBoard : Board
{
[Constructible]
public FrostwoodBoard(int amount = 1)
: base(CraftResource.Frostwood, amount)
{
}
public FrostwoodBoard(Serial serial)
: base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class OakBoard : Board
{
[Constructible]
public OakBoard(int amount = 1)
: base(CraftResource.OakWood, amount)
{
}
public OakBoard(Serial serial)
: base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class AshBoard : Board
{
[Constructible]
public AshBoard(int amount = 1)
: base(CraftResource.AshWood, amount)
{
}
public AshBoard(Serial serial)
: base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class YewBoard : Board
{
[Constructible]
public YewBoard(int amount = 1)
: base(CraftResource.YewWood, amount)
{
}
public YewBoard(Serial serial)
: base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -5,65 +5,65 @@ using Server.Network;
namespace Server.Items
{
public class FishingPole : Item
{
[Constructible]
public FishingPole() : base(0x0DC0)
public class FishingPole : Item
{
Layer = Layer.TwoHanded;
Weight = 8.0;
[Constructible]
public FishingPole() : base(0x0DC0)
{
Layer = Layer.TwoHanded;
Weight = 8.0;
}
public FishingPole(Serial serial) : base(serial)
{
}
public override void OnDoubleClick(Mobile from)
{
var loc = GetWorldLocation();
if (!from.InLOS(loc) || !from.InRange(loc, 2))
from.LocalOverheadMessage(MessageType.Regular, 0x3E9, 1019045); // I can't reach that
else
Fishing.System.BeginHarvesting(from, this);
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
BaseHarvestTool.AddContextMenuEntries(from, this, list, Fishing.System);
}
public override bool CheckConflictingLayer(Mobile m, Item item, Layer layer)
{
if (base.CheckConflictingLayer(m, item, layer))
return true;
if (layer == Layer.OneHanded)
{
m.SendLocalizedMessage(500214); // You already have something in both hands.
return true;
}
return false;
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
if (version < 1 && Layer == Layer.OneHanded)
Layer = Layer.TwoHanded;
}
}
public FishingPole(Serial serial) : base(serial)
{
}
public override void OnDoubleClick(Mobile from)
{
Point3D loc = GetWorldLocation();
if (!from.InLOS(loc) || !from.InRange(loc, 2))
from.LocalOverheadMessage(MessageType.Regular, 0x3E9, 1019045); // I can't reach that
else
Fishing.System.BeginHarvesting(from, this);
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
BaseHarvestTool.AddContextMenuEntries(from, this, list, Fishing.System);
}
public override bool CheckConflictingLayer(Mobile m, Item item, Layer layer)
{
if (base.CheckConflictingLayer(m, item, layer))
return true;
if (layer == Layer.OneHanded)
{
m.SendLocalizedMessage(500214); // You already have something in both hands.
return true;
}
return false;
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
if (version < 1 && Layer == Layer.OneHanded)
Layer = Layer.TwoHanded;
}
}
}
}

View file

@ -3,102 +3,102 @@ using Server.Network;
namespace Server.Items
{
public class MessageInABottle : Item
{
private int m_Level;
[Constructible]
public MessageInABottle(Map map = null) : this(map, GetRandomLevel())
public class MessageInABottle : Item
{
private int m_Level;
[Constructible]
public MessageInABottle(Map map = null) : this(map, GetRandomLevel())
{
}
[Constructible]
public MessageInABottle(Map map, int level) : base(0x099F)
{
Weight = 1.0;
TargetMap = map ?? Map.Trammel;
m_Level = level;
}
public MessageInABottle(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1041080; // a message in a bottle
[CommandProperty(AccessLevel.GameMaster)]
public Map TargetMap { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public int Level
{
get => m_Level;
set => m_Level = Math.Max(1, Math.Min(value, 4));
}
public static int GetRandomLevel()
{
if (Core.AOS && Utility.Random(25) < 1)
return 4; // ancient
return Utility.RandomMinMax(1, 3);
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(3); // version
writer.Write(m_Level);
writer.Write(TargetMap);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
switch (version)
{
case 3:
case 2:
{
m_Level = reader.ReadInt();
goto case 1;
}
case 1:
{
TargetMap = reader.ReadMap();
break;
}
case 0:
{
TargetMap = Map.Trammel;
break;
}
}
if (version < 2)
m_Level = GetRandomLevel();
if (version < 3 && TargetMap == Map.Tokuno)
TargetMap = Map.Trammel;
}
public override void OnDoubleClick(Mobile from)
{
if (IsChildOf(from.Backpack))
{
ReplaceWith(new SOS(TargetMap, m_Level));
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 501891); // You extract the message from the bottle.
}
else
{
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
}
}
}
[Constructible]
public MessageInABottle(Map map, int level) : base(0x099F)
{
Weight = 1.0;
TargetMap = map ?? Map.Trammel;
m_Level = level;
}
public MessageInABottle(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1041080; // a message in a bottle
[CommandProperty(AccessLevel.GameMaster)]
public Map TargetMap { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public int Level
{
get => m_Level;
set => m_Level = Math.Max(1, Math.Min(value, 4));
}
public static int GetRandomLevel()
{
if (Core.AOS && Utility.Random(25) < 1)
return 4; // ancient
return Utility.RandomMinMax(1, 3);
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(3); // version
writer.Write(m_Level);
writer.Write(TargetMap);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch (version)
{
case 3:
case 2:
{
m_Level = reader.ReadInt();
goto case 1;
}
case 1:
{
TargetMap = reader.ReadMap();
break;
}
case 0:
{
TargetMap = Map.Trammel;
break;
}
}
if (version < 2)
m_Level = GetRandomLevel();
if (version < 3 && TargetMap == Map.Tokuno)
TargetMap = Map.Trammel;
}
public override void OnDoubleClick(Mobile from)
{
if (IsChildOf(from.Backpack))
{
ReplaceWith(new SOS(TargetMap, m_Level));
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 501891); // You extract the message from the bottle.
}
else
{
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
}
}
}
}

View file

@ -3,302 +3,345 @@ using Server.Gumps;
namespace Server.Items
{
[Flippable(0x14ED, 0x14EE)]
public class SOS : Item
{
public override int LabelNumber
[Flippable(0x14ED, 0x14EE)]
public class SOS : Item
{
get
{
if (IsAncient)
return 1063450; // an ancient SOS
private static readonly int[] m_WaterTiles =
{
0x00A8, 0x00AB,
0x0136, 0x0137
};
return 1041081; // a waterstained SOS
}
}
private static readonly Rectangle2D[] m_BritRegions = { new Rectangle2D(0, 0, 5120, 4096) };
private int m_Level;
private static readonly Rectangle2D[] m_IlshRegions =
{ new Rectangle2D(1472, 272, 304, 240), new Rectangle2D(1240, 1000, 312, 160) };
[CommandProperty(AccessLevel.GameMaster)]
public bool IsAncient => m_Level >= 4;
private static readonly Rectangle2D[] m_MalasRegions = { new Rectangle2D(1376, 1520, 464, 280) };
[CommandProperty(AccessLevel.GameMaster)]
public int Level
{
get => m_Level;
set
{
m_Level = Math.Max(1, Math.Min(value, 4));
UpdateHue();
InvalidateProperties();
}
}
private int m_Level;
[CommandProperty(AccessLevel.GameMaster)]
public Map TargetMap { get; set; }
[Constructible]
public SOS(Map map = null) : this(map, MessageInABottle.GetRandomLevel())
{
}
[CommandProperty(AccessLevel.GameMaster)]
public Point3D TargetLocation { get; set; }
[Constructible]
public SOS(Map map, int level) : base(0x14EE)
{
Weight = 1.0;
[CommandProperty(AccessLevel.GameMaster)]
public int MessageIndex { get; set; }
public void UpdateHue()
{
if (IsAncient)
Hue = 0x481;
else
Hue = 0;
}
[Constructible]
public SOS(Map map = null) : this(map, MessageInABottle.GetRandomLevel())
{
}
[Constructible]
public SOS(Map map, int level) : base(0x14EE)
{
Weight = 1.0;
m_Level = level;
MessageIndex = Utility.Random(MessageEntry.Entries.Length);
TargetMap = map ?? Map.Trammel;
TargetLocation = FindLocation(TargetMap);
UpdateHue();
}
public SOS(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(4); // version
writer.Write(m_Level);
writer.Write(TargetMap);
writer.Write(TargetLocation);
writer.Write(MessageIndex);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch (version)
{
case 4:
case 3:
case 2:
{
m_Level = reader.ReadInt();
goto case 1;
}
case 1:
{
TargetMap = reader.ReadMap();
TargetLocation = reader.ReadPoint3D();
MessageIndex = reader.ReadInt();
break;
}
case 0:
{
TargetMap = Map;
if (TargetMap == null || TargetMap == Map.Internal)
TargetMap = Map.Trammel;
TargetLocation = FindLocation(TargetMap);
m_Level = level;
MessageIndex = Utility.Random(MessageEntry.Entries.Length);
TargetMap = map ?? Map.Trammel;
TargetLocation = FindLocation(TargetMap);
break;
}
}
UpdateHue();
}
if (version < 2)
m_Level = MessageInABottle.GetRandomLevel();
public SOS(Serial serial) : base(serial)
{
}
if (version < 3)
UpdateHue();
public override int LabelNumber
{
get
{
if (IsAncient)
return 1063450; // an ancient SOS
if (version < 4 && TargetMap == Map.Tokuno)
TargetMap = Map.Trammel;
return 1041081; // a waterstained SOS
}
}
[CommandProperty(AccessLevel.GameMaster)]
public bool IsAncient => m_Level >= 4;
[CommandProperty(AccessLevel.GameMaster)]
public int Level
{
get => m_Level;
set
{
m_Level = Math.Max(1, Math.Min(value, 4));
UpdateHue();
InvalidateProperties();
}
}
[CommandProperty(AccessLevel.GameMaster)]
public Map TargetMap { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public Point3D TargetLocation { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public int MessageIndex { get; set; }
public void UpdateHue()
{
if (IsAncient)
Hue = 0x481;
else
Hue = 0;
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(4); // version
writer.Write(m_Level);
writer.Write(TargetMap);
writer.Write(TargetLocation);
writer.Write(MessageIndex);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
switch (version)
{
case 4:
case 3:
case 2:
{
m_Level = reader.ReadInt();
goto case 1;
}
case 1:
{
TargetMap = reader.ReadMap();
TargetLocation = reader.ReadPoint3D();
MessageIndex = reader.ReadInt();
break;
}
case 0:
{
TargetMap = Map;
if (TargetMap == null || TargetMap == Map.Internal)
TargetMap = Map.Trammel;
TargetLocation = FindLocation(TargetMap);
MessageIndex = Utility.Random(MessageEntry.Entries.Length);
break;
}
}
if (version < 2)
m_Level = MessageInABottle.GetRandomLevel();
if (version < 3)
UpdateHue();
if (version < 4 && TargetMap == Map.Tokuno)
TargetMap = Map.Trammel;
}
public override void OnDoubleClick(Mobile from)
{
if (IsChildOf(from.Backpack))
{
MessageEntry entry;
if (MessageIndex >= 0 && MessageIndex < MessageEntry.Entries.Length)
entry = MessageEntry.Entries[MessageIndex];
else
entry = MessageEntry.Entries[MessageIndex = Utility.Random(MessageEntry.Entries.Length)];
// from.CloseGump( typeof( MessageGump ) );
from.SendGump(new MessageGump(entry, TargetMap, TargetLocation));
}
else
{
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
}
}
public static Point3D FindLocation(Map map)
{
if (map == null || map == Map.Internal)
return Point3D.Zero;
Rectangle2D[] regions;
if (map == Map.Felucca || map == Map.Trammel)
regions = m_BritRegions;
else if (map == Map.Ilshenar)
regions = m_IlshRegions;
else if (map == Map.Malas)
regions = m_MalasRegions;
else
regions = new[] { new Rectangle2D(0, 0, map.Width, map.Height) };
if (regions.Length == 0)
return Point3D.Zero;
for (var i = 0; i < 50; ++i)
{
var reg = regions.RandomElement();
var x = Utility.Random(reg.X, reg.Width);
var y = Utility.Random(reg.Y, reg.Height);
if (!ValidateDeepWater(map, x, y))
continue;
var valid = true;
for (int j = 1, offset = 5; valid && j <= 5; ++j, offset += 5)
if (!ValidateDeepWater(map, x + offset, y + offset))
valid = false;
else if (!ValidateDeepWater(map, x + offset, y - offset))
valid = false;
else if (!ValidateDeepWater(map, x - offset, y + offset))
valid = false;
else if (!ValidateDeepWater(map, x - offset, y - offset))
valid = false;
if (valid)
return new Point3D(x, y, 0);
}
return Point3D.Zero;
}
private static bool ValidateDeepWater(Map map, int x, int y)
{
var tileID = map.Tiles.GetLandTile(x, y).ID;
var water = false;
for (var i = 0; !water && i < m_WaterTiles.Length; i += 2)
water = tileID >= m_WaterTiles[i] && tileID <= m_WaterTiles[i + 1];
return water;
}
private class MessageGump : Gump
{
public MessageGump(MessageEntry entry, Map map, Point3D loc) : base(150, 50)
{
int xLong = 0, yLat = 0;
int xMins = 0, yMins = 0;
bool xEast = false, ySouth = false;
string fmt;
if (Sextant.Format(loc, map, ref xLong, ref yLat, ref xMins, ref yMins, ref xEast, ref ySouth))
fmt = $"{yLat}°{yMins}'{(ySouth ? "S" : "N")},{xLong}°{xMins}'{(xEast ? "E" : "W")}";
else
fmt = "?????";
AddPage(0);
AddBackground(0, 40, 350, 300, 2520);
/* This is a message hastily scribbled by a passenger aboard a sinking ship.
* While it is probably too late to save the passengers and crew,
* perhaps some treasure went down with the ship!
* The message gives the ship's last known sextant co-ordinates.
*/
AddHtmlLocalized(
30,
80,
285,
160,
1018326,
true,
true
);
AddHtml(35, 240, 230, 20, fmt);
AddButton(35, 265, 4005, 4007, 0);
AddHtmlLocalized(70, 265, 100, 20, 1011036); // OKAY
}
}
private class MessageEntry
{
public MessageEntry(int width, int height, string message)
{
Width = width;
Height = height;
Message = message;
}
public int Width { get; }
public int Height { get; }
public string Message { get; }
public static MessageEntry[] Entries { get; } =
{
new MessageEntry(
280,
180,
"...Ar! {0} and a fair wind! No chance... storms, though--ar! Is that a sea serp...<br><br>uh oh."
),
new MessageEntry(
280,
215,
"...been inside this whale for three days now. I've run out of food I can pick out of his teeth. I took a sextant reading through the blowhole: {0}. I'll never see my treasure again..."
),
new MessageEntry(
280,
285,
"...grand adventure! Captain Quacklebush had me swab down the decks daily...<br> ...pirates came, I was in the rigging practicing with my sextant. {0} if I am not mistaken...<br> ....scuttled the ship, and our precious cargo went with her and the screaming pirates, down to the bottom of the sea..."
),
new MessageEntry(
280,
180,
"Help! Ship going dow...n heavy storms...precious cargo...st reach dest...current coordinates {0}...ve any survivors... ease!"
),
new MessageEntry(
280,
215,
"...know that the wreck is near {0} but have not found it. Could the message passed down in my family for generations be wrong? No... I swear on the soul of my grandfather, I will find..."
),
new MessageEntry(
280,
195,
"...never expected an iceberg...silly woman on bow crushed instantly...send help to {0}...ey'll never forget the tragedy of the sinking of the Miniscule..."
),
new MessageEntry(
280,
265,
"...nobody knew I was a girl. They just assumed I was another sailor...then we met the undine. {0}. It was demanded sacrifice...I was youngset, they figured...<br> ...grabbed the captain's treasure, screamed, 'It'll go down with me!'<br> ...they took me up on it."
),
new MessageEntry(
280,
230,
"...so I threw the treasure overboard, before the curse could get me too. But I was too late. Now I am doomed to wander these seas, a ghost forever. Join me: seek ye at {0} if thou wishest my company..."
),
new MessageEntry(
280,
285,
"...then the ship exploded. A dragon swooped by. The slime swallowed Bertie whole--he screamed, it was amazing. The sky glowed orange. A sextant reading put us at {0}. Norma was chattering about sailing over the edge of the world. I looked at my hands and saw through them..."
),
new MessageEntry(
280,
285,
"...trapped on a deserted island, with a magic fountain supplying wood, fresh water springs, gorgeous scenery, and my lovely young wife. I know the ship with all our life's earnings sank at {0} but I don't know what our coordinates are... someone has GOT to rescue me before Sunday's finals game or I'll go mad..."
),
new MessageEntry(
280,
160,
"WANTED: divers exp...d in shipwre...overy. Must have own vess...pply at {0}<br>...good benefits, flexible hours..."
),
new MessageEntry(
280,
250,
"...was a cad and a boor, no matter what momma s...rew him overboard! Oh, Anna, 'twas so exciting!<br> Unfort...y he grabbe...est, and all his riches went with him!<br> ...sked the captain, and he says we're at {0}<br>...so maybe..."
)
};
}
}
public override void OnDoubleClick(Mobile from)
{
if (IsChildOf(from.Backpack))
{
MessageEntry entry;
if (MessageIndex >= 0 && MessageIndex < MessageEntry.Entries.Length)
entry = MessageEntry.Entries[MessageIndex];
else
entry = MessageEntry.Entries[MessageIndex = Utility.Random(MessageEntry.Entries.Length)];
// from.CloseGump( typeof( MessageGump ) );
from.SendGump(new MessageGump(entry, TargetMap, TargetLocation));
}
else
{
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
}
}
private static readonly int[] m_WaterTiles =
{
0x00A8, 0x00AB,
0x0136, 0x0137
};
private static readonly Rectangle2D[] m_BritRegions = { new Rectangle2D(0, 0, 5120, 4096) };
private static readonly Rectangle2D[] m_IlshRegions =
{ new Rectangle2D(1472, 272, 304, 240), new Rectangle2D(1240, 1000, 312, 160) };
private static readonly Rectangle2D[] m_MalasRegions = { new Rectangle2D(1376, 1520, 464, 280) };
public static Point3D FindLocation(Map map)
{
if (map == null || map == Map.Internal)
return Point3D.Zero;
Rectangle2D[] regions;
if (map == Map.Felucca || map == Map.Trammel)
regions = m_BritRegions;
else if (map == Map.Ilshenar)
regions = m_IlshRegions;
else if (map == Map.Malas)
regions = m_MalasRegions;
else
regions = new[] { new Rectangle2D(0, 0, map.Width, map.Height) };
if (regions.Length == 0)
return Point3D.Zero;
for (int i = 0; i < 50; ++i)
{
Rectangle2D reg = regions.RandomElement();
int x = Utility.Random(reg.X, reg.Width);
int y = Utility.Random(reg.Y, reg.Height);
if (!ValidateDeepWater(map, x, y))
continue;
bool valid = true;
for (int j = 1, offset = 5; valid && j <= 5; ++j, offset += 5)
if (!ValidateDeepWater(map, x + offset, y + offset))
valid = false;
else if (!ValidateDeepWater(map, x + offset, y - offset))
valid = false;
else if (!ValidateDeepWater(map, x - offset, y + offset))
valid = false;
else if (!ValidateDeepWater(map, x - offset, y - offset))
valid = false;
if (valid)
return new Point3D(x, y, 0);
}
return Point3D.Zero;
}
private static bool ValidateDeepWater(Map map, int x, int y)
{
int tileID = map.Tiles.GetLandTile(x, y).ID;
bool water = false;
for (int i = 0; !water && i < m_WaterTiles.Length; i += 2)
water = tileID >= m_WaterTiles[i] && tileID <= m_WaterTiles[i + 1];
return water;
}
private class MessageGump : Gump
{
public MessageGump(MessageEntry entry, Map map, Point3D loc) : base(150, 50)
{
int xLong = 0, yLat = 0;
int xMins = 0, yMins = 0;
bool xEast = false, ySouth = false;
string fmt;
if (Sextant.Format(loc, map, ref xLong, ref yLat, ref xMins, ref yMins, ref xEast, ref ySouth))
fmt = $"{yLat}°{yMins}'{(ySouth ? "S" : "N")},{xLong}°{xMins}'{(xEast ? "E" : "W")}";
else
fmt = "?????";
AddPage(0);
AddBackground(0, 40, 350, 300, 2520);
/* This is a message hastily scribbled by a passenger aboard a sinking ship.
* While it is probably too late to save the passengers and crew,
* perhaps some treasure went down with the ship!
* The message gives the ship's last known sextant co-ordinates.
*/
AddHtmlLocalized(30, 80, 285, 160, 1018326, true,
true);
AddHtml(35, 240, 230, 20, fmt);
AddButton(35, 265, 4005, 4007, 0);
AddHtmlLocalized(70, 265, 100, 20, 1011036); // OKAY
}
}
private class MessageEntry
{
public MessageEntry(int width, int height, string message)
{
Width = width;
Height = height;
Message = message;
}
public int Width { get; }
public int Height { get; }
public string Message { get; }
public static MessageEntry[] Entries { get; } =
{
new MessageEntry(280, 180,
"...Ar! {0} and a fair wind! No chance... storms, though--ar! Is that a sea serp...<br><br>uh oh."),
new MessageEntry(280, 215,
"...been inside this whale for three days now. I've run out of food I can pick out of his teeth. I took a sextant reading through the blowhole: {0}. I'll never see my treasure again..."),
new MessageEntry(280, 285,
"...grand adventure! Captain Quacklebush had me swab down the decks daily...<br> ...pirates came, I was in the rigging practicing with my sextant. {0} if I am not mistaken...<br> ....scuttled the ship, and our precious cargo went with her and the screaming pirates, down to the bottom of the sea..."),
new MessageEntry(280, 180,
"Help! Ship going dow...n heavy storms...precious cargo...st reach dest...current coordinates {0}...ve any survivors... ease!"),
new MessageEntry(280, 215,
"...know that the wreck is near {0} but have not found it. Could the message passed down in my family for generations be wrong? No... I swear on the soul of my grandfather, I will find..."),
new MessageEntry(280, 195,
"...never expected an iceberg...silly woman on bow crushed instantly...send help to {0}...ey'll never forget the tragedy of the sinking of the Miniscule..."),
new MessageEntry(280, 265,
"...nobody knew I was a girl. They just assumed I was another sailor...then we met the undine. {0}. It was demanded sacrifice...I was youngset, they figured...<br> ...grabbed the captain's treasure, screamed, 'It'll go down with me!'<br> ...they took me up on it."),
new MessageEntry(280, 230,
"...so I threw the treasure overboard, before the curse could get me too. But I was too late. Now I am doomed to wander these seas, a ghost forever. Join me: seek ye at {0} if thou wishest my company..."),
new MessageEntry(280, 285,
"...then the ship exploded. A dragon swooped by. The slime swallowed Bertie whole--he screamed, it was amazing. The sky glowed orange. A sextant reading put us at {0}. Norma was chattering about sailing over the edge of the world. I looked at my hands and saw through them..."),
new MessageEntry(280, 285,
"...trapped on a deserted island, with a magic fountain supplying wood, fresh water springs, gorgeous scenery, and my lovely young wife. I know the ship with all our life's earnings sank at {0} but I don't know what our coordinates are... someone has GOT to rescue me before Sunday's finals game or I'll go mad..."),
new MessageEntry(280, 160,
"WANTED: divers exp...d in shipwre...overy. Must have own vess...pply at {0}<br>...good benefits, flexible hours..."),
new MessageEntry(280, 250,
"...was a cad and a boor, no matter what momma s...rew him overboard! Oh, Anna, 'twas so exciting!<br> Unfort...y he grabbe...est, and all his riches went with him!<br> ...sked the captain, and he says we're at {0}<br>...so maybe...")
};
}
}
}

View file

@ -2,155 +2,159 @@ using Server.Network;
namespace Server.Items
{
public class Sextant : Item
{
[Constructible]
public Sextant() : base(0x1058) => Weight = 2.0;
public Sextant(Serial serial) : base(serial)
public class Sextant : Item
{
}
[Constructible]
public Sextant() : base(0x1058) => Weight = 2.0;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
public override void OnDoubleClick(Mobile from)
{
int xLong = 0, yLat = 0;
int xMins = 0, yMins = 0;
bool xEast = false, ySouth = false;
if (Format(from.Location, from.Map, ref xLong, ref yLat, ref xMins, ref yMins, ref xEast, ref ySouth))
{
string location = $"{yLat}<7D> {yMins}'{(ySouth ? "S" : "N")}, {xLong}<7D> {xMins}'{(xEast ? "E" : "W")}";
from.LocalOverheadMessage(MessageType.Regular, from.SpeechHue, false, location);
}
}
public static bool ComputeMapDetails(Map map, int x, int y, out int xCenter, out int yCenter, out int xWidth,
out int yHeight)
{
xWidth = 5120;
yHeight = 4096;
if (map == Map.Trammel || map == Map.Felucca)
{
if (x >= 0 && y >= 0 && x < 5120 && y < 4096)
public Sextant(Serial serial) : base(serial)
{
xCenter = 1323;
yCenter = 1624;
}
else if (x >= 5120 && y >= 2304 && x < 6144 && y < 4096)
public override void Serialize(IGenericWriter writer)
{
xCenter = 5936;
yCenter = 3112;
base.Serialize(writer);
writer.Write(0); // version
}
else
public override void Deserialize(IGenericReader reader)
{
xCenter = 0;
yCenter = 0;
return false;
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
else if (x >= 0 && y >= 0 && x < map.Width && y < map.Height)
{
xCenter = 1323;
yCenter = 1624;
}
else
{
xCenter = 0;
yCenter = 0;
return false;
}
return true;
public override void OnDoubleClick(Mobile from)
{
int xLong = 0, yLat = 0;
int xMins = 0, yMins = 0;
bool xEast = false, ySouth = false;
if (Format(from.Location, from.Map, ref xLong, ref yLat, ref xMins, ref yMins, ref xEast, ref ySouth))
{
var location = $"{yLat}<7D> {yMins}'{(ySouth ? "S" : "N")}, {xLong}<7D> {xMins}'{(xEast ? "E" : "W")}";
from.LocalOverheadMessage(MessageType.Regular, from.SpeechHue, false, location);
}
}
public static bool ComputeMapDetails(
Map map, int x, int y, out int xCenter, out int yCenter, out int xWidth,
out int yHeight
)
{
xWidth = 5120;
yHeight = 4096;
if (map == Map.Trammel || map == Map.Felucca)
{
if (x >= 0 && y >= 0 && x < 5120 && y < 4096)
{
xCenter = 1323;
yCenter = 1624;
}
else if (x >= 5120 && y >= 2304 && x < 6144 && y < 4096)
{
xCenter = 5936;
yCenter = 3112;
}
else
{
xCenter = 0;
yCenter = 0;
return false;
}
}
else if (x >= 0 && y >= 0 && x < map.Width && y < map.Height)
{
xCenter = 1323;
yCenter = 1624;
}
else
{
xCenter = 0;
yCenter = 0;
return false;
}
return true;
}
public static Point3D ReverseLookup(Map map, int xLong, int yLat, int xMins, int yMins, bool xEast, bool ySouth)
{
if (map == null || map == Map.Internal)
return Point3D.Zero;
if (!ComputeMapDetails(map, 0, 0, out var xCenter, out var yCenter, out var xWidth, out var yHeight))
return Point3D.Zero;
var absLong = xLong + (double)xMins / 60;
var absLat = yLat + (double)yMins / 60;
if (!xEast)
absLong = 360.0 - absLong;
if (!ySouth)
absLat = 360.0 - absLat;
var x = xCenter + (int)(absLong * xWidth / 360);
var y = yCenter + (int)(absLat * yHeight / 360);
if (x < 0)
x += xWidth;
else if (x >= xWidth)
x -= xWidth;
if (y < 0)
y += yHeight;
else if (y >= yHeight)
y -= yHeight;
var z = map.GetAverageZ(x, y);
return new Point3D(x, y, z);
}
public static bool Format(
Point3D p, Map map, ref int xLong, ref int yLat, ref int xMins, ref int yMins,
ref bool xEast, ref bool ySouth
)
{
if (map == null || map == Map.Internal)
return false;
int x = p.X, y = p.Y;
if (!ComputeMapDetails(map, x, y, out var xCenter, out var yCenter, out var xWidth, out var yHeight))
return false;
var absLong = (double)((x - xCenter) * 360) / xWidth;
var absLat = (double)((y - yCenter) * 360) / yHeight;
if (absLong > 180.0)
absLong = -180.0 + absLong % 180.0;
if (absLat > 180.0)
absLat = -180.0 + absLat % 180.0;
bool east = absLong >= 0, south = absLat >= 0;
if (absLong < 0.0)
absLong = -absLong;
if (absLat < 0.0)
absLat = -absLat;
xLong = (int)absLong;
yLat = (int)absLat;
xMins = (int)(absLong % 1.0 * 60);
yMins = (int)(absLat % 1.0 * 60);
xEast = east;
ySouth = south;
return true;
}
}
public static Point3D ReverseLookup(Map map, int xLong, int yLat, int xMins, int yMins, bool xEast, bool ySouth)
{
if (map == null || map == Map.Internal)
return Point3D.Zero;
if (!ComputeMapDetails(map, 0, 0, out int xCenter, out int yCenter, out int xWidth, out int yHeight))
return Point3D.Zero;
double absLong = xLong + (double)xMins / 60;
double absLat = yLat + (double)yMins / 60;
if (!xEast)
absLong = 360.0 - absLong;
if (!ySouth)
absLat = 360.0 - absLat;
int x = xCenter + (int)(absLong * xWidth / 360);
int y = yCenter + (int)(absLat * yHeight / 360);
if (x < 0)
x += xWidth;
else if (x >= xWidth)
x -= xWidth;
if (y < 0)
y += yHeight;
else if (y >= yHeight)
y -= yHeight;
int z = map.GetAverageZ(x, y);
return new Point3D(x, y, z);
}
public static bool Format(Point3D p, Map map, ref int xLong, ref int yLat, ref int xMins, ref int yMins,
ref bool xEast, ref bool ySouth)
{
if (map == null || map == Map.Internal)
return false;
int x = p.X, y = p.Y;
if (!ComputeMapDetails(map, x, y, out int xCenter, out int yCenter, out int xWidth, out int yHeight))
return false;
double absLong = (double)((x - xCenter) * 360) / xWidth;
double absLat = (double)((y - yCenter) * 360) / yHeight;
if (absLong > 180.0)
absLong = -180.0 + absLong % 180.0;
if (absLat > 180.0)
absLat = -180.0 + absLat % 180.0;
bool east = absLong >= 0, south = absLat >= 0;
if (absLong < 0.0)
absLong = -absLong;
if (absLat < 0.0)
absLat = -absLat;
xLong = (int)absLong;
yLat = (int)absLat;
xMins = (int)(absLong % 1.0 * 60);
yMins = (int)(absLat % 1.0 * 60);
xEast = east;
ySouth = south;
return true;
}
}
}
}

View file

@ -1,70 +1,70 @@
namespace Server.Items
{
public interface IShipwreckedItem
{
bool IsShipwreckedItem { get; set; }
}
public class ShipwreckedItem : Item, IDyable, IShipwreckedItem
{
public ShipwreckedItem(int itemID) : base(itemID)
public interface IShipwreckedItem
{
int weight = ItemData.Weight;
if (weight >= 255)
weight = 1;
Weight = weight;
bool IsShipwreckedItem { get; set; }
}
public ShipwreckedItem(Serial serial) : base(serial)
public class ShipwreckedItem : Item, IDyable, IShipwreckedItem
{
public ShipwreckedItem(int itemID) : base(itemID)
{
var weight = ItemData.Weight;
if (weight >= 255)
weight = 1;
Weight = weight;
}
public ShipwreckedItem(Serial serial) : base(serial)
{
}
public bool Dye(Mobile from, DyeTub sender)
{
if (Deleted)
return false;
if (ItemID >= 0x13A4 && ItemID <= 0x13AE)
{
Hue = sender.DyedHue;
return true;
}
from.SendLocalizedMessage(sender.FailMessage);
return false;
}
bool IShipwreckedItem.IsShipwreckedItem
{
get => true;
set { }
}
public override void OnSingleClick(Mobile from)
{
LabelTo(from, 1050039, $"#{LabelNumber}\t#1041645");
}
public override void AddNameProperties(ObjectPropertyList list)
{
base.AddNameProperties(list);
list.Add(1041645); // recovered from a shipwreck
}
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 bool Dye(Mobile from, DyeTub sender)
{
if (Deleted)
return false;
if (ItemID >= 0x13A4 && ItemID <= 0x13AE)
{
Hue = sender.DyedHue;
return true;
}
from.SendLocalizedMessage(sender.FailMessage);
return false;
}
bool IShipwreckedItem.IsShipwreckedItem
{
get => true;
set { }
}
public override void OnSingleClick(Mobile from)
{
LabelTo(from, 1050039, $"#{LabelNumber}\t#1041645");
}
public override void AddNameProperties(ObjectPropertyList list)
{
base.AddNameProperties(list);
list.Add(1041645); // recovered from a shipwreck
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
}

View file

@ -6,403 +6,411 @@ using Server.Targeting;
namespace Server.Items
{
public class SpecialFishingNet : Item
{
private static readonly int[] m_Hues =
public class SpecialFishingNet : Item
{
0x09B,
0x0CD,
0x0D3,
0x14D,
0x1DD,
0x1E9,
0x1F4,
0x373,
0x451,
0x47F,
0x489,
0x492,
0x4B5,
0x8AA
};
private static readonly int[] m_WaterTiles =
{
0x00A8, 0x00AB,
0x0136, 0x0137
};
private static readonly int[] m_UndeepWaterTiles =
{
0x1797, 0x179C
};
[Constructible]
public SpecialFishingNet() : base(0x0DCA)
{
Weight = 1.0;
if (Utility.RandomDouble() < 0.01)
Hue = m_Hues.RandomElement();
else
Hue = 0x8A0;
}
public SpecialFishingNet(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1041079; // a special fishing net
[CommandProperty(AccessLevel.GameMaster)]
public bool InUse { get; set; }
public virtual bool RequireDeepWater => true;
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
AddNetProperties(list);
}
protected virtual void AddNetProperties(ObjectPropertyList list)
{
// as if the name wasn't enough..
list.Add(1017410); // Special Fishing Net
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
writer.Write(InUse);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch (version)
{
case 1:
{
InUse = reader.ReadBool();
if (InUse)
Delete();
break;
}
}
Stackable = false;
}
public override void OnDoubleClick(Mobile from)
{
if (InUse)
{
from.SendLocalizedMessage(1010483); // Someone is already using that net!
}
else if (IsChildOf(from.Backpack))
{
from.SendLocalizedMessage(1010484); // Where do you wish to use the net?
from.BeginTarget(-1, true, TargetFlags.None, OnTarget);
}
else
{
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
}
}
public void OnTarget(Mobile from, object obj)
{
if (Deleted || InUse)
return;
if (!(obj is IPoint3D p3D))
return;
Map map = from.Map;
if (map == null || map == Map.Internal)
return;
int x = p3D.X, y = p3D.Y, z = map.GetAverageZ(x, y); // OSI just takes the targeted Z
if (!from.InRange(p3D, 6))
{
from.SendLocalizedMessage(500976); // You need to be closer to the water to fish!
}
else if (!from.InLOS(obj))
{
from.SendLocalizedMessage(500979); // You cannot see that location.
}
else if (RequireDeepWater
? FullValidation(map, x, y)
: ValidateDeepWater(map, x, y) || ValidateUndeepWater(map, obj, ref z))
{
Point3D p = new Point3D(x, y, z);
if (GetType() == typeof(SpecialFishingNet))
for (int i = 1; i < Amount; ++i) // these were stackable before, doh
from.AddToBackpack(new SpecialFishingNet());
InUse = true;
Movable = false;
MoveToWorld(p, map);
SpellHelper.Turn(from, p);
from.Animate(12, 5, 1, true, false, 0);
Effects.SendLocationEffect(p, map, 0x352D, 16, 4);
Effects.PlaySound(p, map, 0x364);
int index = 0;
Timer.DelayCall(TimeSpan.FromSeconds(1.0), TimeSpan.FromSeconds(1.25), 14,
() => DoEffect(from, p, index++));
from.SendLocalizedMessage(RequireDeepWater
? 1010487
: 1074492); // You plunge the net into the sea... / You plunge the net into the water...
}
else
{
from.SendLocalizedMessage(RequireDeepWater
? 1010485
: 1074491); // You can only use this net in deep water! / You can only use this net in water!
}
}
private void DoEffect(Mobile from, Point3D p, int index)
{
if (Deleted)
return;
if (index == 1)
{
Effects.SendLocationEffect(p, Map, 0x352D, 16, 4);
Effects.PlaySound(p, Map, 0x364);
}
else if (index <= 7 || index == 14)
{
if (RequireDeepWater)
for (int i = 0; i < 3; ++i)
{
int x, y;
switch (Utility.Random(8))
{
default:
case 0:
x = -1;
y = -1;
break;
case 1:
x = -1;
y = 0;
break;
case 2:
x = -1;
y = +1;
break;
case 3:
x = 0;
y = -1;
break;
case 4:
x = 0;
y = +1;
break;
case 5:
x = +1;
y = -1;
break;
case 6:
x = +1;
y = 0;
break;
case 7:
x = +1;
y = +1;
break;
}
Effects.SendLocationEffect(new Point3D(p.X + x, p.Y + y, p.Z), Map, 0x352D, 16, 4);
}
else
Effects.SendLocationEffect(p, Map, 0x352D, 16, 4);
if (Utility.RandomBool())
Effects.PlaySound(p, Map, 0x364);
if (index == 14)
FinishEffect(p, Map, from);
else
Z -= 1;
}
}
protected virtual int GetSpawnCount()
{
int count = Utility.RandomMinMax(1, 3);
if (Hue != 0x8A0)
count += Utility.RandomMinMax(1, 2);
return count;
}
protected void Spawn(Point3D p, Map map, BaseCreature spawn)
{
if (map == null)
{
spawn.Delete();
return;
}
int x = p.X, y = p.Y;
for (int j = 0; j < 20; ++j)
{
int tx = p.X - 2 + Utility.Random(5);
int ty = p.Y - 2 + Utility.Random(5);
LandTile t = map.Tiles.GetLandTile(tx, ty);
if (t.Z == p.Z && ((t.ID >= 0xA8 && t.ID <= 0xAB) || (t.ID >= 0x136 && t.ID <= 0x137)) &&
!SpellHelper.CheckMulti(new Point3D(tx, ty, p.Z), map))
private static readonly int[] m_Hues =
{
x = tx;
y = ty;
break;
}
}
spawn.MoveToWorld(new Point3D(x, y, p.Z), map);
if (spawn is Kraken && Utility.RandomDouble() < 0.2)
spawn.PackItem(new MessageInABottle(map == Map.Felucca ? Map.Felucca : Map.Trammel));
}
protected virtual void FinishEffect(Point3D p, Map map, Mobile from)
{
from.RevealingAction();
int count = GetSpawnCount();
for (int i = 0; map != null && i < count; ++i)
{
var spawn = Utility.Random(4) switch
{
0 => (BaseCreature)new SeaSerpent(),
1 => new DeepSeaSerpent(),
2 => new WaterElemental(),
3 => new Kraken(),
_ => new SeaSerpent()
0x09B,
0x0CD,
0x0D3,
0x14D,
0x1DD,
0x1E9,
0x1F4,
0x373,
0x451,
0x47F,
0x489,
0x492,
0x4B5,
0x8AA
};
Spawn(p, map, spawn);
spawn.Combatant = from;
}
Delete();
}
public static bool FullValidation(Map map, int x, int y)
{
bool valid = ValidateDeepWater(map, x, y);
for (int j = 1, offset = 5; valid && j <= 5; ++j, offset += 5)
if (!ValidateDeepWater(map, x + offset, y + offset))
valid = false;
else if (!ValidateDeepWater(map, x + offset, y - offset))
valid = false;
else if (!ValidateDeepWater(map, x - offset, y + offset))
valid = false;
else if (!ValidateDeepWater(map, x - offset, y - offset))
valid = false;
return valid;
}
private static bool ValidateDeepWater(Map map, int x, int y)
{
int tileID = map.Tiles.GetLandTile(x, y).ID;
bool water = false;
for (int i = 0; !water && i < m_WaterTiles.Length; i += 2)
water = tileID >= m_WaterTiles[i] && tileID <= m_WaterTiles[i + 1];
return water;
}
private static bool ValidateUndeepWater(Map map, object obj, ref int z)
{
if (!(obj is StaticTarget))
return false;
StaticTarget target = (StaticTarget)obj;
if (BaseHouse.FindHouseAt(target.Location, map, 0) != null)
return false;
int itemID = target.ItemID;
for (int i = 0; i < m_UndeepWaterTiles.Length; i += 2)
if (itemID >= m_UndeepWaterTiles[i] && itemID <= m_UndeepWaterTiles[i + 1])
private static readonly int[] m_WaterTiles =
{
z = target.Z;
return true;
0x00A8, 0x00AB,
0x0136, 0x0137
};
private static readonly int[] m_UndeepWaterTiles =
{
0x1797, 0x179C
};
[Constructible]
public SpecialFishingNet() : base(0x0DCA)
{
Weight = 1.0;
if (Utility.RandomDouble() < 0.01)
Hue = m_Hues.RandomElement();
else
Hue = 0x8A0;
}
return false;
public SpecialFishingNet(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1041079; // a special fishing net
[CommandProperty(AccessLevel.GameMaster)]
public bool InUse { get; set; }
public virtual bool RequireDeepWater => true;
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
AddNetProperties(list);
}
protected virtual void AddNetProperties(ObjectPropertyList list)
{
// as if the name wasn't enough..
list.Add(1017410); // Special Fishing Net
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
writer.Write(InUse);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
switch (version)
{
case 1:
{
InUse = reader.ReadBool();
if (InUse)
Delete();
break;
}
}
Stackable = false;
}
public override void OnDoubleClick(Mobile from)
{
if (InUse)
{
from.SendLocalizedMessage(1010483); // Someone is already using that net!
}
else if (IsChildOf(from.Backpack))
{
from.SendLocalizedMessage(1010484); // Where do you wish to use the net?
from.BeginTarget(-1, true, TargetFlags.None, OnTarget);
}
else
{
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
}
}
public void OnTarget(Mobile from, object obj)
{
if (Deleted || InUse)
return;
if (!(obj is IPoint3D p3D))
return;
var map = from.Map;
if (map == null || map == Map.Internal)
return;
int x = p3D.X, y = p3D.Y, z = map.GetAverageZ(x, y); // OSI just takes the targeted Z
if (!from.InRange(p3D, 6))
{
from.SendLocalizedMessage(500976); // You need to be closer to the water to fish!
}
else if (!from.InLOS(obj))
{
from.SendLocalizedMessage(500979); // You cannot see that location.
}
else if (RequireDeepWater
? FullValidation(map, x, y)
: ValidateDeepWater(map, x, y) || ValidateUndeepWater(map, obj, ref z))
{
var p = new Point3D(x, y, z);
if (GetType() == typeof(SpecialFishingNet))
for (var i = 1; i < Amount; ++i) // these were stackable before, doh
from.AddToBackpack(new SpecialFishingNet());
InUse = true;
Movable = false;
MoveToWorld(p, map);
SpellHelper.Turn(from, p);
from.Animate(12, 5, 1, true, false, 0);
Effects.SendLocationEffect(p, map, 0x352D, 16, 4);
Effects.PlaySound(p, map, 0x364);
var index = 0;
Timer.DelayCall(
TimeSpan.FromSeconds(1.0),
TimeSpan.FromSeconds(1.25),
14,
() => DoEffect(from, p, index++)
);
from.SendLocalizedMessage(
RequireDeepWater
? 1010487
: 1074492
); // You plunge the net into the sea... / You plunge the net into the water...
}
else
{
from.SendLocalizedMessage(
RequireDeepWater
? 1010485
: 1074491
); // You can only use this net in deep water! / You can only use this net in water!
}
}
private void DoEffect(Mobile from, Point3D p, int index)
{
if (Deleted)
return;
if (index == 1)
{
Effects.SendLocationEffect(p, Map, 0x352D, 16, 4);
Effects.PlaySound(p, Map, 0x364);
}
else if (index <= 7 || index == 14)
{
if (RequireDeepWater)
for (var i = 0; i < 3; ++i)
{
int x, y;
switch (Utility.Random(8))
{
default:
case 0:
x = -1;
y = -1;
break;
case 1:
x = -1;
y = 0;
break;
case 2:
x = -1;
y = +1;
break;
case 3:
x = 0;
y = -1;
break;
case 4:
x = 0;
y = +1;
break;
case 5:
x = +1;
y = -1;
break;
case 6:
x = +1;
y = 0;
break;
case 7:
x = +1;
y = +1;
break;
}
Effects.SendLocationEffect(new Point3D(p.X + x, p.Y + y, p.Z), Map, 0x352D, 16, 4);
}
else
Effects.SendLocationEffect(p, Map, 0x352D, 16, 4);
if (Utility.RandomBool())
Effects.PlaySound(p, Map, 0x364);
if (index == 14)
FinishEffect(p, Map, from);
else
Z -= 1;
}
}
protected virtual int GetSpawnCount()
{
var count = Utility.RandomMinMax(1, 3);
if (Hue != 0x8A0)
count += Utility.RandomMinMax(1, 2);
return count;
}
protected void Spawn(Point3D p, Map map, BaseCreature spawn)
{
if (map == null)
{
spawn.Delete();
return;
}
int x = p.X, y = p.Y;
for (var j = 0; j < 20; ++j)
{
var tx = p.X - 2 + Utility.Random(5);
var ty = p.Y - 2 + Utility.Random(5);
var t = map.Tiles.GetLandTile(tx, ty);
if (t.Z == p.Z && (t.ID >= 0xA8 && t.ID <= 0xAB || t.ID >= 0x136 && t.ID <= 0x137) &&
!SpellHelper.CheckMulti(new Point3D(tx, ty, p.Z), map))
{
x = tx;
y = ty;
break;
}
}
spawn.MoveToWorld(new Point3D(x, y, p.Z), map);
if (spawn is Kraken && Utility.RandomDouble() < 0.2)
spawn.PackItem(new MessageInABottle(map == Map.Felucca ? Map.Felucca : Map.Trammel));
}
protected virtual void FinishEffect(Point3D p, Map map, Mobile from)
{
from.RevealingAction();
var count = GetSpawnCount();
for (var i = 0; map != null && i < count; ++i)
{
var spawn = Utility.Random(4) switch
{
0 => (BaseCreature)new SeaSerpent(),
1 => new DeepSeaSerpent(),
2 => new WaterElemental(),
3 => new Kraken(),
_ => new SeaSerpent()
};
Spawn(p, map, spawn);
spawn.Combatant = from;
}
Delete();
}
public static bool FullValidation(Map map, int x, int y)
{
var valid = ValidateDeepWater(map, x, y);
for (int j = 1, offset = 5; valid && j <= 5; ++j, offset += 5)
if (!ValidateDeepWater(map, x + offset, y + offset))
valid = false;
else if (!ValidateDeepWater(map, x + offset, y - offset))
valid = false;
else if (!ValidateDeepWater(map, x - offset, y + offset))
valid = false;
else if (!ValidateDeepWater(map, x - offset, y - offset))
valid = false;
return valid;
}
private static bool ValidateDeepWater(Map map, int x, int y)
{
var tileID = map.Tiles.GetLandTile(x, y).ID;
var water = false;
for (var i = 0; !water && i < m_WaterTiles.Length; i += 2)
water = tileID >= m_WaterTiles[i] && tileID <= m_WaterTiles[i + 1];
return water;
}
private static bool ValidateUndeepWater(Map map, object obj, ref int z)
{
if (!(obj is StaticTarget))
return false;
var target = (StaticTarget)obj;
if (BaseHouse.FindHouseAt(target.Location, map, 0) != null)
return false;
var itemID = target.ItemID;
for (var i = 0; i < m_UndeepWaterTiles.Length; i += 2)
if (itemID >= m_UndeepWaterTiles[i] && itemID <= m_UndeepWaterTiles[i + 1])
{
z = target.Z;
return true;
}
return false;
}
}
}
public class FabledFishingNet : SpecialFishingNet
{
[Constructible]
public FabledFishingNet() => Hue = 0x481;
public FabledFishingNet(Serial serial) : base(serial)
public class FabledFishingNet : SpecialFishingNet
{
[Constructible]
public FabledFishingNet() => Hue = 0x481;
public FabledFishingNet(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1063451; // a fabled fishing net
protected override void AddNetProperties(ObjectPropertyList list)
{
}
protected override int GetSpawnCount() => base.GetSpawnCount() + 4;
protected override void FinishEffect(Point3D p, Map map, Mobile from)
{
Spawn(p, map, new Leviathan(from));
base.FinishEffect(p, map, from);
}
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 int LabelNumber => 1063451; // a fabled fishing net
protected override void AddNetProperties(ObjectPropertyList list)
{
}
protected override int GetSpawnCount() => base.GetSpawnCount() + 4;
protected override void FinishEffect(Point3D p, Map map, Mobile from)
{
Spawn(p, map, new Leviathan(from));
base.FinishEffect(p, map, from);
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -8,245 +8,248 @@ using Server.Network;
namespace Server.Items
{
public interface IUsesRemaining
{
int UsesRemaining { get; set; }
bool ShowUsesRemaining { get; set; }
}
public abstract class BaseHarvestTool : Item, IUsesRemaining, ICraftable
{
private Mobile m_Crafter;
private ToolQuality m_Quality;
private int m_UsesRemaining;
public BaseHarvestTool(int itemID, int usesRemaining = 50) : base(itemID)
public interface IUsesRemaining
{
m_UsesRemaining = usesRemaining;
m_Quality = ToolQuality.Regular;
int UsesRemaining { get; set; }
bool ShowUsesRemaining { get; set; }
}
public BaseHarvestTool(Serial serial) : base(serial)
public abstract class BaseHarvestTool : Item, IUsesRemaining, ICraftable
{
}
private Mobile m_Crafter;
private ToolQuality m_Quality;
private int m_UsesRemaining;
[CommandProperty(AccessLevel.GameMaster)]
public Mobile Crafter
{
get => m_Crafter;
set
{
m_Crafter = value;
InvalidateProperties();
}
}
[CommandProperty(AccessLevel.GameMaster)]
public ToolQuality Quality
{
get => m_Quality;
set
{
UnscaleUses();
m_Quality = value;
InvalidateProperties();
ScaleUses();
}
}
public abstract HarvestSystem HarvestSystem { get; }
public int OnCraft(int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool,
CraftItem craftItem, int resHue)
{
Quality = (ToolQuality)quality;
if (makersMark)
Crafter = from;
return quality;
}
[CommandProperty(AccessLevel.GameMaster)]
public int UsesRemaining
{
get => m_UsesRemaining;
set
{
m_UsesRemaining = value;
InvalidateProperties();
}
}
bool IUsesRemaining.ShowUsesRemaining
{
get => true;
set { }
}
public void ScaleUses()
{
m_UsesRemaining = m_UsesRemaining * GetUsesScalar() / 100;
InvalidateProperties();
}
public void UnscaleUses()
{
m_UsesRemaining = m_UsesRemaining * 100 / GetUsesScalar();
}
public int GetUsesScalar()
{
if (m_Quality == ToolQuality.Exceptional)
return 200;
return 100;
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
// Makers mark not displayed on OSI
// if (m_Crafter != null)
// list.Add( 1050043, m_Crafter.Name ); // crafted by ~1_NAME~
if (m_Quality == ToolQuality.Exceptional)
list.Add(1060636); // exceptional
list.Add(1060584, m_UsesRemaining.ToString()); // uses remaining: ~1_val~
}
public virtual void DisplayDurabilityTo(Mobile m)
{
LabelToAffix(m, 1017323, AffixType.Append, $": {m_UsesRemaining}"); // Durability
}
public override void OnSingleClick(Mobile from)
{
DisplayDurabilityTo(from);
base.OnSingleClick(from);
}
public override void OnDoubleClick(Mobile from)
{
if (IsChildOf(from.Backpack) || Parent == from)
HarvestSystem.BeginHarvesting(from, this);
else
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
AddContextMenuEntries(from, this, list, HarvestSystem);
}
public static void AddContextMenuEntries(Mobile from, Item item, List<ContextMenuEntry> list, HarvestSystem system)
{
if (system != Mining.System)
return;
if (!item.IsChildOf(from.Backpack) && item.Parent != from)
return;
if (!(from is PlayerMobile pm))
return;
ContextMenuEntry miningEntry = new ContextMenuEntry(pm.ToggleMiningStone ? 6179 : 6178);
miningEntry.Color = 0x421F;
list.Add(miningEntry);
list.Add(new ToggleMiningStoneEntry(pm, false, 6176));
list.Add(new ToggleMiningStoneEntry(pm, true, 6177));
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
writer.Write(m_Crafter);
writer.Write((int)m_Quality);
writer.Write(m_UsesRemaining);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch (version)
{
case 1:
{
m_Crafter = reader.ReadMobile();
m_Quality = (ToolQuality)reader.ReadInt();
goto case 0;
}
case 0:
{
m_UsesRemaining = reader.ReadInt();
break;
}
}
}
private class ToggleMiningStoneEntry : ContextMenuEntry
{
private readonly PlayerMobile m_Mobile;
private readonly bool m_Value;
public ToggleMiningStoneEntry(PlayerMobile mobile, bool value, int number) : base(number)
{
m_Mobile = mobile;
m_Value = value;
bool stoneMining = mobile.StoneMining && mobile.Skills.Mining.Base >= 100.0;
if (mobile.ToggleMiningStone == value || (value && !stoneMining))
Flags |= CMEFlags.Disabled;
}
public override void OnClick()
{
bool oldValue = m_Mobile.ToggleMiningStone;
if (m_Value)
public BaseHarvestTool(int itemID, int usesRemaining = 50) : base(itemID)
{
if (oldValue)
{
m_Mobile.SendLocalizedMessage(1054023); // You are already set to mine both ore and stone!
}
else if (!m_Mobile.StoneMining || m_Mobile.Skills.Mining.Base < 100.0)
{
m_Mobile.SendLocalizedMessage(
1054024); // You have not learned how to mine stone or you do not have enough skill!
}
else
{
m_Mobile.ToggleMiningStone = true;
m_Mobile.SendLocalizedMessage(1054022); // You are now set to mine both ore and stone.
}
m_UsesRemaining = usesRemaining;
m_Quality = ToolQuality.Regular;
}
else
public BaseHarvestTool(Serial serial) : base(serial)
{
if (oldValue)
{
m_Mobile.ToggleMiningStone = false;
m_Mobile.SendLocalizedMessage(1054020); // You are now set to mine only ore.
}
else
{
m_Mobile.SendLocalizedMessage(1054021); // You are already set to mine only ore!
}
}
}
[CommandProperty(AccessLevel.GameMaster)]
public Mobile Crafter
{
get => m_Crafter;
set
{
m_Crafter = value;
InvalidateProperties();
}
}
[CommandProperty(AccessLevel.GameMaster)]
public ToolQuality Quality
{
get => m_Quality;
set
{
UnscaleUses();
m_Quality = value;
InvalidateProperties();
ScaleUses();
}
}
public abstract HarvestSystem HarvestSystem { get; }
public int OnCraft(
int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool,
CraftItem craftItem, int resHue
)
{
Quality = (ToolQuality)quality;
if (makersMark)
Crafter = from;
return quality;
}
[CommandProperty(AccessLevel.GameMaster)]
public int UsesRemaining
{
get => m_UsesRemaining;
set
{
m_UsesRemaining = value;
InvalidateProperties();
}
}
bool IUsesRemaining.ShowUsesRemaining
{
get => true;
set { }
}
public void ScaleUses()
{
m_UsesRemaining = m_UsesRemaining * GetUsesScalar() / 100;
InvalidateProperties();
}
public void UnscaleUses()
{
m_UsesRemaining = m_UsesRemaining * 100 / GetUsesScalar();
}
public int GetUsesScalar()
{
if (m_Quality == ToolQuality.Exceptional)
return 200;
return 100;
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
// Makers mark not displayed on OSI
// if (m_Crafter != null)
// list.Add( 1050043, m_Crafter.Name ); // crafted by ~1_NAME~
if (m_Quality == ToolQuality.Exceptional)
list.Add(1060636); // exceptional
list.Add(1060584, m_UsesRemaining.ToString()); // uses remaining: ~1_val~
}
public virtual void DisplayDurabilityTo(Mobile m)
{
LabelToAffix(m, 1017323, AffixType.Append, $": {m_UsesRemaining}"); // Durability
}
public override void OnSingleClick(Mobile from)
{
DisplayDurabilityTo(from);
base.OnSingleClick(from);
}
public override void OnDoubleClick(Mobile from)
{
if (IsChildOf(from.Backpack) || Parent == from)
HarvestSystem.BeginHarvesting(from, this);
else
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
AddContextMenuEntries(from, this, list, HarvestSystem);
}
public static void AddContextMenuEntries(Mobile from, Item item, List<ContextMenuEntry> list, HarvestSystem system)
{
if (system != Mining.System)
return;
if (!item.IsChildOf(from.Backpack) && item.Parent != from)
return;
if (!(from is PlayerMobile pm))
return;
var miningEntry = new ContextMenuEntry(pm.ToggleMiningStone ? 6179 : 6178);
miningEntry.Color = 0x421F;
list.Add(miningEntry);
list.Add(new ToggleMiningStoneEntry(pm, false, 6176));
list.Add(new ToggleMiningStoneEntry(pm, true, 6177));
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
writer.Write(m_Crafter);
writer.Write((int)m_Quality);
writer.Write(m_UsesRemaining);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
switch (version)
{
case 1:
{
m_Crafter = reader.ReadMobile();
m_Quality = (ToolQuality)reader.ReadInt();
goto case 0;
}
case 0:
{
m_UsesRemaining = reader.ReadInt();
break;
}
}
}
private class ToggleMiningStoneEntry : ContextMenuEntry
{
private readonly PlayerMobile m_Mobile;
private readonly bool m_Value;
public ToggleMiningStoneEntry(PlayerMobile mobile, bool value, int number) : base(number)
{
m_Mobile = mobile;
m_Value = value;
var stoneMining = mobile.StoneMining && mobile.Skills.Mining.Base >= 100.0;
if (mobile.ToggleMiningStone == value || value && !stoneMining)
Flags |= CMEFlags.Disabled;
}
public override void OnClick()
{
var oldValue = m_Mobile.ToggleMiningStone;
if (m_Value)
{
if (oldValue)
{
m_Mobile.SendLocalizedMessage(1054023); // You are already set to mine both ore and stone!
}
else if (!m_Mobile.StoneMining || m_Mobile.Skills.Mining.Base < 100.0)
{
m_Mobile.SendLocalizedMessage(
1054024
); // You have not learned how to mine stone or you do not have enough skill!
}
else
{
m_Mobile.ToggleMiningStone = true;
m_Mobile.SendLocalizedMessage(1054022); // You are now set to mine both ore and stone.
}
}
else
{
if (oldValue)
{
m_Mobile.ToggleMiningStone = false;
m_Mobile.SendLocalizedMessage(1054020); // You are now set to mine only ore.
}
else
{
m_Mobile.SendLocalizedMessage(1054021); // You are already set to mine only ore!
}
}
}
}
}
}
}

View file

@ -2,62 +2,62 @@ using Server.Engines.Harvest;
namespace Server.Items
{
public class GargoylesPickaxe : BaseAxe, IUsesRemaining
{
[Constructible]
public GargoylesPickaxe() : this(Utility.RandomMinMax(101, 125))
public class GargoylesPickaxe : BaseAxe, IUsesRemaining
{
[Constructible]
public GargoylesPickaxe() : this(Utility.RandomMinMax(101, 125))
{
}
[Constructible]
public GargoylesPickaxe(int uses) : base(0xE85 + Utility.Random(2))
{
Weight = 11.0;
UsesRemaining = uses;
ShowUsesRemaining = true;
}
public GargoylesPickaxe(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1041281; // a gargoyle's pickaxe
public override HarvestSystem HarvestSystem => Mining.System;
public override WeaponAbility PrimaryAbility => WeaponAbility.DoubleStrike;
public override WeaponAbility SecondaryAbility => WeaponAbility.Disarm;
public override int AosStrengthReq => 50;
public override int AosMinDamage => 13;
public override int AosMaxDamage => 15;
public override int AosSpeed => 35;
public override float MlSpeed => 3.00f;
public override int OldStrengthReq => 25;
public override int OldMinDamage => 1;
public override int OldMaxDamage => 15;
public override int OldSpeed => 35;
public override int InitMinHits => 31;
public override int InitMaxHits => 60;
public override WeaponAnimation DefAnimation => WeaponAnimation.Slash1H;
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();
if (Hue == 0x973)
Hue = 0x0;
}
}
[Constructible]
public GargoylesPickaxe(int uses) : base(0xE85 + Utility.Random(2))
{
Weight = 11.0;
UsesRemaining = uses;
ShowUsesRemaining = true;
}
public GargoylesPickaxe(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1041281; // a gargoyle's pickaxe
public override HarvestSystem HarvestSystem => Mining.System;
public override WeaponAbility PrimaryAbility => WeaponAbility.DoubleStrike;
public override WeaponAbility SecondaryAbility => WeaponAbility.Disarm;
public override int AosStrengthReq => 50;
public override int AosMinDamage => 13;
public override int AosMaxDamage => 15;
public override int AosSpeed => 35;
public override float MlSpeed => 3.00f;
public override int OldStrengthReq => 25;
public override int OldMinDamage => 1;
public override int OldMaxDamage => 15;
public override int OldSpeed => 35;
public override int InitMinHits => 31;
public override int InitMaxHits => 60;
public override WeaponAnimation DefAnimation => WeaponAnimation.Slash1H;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
if (Hue == 0x973)
Hue = 0x0;
}
}
}
}

View file

@ -4,171 +4,171 @@ using Server.Targeting;
namespace Server.Items
{
public class ProspectorsTool : BaseBashing, IUsesRemaining
{
private int m_UsesRemaining;
[Constructible]
public ProspectorsTool() : base(0xFB4)
public class ProspectorsTool : BaseBashing, IUsesRemaining
{
Weight = 9.0;
UsesRemaining = 50;
}
private int m_UsesRemaining;
public ProspectorsTool(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1049065; // prospector's tool
public override WeaponAbility PrimaryAbility => WeaponAbility.CrushingBlow;
public override WeaponAbility SecondaryAbility => WeaponAbility.ShadowStrike;
public override int AosStrengthReq => 40;
public override int AosMinDamage => 13;
public override int AosMaxDamage => 15;
public override int AosSpeed => 33;
public override int OldStrengthReq => 10;
public override int OldMinDamage => 6;
public override int OldMaxDamage => 8;
public override int OldSpeed => 33;
[CommandProperty(AccessLevel.GameMaster)]
public int UsesRemaining
{
get => m_UsesRemaining;
set
{
m_UsesRemaining = value;
InvalidateProperties();
}
}
bool IUsesRemaining.ShowUsesRemaining
{
get => true;
set { }
}
public override void OnDoubleClick(Mobile from)
{
if (IsChildOf(from.Backpack) || Parent == from)
from.Target = new InternalTarget(this);
else
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
}
public void Prospect(Mobile from, object toProspect)
{
if (!IsChildOf(from.Backpack) && Parent != from)
{
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
return;
}
HarvestSystem system = Mining.System;
if (!system.GetHarvestDetails(from, this, toProspect, out int tileID, out Map map, out Point3D loc))
{
from.SendLocalizedMessage(1049048); // You cannot use your prospector tool on that.
return;
}
HarvestDefinition def = system.GetDefinition(tileID);
if (def == null || def.Veins.Length <= 1)
{
from.SendLocalizedMessage(1049048); // You cannot use your prospector tool on that.
return;
}
HarvestBank bank = def.GetBank(map, loc.X, loc.Y);
if (bank == null)
{
from.SendLocalizedMessage(1049048); // You cannot use your prospector tool on that.
return;
}
HarvestVein vein = bank.Vein, defaultVein = bank.DefaultVein;
if (vein == null || defaultVein == null)
{
from.SendLocalizedMessage(1049048); // You cannot use your prospector tool on that.
return;
}
if (vein != defaultVein)
{
from.SendLocalizedMessage(1049049); // That ore looks to be prospected already.
return;
}
int veinIndex = Array.IndexOf(def.Veins, vein);
if (veinIndex < 0)
{
from.SendLocalizedMessage(1049048); // You cannot use your prospector tool on that.
}
else if (veinIndex >= def.Veins.Length - 1)
{
from.SendLocalizedMessage(1049061); // You cannot improve valorite ore through prospecting.
}
else
{
bank.Vein = def.Veins[veinIndex + 1];
from.SendLocalizedMessage(1049050 + veinIndex);
--UsesRemaining;
if (UsesRemaining <= 0)
[Constructible]
public ProspectorsTool() : base(0xFB4)
{
from.SendLocalizedMessage(1049062); // You have used up your prospector's tool.
Delete();
Weight = 9.0;
UsesRemaining = 50;
}
public ProspectorsTool(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1049065; // prospector's tool
public override WeaponAbility PrimaryAbility => WeaponAbility.CrushingBlow;
public override WeaponAbility SecondaryAbility => WeaponAbility.ShadowStrike;
public override int AosStrengthReq => 40;
public override int AosMinDamage => 13;
public override int AosMaxDamage => 15;
public override int AosSpeed => 33;
public override int OldStrengthReq => 10;
public override int OldMinDamage => 6;
public override int OldMaxDamage => 8;
public override int OldSpeed => 33;
[CommandProperty(AccessLevel.GameMaster)]
public int UsesRemaining
{
get => m_UsesRemaining;
set
{
m_UsesRemaining = value;
InvalidateProperties();
}
}
bool IUsesRemaining.ShowUsesRemaining
{
get => true;
set { }
}
public override void OnDoubleClick(Mobile from)
{
if (IsChildOf(from.Backpack) || Parent == from)
from.Target = new InternalTarget(this);
else
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
}
public void Prospect(Mobile from, object toProspect)
{
if (!IsChildOf(from.Backpack) && Parent != from)
{
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
return;
}
HarvestSystem system = Mining.System;
if (!system.GetHarvestDetails(from, this, toProspect, out var tileID, out var map, out var loc))
{
from.SendLocalizedMessage(1049048); // You cannot use your prospector tool on that.
return;
}
var def = system.GetDefinition(tileID);
if (def == null || def.Veins.Length <= 1)
{
from.SendLocalizedMessage(1049048); // You cannot use your prospector tool on that.
return;
}
var bank = def.GetBank(map, loc.X, loc.Y);
if (bank == null)
{
from.SendLocalizedMessage(1049048); // You cannot use your prospector tool on that.
return;
}
HarvestVein vein = bank.Vein, defaultVein = bank.DefaultVein;
if (vein == null || defaultVein == null)
{
from.SendLocalizedMessage(1049048); // You cannot use your prospector tool on that.
return;
}
if (vein != defaultVein)
{
from.SendLocalizedMessage(1049049); // That ore looks to be prospected already.
return;
}
var veinIndex = Array.IndexOf(def.Veins, vein);
if (veinIndex < 0)
{
from.SendLocalizedMessage(1049048); // You cannot use your prospector tool on that.
}
else if (veinIndex >= def.Veins.Length - 1)
{
from.SendLocalizedMessage(1049061); // You cannot improve valorite ore through prospecting.
}
else
{
bank.Vein = def.Veins[veinIndex + 1];
from.SendLocalizedMessage(1049050 + veinIndex);
--UsesRemaining;
if (UsesRemaining <= 0)
{
from.SendLocalizedMessage(1049062); // You have used up your prospector's tool.
Delete();
}
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
writer.Write(m_UsesRemaining);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
switch (version)
{
case 1:
{
m_UsesRemaining = reader.ReadInt();
break;
}
case 0:
{
m_UsesRemaining = 50;
break;
}
}
}
private class InternalTarget : Target
{
private readonly ProspectorsTool m_Tool;
public InternalTarget(ProspectorsTool tool) : base(2, true, TargetFlags.None) => m_Tool = tool;
protected override void OnTarget(Mobile from, object targeted)
{
m_Tool.Prospect(from, targeted);
}
}
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
writer.Write(m_UsesRemaining);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch (version)
{
case 1:
{
m_UsesRemaining = reader.ReadInt();
break;
}
case 0:
{
m_UsesRemaining = 50;
break;
}
}
}
private class InternalTarget : Target
{
private readonly ProspectorsTool m_Tool;
public InternalTarget(ProspectorsTool tool) : base(2, true, TargetFlags.None) => m_Tool = tool;
protected override void OnTarget(Mobile from, object targeted)
{
m_Tool.Prospect(from, targeted);
}
}
}
}
}

View file

@ -2,29 +2,29 @@ using Server.Engines.Harvest;
namespace Server.Items
{
public class Shovel : BaseHarvestTool
{
[Constructible]
public Shovel(int uses = 50) : base(0xF39, uses) => Weight = 5.0;
public Shovel(Serial serial) : base(serial)
public class Shovel : BaseHarvestTool
{
[Constructible]
public Shovel(int uses = 50) : base(0xF39, uses) => Weight = 5.0;
public Shovel(Serial serial) : base(serial)
{
}
public override HarvestSystem HarvestSystem => Mining.System;
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 HarvestSystem HarvestSystem => Mining.System;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -2,52 +2,52 @@ using Server.Engines.Harvest;
namespace Server.Items
{
public class SturdyPickaxe : BaseAxe, IUsesRemaining
{
[Constructible]
public SturdyPickaxe(int uses = 180) : base(0xE86)
public class SturdyPickaxe : BaseAxe, IUsesRemaining
{
Weight = 11.0;
Hue = 0x973;
UsesRemaining = uses;
ShowUsesRemaining = true;
[Constructible]
public SturdyPickaxe(int uses = 180) : base(0xE86)
{
Weight = 11.0;
Hue = 0x973;
UsesRemaining = uses;
ShowUsesRemaining = true;
}
public SturdyPickaxe(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1045126; // sturdy pickaxe
public override HarvestSystem HarvestSystem => Mining.System;
public override WeaponAbility PrimaryAbility => WeaponAbility.DoubleStrike;
public override WeaponAbility SecondaryAbility => WeaponAbility.Disarm;
public override int AosStrengthReq => 50;
public override int AosMinDamage => 13;
public override int AosMaxDamage => 15;
public override int AosSpeed => 35;
public override float MlSpeed => 3.00f;
public override int OldStrengthReq => 25;
public override int OldMinDamage => 1;
public override int OldMaxDamage => 15;
public override int OldSpeed => 35;
public override WeaponAnimation DefAnimation => WeaponAnimation.Slash1H;
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 SturdyPickaxe(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1045126; // sturdy pickaxe
public override HarvestSystem HarvestSystem => Mining.System;
public override WeaponAbility PrimaryAbility => WeaponAbility.DoubleStrike;
public override WeaponAbility SecondaryAbility => WeaponAbility.Disarm;
public override int AosStrengthReq => 50;
public override int AosMinDamage => 13;
public override int AosMaxDamage => 15;
public override int AosSpeed => 35;
public override float MlSpeed => 3.00f;
public override int OldStrengthReq => 25;
public override int OldMinDamage => 1;
public override int OldMaxDamage => 15;
public override int OldSpeed => 35;
public override WeaponAnimation DefAnimation => WeaponAnimation.Slash1H;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -2,34 +2,34 @@ using Server.Engines.Harvest;
namespace Server.Items
{
public class SturdyShovel : BaseHarvestTool
{
[Constructible]
public SturdyShovel(int uses = 180) : base(0xF39, uses)
public class SturdyShovel : BaseHarvestTool
{
Weight = 5.0;
Hue = 0x973;
[Constructible]
public SturdyShovel(int uses = 180) : base(0xF39, uses)
{
Weight = 5.0;
Hue = 0x973;
}
public SturdyShovel(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1045125; // sturdy shovel
public override HarvestSystem HarvestSystem => Mining.System;
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 SturdyShovel(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1045125; // sturdy shovel
public override HarvestSystem HarvestSystem => Mining.System;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,334 +1,334 @@
namespace Server.Items
{
[Flippable(0x1bdd, 0x1be0)]
public class Log : Item, ICommodity, IAxe
{
private CraftResource m_Resource;
[Constructible]
public Log(int amount = 1) : this(CraftResource.RegularWood, amount)
[Flippable(0x1bdd, 0x1be0)]
public class Log : Item, ICommodity, IAxe
{
private CraftResource m_Resource;
[Constructible]
public Log(int amount = 1) : this(CraftResource.RegularWood, amount)
{
}
[Constructible]
public Log(CraftResource resource)
: this(resource, 1)
{
}
[Constructible]
public Log(CraftResource resource, int amount)
: base(0x1BDD)
{
Stackable = true;
Weight = 2.0;
Amount = amount;
m_Resource = resource;
Hue = CraftResources.GetHue(resource);
}
public Log(Serial serial) : base(serial)
{
}
[CommandProperty(AccessLevel.GameMaster)]
public CraftResource Resource
{
get => m_Resource;
set
{
m_Resource = value;
InvalidateProperties();
}
}
public virtual bool Axe(Mobile from, BaseAxe axe)
{
if (!TryCreateBoards(from, 0, new Board()))
return false;
return true;
}
int ICommodity.DescriptionNumber => CraftResources.IsStandard(m_Resource)
? LabelNumber
: 1075062 + ((int)m_Resource - (int)CraftResource.RegularWood);
bool ICommodity.IsDeedable => true;
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
if (!CraftResources.IsStandard(m_Resource))
{
var num = CraftResources.GetLocalizationNumber(m_Resource);
if (num > 0)
list.Add(num);
else
list.Add(CraftResources.GetName(m_Resource));
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
writer.Write((int)m_Resource);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
switch (version)
{
case 1:
{
m_Resource = (CraftResource)reader.ReadInt();
break;
}
}
if (version == 0)
m_Resource = CraftResource.RegularWood;
}
public virtual bool TryCreateBoards(Mobile from, double skill, Item item)
{
if (Deleted || !from.CanSee(this))
return false;
if (from.Skills.Carpentry.Value < skill &&
from.Skills.Lumberjacking.Value < skill)
{
item.Delete();
from.SendLocalizedMessage(1072652); // You cannot work this strange and unusual wood.
return false;
}
ScissorHelper(from, item, 1, false);
return true;
}
}
[Constructible]
public Log(CraftResource resource)
: this(resource, 1)
public class HeartwoodLog : Log
{
[Constructible]
public HeartwoodLog(int amount = 1)
: base(CraftResource.Heartwood, amount)
{
}
public HeartwoodLog(Serial serial) : base(serial)
{
}
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 Axe(Mobile from, BaseAxe axe)
{
if (!TryCreateBoards(from, 100, new HeartwoodBoard()))
return false;
return true;
}
}
[Constructible]
public Log(CraftResource resource, int amount)
: base(0x1BDD)
public class BloodwoodLog : Log
{
Stackable = true;
Weight = 2.0;
Amount = amount;
[Constructible]
public BloodwoodLog(int amount = 1)
: base(CraftResource.Bloodwood, amount)
{
}
m_Resource = resource;
Hue = CraftResources.GetHue(resource);
public BloodwoodLog(Serial serial)
: base(serial)
{
}
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 Axe(Mobile from, BaseAxe axe)
{
if (!TryCreateBoards(from, 100, new BloodwoodBoard()))
return false;
return true;
}
}
public Log(Serial serial) : base(serial)
public class FrostwoodLog : Log
{
[Constructible]
public FrostwoodLog(int amount = 1)
: base(CraftResource.Frostwood, amount)
{
}
public FrostwoodLog(Serial serial)
: base(serial)
{
}
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 Axe(Mobile from, BaseAxe axe)
{
if (!TryCreateBoards(from, 100, new FrostwoodBoard()))
return false;
return true;
}
}
[CommandProperty(AccessLevel.GameMaster)]
public CraftResource Resource
public class OakLog : Log
{
get => m_Resource;
set
{
m_Resource = value;
InvalidateProperties();
}
[Constructible]
public OakLog(int amount = 1)
: base(CraftResource.OakWood, amount)
{
}
public OakLog(Serial serial)
: base(serial)
{
}
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 Axe(Mobile from, BaseAxe axe)
{
if (!TryCreateBoards(from, 65, new OakBoard()))
return false;
return true;
}
}
public virtual bool Axe(Mobile from, BaseAxe axe)
public class AshLog : Log
{
if (!TryCreateBoards(from, 0, new Board()))
return false;
[Constructible]
public AshLog(int amount = 1)
: base(CraftResource.AshWood, amount)
{
}
return true;
public AshLog(Serial serial)
: base(serial)
{
}
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 Axe(Mobile from, BaseAxe axe)
{
if (!TryCreateBoards(from, 80, new AshBoard()))
return false;
return true;
}
}
int ICommodity.DescriptionNumber => CraftResources.IsStandard(m_Resource)
? LabelNumber
: 1075062 + ((int)m_Resource - (int)CraftResource.RegularWood);
bool ICommodity.IsDeedable => true;
public override void GetProperties(ObjectPropertyList list)
public class YewLog : Log
{
base.GetProperties(list);
[Constructible]
public YewLog(int amount = 1)
: base(CraftResource.YewWood, amount)
{
}
if (!CraftResources.IsStandard(m_Resource))
{
int num = CraftResources.GetLocalizationNumber(m_Resource);
public YewLog(Serial serial)
: base(serial)
{
}
if (num > 0)
list.Add(num);
else
list.Add(CraftResources.GetName(m_Resource));
}
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 Axe(Mobile from, BaseAxe axe)
{
if (!TryCreateBoards(from, 95, new YewBoard()))
return false;
return true;
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
writer.Write((int)m_Resource);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch (version)
{
case 1:
{
m_Resource = (CraftResource)reader.ReadInt();
break;
}
}
if (version == 0)
m_Resource = CraftResource.RegularWood;
}
public virtual bool TryCreateBoards(Mobile from, double skill, Item item)
{
if (Deleted || !from.CanSee(this))
return false;
if (from.Skills.Carpentry.Value < skill &&
from.Skills.Lumberjacking.Value < skill)
{
item.Delete();
from.SendLocalizedMessage(1072652); // You cannot work this strange and unusual wood.
return false;
}
ScissorHelper(from, item, 1, false);
return true;
}
}
public class HeartwoodLog : Log
{
[Constructible]
public HeartwoodLog(int amount = 1)
: base(CraftResource.Heartwood, amount)
{
}
public HeartwoodLog(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
public override bool Axe(Mobile from, BaseAxe axe)
{
if (!TryCreateBoards(from, 100, new HeartwoodBoard()))
return false;
return true;
}
}
public class BloodwoodLog : Log
{
[Constructible]
public BloodwoodLog(int amount = 1)
: base(CraftResource.Bloodwood, amount)
{
}
public BloodwoodLog(Serial serial)
: base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
public override bool Axe(Mobile from, BaseAxe axe)
{
if (!TryCreateBoards(from, 100, new BloodwoodBoard()))
return false;
return true;
}
}
public class FrostwoodLog : Log
{
[Constructible]
public FrostwoodLog(int amount = 1)
: base(CraftResource.Frostwood, amount)
{
}
public FrostwoodLog(Serial serial)
: base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
public override bool Axe(Mobile from, BaseAxe axe)
{
if (!TryCreateBoards(from, 100, new FrostwoodBoard()))
return false;
return true;
}
}
public class OakLog : Log
{
[Constructible]
public OakLog(int amount = 1)
: base(CraftResource.OakWood, amount)
{
}
public OakLog(Serial serial)
: base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
public override bool Axe(Mobile from, BaseAxe axe)
{
if (!TryCreateBoards(from, 65, new OakBoard()))
return false;
return true;
}
}
public class AshLog : Log
{
[Constructible]
public AshLog(int amount = 1)
: base(CraftResource.AshWood, amount)
{
}
public AshLog(Serial serial)
: base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
public override bool Axe(Mobile from, BaseAxe axe)
{
if (!TryCreateBoards(from, 80, new AshBoard()))
return false;
return true;
}
}
public class YewLog : Log
{
[Constructible]
public YewLog(int amount = 1)
: base(CraftResource.YewWood, amount)
{
}
public YewLog(Serial serial)
: base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
public override bool Axe(Mobile from, BaseAxe axe)
{
if (!TryCreateBoards(from, 95, new YewBoard()))
return false;
return true;
}
}
}

View file

@ -1,33 +1,34 @@
namespace Server.Items
{
public class BookOfBushido : Spellbook
{
[Constructible]
public BookOfBushido(ulong content = 0x3F) : base(content, 0x238C) => Layer = Core.ML ? Layer.OneHanded : Layer.Invalid;
public BookOfBushido(Serial serial) : base(serial)
public class BookOfBushido : Spellbook
{
[Constructible]
public BookOfBushido(ulong content = 0x3F) : base(content, 0x238C) =>
Layer = Core.ML ? Layer.OneHanded : Layer.Invalid;
public BookOfBushido(Serial serial) : base(serial)
{
}
public override SpellbookType SpellbookType => SpellbookType.Samurai;
public override int BookOffset => 400;
public override int BookCount => 6;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
if (version == 0 && Core.ML)
Layer = Layer.OneHanded;
}
}
public override SpellbookType SpellbookType => SpellbookType.Samurai;
public override int BookOffset => 400;
public override int BookCount => 6;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
if (version == 0 && Core.ML)
Layer = Layer.OneHanded;
}
}
}

View file

@ -1,33 +1,34 @@
namespace Server.Items
{
public class BookOfChivalry : Spellbook
{
[Constructible]
public BookOfChivalry(ulong content = 0x3FF) : base(content, 0x2252) => Layer = Core.ML ? Layer.OneHanded : Layer.Invalid;
public BookOfChivalry(Serial serial) : base(serial)
public class BookOfChivalry : Spellbook
{
[Constructible]
public BookOfChivalry(ulong content = 0x3FF) : base(content, 0x2252) =>
Layer = Core.ML ? Layer.OneHanded : Layer.Invalid;
public BookOfChivalry(Serial serial) : base(serial)
{
}
public override SpellbookType SpellbookType => SpellbookType.Paladin;
public override int BookOffset => 200;
public override int BookCount => 10;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
if (version == 0 && Core.ML)
Layer = Layer.OneHanded;
}
}
public override SpellbookType SpellbookType => SpellbookType.Paladin;
public override int BookOffset => 200;
public override int BookCount => 10;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
if (version == 0 && Core.ML)
Layer = Layer.OneHanded;
}
}
}

View file

@ -1,33 +1,34 @@
namespace Server.Items
{
public class BookOfNinjitsu : Spellbook
{
[Constructible]
public BookOfNinjitsu(ulong content = 0xFF) : base(content, 0x23A0) => Layer = Core.ML ? Layer.OneHanded : Layer.Invalid;
public BookOfNinjitsu(Serial serial) : base(serial)
public class BookOfNinjitsu : Spellbook
{
[Constructible]
public BookOfNinjitsu(ulong content = 0xFF) : base(content, 0x23A0) =>
Layer = Core.ML ? Layer.OneHanded : Layer.Invalid;
public BookOfNinjitsu(Serial serial) : base(serial)
{
}
public override SpellbookType SpellbookType => SpellbookType.Ninja;
public override int BookOffset => 500;
public override int BookCount => 8;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
if (version == 0 && Core.ML)
Layer = Layer.OneHanded;
}
}
public override SpellbookType SpellbookType => SpellbookType.Ninja;
public override int BookOffset => 500;
public override int BookCount => 8;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
if (version == 0 && Core.ML)
Layer = Layer.OneHanded;
}
}
}

View file

@ -1,34 +1,34 @@
namespace Server.Items
{
public class BlankScroll : Item, ICommodity
{
[Constructible]
public BlankScroll(int amount = 1) : base(0xEF3)
public class BlankScroll : Item, ICommodity
{
Stackable = true;
Weight = 1.0;
Amount = amount;
[Constructible]
public BlankScroll(int amount = 1) : base(0xEF3)
{
Stackable = true;
Weight = 1.0;
Amount = amount;
}
public BlankScroll(Serial serial) : base(serial)
{
}
int ICommodity.DescriptionNumber => LabelNumber;
bool ICommodity.IsDeedable => Core.ML;
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 BlankScroll(Serial serial) : base(serial)
{
}
int ICommodity.DescriptionNumber => LabelNumber;
bool ICommodity.IsDeedable => Core.ML;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,34 +1,34 @@
namespace Server.Items
{
public class Bottle : Item, ICommodity
{
[Constructible]
public Bottle(int amount = 1) : base(0xF0E)
public class Bottle : Item, ICommodity
{
Stackable = true;
Weight = 1.0;
Amount = amount;
[Constructible]
public Bottle(int amount = 1) : base(0xF0E)
{
Stackable = true;
Weight = 1.0;
Amount = amount;
}
public Bottle(Serial serial) : base(serial)
{
}
int ICommodity.DescriptionNumber => LabelNumber;
bool ICommodity.IsDeedable => Core.ML;
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 Bottle(Serial serial) : base(serial)
{
}
int ICommodity.DescriptionNumber => LabelNumber;
bool ICommodity.IsDeedable => Core.ML;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -8,377 +8,407 @@ using Server.Regions;
namespace Server.Items
{
[DispellableField]
public class Moongate : Item
{
[Constructible]
public Moongate(bool dispellable = true) : this(Point3D.Zero, null, dispellable)
[DispellableField]
public class Moongate : Item
{
[Constructible]
public Moongate(bool dispellable = true) : this(Point3D.Zero, null, dispellable)
{
}
[Constructible]
public Moongate(Point3D target, Map targetMap = null, bool dispellable = true) : base(0xF6C)
{
Movable = false;
Light = LightType.Circle300;
Target = target;
TargetMap = targetMap;
Dispellable = dispellable;
}
public Moongate(Serial serial) : base(serial)
{
}
[CommandProperty(AccessLevel.GameMaster)]
public Point3D Target { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public Map TargetMap { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public bool Dispellable { get; set; }
public virtual bool ShowFeluccaWarning => false;
public override void OnDoubleClick(Mobile from)
{
if (!from.Player)
return;
if (from.InRange(GetWorldLocation(), 1))
CheckGate(from, 1);
else
from.SendLocalizedMessage(500446); // That is too far away.
}
public override bool OnMoveOver(Mobile m)
{
if (m.Player)
CheckGate(m, 0);
return true;
}
public virtual void CheckGate(Mobile m, int range)
{
if (m.Hidden && m.AccessLevel == AccessLevel.Player && Core.ML)
m.RevealingAction();
new DelayTimer(m, this, range).Start();
}
public virtual void OnGateUsed(Mobile m)
{
}
public virtual void UseGate(Mobile m)
{
var flags = m.NetState?.Flags ?? ClientFlags.None;
if (Sigil.ExistsOn(m))
{
m.SendLocalizedMessage(1061632); // You can't do that while carrying the sigil.
}
else if (TargetMap == Map.Felucca && m is PlayerMobile mobile && mobile.Young)
{
mobile.SendLocalizedMessage(1049543); // You decide against traveling to Felucca while you are still young.
}
else if (m.Kills >= 5 && TargetMap != Map.Felucca ||
TargetMap == Map.Tokuno && (flags & ClientFlags.Tokuno) == 0 ||
TargetMap == Map.Malas && (flags & ClientFlags.Malas) == 0 ||
TargetMap == Map.Ilshenar && (flags & ClientFlags.Ilshenar) == 0)
{
m.SendLocalizedMessage(1019004); // You are not allowed to travel there.
}
else if (m.Spell != null)
{
m.SendLocalizedMessage(1049616); // You are too busy to do that at the moment.
}
else if (TargetMap != null && TargetMap != Map.Internal)
{
BaseCreature.TeleportPets(m, Target, TargetMap);
m.MoveToWorld(Target, TargetMap);
if (m.AccessLevel == AccessLevel.Player || !m.Hidden)
m.PlaySound(0x1FE);
OnGateUsed(m);
}
else
{
m.SendMessage("This moongate does not seem to go anywhere.");
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
writer.Write(Target);
writer.Write(TargetMap);
// Version 1
writer.Write(Dispellable);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
Target = reader.ReadPoint3D();
TargetMap = reader.ReadMap();
if (version >= 1)
Dispellable = reader.ReadBool();
}
public virtual bool ValidateUse(Mobile from, bool message)
{
if (from.Deleted || Deleted)
return false;
if (from.Map != Map || !from.InRange(this, 1))
{
if (message)
from.SendLocalizedMessage(500446); // That is too far away.
return false;
}
return true;
}
public virtual void BeginConfirmation(Mobile from)
{
if (IsInTown(@from.Location, @from.Map) && !IsInTown(Target, TargetMap) ||
@from.Map != Map.Felucca && TargetMap == Map.Felucca && ShowFeluccaWarning)
{
if (from.AccessLevel == AccessLevel.Player || !from.Hidden)
from.Send(new PlaySound(0x20E, from.Location));
from.CloseGump<MoongateConfirmGump>();
from.SendGump(new MoongateConfirmGump(from, this));
}
else
{
EndConfirmation(from);
}
}
public virtual void EndConfirmation(Mobile from)
{
if (!ValidateUse(from, true))
return;
UseGate(from);
}
public virtual void DelayCallback(Mobile from, int range)
{
if (!ValidateUse(from, false) || !from.InRange(this, range))
return;
if (TargetMap != null)
BeginConfirmation(from);
else
from.SendMessage("This moongate does not seem to go anywhere.");
}
public static bool IsInTown(Point3D p, Map map) =>
map != null && Region.Find(p, map).GetRegion<GuardedRegion>()?.IsDisabled() == false;
private class DelayTimer : Timer
{
private readonly Mobile m_From;
private readonly Moongate m_Gate;
private readonly int m_Range;
public DelayTimer(Mobile from, Moongate gate, int range) : base(TimeSpan.FromSeconds(1.0))
{
m_From = from;
m_Gate = gate;
m_Range = range;
}
protected override void OnTick()
{
m_Gate.DelayCallback(m_From, m_Range);
}
}
}
[Constructible]
public Moongate(Point3D target, Map targetMap = null, bool dispellable = true) : base(0xF6C)
public class ConfirmationMoongate : Moongate
{
Movable = false;
Light = LightType.Circle300;
[Constructible]
public ConfirmationMoongate() : this(Point3D.Zero)
{
}
Target = target;
TargetMap = targetMap;
Dispellable = dispellable;
[Constructible]
public ConfirmationMoongate(Point3D target, Map targetMap = null) : base(target, targetMap)
{
}
public ConfirmationMoongate(Serial serial) : base(serial)
{
}
[CommandProperty(AccessLevel.GameMaster)]
public int GumpWidth { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public int GumpHeight { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public int TitleColor { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public int MessageColor { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public int TitleNumber { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public int MessageNumber { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public string MessageString { get; set; }
public virtual void Warning_Callback(Mobile from, bool okay)
{
if (okay)
EndConfirmation(from);
}
public override void BeginConfirmation(Mobile from)
{
if (GumpWidth > 0 && GumpHeight > 0 && TitleNumber > 0 && (MessageNumber > 0 || MessageString != null))
{
from.CloseGump<WarningGump>();
from.SendGump(
new WarningGump(
TitleNumber,
TitleColor,
MessageString ?? (object)MessageNumber,
MessageColor,
GumpWidth,
GumpHeight,
okay => Warning_Callback(from, okay)
)
);
}
else
{
base.BeginConfirmation(from);
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
writer.WriteEncodedInt(GumpWidth);
writer.WriteEncodedInt(GumpHeight);
writer.WriteEncodedInt(TitleColor);
writer.WriteEncodedInt(MessageColor);
writer.WriteEncodedInt(TitleNumber);
writer.WriteEncodedInt(MessageNumber);
writer.Write(MessageString);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
switch (version)
{
case 0:
{
GumpWidth = reader.ReadEncodedInt();
GumpHeight = reader.ReadEncodedInt();
TitleColor = reader.ReadEncodedInt();
MessageColor = reader.ReadEncodedInt();
TitleNumber = reader.ReadEncodedInt();
MessageNumber = reader.ReadEncodedInt();
MessageString = reader.ReadString();
break;
}
}
}
}
public Moongate(Serial serial) : base(serial)
public class MoongateConfirmGump : Gump
{
private readonly Mobile m_From;
private readonly Moongate m_Gate;
public MoongateConfirmGump(Mobile from, Moongate gate) : base(Core.AOS ? 110 : 20, Core.AOS ? 100 : 30)
{
m_From = from;
m_Gate = gate;
if (Core.AOS)
{
Closable = false;
AddPage(0);
AddBackground(0, 0, 420, 280, 5054);
AddImageTiled(10, 10, 400, 20, 2624);
AddAlphaRegion(10, 10, 400, 20);
AddHtmlLocalized(10, 10, 400, 20, 1062051, 30720); // Gate Warning
AddImageTiled(10, 40, 400, 200, 2624);
AddAlphaRegion(10, 40, 400, 200);
if (from.Map != Map.Felucca && gate.TargetMap == Map.Felucca && gate.ShowFeluccaWarning)
AddHtmlLocalized(
10,
40,
400,
200,
1062050,
32512,
false,
true
); // This Gate goes to Felucca... Continue to enter the gate, Cancel to stay here
else
AddHtmlLocalized(
10,
40,
400,
200,
1062049,
32512,
false,
true
); // Dost thou wish to step into the moongate? Continue to enter the gate, Cancel to stay here
AddImageTiled(10, 250, 400, 20, 2624);
AddAlphaRegion(10, 250, 400, 20);
AddButton(10, 250, 4005, 4007, 1);
AddHtmlLocalized(40, 250, 170, 20, 1011036, 32767); // OKAY
AddButton(210, 250, 4005, 4007, 0);
AddHtmlLocalized(240, 250, 170, 20, 1011012, 32767); // CANCEL
}
else
{
AddPage(0);
AddBackground(0, 0, 420, 400, 5054);
AddBackground(10, 10, 400, 380, 3000);
AddHtml(
20,
40,
380,
60,
@"Dost thou wish to step into the moongate? Continue to enter the gate, Cancel to stay here"
);
AddHtmlLocalized(55, 110, 290, 20, 1011012); // CANCEL
AddButton(20, 110, 4005, 4007, 0);
AddHtmlLocalized(55, 140, 290, 40, 1011011); // CONTINUE
AddButton(20, 140, 4005, 4007, 1);
}
}
public override void OnResponse(NetState state, RelayInfo info)
{
if (info.ButtonID == 1)
m_Gate.EndConfirmation(m_From);
}
}
[CommandProperty(AccessLevel.GameMaster)]
public Point3D Target { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public Map TargetMap { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public bool Dispellable { get; set; }
public virtual bool ShowFeluccaWarning => false;
public override void OnDoubleClick(Mobile from)
{
if (!from.Player)
return;
if (from.InRange(GetWorldLocation(), 1))
CheckGate(from, 1);
else
from.SendLocalizedMessage(500446); // That is too far away.
}
public override bool OnMoveOver(Mobile m)
{
if (m.Player)
CheckGate(m, 0);
return true;
}
public virtual void CheckGate(Mobile m, int range)
{
if (m.Hidden && m.AccessLevel == AccessLevel.Player && Core.ML)
m.RevealingAction();
new DelayTimer(m, this, range).Start();
}
public virtual void OnGateUsed(Mobile m)
{
}
public virtual void UseGate(Mobile m)
{
ClientFlags flags = m.NetState?.Flags ?? ClientFlags.None;
if (Sigil.ExistsOn(m))
{
m.SendLocalizedMessage(1061632); // You can't do that while carrying the sigil.
}
else if (TargetMap == Map.Felucca && m is PlayerMobile mobile && mobile.Young)
{
mobile.SendLocalizedMessage(1049543); // You decide against traveling to Felucca while you are still young.
}
else if ((m.Kills >= 5 && TargetMap != Map.Felucca) ||
(TargetMap == Map.Tokuno && (flags & ClientFlags.Tokuno) == 0) ||
(TargetMap == Map.Malas && (flags & ClientFlags.Malas) == 0) ||
(TargetMap == Map.Ilshenar && (flags & ClientFlags.Ilshenar) == 0))
{
m.SendLocalizedMessage(1019004); // You are not allowed to travel there.
}
else if (m.Spell != null)
{
m.SendLocalizedMessage(1049616); // You are too busy to do that at the moment.
}
else if (TargetMap != null && TargetMap != Map.Internal)
{
BaseCreature.TeleportPets(m, Target, TargetMap);
m.MoveToWorld(Target, TargetMap);
if (m.AccessLevel == AccessLevel.Player || !m.Hidden)
m.PlaySound(0x1FE);
OnGateUsed(m);
}
else
{
m.SendMessage("This moongate does not seem to go anywhere.");
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
writer.Write(Target);
writer.Write(TargetMap);
// Version 1
writer.Write(Dispellable);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
Target = reader.ReadPoint3D();
TargetMap = reader.ReadMap();
if (version >= 1)
Dispellable = reader.ReadBool();
}
public virtual bool ValidateUse(Mobile from, bool message)
{
if (from.Deleted || Deleted)
return false;
if (from.Map != Map || !from.InRange(this, 1))
{
if (message)
from.SendLocalizedMessage(500446); // That is too far away.
return false;
}
return true;
}
public virtual void BeginConfirmation(Mobile from)
{
if ((IsInTown(from.Location, from.Map) && !IsInTown(Target, TargetMap)) ||
(from.Map != Map.Felucca && TargetMap == Map.Felucca && ShowFeluccaWarning))
{
if (from.AccessLevel == AccessLevel.Player || !from.Hidden)
from.Send(new PlaySound(0x20E, from.Location));
from.CloseGump<MoongateConfirmGump>();
from.SendGump(new MoongateConfirmGump(from, this));
}
else
{
EndConfirmation(from);
}
}
public virtual void EndConfirmation(Mobile from)
{
if (!ValidateUse(from, true))
return;
UseGate(from);
}
public virtual void DelayCallback(Mobile from, int range)
{
if (!ValidateUse(from, false) || !from.InRange(this, range))
return;
if (TargetMap != null)
BeginConfirmation(from);
else
from.SendMessage("This moongate does not seem to go anywhere.");
}
public static bool IsInTown(Point3D p, Map map) => map != null && Region.Find(p, map).GetRegion<GuardedRegion>()?.IsDisabled() == false;
private class DelayTimer : Timer
{
private readonly Mobile m_From;
private readonly Moongate m_Gate;
private readonly int m_Range;
public DelayTimer(Mobile from, Moongate gate, int range) : base(TimeSpan.FromSeconds(1.0))
{
m_From = from;
m_Gate = gate;
m_Range = range;
}
protected override void OnTick()
{
m_Gate.DelayCallback(m_From, m_Range);
}
}
}
public class ConfirmationMoongate : Moongate
{
[Constructible]
public ConfirmationMoongate() : this(Point3D.Zero)
{
}
[Constructible]
public ConfirmationMoongate(Point3D target, Map targetMap = null) : base(target, targetMap)
{
}
public ConfirmationMoongate(Serial serial) : base(serial)
{
}
[CommandProperty(AccessLevel.GameMaster)]
public int GumpWidth { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public int GumpHeight { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public int TitleColor { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public int MessageColor { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public int TitleNumber { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public int MessageNumber { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public string MessageString { get; set; }
public virtual void Warning_Callback(Mobile from, bool okay)
{
if (okay)
EndConfirmation(from);
}
public override void BeginConfirmation(Mobile from)
{
if (GumpWidth > 0 && GumpHeight > 0 && TitleNumber > 0 && (MessageNumber > 0 || MessageString != null))
{
from.CloseGump<WarningGump>();
from.SendGump(new WarningGump(TitleNumber, TitleColor,
MessageString ?? (object)MessageNumber, MessageColor, GumpWidth, GumpHeight,
okay => Warning_Callback(from, okay)));
}
else
{
base.BeginConfirmation(from);
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
writer.WriteEncodedInt(GumpWidth);
writer.WriteEncodedInt(GumpHeight);
writer.WriteEncodedInt(TitleColor);
writer.WriteEncodedInt(MessageColor);
writer.WriteEncodedInt(TitleNumber);
writer.WriteEncodedInt(MessageNumber);
writer.Write(MessageString);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch (version)
{
case 0:
{
GumpWidth = reader.ReadEncodedInt();
GumpHeight = reader.ReadEncodedInt();
TitleColor = reader.ReadEncodedInt();
MessageColor = reader.ReadEncodedInt();
TitleNumber = reader.ReadEncodedInt();
MessageNumber = reader.ReadEncodedInt();
MessageString = reader.ReadString();
break;
}
}
}
}
public class MoongateConfirmGump : Gump
{
private readonly Mobile m_From;
private readonly Moongate m_Gate;
public MoongateConfirmGump(Mobile from, Moongate gate) : base(Core.AOS ? 110 : 20, Core.AOS ? 100 : 30)
{
m_From = from;
m_Gate = gate;
if (Core.AOS)
{
Closable = false;
AddPage(0);
AddBackground(0, 0, 420, 280, 5054);
AddImageTiled(10, 10, 400, 20, 2624);
AddAlphaRegion(10, 10, 400, 20);
AddHtmlLocalized(10, 10, 400, 20, 1062051, 30720); // Gate Warning
AddImageTiled(10, 40, 400, 200, 2624);
AddAlphaRegion(10, 40, 400, 200);
if (from.Map != Map.Felucca && gate.TargetMap == Map.Felucca && gate.ShowFeluccaWarning)
AddHtmlLocalized(10, 40, 400, 200, 1062050, 32512, false,
true); // This Gate goes to Felucca... Continue to enter the gate, Cancel to stay here
else
AddHtmlLocalized(10, 40, 400, 200, 1062049, 32512, false,
true); // Dost thou wish to step into the moongate? Continue to enter the gate, Cancel to stay here
AddImageTiled(10, 250, 400, 20, 2624);
AddAlphaRegion(10, 250, 400, 20);
AddButton(10, 250, 4005, 4007, 1);
AddHtmlLocalized(40, 250, 170, 20, 1011036, 32767); // OKAY
AddButton(210, 250, 4005, 4007, 0);
AddHtmlLocalized(240, 250, 170, 20, 1011012, 32767); // CANCEL
}
else
{
AddPage(0);
AddBackground(0, 0, 420, 400, 5054);
AddBackground(10, 10, 400, 380, 3000);
AddHtml(20, 40, 380, 60,
@"Dost thou wish to step into the moongate? Continue to enter the gate, Cancel to stay here");
AddHtmlLocalized(55, 110, 290, 20, 1011012); // CANCEL
AddButton(20, 110, 4005, 4007, 0);
AddHtmlLocalized(55, 140, 290, 40, 1011011); // CONTINUE
AddButton(20, 140, 4005, 4007, 1);
}
}
public override void OnResponse(NetState state, RelayInfo info)
{
if (info.ButtonID == 1)
m_Gate.EndConfirmation(m_From);
}
}
}

View file

@ -3,327 +3,328 @@ using Server.Network;
namespace Server.Items
{
public class PotionKeg : Item
{
private int m_Held;
private PotionEffect m_Type;
[Constructible]
public PotionKeg() : base(0x1940)
public class PotionKeg : Item
{
UpdateWeight();
}
private int m_Held;
private PotionEffect m_Type;
public PotionKeg(Serial serial) : base(serial)
{
}
[CommandProperty(AccessLevel.GameMaster)]
public int Held
{
get => m_Held;
set
{
if (m_Held != value)
[Constructible]
public PotionKeg() : base(0x1940)
{
m_Held = value;
UpdateWeight();
InvalidateProperties();
UpdateWeight();
}
}
}
[CommandProperty(AccessLevel.GameMaster)]
public PotionEffect Type
{
get => m_Type;
set
{
m_Type = value;
InvalidateProperties();
}
}
public override int LabelNumber
{
get
{
if (m_Held > 0 && (int)m_Type >= (int)PotionEffect.Conflagration)
return 1072658 + (int)m_Type - (int)PotionEffect.Conflagration;
return m_Held > 0 ? 1041620 + (int)m_Type : 1041641;
}
}
public virtual void UpdateWeight()
{
int held = Math.Max(0, Math.Min(m_Held, 100));
Weight = 20 + held * 80 / 100;
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
writer.Write((int)m_Type);
writer.Write(m_Held);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch (version)
{
case 1:
case 0:
{
m_Type = (PotionEffect)reader.ReadInt();
m_Held = reader.ReadInt();
break;
}
}
if (version < 1)
Timer.DelayCall(UpdateWeight);
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
int number;
if (m_Held <= 0)
number = 502246; // The keg is empty.
else if (m_Held < 5)
number = 502248; // The keg is nearly empty.
else if (m_Held < 20)
number = 502249; // The keg is not very full.
else if (m_Held < 30)
number = 502250; // The keg is about one quarter full.
else if (m_Held < 40)
number = 502251; // The keg is about one third full.
else if (m_Held < 47)
number = 502252; // The keg is almost half full.
else if (m_Held < 54)
number = 502254; // The keg is approximately half full.
else if (m_Held < 70)
number = 502253; // The keg is more than half full.
else if (m_Held < 80)
number = 502255; // The keg is about three quarters full.
else if (m_Held < 96)
number = 502256; // The keg is very full.
else if (m_Held < 100)
number = 502257; // The liquid is almost to the top of the keg.
else
number = 502258; // The keg is completely full.
list.Add(number);
}
public override void OnSingleClick(Mobile from)
{
base.OnSingleClick(from);
int number;
if (m_Held <= 0)
number = 502246; // The keg is empty.
else if (m_Held < 5)
number = 502248; // The keg is nearly empty.
else if (m_Held < 20)
number = 502249; // The keg is not very full.
else if (m_Held < 30)
number = 502250; // The keg is about one quarter full.
else if (m_Held < 40)
number = 502251; // The keg is about one third full.
else if (m_Held < 47)
number = 502252; // The keg is almost half full.
else if (m_Held < 54)
number = 502254; // The keg is approximately half full.
else if (m_Held < 70)
number = 502253; // The keg is more than half full.
else if (m_Held < 80)
number = 502255; // The keg is about three quarters full.
else if (m_Held < 96)
number = 502256; // The keg is very full.
else if (m_Held < 100)
number = 502257; // The liquid is almost to the top of the keg.
else
number = 502258; // The keg is completely full.
LabelTo(from, number);
}
public override void OnDoubleClick(Mobile from)
{
if (from.InRange(GetWorldLocation(), 2))
{
if (m_Held > 0)
public PotionKeg(Serial serial) : base(serial)
{
Container pack = from.Backpack;
}
if (pack?.ConsumeTotal(typeof(Bottle)) == true)
{
from.SendLocalizedMessage(502242); // You pour some of the keg's contents into an empty bottle...
BasePotion pot = FillBottle();
if (pack.TryDropItem(from, pot, false))
[CommandProperty(AccessLevel.GameMaster)]
public int Held
{
get => m_Held;
set
{
from.SendLocalizedMessage(502243); // ...and place it into your backpack.
from.PlaySound(0x240);
if (m_Held != value)
{
m_Held = value;
UpdateWeight();
InvalidateProperties();
}
}
}
if (--Held == 0)
from.SendLocalizedMessage(502245); // The keg is now empty.
[CommandProperty(AccessLevel.GameMaster)]
public PotionEffect Type
{
get => m_Type;
set
{
m_Type = value;
InvalidateProperties();
}
}
public override int LabelNumber
{
get
{
if (m_Held > 0 && (int)m_Type >= (int)PotionEffect.Conflagration)
return 1072658 + (int)m_Type - (int)PotionEffect.Conflagration;
return m_Held > 0 ? 1041620 + (int)m_Type : 1041641;
}
}
public virtual void UpdateWeight()
{
var held = Math.Max(0, Math.Min(m_Held, 100));
Weight = 20 + held * 80 / 100;
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
writer.Write((int)m_Type);
writer.Write(m_Held);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
switch (version)
{
case 1:
case 0:
{
m_Type = (PotionEffect)reader.ReadInt();
m_Held = reader.ReadInt();
break;
}
}
if (version < 1)
Timer.DelayCall(UpdateWeight);
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
int number;
if (m_Held <= 0)
number = 502246; // The keg is empty.
else if (m_Held < 5)
number = 502248; // The keg is nearly empty.
else if (m_Held < 20)
number = 502249; // The keg is not very full.
else if (m_Held < 30)
number = 502250; // The keg is about one quarter full.
else if (m_Held < 40)
number = 502251; // The keg is about one third full.
else if (m_Held < 47)
number = 502252; // The keg is almost half full.
else if (m_Held < 54)
number = 502254; // The keg is approximately half full.
else if (m_Held < 70)
number = 502253; // The keg is more than half full.
else if (m_Held < 80)
number = 502255; // The keg is about three quarters full.
else if (m_Held < 96)
number = 502256; // The keg is very full.
else if (m_Held < 100)
number = 502257; // The liquid is almost to the top of the keg.
else
number = 502258; // The keg is completely full.
list.Add(number);
}
public override void OnSingleClick(Mobile from)
{
base.OnSingleClick(from);
int number;
if (m_Held <= 0)
number = 502246; // The keg is empty.
else if (m_Held < 5)
number = 502248; // The keg is nearly empty.
else if (m_Held < 20)
number = 502249; // The keg is not very full.
else if (m_Held < 30)
number = 502250; // The keg is about one quarter full.
else if (m_Held < 40)
number = 502251; // The keg is about one third full.
else if (m_Held < 47)
number = 502252; // The keg is almost half full.
else if (m_Held < 54)
number = 502254; // The keg is approximately half full.
else if (m_Held < 70)
number = 502253; // The keg is more than half full.
else if (m_Held < 80)
number = 502255; // The keg is about three quarters full.
else if (m_Held < 96)
number = 502256; // The keg is very full.
else if (m_Held < 100)
number = 502257; // The liquid is almost to the top of the keg.
else
number = 502258; // The keg is completely full.
LabelTo(from, number);
}
public override void OnDoubleClick(Mobile from)
{
if (from.InRange(GetWorldLocation(), 2))
{
if (m_Held > 0)
{
var pack = from.Backpack;
if (pack?.ConsumeTotal(typeof(Bottle)) == true)
{
from.SendLocalizedMessage(502242); // You pour some of the keg's contents into an empty bottle...
var pot = FillBottle();
if (pack.TryDropItem(from, pot, false))
{
from.SendLocalizedMessage(502243); // ...and place it into your backpack.
from.PlaySound(0x240);
if (--Held == 0)
from.SendLocalizedMessage(502245); // The keg is now empty.
}
else
{
from.SendLocalizedMessage(502244); // ...but there is no room for the bottle in your backpack.
pot.Delete();
}
}
}
else
{
from.SendLocalizedMessage(502246); // The keg is empty.
}
}
else
{
from.SendLocalizedMessage(502244); // ...but there is no room for the bottle in your backpack.
pot.Delete();
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
}
}
}
else
public override bool OnDragDrop(Mobile from, Item item)
{
from.SendLocalizedMessage(502246); // The keg is empty.
if (!(item is BasePotion pot))
{
from.SendLocalizedMessage(502232); // The keg is not designed to hold that type of object.
return false;
}
var toHold = Math.Min(100 - m_Held, pot.Amount);
if (toHold <= 0)
{
from.SendLocalizedMessage(502233); // The keg will not hold any more!
return false;
}
if (m_Held == 0)
{
if ((int)pot.PotionEffect >= (int)PotionEffect.Invisibility)
{
from.SendLocalizedMessage(502232); // The keg is not designed to hold that type of object.
return false;
}
if (GiveBottle(from, toHold))
{
m_Type = pot.PotionEffect;
Held = toHold;
from.PlaySound(0x240);
from.SendLocalizedMessage(502237); // You place the empty bottle in your backpack.
pot.Consume(toHold);
if (!pot.Deleted)
pot.Bounce(from);
return true;
}
from.SendLocalizedMessage(502238); // You don't have room for the empty bottle in your backpack.
return false;
}
if (pot.PotionEffect != m_Type)
{
from.SendLocalizedMessage(
502236
); // You decide that it would be a bad idea to mix different types of potions.
return false;
}
if (GiveBottle(from, toHold))
{
Held += toHold;
from.PlaySound(0x240);
from.SendLocalizedMessage(502237); // You place the empty bottle in your backpack.
pot.Consume(toHold);
if (!pot.Deleted)
pot.Bounce(from);
return true;
}
from.SendLocalizedMessage(502238); // You don't have room for the empty bottle in your backpack.
return false;
}
}
else
{
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
}
}
public override bool OnDragDrop(Mobile from, Item item)
{
if (!(item is BasePotion pot))
{
from.SendLocalizedMessage(502232); // The keg is not designed to hold that type of object.
return false;
}
int toHold = Math.Min(100 - m_Held, pot.Amount);
if (toHold <= 0)
{
from.SendLocalizedMessage(502233); // The keg will not hold any more!
return false;
}
if (m_Held == 0)
{
if ((int)pot.PotionEffect >= (int)PotionEffect.Invisibility)
public bool GiveBottle(Mobile m, int amount)
{
from.SendLocalizedMessage(502232); // The keg is not designed to hold that type of object.
return false;
var pack = m.Backpack;
var bottle = new Bottle(amount);
if (pack?.TryDropItem(m, bottle, false) != true)
{
bottle.Delete();
return false;
}
return true;
}
if (GiveBottle(from, toHold))
public BasePotion FillBottle()
{
m_Type = pot.PotionEffect;
Held = toHold;
from.PlaySound(0x240);
from.SendLocalizedMessage(502237); // You place the empty bottle in your backpack.
pot.Consume(toHold);
if (!pot.Deleted)
pot.Bounce(from);
return true;
return m_Type switch
{
PotionEffect.Nightsight => new NightSightPotion(),
PotionEffect.CureLesser => new LesserCurePotion(),
PotionEffect.Cure => new CurePotion(),
PotionEffect.CureGreater => new GreaterCurePotion(),
PotionEffect.Agility => new AgilityPotion(),
PotionEffect.AgilityGreater => new GreaterAgilityPotion(),
PotionEffect.Strength => new StrengthPotion(),
PotionEffect.StrengthGreater => new GreaterStrengthPotion(),
PotionEffect.PoisonLesser => new LesserPoisonPotion(),
PotionEffect.Poison => new PoisonPotion(),
PotionEffect.PoisonGreater => new GreaterPoisonPotion(),
PotionEffect.PoisonDeadly => new DeadlyPoisonPotion(),
PotionEffect.Refresh => new RefreshPotion(),
PotionEffect.RefreshTotal => new TotalRefreshPotion(),
PotionEffect.HealLesser => new LesserHealPotion(),
PotionEffect.Heal => new HealPotion(),
PotionEffect.HealGreater => new GreaterHealPotion(),
PotionEffect.ExplosionLesser => new LesserExplosionPotion(),
PotionEffect.Explosion => new ExplosionPotion(),
PotionEffect.ExplosionGreater => new GreaterExplosionPotion(),
PotionEffect.Conflagration => new ConflagrationPotion(),
PotionEffect.ConflagrationGreater => new GreaterConflagrationPotion(),
PotionEffect.ConfusionBlast => new ConfusionBlastPotion(),
PotionEffect.ConfusionBlastGreater => new GreaterConfusionBlastPotion(),
_ => new NightSightPotion()
};
}
from.SendLocalizedMessage(502238); // You don't have room for the empty bottle in your backpack.
return false;
}
if (pot.PotionEffect != m_Type)
{
from.SendLocalizedMessage(
502236); // You decide that it would be a bad idea to mix different types of potions.
return false;
}
if (GiveBottle(from, toHold))
{
Held += toHold;
from.PlaySound(0x240);
from.SendLocalizedMessage(502237); // You place the empty bottle in your backpack.
pot.Consume(toHold);
if (!pot.Deleted)
pot.Bounce(from);
return true;
}
from.SendLocalizedMessage(502238); // You don't have room for the empty bottle in your backpack.
return false;
public static void Initialize()
{
TileData.ItemTable[0x1940].Height = 4;
}
}
public bool GiveBottle(Mobile m, int amount)
{
Container pack = m.Backpack;
Bottle bottle = new Bottle(amount);
if (pack?.TryDropItem(m, bottle, false) != true)
{
bottle.Delete();
return false;
}
return true;
}
public BasePotion FillBottle()
{
return m_Type switch
{
PotionEffect.Nightsight => (BasePotion)new NightSightPotion(),
PotionEffect.CureLesser => new LesserCurePotion(),
PotionEffect.Cure => new CurePotion(),
PotionEffect.CureGreater => new GreaterCurePotion(),
PotionEffect.Agility => new AgilityPotion(),
PotionEffect.AgilityGreater => new GreaterAgilityPotion(),
PotionEffect.Strength => new StrengthPotion(),
PotionEffect.StrengthGreater => new GreaterStrengthPotion(),
PotionEffect.PoisonLesser => new LesserPoisonPotion(),
PotionEffect.Poison => new PoisonPotion(),
PotionEffect.PoisonGreater => new GreaterPoisonPotion(),
PotionEffect.PoisonDeadly => new DeadlyPoisonPotion(),
PotionEffect.Refresh => new RefreshPotion(),
PotionEffect.RefreshTotal => new TotalRefreshPotion(),
PotionEffect.HealLesser => new LesserHealPotion(),
PotionEffect.Heal => new HealPotion(),
PotionEffect.HealGreater => new GreaterHealPotion(),
PotionEffect.ExplosionLesser => new LesserExplosionPotion(),
PotionEffect.Explosion => new ExplosionPotion(),
PotionEffect.ExplosionGreater => new GreaterExplosionPotion(),
PotionEffect.Conflagration => new ConflagrationPotion(),
PotionEffect.ConflagrationGreater => new GreaterConflagrationPotion(),
PotionEffect.ConfusionBlast => new ConfusionBlastPotion(),
PotionEffect.ConfusionBlastGreater => new GreaterConfusionBlastPotion(),
_ => new NightSightPotion()
};
}
public static void Initialize()
{
TileData.ItemTable[0x1940].Height = 4;
}
}
}

View file

@ -4,293 +4,309 @@ using Server.Regions;
namespace Server.Items
{
[Flippable(0x1f14, 0x1f15, 0x1f16, 0x1f17)]
public class RecallRune : Item
{
private const string RuneFormat = "a recall rune for {0}";
private string m_Description;
private BaseHouse m_House;
private bool m_Marked;
private Map m_TargetMap;
[Constructible]
public RecallRune() : base(0x1F14)
[Flippable(0x1f14, 0x1f15, 0x1f16, 0x1f17)]
public class RecallRune : Item
{
Weight = 1.0;
CalculateHue();
}
private const string RuneFormat = "a recall rune for {0}";
private string m_Description;
private BaseHouse m_House;
private bool m_Marked;
private Map m_TargetMap;
public RecallRune(Serial serial) : base(serial)
{
}
[CommandProperty(AccessLevel.Counselor, AccessLevel.GameMaster)]
public BaseHouse House
{
get
{
if (m_House?.Deleted == true)
House = null;
return m_House;
}
set
{
m_House = value;
CalculateHue();
InvalidateProperties();
}
}
[CommandProperty(AccessLevel.Counselor, AccessLevel.GameMaster)]
public string Description
{
get => m_Description;
set
{
m_Description = value;
InvalidateProperties();
}
}
[CommandProperty(AccessLevel.Counselor, AccessLevel.GameMaster)]
public bool Marked
{
get => m_Marked;
set
{
if (m_Marked != value)
[Constructible]
public RecallRune() : base(0x1F14)
{
m_Marked = value;
CalculateHue();
InvalidateProperties();
Weight = 1.0;
CalculateHue();
}
}
}
[CommandProperty(AccessLevel.Counselor, AccessLevel.GameMaster)]
public Point3D Target { get; set; }
[CommandProperty(AccessLevel.Counselor, AccessLevel.GameMaster)]
public Map TargetMap
{
get => m_TargetMap;
set
{
if (m_TargetMap != value)
public RecallRune(Serial serial) : base(serial)
{
m_TargetMap = value;
CalculateHue();
InvalidateProperties();
}
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
[CommandProperty(AccessLevel.Counselor, AccessLevel.GameMaster)]
public BaseHouse House
{
get
{
if (m_House?.Deleted == true)
House = null;
if (m_House?.Deleted == false)
{
writer.Write(1); // version
return m_House;
}
set
{
m_House = value;
CalculateHue();
InvalidateProperties();
}
}
writer.Write(m_House);
}
else
{
writer.Write(0); // version
}
[CommandProperty(AccessLevel.Counselor, AccessLevel.GameMaster)]
public string Description
{
get => m_Description;
set
{
m_Description = value;
InvalidateProperties();
}
}
writer.Write(m_Description);
writer.Write(m_Marked);
writer.Write(Target);
writer.Write(m_TargetMap);
}
[CommandProperty(AccessLevel.Counselor, AccessLevel.GameMaster)]
public bool Marked
{
get => m_Marked;
set
{
if (m_Marked != value)
{
m_Marked = value;
CalculateHue();
InvalidateProperties();
}
}
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
[CommandProperty(AccessLevel.Counselor, AccessLevel.GameMaster)]
public Point3D Target { get; set; }
int version = reader.ReadInt();
[CommandProperty(AccessLevel.Counselor, AccessLevel.GameMaster)]
public Map TargetMap
{
get => m_TargetMap;
set
{
if (m_TargetMap != value)
{
m_TargetMap = value;
CalculateHue();
InvalidateProperties();
}
}
}
switch (version)
{
case 1:
{
m_House = reader.ReadItem() as BaseHouse;
goto case 0;
}
case 0:
{
m_Description = reader.ReadString();
m_Marked = reader.ReadBool();
Target = reader.ReadPoint3D();
m_TargetMap = reader.ReadMap();
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
if (m_House?.Deleted == false)
{
writer.Write(1); // version
writer.Write(m_House);
}
else
{
writer.Write(0); // version
}
writer.Write(m_Description);
writer.Write(m_Marked);
writer.Write(Target);
writer.Write(m_TargetMap);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
switch (version)
{
case 1:
{
m_House = reader.ReadItem() as BaseHouse;
goto case 0;
}
case 0:
{
m_Description = reader.ReadString();
m_Marked = reader.ReadBool();
Target = reader.ReadPoint3D();
m_TargetMap = reader.ReadMap();
CalculateHue();
break;
}
}
}
private void CalculateHue()
{
if (!m_Marked)
Hue = 0;
else if (m_TargetMap == Map.Trammel)
Hue = House != null ? 0x47F : 50;
else if (m_TargetMap == Map.Felucca)
Hue = House != null ? 0x66D : 0;
else if (m_TargetMap == Map.Ilshenar)
Hue = House != null ? 0x55F : 1102;
else if (m_TargetMap == Map.Malas)
Hue = House != null ? 0x55F : 1102;
else if (m_TargetMap == Map.Tokuno)
Hue = House != null ? 0x47F : 1154;
}
public void Mark(Mobile m)
{
m_Marked = true;
var setDesc = false;
if (Core.AOS)
{
m_House = BaseHouse.FindHouseAt(m);
if (m_House == null)
{
Target = m.Location;
m_TargetMap = m.Map;
}
else
{
var sign = m_House.Sign;
m_Description = sign?.Name?.Trim().IsNullOrDefault("an unnamed house");
setDesc = true;
var x = m_House.BanLocation.X;
var y = m_House.BanLocation.Y + 2;
var z = m_House.BanLocation.Z;
var map = m_House.Map;
if (map?.CanFit(x, y, z, 16, false, false) == false)
z = map.GetAverageZ(x, y);
Target = new Point3D(x, y, z);
m_TargetMap = map;
}
}
else
{
m_House = null;
Target = m.Location;
m_TargetMap = m.Map;
}
if (!setDesc)
m_Description = BaseRegion.GetRuneNameFor(Region.Find(Target, m_TargetMap));
CalculateHue();
break;
}
}
}
private void CalculateHue()
{
if (!m_Marked)
Hue = 0;
else if (m_TargetMap == Map.Trammel)
Hue = House != null ? 0x47F : 50;
else if (m_TargetMap == Map.Felucca)
Hue = House != null ? 0x66D : 0;
else if (m_TargetMap == Map.Ilshenar)
Hue = House != null ? 0x55F : 1102;
else if (m_TargetMap == Map.Malas)
Hue = House != null ? 0x55F : 1102;
else if (m_TargetMap == Map.Tokuno)
Hue = House != null ? 0x47F : 1154;
}
public void Mark(Mobile m)
{
m_Marked = true;
bool setDesc = false;
if (Core.AOS)
{
m_House = BaseHouse.FindHouseAt(m);
if (m_House == null)
{
Target = m.Location;
m_TargetMap = m.Map;
InvalidateProperties();
}
else
public override void GetProperties(ObjectPropertyList list)
{
HouseSign sign = m_House.Sign;
base.GetProperties(list);
m_Description = sign?.Name?.Trim().IsNullOrDefault("an unnamed house");
if (m_Marked)
{
string desc;
setDesc = true;
if ((desc = m_Description) == null || (desc = desc.Trim()).Length == 0)
desc = "an unknown location";
int x = m_House.BanLocation.X;
int y = m_House.BanLocation.Y + 2;
int z = m_House.BanLocation.Z;
Map map = m_House.Map;
if (map?.CanFit(x, y, z, 16, false, false) == false)
z = map.GetAverageZ(x, y);
Target = new Point3D(x, y, z);
m_TargetMap = map;
if (m_TargetMap == Map.Tokuno)
list.Add(House != null ? 1063260 : 1063259, RuneFormat, desc); // ~1_val~ (Tokuno Islands)[(House)]
else if (m_TargetMap == Map.Malas)
list.Add(House != null ? 1062454 : 1060804, RuneFormat, desc); // ~1_val~ (Malas)[(House)]
else if (m_TargetMap == Map.Felucca)
list.Add(House != null ? 1062452 : 1060805, RuneFormat, desc); // ~1_val~ (Felucca)[(House)]
else if (m_TargetMap == Map.Trammel)
list.Add(House != null ? 1062453 : 1060806, RuneFormat, desc); // ~1_val~ (Trammel)[(House)]
else
list.Add(House != null ? "{0} ({1})(House)" : "{0} ({1})", string.Format(RuneFormat, desc), m_TargetMap);
}
}
}
else
{
m_House = null;
Target = m.Location;
m_TargetMap = m.Map;
}
if (!setDesc)
m_Description = BaseRegion.GetRuneNameFor(Region.Find(Target, m_TargetMap));
CalculateHue();
InvalidateProperties();
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
if (m_Marked)
{
string desc;
if ((desc = m_Description) == null || (desc = desc.Trim()).Length == 0)
desc = "an unknown location";
if (m_TargetMap == Map.Tokuno)
list.Add(House != null ? 1063260 : 1063259, RuneFormat, desc); // ~1_val~ (Tokuno Islands)[(House)]
else if (m_TargetMap == Map.Malas)
list.Add(House != null ? 1062454 : 1060804, RuneFormat, desc); // ~1_val~ (Malas)[(House)]
else if (m_TargetMap == Map.Felucca)
list.Add(House != null ? 1062452 : 1060805, RuneFormat, desc); // ~1_val~ (Felucca)[(House)]
else if (m_TargetMap == Map.Trammel)
list.Add(House != null ? 1062453 : 1060806, RuneFormat, desc); // ~1_val~ (Trammel)[(House)]
else
list.Add(House != null ? "{0} ({1})(House)" : "{0} ({1})", string.Format(RuneFormat, desc), m_TargetMap);
}
}
public override void OnSingleClick(Mobile from)
{
if (m_Marked)
{
string desc = m_Description?.Trim().IsNullOrDefault("an unknown location");
if (m_TargetMap == Map.Tokuno)
LabelTo(from, House != null ? 1063260 : 1063259,
string.Format(RuneFormat, desc)); // ~1_val~ (Tokuno Islands)[(House)]
else if (m_TargetMap == Map.Malas)
LabelTo(from, House != null ? 1062454 : 1060804,
string.Format(RuneFormat, desc)); // ~1_val~ (Malas)[(House)]
else if (m_TargetMap == Map.Felucca)
LabelTo(from, House != null ? 1062452 : 1060805,
string.Format(RuneFormat, desc)); // ~1_val~ (Felucca)[(House)]
else if (m_TargetMap == Map.Trammel)
LabelTo(from, House != null ? 1062453 : 1060806,
string.Format(RuneFormat, desc)); // ~1_val~ (Trammel)[(House)]
else
LabelTo(from, House != null ? "{0} ({1})(House)" : "{0} ({1})", string.Format(RuneFormat, desc),
m_TargetMap);
}
else
{
LabelTo(from, "an unmarked recall rune");
}
}
public override void OnDoubleClick(Mobile from)
{
int number;
if (!IsChildOf(from.Backpack))
{
number = 1042001; // That must be in your pack for you to use it.
}
else if (House != null)
{
number = 1062399; // You cannot edit the description for this rune.
}
else if (m_Marked)
{
number = 501804; // Please enter a description for this marked object.
from.Prompt = new RenamePrompt(this);
}
else
{
number = 501805; // That rune is not yet marked.
}
from.SendLocalizedMessage(number);
}
private class RenamePrompt : Prompt
{
private readonly RecallRune m_Rune;
public RenamePrompt(RecallRune rune) => m_Rune = rune;
public override void OnResponse(Mobile from, string text)
{
if (m_Rune.House == null && m_Rune.Marked)
public override void OnSingleClick(Mobile from)
{
m_Rune.Description = text;
from.SendLocalizedMessage(1010474); // The etching on the rune has been changed.
if (m_Marked)
{
var desc = m_Description?.Trim().IsNullOrDefault("an unknown location");
if (m_TargetMap == Map.Tokuno)
LabelTo(
from,
House != null ? 1063260 : 1063259,
string.Format(RuneFormat, desc)
); // ~1_val~ (Tokuno Islands)[(House)]
else if (m_TargetMap == Map.Malas)
LabelTo(
from,
House != null ? 1062454 : 1060804,
string.Format(RuneFormat, desc)
); // ~1_val~ (Malas)[(House)]
else if (m_TargetMap == Map.Felucca)
LabelTo(
from,
House != null ? 1062452 : 1060805,
string.Format(RuneFormat, desc)
); // ~1_val~ (Felucca)[(House)]
else if (m_TargetMap == Map.Trammel)
LabelTo(
from,
House != null ? 1062453 : 1060806,
string.Format(RuneFormat, desc)
); // ~1_val~ (Trammel)[(House)]
else
LabelTo(
from,
House != null ? "{0} ({1})(House)" : "{0} ({1})",
string.Format(RuneFormat, desc),
m_TargetMap
);
}
else
{
LabelTo(from, "an unmarked recall rune");
}
}
public override void OnDoubleClick(Mobile from)
{
int number;
if (!IsChildOf(from.Backpack))
{
number = 1042001; // That must be in your pack for you to use it.
}
else if (House != null)
{
number = 1062399; // You cannot edit the description for this rune.
}
else if (m_Marked)
{
number = 501804; // Please enter a description for this marked object.
from.Prompt = new RenamePrompt(this);
}
else
{
number = 501805; // That rune is not yet marked.
}
from.SendLocalizedMessage(number);
}
private class RenamePrompt : Prompt
{
private readonly RecallRune m_Rune;
public RenamePrompt(RecallRune rune) => m_Rune = rune;
public override void OnResponse(Mobile from, string text)
{
if (m_Rune.House == null && m_Rune.Marked)
{
m_Rune.Description = text;
from.SendLocalizedMessage(1010474); // The etching on the rune has been changed.
}
}
}
}
}
}
}

View file

@ -1,35 +1,35 @@
namespace Server.Items
{
public class MysticSpellbook : Spellbook
{
[Constructible]
public MysticSpellbook(ulong content = 0)
: base(content, 0x2D9D) =>
Layer = Layer.OneHanded;
public MysticSpellbook(Serial serial)
: base(serial)
public class MysticSpellbook : Spellbook
{
[Constructible]
public MysticSpellbook(ulong content = 0)
: base(content, 0x2D9D) =>
Layer = Layer.OneHanded;
public MysticSpellbook(Serial serial)
: base(serial)
{
}
public override SpellbookType SpellbookType => SpellbookType.Mystic;
public override int BookOffset => 677;
public override int BookCount => 16;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
/*int version = */
reader.ReadInt();
}
}
public override SpellbookType SpellbookType => SpellbookType.Mystic;
public override int BookOffset => 677;
public override int BookCount => 16;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
/*int version = */
reader.ReadInt();
}
}
}

View file

@ -1,33 +1,34 @@
namespace Server.Items
{
public class NecromancerSpellbook : Spellbook
{
[Constructible]
public NecromancerSpellbook(ulong content = 0) : base(content, 0x2253) => Layer = Core.ML ? Layer.OneHanded : Layer.Invalid;
public NecromancerSpellbook(Serial serial) : base(serial)
public class NecromancerSpellbook : Spellbook
{
[Constructible]
public NecromancerSpellbook(ulong content = 0) : base(content, 0x2253) =>
Layer = Core.ML ? Layer.OneHanded : Layer.Invalid;
public NecromancerSpellbook(Serial serial) : base(serial)
{
}
public override SpellbookType SpellbookType => SpellbookType.Necromancer;
public override int BookOffset => 100;
public override int BookCount => Core.SE ? 17 : 16;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
if (version == 0 && Core.ML)
Layer = Layer.OneHanded;
}
}
public override SpellbookType SpellbookType => SpellbookType.Necromancer;
public override int BookOffset => 100;
public override int BookCount => Core.SE ? 17 : 16;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
if (version == 0 && Core.ML)
Layer = Layer.OneHanded;
}
}
}

View file

@ -2,32 +2,32 @@ using System;
namespace Server.Items
{
public class AgilityPotion : BaseAgilityPotion
{
[Constructible]
public AgilityPotion() : base(PotionEffect.Agility)
public class AgilityPotion : BaseAgilityPotion
{
[Constructible]
public AgilityPotion() : base(PotionEffect.Agility)
{
}
public AgilityPotion(Serial serial) : base(serial)
{
}
public override int DexOffset => 10;
public override TimeSpan Duration => TimeSpan.FromMinutes(2.0);
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 AgilityPotion(Serial serial) : base(serial)
{
}
public override int DexOffset => 10;
public override TimeSpan Duration => TimeSpan.FromMinutes(2.0);
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
}

View file

@ -4,56 +4,56 @@ using Server.Spells;
namespace Server.Items
{
public abstract class BaseAgilityPotion : BasePotion
{
public BaseAgilityPotion(PotionEffect effect) : base(0xF08, effect)
public abstract class BaseAgilityPotion : BasePotion
{
public BaseAgilityPotion(PotionEffect effect) : base(0xF08, effect)
{
}
public BaseAgilityPotion(Serial serial) : base(serial)
{
}
public abstract int DexOffset { get; }
public abstract TimeSpan Duration { get; }
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 bool DoAgility(Mobile from)
{
// TODO: Verify scaled; is it offset, duration, or both?
if (SpellHelper.AddStatOffset(from, StatType.Dex, Scale(from, DexOffset), Duration))
{
from.FixedEffect(0x375A, 10, 15);
from.PlaySound(0x1E7);
return true;
}
from.SendLocalizedMessage(502173); // You are already under a similar effect.
return false;
}
public override void Drink(Mobile from)
{
if (DoAgility(from))
{
PlayDrinkEffect(from);
if (!DuelContext.IsFreeConsume(from))
Consume();
}
}
}
public BaseAgilityPotion(Serial serial) : base(serial)
{
}
public abstract int DexOffset { get; }
public abstract TimeSpan Duration { get; }
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
public bool DoAgility(Mobile from)
{
// TODO: Verify scaled; is it offset, duration, or both?
if (SpellHelper.AddStatOffset(from, StatType.Dex, Scale(from, DexOffset), Duration))
{
from.FixedEffect(0x375A, 10, 15);
from.PlaySound(0x1E7);
return true;
}
from.SendLocalizedMessage(502173); // You are already under a similar effect.
return false;
}
public override void Drink(Mobile from)
{
if (DoAgility(from))
{
PlayDrinkEffect(from);
if (!DuelContext.IsFreeConsume(from))
Consume();
}
}
}
}
}

View file

@ -2,32 +2,32 @@ using System;
namespace Server.Items
{
public class GreaterAgilityPotion : BaseAgilityPotion
{
[Constructible]
public GreaterAgilityPotion() : base(PotionEffect.AgilityGreater)
public class GreaterAgilityPotion : BaseAgilityPotion
{
[Constructible]
public GreaterAgilityPotion() : base(PotionEffect.AgilityGreater)
{
}
public GreaterAgilityPotion(Serial serial) : base(serial)
{
}
public override int DexOffset => 20;
public override TimeSpan Duration => TimeSpan.FromMinutes(2.0);
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 GreaterAgilityPotion(Serial serial) : base(serial)
{
}
public override int DexOffset => 20;
public override TimeSpan Duration => TimeSpan.FromMinutes(2.0);
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
}

View file

@ -1,254 +1,255 @@
using System;
using System.Collections.Generic;
using Server.Engines.ConPVP;
using Server.Engines.Craft;
using Server.Utilities;
namespace Server.Items
{
public enum PotionEffect
{
Nightsight,
CureLesser,
Cure,
CureGreater,
Agility,
AgilityGreater,
Strength,
StrengthGreater,
PoisonLesser,
Poison,
PoisonGreater,
PoisonDeadly,
Refresh,
RefreshTotal,
HealLesser,
Heal,
HealGreater,
ExplosionLesser,
Explosion,
ExplosionGreater,
Conflagration,
ConflagrationGreater,
MaskOfDeath, // Mask of Death is not available in OSI but does exist in cliloc files
MaskOfDeathGreater, // included in enumeration for compatibility if later enabled by OSI
ConfusionBlast,
ConfusionBlastGreater,
Invisibility,
Parasitic,
Darkglow
}
public abstract class BasePotion : Item, ICraftable, ICommodity
{
private PotionEffect m_PotionEffect;
public BasePotion(int itemID, PotionEffect effect) : base(itemID)
public enum PotionEffect
{
m_PotionEffect = effect;
Stackable = Core.ML;
Weight = 1.0;
Nightsight,
CureLesser,
Cure,
CureGreater,
Agility,
AgilityGreater,
Strength,
StrengthGreater,
PoisonLesser,
Poison,
PoisonGreater,
PoisonDeadly,
Refresh,
RefreshTotal,
HealLesser,
Heal,
HealGreater,
ExplosionLesser,
Explosion,
ExplosionGreater,
Conflagration,
ConflagrationGreater,
MaskOfDeath, // Mask of Death is not available in OSI but does exist in cliloc files
MaskOfDeathGreater, // included in enumeration for compatibility if later enabled by OSI
ConfusionBlast,
ConfusionBlastGreater,
Invisibility,
Parasitic,
Darkglow
}
public BasePotion(Serial serial) : base(serial)
public abstract class BasePotion : Item, ICraftable, ICommodity
{
}
private PotionEffect m_PotionEffect;
public PotionEffect PotionEffect
{
get => m_PotionEffect;
set
{
m_PotionEffect = value;
InvalidateProperties();
}
}
public override int LabelNumber => 1041314 + (int)m_PotionEffect;
public virtual bool RequireFreeHand => true;
int ICommodity.DescriptionNumber => LabelNumber;
bool ICommodity.IsDeedable => Core.ML;
public int OnCraft(int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool,
CraftItem craftItem, int resHue)
{
if (craftSystem is DefAlchemy)
{
Container pack = from.Backpack;
if (pack != null)
public BasePotion(int itemID, PotionEffect effect) : base(itemID)
{
if ((int)PotionEffect >= (int)PotionEffect.Invisibility)
m_PotionEffect = effect;
Stackable = Core.ML;
Weight = 1.0;
}
public BasePotion(Serial serial) : base(serial)
{
}
public PotionEffect PotionEffect
{
get => m_PotionEffect;
set
{
m_PotionEffect = value;
InvalidateProperties();
}
}
public override int LabelNumber => 1041314 + (int)m_PotionEffect;
public virtual bool RequireFreeHand => true;
int ICommodity.DescriptionNumber => LabelNumber;
bool ICommodity.IsDeedable => Core.ML;
public int OnCraft(
int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool,
CraftItem craftItem, int resHue
)
{
if (craftSystem is DefAlchemy)
{
var pack = from.Backpack;
if (pack != null)
{
if ((int)PotionEffect >= (int)PotionEffect.Invisibility)
return 1;
var kegs = pack.FindItemsByType<PotionKeg>();
for (var i = 0; i < kegs.Count; ++i)
{
var keg = kegs[i];
// Should never happen
// if (keg == null)
// continue;
if (keg.Held <= 0 || keg.Held >= 100)
continue;
if (keg.Type != PotionEffect)
continue;
++keg.Held;
Consume();
from.AddToBackpack(new Bottle());
return -1; // signal placed in keg
}
}
}
return 1;
List<PotionKeg> kegs = pack.FindItemsByType<PotionKeg>();
for (int i = 0; i < kegs.Count; ++i)
{
PotionKeg keg = kegs[i];
// Should never happen
// if (keg == null)
// continue;
if (keg.Held <= 0 || keg.Held >= 100)
continue;
if (keg.Type != PotionEffect)
continue;
++keg.Held;
Consume();
from.AddToBackpack(new Bottle());
return -1; // signal placed in keg
}
}
}
return 1;
}
public static bool HasFreeHand(Mobile m)
{
Item handOne = m.FindItemOnLayer(Layer.OneHanded);
Item handTwo = m.FindItemOnLayer(Layer.TwoHanded);
if (handTwo is BaseWeapon)
handOne = handTwo;
if (handTwo is BaseRanged ranged && ranged.Balanced)
return true;
return handOne == null || handTwo == null;
}
public override void OnDoubleClick(Mobile from)
{
if (!Movable)
return;
if (from.InRange(GetWorldLocation(), 1))
{
if (!RequireFreeHand || HasFreeHand(from))
public static bool HasFreeHand(Mobile m)
{
if (this is BaseExplosionPotion && Amount > 1)
{
BasePotion pot = (BasePotion)ActivatorUtil.CreateInstance(GetType());
var handOne = m.FindItemOnLayer(Layer.OneHanded);
var handTwo = m.FindItemOnLayer(Layer.TwoHanded);
Amount--;
if (handTwo is BaseWeapon)
handOne = handTwo;
if (from.Backpack?.Deleted != false)
from.Backpack.DropItem(pot);
if (handTwo is BaseRanged ranged && ranged.Balanced)
return true;
return handOne == null || handTwo == null;
}
public override void OnDoubleClick(Mobile from)
{
if (!Movable)
return;
if (from.InRange(GetWorldLocation(), 1))
{
if (!RequireFreeHand || HasFreeHand(from))
{
if (this is BaseExplosionPotion && Amount > 1)
{
var pot = (BasePotion)ActivatorUtil.CreateInstance(GetType());
Amount--;
if (from.Backpack?.Deleted != false)
from.Backpack.DropItem(pot);
else
pot.MoveToWorld(from.Location, from.Map);
pot.Drink(from);
}
else
{
Drink(from);
}
}
else
{
from.SendLocalizedMessage(502172); // You must have a free hand to drink a potion.
}
}
else
pot.MoveToWorld(from.Location, from.Map);
pot.Drink(from);
}
else
{
Drink(from);
}
{
from.SendLocalizedMessage(502138); // That is too far away for you to use
}
}
else
public override void Serialize(IGenericWriter writer)
{
from.SendLocalizedMessage(502172); // You must have a free hand to drink a potion.
base.Serialize(writer);
writer.Write(1); // version
writer.Write((int)m_PotionEffect);
}
}
else
{
from.SendLocalizedMessage(502138); // That is too far away for you to use
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
switch (version)
{
case 1:
case 0:
{
m_PotionEffect = (PotionEffect)reader.ReadInt();
break;
}
}
if (version == 0)
Stackable = Core.ML;
}
public abstract void Drink(Mobile from);
public static void PlayDrinkEffect(Mobile m)
{
m.RevealingAction();
m.PlaySound(0x2D6);
if (!DuelContext.IsFreeConsume(m))
m.AddToBackpack(new Bottle());
if (m.Body.IsHuman && !m.Mounted)
m.Animate(34, 5, 1, true, false, 0);
}
public static int EnhancePotions(Mobile m)
{
var EP = AosAttributes.GetValue(m, AosAttribute.EnhancePotions);
var skillBonus = m.Skills.Alchemy.Fixed / 330 * 10;
if (Core.ML && EP > 50 && m.AccessLevel <= AccessLevel.Player)
EP = 50;
return EP + skillBonus;
}
public static TimeSpan Scale(Mobile m, TimeSpan v)
{
if (!Core.AOS)
return v;
var scalar = 1.0 + 0.01 * EnhancePotions(m);
return TimeSpan.FromSeconds(v.TotalSeconds * scalar);
}
public static double Scale(Mobile m, double v)
{
if (!Core.AOS)
return v;
var scalar = 1.0 + 0.01 * EnhancePotions(m);
return v * scalar;
}
public static int Scale(Mobile m, int v)
{
if (!Core.AOS)
return v;
return AOS.Scale(v, 100 + EnhancePotions(m));
}
public override bool StackWith(Mobile from, Item dropped, bool playSound) =>
dropped is BasePotion potion && potion.m_PotionEffect == m_PotionEffect &&
base.StackWith(from, potion, playSound);
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
writer.Write((int)m_PotionEffect);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch (version)
{
case 1:
case 0:
{
m_PotionEffect = (PotionEffect)reader.ReadInt();
break;
}
}
if (version == 0)
Stackable = Core.ML;
}
public abstract void Drink(Mobile from);
public static void PlayDrinkEffect(Mobile m)
{
m.RevealingAction();
m.PlaySound(0x2D6);
if (!DuelContext.IsFreeConsume(m))
m.AddToBackpack(new Bottle());
if (m.Body.IsHuman && !m.Mounted)
m.Animate(34, 5, 1, true, false, 0);
}
public static int EnhancePotions(Mobile m)
{
int EP = AosAttributes.GetValue(m, AosAttribute.EnhancePotions);
int skillBonus = m.Skills.Alchemy.Fixed / 330 * 10;
if (Core.ML && EP > 50 && m.AccessLevel <= AccessLevel.Player)
EP = 50;
return EP + skillBonus;
}
public static TimeSpan Scale(Mobile m, TimeSpan v)
{
if (!Core.AOS)
return v;
double scalar = 1.0 + 0.01 * EnhancePotions(m);
return TimeSpan.FromSeconds(v.TotalSeconds * scalar);
}
public static double Scale(Mobile m, double v)
{
if (!Core.AOS)
return v;
double scalar = 1.0 + 0.01 * EnhancePotions(m);
return v * scalar;
}
public static int Scale(Mobile m, int v)
{
if (!Core.AOS)
return v;
return AOS.Scale(v, 100 + EnhancePotions(m));
}
public override bool StackWith(Mobile from, Item dropped, bool playSound) =>
dropped is BasePotion potion && potion.m_PotionEffect == m_PotionEffect &&
base.StackWith(from, potion, playSound);
}
}

View file

@ -5,288 +5,289 @@ using Server.Targeting;
namespace Server.Items
{
public abstract class BaseConflagrationPotion : BasePotion
{
private readonly List<Mobile> m_Users = new List<Mobile>();
public BaseConflagrationPotion(PotionEffect effect) : base(0xF06, effect) => Hue = 0x489;
public BaseConflagrationPotion(Serial serial) : base(serial)
public abstract class BaseConflagrationPotion : BasePotion
{
}
private static readonly Dictionary<Mobile, Timer> m_Delay = new Dictionary<Mobile, Timer>();
private readonly List<Mobile> m_Users = new List<Mobile>();
public abstract int MinDamage { get; }
public abstract int MaxDamage { get; }
public BaseConflagrationPotion(PotionEffect effect) : base(0xF06, effect) => Hue = 0x489;
public override bool RequireFreeHand => false;
public override void Drink(Mobile from)
{
if (Core.AOS && (from.Paralyzed || from.Frozen || from.Spell?.IsCasting == true))
{
from.SendLocalizedMessage(1062725); // You can not use that potion while paralyzed.
return;
}
int delay = GetDelay(from);
if (delay > 0)
{
from.SendLocalizedMessage(1072529,
$"{delay}\t{(delay > 1 ? "seconds." : "second.")}"); // You cannot use that for another ~1_NUM~ ~2_TIMEUNITS~
return;
}
if (from.Target is ThrowTarget targ && targ.Potion == this)
return;
from.RevealingAction();
if (!m_Users.Contains(from))
m_Users.Add(from);
from.Target = new ThrowTarget(this);
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
public virtual void Explode(Mobile from, Point3D loc, Map map)
{
if (Deleted || map == null)
return;
Consume();
// Check if any other players are using this potion
for (int i = 0; i < m_Users.Count; i++)
if (m_Users[i].Target is ThrowTarget targ && targ.Potion == this)
Target.Cancel(from);
// Effects
Effects.PlaySound(loc, map, 0x20C);
for (int i = -2; i <= 2; i++)
for (int j = -2; j <= 2; j++)
public BaseConflagrationPotion(Serial serial) : base(serial)
{
Point3D p = new Point3D(loc.X + i, loc.Y + j, loc.Z);
if (map.CanFit(p, 12, true, false) && from.InLOS(p))
new InternalItem(from, p, map, MinDamage, MaxDamage);
}
}
private class ThrowTarget : Target
{
public ThrowTarget(BaseConflagrationPotion potion) : base(12, true, TargetFlags.None) => Potion = potion;
public BaseConflagrationPotion Potion { get; }
protected override void OnTarget(Mobile from, object targeted)
{
if (Potion.Deleted || Potion.Map == Map.Internal)
return;
if (!(targeted is IPoint3D p) || from.Map == null)
return;
// Add delay
AddDelay(from);
SpellHelper.GetSurfaceTop(ref p);
from.RevealingAction();
IEntity to;
if (p is Mobile mobile)
to = mobile;
else
to = new Entity(Serial.Zero, new Point3D(p), from.Map);
Effects.SendMovingEffect(from, to, 0xF0D, 7, 0, false, false, Potion.Hue);
Timer.DelayCall(TimeSpan.FromSeconds(1.5), Potion.Explode, from, new Point3D(p), from.Map);
}
}
public class InternalItem : Item
{
private DateTime m_End;
private int m_MaxDamage;
private int m_MinDamage;
private Timer m_Timer;
public InternalItem(Mobile from, Point3D loc, Map map, int min, int max) : base(0x398C)
{
Movable = false;
Light = LightType.Circle300;
MoveToWorld(loc, map);
From = from;
m_End = DateTime.UtcNow + TimeSpan.FromSeconds(10);
SetDamage(min, max);
m_Timer = new InternalTimer(this, m_End);
m_Timer.Start();
}
public InternalItem(Serial serial) : base(serial)
{
}
public Mobile From { get; private set; }
public override bool BlocksFit => true;
public override void OnAfterDelete()
{
base.OnAfterDelete();
m_Timer?.Stop();
}
public int GetDamage() => Utility.RandomMinMax(m_MinDamage, m_MaxDamage);
private void SetDamage(int min, int max)
{
/* new way to apply alchemy bonus according to Stratics' calculator.
this gives a mean to values 25, 50, 75 and 100. Stratics' calculator is outdated.
Those goals will give 2 to alchemy bonus. It's not really OSI-like but it's an approximation. */
m_MinDamage = min;
m_MaxDamage = max;
if (From == null)
return;
int alchemySkill = From.Skills.Alchemy.Fixed;
int alchemyBonus = alchemySkill / 125 + alchemySkill / 250;
m_MinDamage = Scale(From, m_MinDamage + alchemyBonus);
m_MaxDamage = Scale(From, m_MaxDamage + alchemyBonus);
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
writer.Write(From);
writer.Write(m_End);
writer.Write(m_MinDamage);
writer.Write(m_MaxDamage);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
From = reader.ReadMobile();
m_End = reader.ReadDateTime();
m_MinDamage = reader.ReadInt();
m_MaxDamage = reader.ReadInt();
m_Timer = new InternalTimer(this, m_End);
m_Timer.Start();
}
public override bool OnMoveOver(Mobile m)
{
if (Visible && From != null && (!Core.AOS || m != From) && SpellHelper.ValidIndirectTarget(From, m) &&
From.CanBeHarmful(m, false))
{
From.DoHarmful(m);
AOS.Damage(m, From, GetDamage(), 0, 100, 0, 0, 0);
m.PlaySound(0x208);
}
return true;
}
public abstract int MinDamage { get; }
public abstract int MaxDamage { get; }
private class InternalTimer : Timer
{
private readonly DateTime m_End;
private readonly InternalItem m_Item;
public override bool RequireFreeHand => false;
public InternalTimer(InternalItem item, DateTime end) : base(TimeSpan.Zero, TimeSpan.FromSeconds(1.0))
public override void Drink(Mobile from)
{
m_Item = item;
m_End = end;
Priority = TimerPriority.FiftyMS;
}
protected override void OnTick()
{
if (m_Item.Deleted)
return;
if (DateTime.UtcNow > m_End)
{
m_Item.Delete();
Stop();
return;
}
Mobile from = m_Item.From;
if (m_Item.Map == null || from == null)
return;
foreach (Mobile m in m_Item.GetMobilesInRange(0))
if (m.Z + 16 > m_Item.Z && m_Item.Z + 12 > m.Z && (!Core.AOS || m != from) &&
SpellHelper.ValidIndirectTarget(from, m) && from.CanBeHarmful(m, false))
if (Core.AOS && (from.Paralyzed || from.Frozen || from.Spell?.IsCasting == true))
{
from.DoHarmful(m);
from.SendLocalizedMessage(1062725); // You can not use that potion while paralyzed.
return;
}
AOS.Damage(m, from, m_Item.GetDamage(), 0, 100, 0, 0, 0);
m.PlaySound(0x208);
var delay = GetDelay(from);
if (delay > 0)
{
from.SendLocalizedMessage(
1072529,
$"{delay}\t{(delay > 1 ? "seconds." : "second.")}"
); // You cannot use that for another ~1_NUM~ ~2_TIMEUNITS~
return;
}
if (from.Target is ThrowTarget targ && targ.Potion == this)
return;
from.RevealingAction();
if (!m_Users.Contains(from))
m_Users.Add(from);
from.Target = new ThrowTarget(this);
}
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 virtual void Explode(Mobile from, Point3D loc, Map map)
{
if (Deleted || map == null)
return;
Consume();
// Check if any other players are using this potion
for (var i = 0; i < m_Users.Count; i++)
if (m_Users[i].Target is ThrowTarget targ && targ.Potion == this)
Target.Cancel(from);
// Effects
Effects.PlaySound(loc, map, 0x20C);
for (var i = -2; i <= 2; i++)
for (var j = -2; j <= 2; j++)
{
var p = new Point3D(loc.X + i, loc.Y + j, loc.Z);
if (map.CanFit(p, 12, true, false) && from.InLOS(p))
new InternalItem(from, p, map, MinDamage, MaxDamage);
}
}
public static void AddDelay(Mobile m)
{
m_Delay.TryGetValue(m, out var timer);
timer?.Stop();
m_Delay[m] = Timer.DelayCall(TimeSpan.FromSeconds(30), EndDelay, m);
}
public static int GetDelay(Mobile m)
{
if (m_Delay.TryGetValue(m, out var timer) && timer.Next > DateTime.UtcNow)
return (int)(timer.Next - DateTime.UtcNow).TotalSeconds;
return 0;
}
public static void EndDelay(Mobile m)
{
if (m_Delay.TryGetValue(m, out var timer))
{
timer.Stop();
m_Delay.Remove(m);
}
}
private class ThrowTarget : Target
{
public ThrowTarget(BaseConflagrationPotion potion) : base(12, true, TargetFlags.None) => Potion = potion;
public BaseConflagrationPotion Potion { get; }
protected override void OnTarget(Mobile from, object targeted)
{
if (Potion.Deleted || Potion.Map == Map.Internal)
return;
if (!(targeted is IPoint3D p) || from.Map == null)
return;
// Add delay
AddDelay(from);
SpellHelper.GetSurfaceTop(ref p);
from.RevealingAction();
IEntity to;
if (p is Mobile mobile)
to = mobile;
else
to = new Entity(Serial.Zero, new Point3D(p), from.Map);
Effects.SendMovingEffect(from, to, 0xF0D, 7, 0, false, false, Potion.Hue);
Timer.DelayCall(TimeSpan.FromSeconds(1.5), Potion.Explode, from, new Point3D(p), from.Map);
}
}
public class InternalItem : Item
{
private DateTime m_End;
private int m_MaxDamage;
private int m_MinDamage;
private Timer m_Timer;
public InternalItem(Mobile from, Point3D loc, Map map, int min, int max) : base(0x398C)
{
Movable = false;
Light = LightType.Circle300;
MoveToWorld(loc, map);
From = from;
m_End = DateTime.UtcNow + TimeSpan.FromSeconds(10);
SetDamage(min, max);
m_Timer = new InternalTimer(this, m_End);
m_Timer.Start();
}
public InternalItem(Serial serial) : base(serial)
{
}
public Mobile From { get; private set; }
public override bool BlocksFit => true;
public override void OnAfterDelete()
{
base.OnAfterDelete();
m_Timer?.Stop();
}
public int GetDamage() => Utility.RandomMinMax(m_MinDamage, m_MaxDamage);
private void SetDamage(int min, int max)
{
/* new way to apply alchemy bonus according to Stratics' calculator.
this gives a mean to values 25, 50, 75 and 100. Stratics' calculator is outdated.
Those goals will give 2 to alchemy bonus. It's not really OSI-like but it's an approximation. */
m_MinDamage = min;
m_MaxDamage = max;
if (From == null)
return;
var alchemySkill = From.Skills.Alchemy.Fixed;
var alchemyBonus = alchemySkill / 125 + alchemySkill / 250;
m_MinDamage = Scale(From, m_MinDamage + alchemyBonus);
m_MaxDamage = Scale(From, m_MaxDamage + alchemyBonus);
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
writer.Write(From);
writer.Write(m_End);
writer.Write(m_MinDamage);
writer.Write(m_MaxDamage);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
From = reader.ReadMobile();
m_End = reader.ReadDateTime();
m_MinDamage = reader.ReadInt();
m_MaxDamage = reader.ReadInt();
m_Timer = new InternalTimer(this, m_End);
m_Timer.Start();
}
public override bool OnMoveOver(Mobile m)
{
if (Visible && From != null && (!Core.AOS || m != From) && SpellHelper.ValidIndirectTarget(From, m) &&
From.CanBeHarmful(m, false))
{
From.DoHarmful(m);
AOS.Damage(m, From, GetDamage(), 0, 100, 0, 0, 0);
m.PlaySound(0x208);
}
return true;
}
private class InternalTimer : Timer
{
private readonly DateTime m_End;
private readonly InternalItem m_Item;
public InternalTimer(InternalItem item, DateTime end) : base(TimeSpan.Zero, TimeSpan.FromSeconds(1.0))
{
m_Item = item;
m_End = end;
Priority = TimerPriority.FiftyMS;
}
protected override void OnTick()
{
if (m_Item.Deleted)
return;
if (DateTime.UtcNow > m_End)
{
m_Item.Delete();
Stop();
return;
}
var from = m_Item.From;
if (m_Item.Map == null || from == null)
return;
foreach (var m in m_Item.GetMobilesInRange(0))
if (m.Z + 16 > m_Item.Z && m_Item.Z + 12 > m.Z && (!Core.AOS || m != from) &&
SpellHelper.ValidIndirectTarget(from, m) && from.CanBeHarmful(m, false))
{
from.DoHarmful(m);
AOS.Damage(m, from, m_Item.GetDamage(), 0, 100, 0, 0, 0);
m.PlaySound(0x208);
}
}
}
}
}
}
private static readonly Dictionary<Mobile, Timer> m_Delay = new Dictionary<Mobile, Timer>();
public static void AddDelay(Mobile m)
{
m_Delay.TryGetValue(m, out Timer timer);
timer?.Stop();
m_Delay[m] = Timer.DelayCall(TimeSpan.FromSeconds(30), EndDelay, m);
}
public static int GetDelay(Mobile m)
{
if (m_Delay.TryGetValue(m, out Timer timer) && timer.Next > DateTime.UtcNow)
return (int)(timer.Next - DateTime.UtcNow).TotalSeconds;
return 0;
}
public static void EndDelay(Mobile m)
{
if (m_Delay.TryGetValue(m, out Timer timer))
{
timer.Stop();
m_Delay.Remove(m);
}
}
}
}

View file

@ -1,33 +1,33 @@
namespace Server.Items
{
public class ConflagrationPotion : BaseConflagrationPotion
{
[Constructible]
public ConflagrationPotion() : base(PotionEffect.Conflagration)
public class ConflagrationPotion : BaseConflagrationPotion
{
[Constructible]
public ConflagrationPotion() : base(PotionEffect.Conflagration)
{
}
public ConflagrationPotion(Serial serial) : base(serial)
{
}
public override int MinDamage => 2;
public override int MaxDamage => 4;
public override int LabelNumber => 1072095; // a Conflagration potion
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 ConflagrationPotion(Serial serial) : base(serial)
{
}
public override int MinDamage => 2;
public override int MaxDamage => 4;
public override int LabelNumber => 1072095; // a Conflagration potion
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
}

View file

@ -1,33 +1,33 @@
namespace Server.Items
{
public class GreaterConflagrationPotion : BaseConflagrationPotion
{
[Constructible]
public GreaterConflagrationPotion() : base(PotionEffect.ConflagrationGreater)
public class GreaterConflagrationPotion : BaseConflagrationPotion
{
[Constructible]
public GreaterConflagrationPotion() : base(PotionEffect.ConflagrationGreater)
{
}
public GreaterConflagrationPotion(Serial serial) : base(serial)
{
}
public override int MinDamage => 4;
public override int MaxDamage => 8;
public override int LabelNumber => 1072098; // a Greater Conflagration potion
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 GreaterConflagrationPotion(Serial serial) : base(serial)
{
}
public override int MinDamage => 4;
public override int MaxDamage => 8;
public override int LabelNumber => 1072098; // a Greater Conflagration potion
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
}

View file

@ -7,159 +7,160 @@ using Server.Targeting;
namespace Server.Items
{
public abstract class BaseConfusionBlastPotion : BasePotion
{
private readonly List<Mobile> m_Users = new List<Mobile>();
public BaseConfusionBlastPotion(PotionEffect effect) : base(0xF06, effect) => Hue = 0x48D;
public BaseConfusionBlastPotion(Serial serial) : base(serial)
public abstract class BaseConfusionBlastPotion : BasePotion
{
}
private static readonly Dictionary<Mobile, Timer> m_Delay = new Dictionary<Mobile, Timer>();
private readonly List<Mobile> m_Users = new List<Mobile>();
public abstract int Radius { get; }
public BaseConfusionBlastPotion(PotionEffect effect) : base(0xF06, effect) => Hue = 0x48D;
public override bool RequireFreeHand => false;
public override void Drink(Mobile from)
{
if (Core.AOS && (from.Paralyzed || from.Frozen || from.Spell?.IsCasting == true))
{
from.SendLocalizedMessage(1062725); // You can not use that potion while paralyzed.
return;
}
int delay = GetDelay(from);
if (delay > 0)
{
from.SendLocalizedMessage(1072529,
$"{delay}\t{(delay > 1 ? "seconds." : "second.")}"); // You cannot use that for another ~1_NUM~ ~2_TIMEUNITS~
return;
}
if (from.Target is ThrowTarget targ && targ.Potion == this)
return;
from.RevealingAction();
if (!m_Users.Contains(from))
m_Users.Add(from);
from.Target = new ThrowTarget(this);
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
public virtual void Explode(Mobile from, Point3D loc, Map map)
{
if (Deleted || map == null)
return;
Consume();
// Check if any other players are using this potion
for (int i = 0; i < m_Users.Count; i++)
if (m_Users[i].Target is ThrowTarget targ && targ.Potion == this)
Target.Cancel(from);
// Effects
Effects.PlaySound(loc, map, 0x207);
Geometry.Circle2D(loc, map, Radius, BlastEffect, 270, 90);
Timer.DelayCall(TimeSpan.FromSeconds(0.3), CircleEffect2, loc, map);
foreach (Mobile mobile in map.GetMobilesInRange(loc, Radius))
if (mobile is BaseCreature mon)
public BaseConfusionBlastPotion(Serial serial) : base(serial)
{
if (mon.Controlled || mon.Summoned)
continue;
}
mon.Pacify(from, DateTime.UtcNow + TimeSpan.FromSeconds(5.0)); // TODO check
public abstract int Radius { get; }
public override bool RequireFreeHand => false;
public override void Drink(Mobile from)
{
if (Core.AOS && (from.Paralyzed || from.Frozen || from.Spell?.IsCasting == true))
{
from.SendLocalizedMessage(1062725); // You can not use that potion while paralyzed.
return;
}
var delay = GetDelay(from);
if (delay > 0)
{
from.SendLocalizedMessage(
1072529,
$"{delay}\t{(delay > 1 ? "seconds." : "second.")}"
); // You cannot use that for another ~1_NUM~ ~2_TIMEUNITS~
return;
}
if (from.Target is ThrowTarget targ && targ.Potion == this)
return;
from.RevealingAction();
if (!m_Users.Contains(from))
m_Users.Add(from);
from.Target = new ThrowTarget(this);
}
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 virtual void Explode(Mobile from, Point3D loc, Map map)
{
if (Deleted || map == null)
return;
Consume();
// Check if any other players are using this potion
for (var i = 0; i < m_Users.Count; i++)
if (m_Users[i].Target is ThrowTarget targ && targ.Potion == this)
Target.Cancel(from);
// Effects
Effects.PlaySound(loc, map, 0x207);
Geometry.Circle2D(loc, map, Radius, BlastEffect, 270, 90);
Timer.DelayCall(TimeSpan.FromSeconds(0.3), CircleEffect2, loc, map);
foreach (var mobile in map.GetMobilesInRange(loc, Radius))
if (mobile is BaseCreature mon)
{
if (mon.Controlled || mon.Summoned)
continue;
mon.Pacify(from, DateTime.UtcNow + TimeSpan.FromSeconds(5.0)); // TODO check
}
}
public virtual void BlastEffect(Point3D p, Map map)
{
if (map.CanFit(p, 12, true, false))
Effects.SendLocationEffect(p, map, 0x376A, 4, 9);
}
public void CircleEffect2(Point3D p, Map m)
{
Geometry.Circle2D(p, m, Radius, BlastEffect, 90, 270);
}
public static void AddDelay(Mobile m)
{
m_Delay.TryGetValue(m, out var timer);
timer?.Stop();
m_Delay[m] = Timer.DelayCall(TimeSpan.FromSeconds(60), EndDelay, m);
}
public static int GetDelay(Mobile m)
{
if (m_Delay.TryGetValue(m, out var timer) && timer.Next > DateTime.UtcNow)
return (int)(timer.Next - DateTime.UtcNow).TotalSeconds;
return 0;
}
public static void EndDelay(Mobile m)
{
if (m_Delay.TryGetValue(m, out var timer))
{
timer.Stop();
m_Delay.Remove(m);
}
}
private class ThrowTarget : Target
{
public ThrowTarget(BaseConfusionBlastPotion potion) : base(12, true, TargetFlags.None) => Potion = potion;
public BaseConfusionBlastPotion Potion { get; }
protected override void OnTarget(Mobile from, object targeted)
{
if (Potion.Deleted || Potion.Map == Map.Internal)
return;
if (!(targeted is IPoint3D p) || from.Map == null)
return;
// Add delay
AddDelay(from);
SpellHelper.GetSurfaceTop(ref p);
from.RevealingAction();
IEntity to;
if (p is Mobile mobile)
to = mobile;
else
to = new Entity(Serial.Zero, new Point3D(p), from.Map);
Effects.SendMovingEffect(from, to, 0xF0D, 7, 0, false, false, Potion.Hue);
Timer.DelayCall(TimeSpan.FromSeconds(1.0), Potion.Explode, from, new Point3D(p), from.Map);
}
}
}
private class ThrowTarget : Target
{
public ThrowTarget(BaseConfusionBlastPotion potion) : base(12, true, TargetFlags.None) => Potion = potion;
public BaseConfusionBlastPotion Potion { get; }
protected override void OnTarget(Mobile from, object targeted)
{
if (Potion.Deleted || Potion.Map == Map.Internal)
return;
if (!(targeted is IPoint3D p) || from.Map == null)
return;
// Add delay
AddDelay(from);
SpellHelper.GetSurfaceTop(ref p);
from.RevealingAction();
IEntity to;
if (p is Mobile mobile)
to = mobile;
else
to = new Entity(Serial.Zero, new Point3D(p), from.Map);
Effects.SendMovingEffect(from, to, 0xF0D, 7, 0, false, false, Potion.Hue);
Timer.DelayCall(TimeSpan.FromSeconds(1.0), Potion.Explode, from, new Point3D(p), from.Map);
}
}
public virtual void BlastEffect(Point3D p, Map map)
{
if (map.CanFit(p, 12, true, false))
Effects.SendLocationEffect(p, map, 0x376A, 4, 9);
}
public void CircleEffect2(Point3D p, Map m)
{
Geometry.Circle2D(p, m, Radius, BlastEffect, 90, 270);
}
private static readonly Dictionary<Mobile, Timer> m_Delay = new Dictionary<Mobile, Timer>();
public static void AddDelay(Mobile m)
{
m_Delay.TryGetValue(m, out Timer timer);
timer?.Stop();
m_Delay[m] = Timer.DelayCall(TimeSpan.FromSeconds(60), EndDelay, m);
}
public static int GetDelay(Mobile m)
{
if (m_Delay.TryGetValue(m, out Timer timer) && timer.Next > DateTime.UtcNow)
return (int)(timer.Next - DateTime.UtcNow).TotalSeconds;
return 0;
}
public static void EndDelay(Mobile m)
{
if (m_Delay.TryGetValue(m, out Timer timer))
{
timer.Stop();
m_Delay.Remove(m);
}
}
}
}

View file

@ -1,32 +1,32 @@
namespace Server.Items
{
public class ConfusionBlastPotion : BaseConfusionBlastPotion
{
[Constructible]
public ConfusionBlastPotion() : base(PotionEffect.ConfusionBlast)
public class ConfusionBlastPotion : BaseConfusionBlastPotion
{
[Constructible]
public ConfusionBlastPotion() : base(PotionEffect.ConfusionBlast)
{
}
public ConfusionBlastPotion(Serial serial) : base(serial)
{
}
public override int Radius => 5;
public override int LabelNumber => 1072105; // a Confusion Blast potion
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 ConfusionBlastPotion(Serial serial) : base(serial)
{
}
public override int Radius => 5;
public override int LabelNumber => 1072105; // a Confusion Blast potion
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
}

View file

@ -1,32 +1,32 @@
namespace Server.Items
{
public class GreaterConfusionBlastPotion : BaseConfusionBlastPotion
{
[Constructible]
public GreaterConfusionBlastPotion() : base(PotionEffect.ConfusionBlastGreater)
public class GreaterConfusionBlastPotion : BaseConfusionBlastPotion
{
[Constructible]
public GreaterConfusionBlastPotion() : base(PotionEffect.ConfusionBlastGreater)
{
}
public GreaterConfusionBlastPotion(Serial serial) : base(serial)
{
}
public override int Radius => 7;
public override int LabelNumber => 1072108; // a Greater Confusion Blast potion
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 GreaterConfusionBlastPotion(Serial serial) : base(serial)
{
}
public override int Radius => 7;
public override int LabelNumber => 1072108; // a Greater Confusion Blast potion
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
}

View file

@ -4,97 +4,97 @@ using Server.Spells.Necromancy;
namespace Server.Items
{
public class CureLevelInfo
{
public CureLevelInfo(Poison poison, double chance)
public class CureLevelInfo
{
Poison = poison;
Chance = chance;
}
public Poison Poison { get; }
public double Chance { get; }
}
public abstract class BaseCurePotion : BasePotion
{
public BaseCurePotion(PotionEffect effect) : base(0xF07, effect)
{
}
public BaseCurePotion(Serial serial) : base(serial)
{
}
public abstract CureLevelInfo[] LevelInfo { get; }
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
public void DoCure(Mobile from)
{
bool cure = false;
CureLevelInfo[] info = LevelInfo;
for (int i = 0; i < info.Length; ++i)
{
CureLevelInfo li = info[i];
if (li.Poison == from.Poison && Scale(from, li.Chance) > Utility.RandomDouble())
public CureLevelInfo(Poison poison, double chance)
{
cure = true;
break;
Poison = poison;
Chance = chance;
}
}
if (cure && from.CurePoison(from))
{
from.SendLocalizedMessage(500231); // You feel cured of poison!
public Poison Poison { get; }
from.FixedEffect(0x373A, 10, 15);
from.PlaySound(0x1E0);
}
else if (!cure)
{
from.SendLocalizedMessage(500232); // That potion was not strong enough to cure your ailment!
}
public double Chance { get; }
}
public override void Drink(Mobile from)
public abstract class BaseCurePotion : BasePotion
{
if (TransformationSpellHelper.UnderTransformation(from, typeof(VampiricEmbraceSpell)))
{
from.SendLocalizedMessage(1061652); // The garlic in the potion would surely kill you.
}
else if (from.Poisoned)
{
DoCure(from);
public BaseCurePotion(PotionEffect effect) : base(0xF07, effect)
{
}
PlayDrinkEffect(from);
public BaseCurePotion(Serial serial) : base(serial)
{
}
from.FixedParticles(0x373A, 10, 15, 5012, EffectLayer.Waist);
from.PlaySound(0x1E0);
public abstract CureLevelInfo[] LevelInfo { get; }
if (!DuelContext.IsFreeConsume(from))
Consume();
}
else
{
from.SendLocalizedMessage(1042000); // You are not poisoned.
}
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 void DoCure(Mobile from)
{
var cure = false;
var info = LevelInfo;
for (var i = 0; i < info.Length; ++i)
{
var li = info[i];
if (li.Poison == from.Poison && Scale(from, li.Chance) > Utility.RandomDouble())
{
cure = true;
break;
}
}
if (cure && from.CurePoison(from))
{
from.SendLocalizedMessage(500231); // You feel cured of poison!
from.FixedEffect(0x373A, 10, 15);
from.PlaySound(0x1E0);
}
else if (!cure)
{
from.SendLocalizedMessage(500232); // That potion was not strong enough to cure your ailment!
}
}
public override void Drink(Mobile from)
{
if (TransformationSpellHelper.UnderTransformation(from, typeof(VampiricEmbraceSpell)))
{
from.SendLocalizedMessage(1061652); // The garlic in the potion would surely kill you.
}
else if (from.Poisoned)
{
DoCure(from);
PlayDrinkEffect(from);
from.FixedParticles(0x373A, 10, 15, 5012, EffectLayer.Waist);
from.PlaySound(0x1E0);
if (!DuelContext.IsFreeConsume(from))
Consume();
}
else
{
from.SendLocalizedMessage(1042000); // You are not poisoned.
}
}
}
}
}
}

View file

@ -1,47 +1,47 @@
namespace Server.Items
{
public class CurePotion : BaseCurePotion
{
private static readonly CureLevelInfo[] m_OldLevelInfo =
public class CurePotion : BaseCurePotion
{
new CureLevelInfo(Poison.Lesser, 1.00), // 100% chance to cure lesser poison
new CureLevelInfo(Poison.Regular, 0.75), // 75% chance to cure regular poison
new CureLevelInfo(Poison.Greater, 0.50), // 50% chance to cure greater poison
new CureLevelInfo(Poison.Deadly, 0.15) // 15% chance to cure deadly poison
};
private static readonly CureLevelInfo[] m_OldLevelInfo =
{
new CureLevelInfo(Poison.Lesser, 1.00), // 100% chance to cure lesser poison
new CureLevelInfo(Poison.Regular, 0.75), // 75% chance to cure regular poison
new CureLevelInfo(Poison.Greater, 0.50), // 50% chance to cure greater poison
new CureLevelInfo(Poison.Deadly, 0.15) // 15% chance to cure deadly poison
};
private static readonly CureLevelInfo[] m_AosLevelInfo =
{
new CureLevelInfo(Poison.Lesser, 1.00),
new CureLevelInfo(Poison.Regular, 0.95),
new CureLevelInfo(Poison.Greater, 0.75),
new CureLevelInfo(Poison.Deadly, 0.50),
new CureLevelInfo(Poison.Lethal, 0.25)
};
private static readonly CureLevelInfo[] m_AosLevelInfo =
{
new CureLevelInfo(Poison.Lesser, 1.00),
new CureLevelInfo(Poison.Regular, 0.95),
new CureLevelInfo(Poison.Greater, 0.75),
new CureLevelInfo(Poison.Deadly, 0.50),
new CureLevelInfo(Poison.Lethal, 0.25)
};
[Constructible]
public CurePotion() : base(PotionEffect.Cure)
{
[Constructible]
public CurePotion() : base(PotionEffect.Cure)
{
}
public CurePotion(Serial serial) : base(serial)
{
}
public override CureLevelInfo[] LevelInfo => Core.AOS ? m_AosLevelInfo : m_OldLevelInfo;
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 CurePotion(Serial serial) : base(serial)
{
}
public override CureLevelInfo[] LevelInfo => Core.AOS ? m_AosLevelInfo : m_OldLevelInfo;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
}

View file

@ -1,48 +1,48 @@
namespace Server.Items
{
public class GreaterCurePotion : BaseCurePotion
{
private static readonly CureLevelInfo[] m_OldLevelInfo =
public class GreaterCurePotion : BaseCurePotion
{
new CureLevelInfo(Poison.Lesser, 1.00), // 100% chance to cure lesser poison
new CureLevelInfo(Poison.Regular, 1.00), // 100% chance to cure regular poison
new CureLevelInfo(Poison.Greater, 1.00), // 100% chance to cure greater poison
new CureLevelInfo(Poison.Deadly, 0.75), // 75% chance to cure deadly poison
new CureLevelInfo(Poison.Lethal, 0.25) // 25% chance to cure lethal poison
};
private static readonly CureLevelInfo[] m_OldLevelInfo =
{
new CureLevelInfo(Poison.Lesser, 1.00), // 100% chance to cure lesser poison
new CureLevelInfo(Poison.Regular, 1.00), // 100% chance to cure regular poison
new CureLevelInfo(Poison.Greater, 1.00), // 100% chance to cure greater poison
new CureLevelInfo(Poison.Deadly, 0.75), // 75% chance to cure deadly poison
new CureLevelInfo(Poison.Lethal, 0.25) // 25% chance to cure lethal poison
};
private static readonly CureLevelInfo[] m_AosLevelInfo =
{
new CureLevelInfo(Poison.Lesser, 1.00),
new CureLevelInfo(Poison.Regular, 1.00),
new CureLevelInfo(Poison.Greater, 1.00),
new CureLevelInfo(Poison.Deadly, 0.95),
new CureLevelInfo(Poison.Lethal, 0.75)
};
private static readonly CureLevelInfo[] m_AosLevelInfo =
{
new CureLevelInfo(Poison.Lesser, 1.00),
new CureLevelInfo(Poison.Regular, 1.00),
new CureLevelInfo(Poison.Greater, 1.00),
new CureLevelInfo(Poison.Deadly, 0.95),
new CureLevelInfo(Poison.Lethal, 0.75)
};
[Constructible]
public GreaterCurePotion() : base(PotionEffect.CureGreater)
{
[Constructible]
public GreaterCurePotion() : base(PotionEffect.CureGreater)
{
}
public GreaterCurePotion(Serial serial) : base(serial)
{
}
public override CureLevelInfo[] LevelInfo => Core.AOS ? m_AosLevelInfo : m_OldLevelInfo;
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 GreaterCurePotion(Serial serial) : base(serial)
{
}
public override CureLevelInfo[] LevelInfo => Core.AOS ? m_AosLevelInfo : m_OldLevelInfo;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
}

View file

@ -1,44 +1,44 @@
namespace Server.Items
{
public class LesserCurePotion : BaseCurePotion
{
private static readonly CureLevelInfo[] m_OldLevelInfo =
public class LesserCurePotion : BaseCurePotion
{
new CureLevelInfo(Poison.Lesser, 0.75), // 75% chance to cure lesser poison
new CureLevelInfo(Poison.Regular, 0.50), // 50% chance to cure regular poison
new CureLevelInfo(Poison.Greater, 0.15) // 15% chance to cure greater poison
};
private static readonly CureLevelInfo[] m_OldLevelInfo =
{
new CureLevelInfo(Poison.Lesser, 0.75), // 75% chance to cure lesser poison
new CureLevelInfo(Poison.Regular, 0.50), // 50% chance to cure regular poison
new CureLevelInfo(Poison.Greater, 0.15) // 15% chance to cure greater poison
};
private static readonly CureLevelInfo[] m_AosLevelInfo =
{
new CureLevelInfo(Poison.Lesser, 0.75),
new CureLevelInfo(Poison.Regular, 0.50),
new CureLevelInfo(Poison.Greater, 0.25)
};
private static readonly CureLevelInfo[] m_AosLevelInfo =
{
new CureLevelInfo(Poison.Lesser, 0.75),
new CureLevelInfo(Poison.Regular, 0.50),
new CureLevelInfo(Poison.Greater, 0.25)
};
[Constructible]
public LesserCurePotion() : base(PotionEffect.CureLesser)
{
[Constructible]
public LesserCurePotion() : base(PotionEffect.CureLesser)
{
}
public LesserCurePotion(Serial serial) : base(serial)
{
}
public override CureLevelInfo[] LevelInfo => Core.AOS ? m_AosLevelInfo : m_OldLevelInfo;
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 LesserCurePotion(Serial serial) : base(serial)
{
}
public override CureLevelInfo[] LevelInfo => Core.AOS ? m_AosLevelInfo : m_OldLevelInfo;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
}

View file

@ -1,33 +1,33 @@
namespace Server.Items
{
public class DarkglowPotion : BasePoisonPotion
{
[Constructible]
public DarkglowPotion() : base(PotionEffect.Darkglow) => Hue = 0x96;
public DarkglowPotion(Serial serial) : base(serial)
public class DarkglowPotion : BasePoisonPotion
{
[Constructible]
public DarkglowPotion() : base(PotionEffect.Darkglow) => Hue = 0x96;
public DarkglowPotion(Serial serial) : base(serial)
{
}
public override Poison Poison => Poison.Greater; /* MUST be restored when prerequisites are done */
public override double MinPoisoningSkill => 95.0;
public override double MaxPoisoningSkill => 100.0;
public override int LabelNumber => 1072849; // Darkglow Poison
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 Poison Poison => Poison.Greater; /* MUST be restored when prerequisites are done */
public override double MinPoisoningSkill => 95.0;
public override double MaxPoisoningSkill => 100.0;
public override int LabelNumber => 1072849; // Darkglow Poison
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
}

View file

@ -7,257 +7,268 @@ using Server.Targeting;
namespace Server.Items
{
public abstract class BaseExplosionPotion : BasePotion
{
private const int ExplosionRange = 2; // How long is the blast radius?
private static readonly bool LeveledExplosion = false; // Should explosion potions explode other nearby potions?
private static readonly bool InstantExplosion = false; // Should explosion potions explode on impact?
private static readonly bool RelativeLocation = false; // Is the explosion target location relative for mobiles?
private Timer m_Timer;
public BaseExplosionPotion(PotionEffect effect) : base(0xF0D, effect)
public abstract class BaseExplosionPotion : BasePotion
{
}
private const int ExplosionRange = 2; // How long is the blast radius?
public BaseExplosionPotion(Serial serial) : base(serial)
{
}
private static readonly bool LeveledExplosion = false; // Should explosion potions explode other nearby potions?
private static readonly bool InstantExplosion = false; // Should explosion potions explode on impact?
private static readonly bool RelativeLocation = false; // Is the explosion target location relative for mobiles?
public abstract int MinDamage { get; }
public abstract int MaxDamage { get; }
private Timer m_Timer;
public override bool RequireFreeHand => false;
public List<Mobile> Users { get; private set; }
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
public virtual IEntity FindParent(Mobile from)
{
if (HeldBy?.Holding == this)
return HeldBy;
if (RootParent != null)
return RootParent;
if (Map == Map.Internal)
return from;
return this;
}
public override void Drink(Mobile from)
{
if (Core.AOS && (from.Paralyzed || from.Frozen || from.Spell?.IsCasting == true))
{
from.SendLocalizedMessage(1062725); // You can not use a purple potion while paralyzed.
return;
}
ThrowTarget targ = from.Target as ThrowTarget;
Stackable = false; // Scavenged explosion potions won't stack with those ones in backpack, and still will explode.
if (targ?.Potion == this)
return;
from.RevealingAction();
Users ??= new List<Mobile>();
if (!Users.Contains(from))
Users.Add(from);
from.Target = new ThrowTarget(this);
if (m_Timer == null)
{
from.SendLocalizedMessage(500236); // You should throw it now!
int timer = 3;
if (Core.ML)
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(1.0), TimeSpan.FromSeconds(1.25), 5,
() => Detonate_OnTick(from, timer--)); // 3.6 seconds explosion delay
else
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(0.75), TimeSpan.FromSeconds(1.0), 4,
() => Detonate_OnTick(from, timer--)); // 2.6 seconds explosion delay
}
}
private void Detonate_OnTick(Mobile from, int timer)
{
if (Deleted)
return;
IEntity parent = FindParent(from);
if (timer == 0)
{
Point3D loc;
Map map;
if (parent is Item item)
public BaseExplosionPotion(PotionEffect effect) : base(0xF0D, effect)
{
loc = item.GetWorldLocation();
map = item.Map;
}
else if (parent is Mobile m)
{
loc = m.Location;
map = m.Map;
}
else
{
return;
}
Explode(from, true, loc, map);
m_Timer = null;
}
else
{
if (parent is Item item)
item.PublicOverheadMessage(MessageType.Regular, 0x22, false, timer.ToString());
else if (parent is Mobile mobile)
mobile.PublicOverheadMessage(MessageType.Regular, 0x22, false, timer.ToString());
}
}
private void Reposition_OnTick(Mobile from, Point3D loc, Map map)
{
if (Deleted)
return;
if (InstantExplosion)
Explode(from, true, loc, map);
else
MoveToWorld(loc, map);
}
public void Explode(Mobile from, bool direct, Point3D loc, Map map)
{
if (Deleted)
return;
Consume();
for (int i = 0; Users != null && i < Users.Count; ++i)
{
Mobile m = Users[i];
if (m.Target is ThrowTarget targ && targ.Potion == this)
Target.Cancel(m);
}
if (map == null)
return;
Effects.PlaySound(loc, map, 0x307);
Effects.SendLocationEffect(loc, map, 0x36B0, 9, 10, 0, 0);
int alchemyBonus = 0;
if (direct)
alchemyBonus = (int)(from.Skills.Alchemy.Value / (Core.AOS ? 5 : 10));
IPooledEnumerable<IEntity> eable = map.GetObjectsInRange(loc, ExplosionRange, LeveledExplosion);
int toDamage = 0;
List<IEntity> toExplode = eable.Where(o =>
{
if (!(o is Mobile mobile) || (from != null &&
(!SpellHelper.ValidIndirectTarget(from, mobile) || !from.CanBeHarmful(mobile, false))))
return o is BaseExplosionPotion && o != this;
++toDamage;
return true;
}).ToList();
eable.Free();
int min = Scale(from, MinDamage);
int max = Scale(from, MaxDamage);
for (int i = 0; i < toExplode.Count; ++i)
{
IEntity o = toExplode[i];
if (o is Mobile m)
public BaseExplosionPotion(Serial serial) : base(serial)
{
from?.DoHarmful(m);
int damage = Utility.RandomMinMax(min, max);
damage += alchemyBonus;
if (!Core.AOS && damage > 40)
damage = 40;
else if (Core.AOS && toDamage > 2)
damage /= toDamage - 1;
AOS.Damage(m, from, damage, 0, 100, 0, 0, 0);
}
else if (o is BaseExplosionPotion pot)
{
pot.Explode(from, false, pot.GetWorldLocation(), pot.Map);
}
}
}
private class ThrowTarget : Target
{
public ThrowTarget(BaseExplosionPotion potion) : base(12, true, TargetFlags.None) => Potion = potion;
public BaseExplosionPotion Potion { get; }
protected override void OnTarget(Mobile from, object targeted)
{
if (Potion.Deleted || Potion.Map == Map.Internal)
return;
if (!(targeted is IPoint3D p))
return;
Map map = from.Map;
if (map == null)
return;
SpellHelper.GetSurfaceTop(ref p);
from.RevealingAction();
IEntity to = new Entity(Serial.Zero, new Point3D(p), map);
if (p is Mobile m)
{
if (!RelativeLocation) // explosion location = current mob location.
p = m.Location;
else
to = m;
}
Effects.SendMovingEffect(from, to, Potion.ItemID, 7, 0, false, false, Potion.Hue);
public abstract int MinDamage { get; }
public abstract int MaxDamage { get; }
if (Potion.Amount > 1) Mobile.LiftItemDupe(Potion, 1);
public override bool RequireFreeHand => false;
Potion.Internalize();
Timer.DelayCall(TimeSpan.FromSeconds(1.0), Potion.Reposition_OnTick, from, new Point3D(p), map);
}
public List<Mobile> Users { get; private set; }
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 virtual IEntity FindParent(Mobile from)
{
if (HeldBy?.Holding == this)
return HeldBy;
if (RootParent != null)
return RootParent;
if (Map == Map.Internal)
return from;
return this;
}
public override void Drink(Mobile from)
{
if (Core.AOS && (from.Paralyzed || from.Frozen || from.Spell?.IsCasting == true))
{
from.SendLocalizedMessage(1062725); // You can not use a purple potion while paralyzed.
return;
}
var targ = from.Target as ThrowTarget;
Stackable = false; // Scavenged explosion potions won't stack with those ones in backpack, and still will explode.
if (targ?.Potion == this)
return;
from.RevealingAction();
Users ??= new List<Mobile>();
if (!Users.Contains(from))
Users.Add(from);
from.Target = new ThrowTarget(this);
if (m_Timer == null)
{
from.SendLocalizedMessage(500236); // You should throw it now!
var timer = 3;
if (Core.ML)
m_Timer = Timer.DelayCall(
TimeSpan.FromSeconds(1.0),
TimeSpan.FromSeconds(1.25),
5,
() => Detonate_OnTick(from, timer--)
); // 3.6 seconds explosion delay
else
m_Timer = Timer.DelayCall(
TimeSpan.FromSeconds(0.75),
TimeSpan.FromSeconds(1.0),
4,
() => Detonate_OnTick(from, timer--)
); // 2.6 seconds explosion delay
}
}
private void Detonate_OnTick(Mobile from, int timer)
{
if (Deleted)
return;
var parent = FindParent(from);
if (timer == 0)
{
Point3D loc;
Map map;
if (parent is Item item)
{
loc = item.GetWorldLocation();
map = item.Map;
}
else if (parent is Mobile m)
{
loc = m.Location;
map = m.Map;
}
else
{
return;
}
Explode(from, true, loc, map);
m_Timer = null;
}
else
{
if (parent is Item item)
item.PublicOverheadMessage(MessageType.Regular, 0x22, false, timer.ToString());
else if (parent is Mobile mobile)
mobile.PublicOverheadMessage(MessageType.Regular, 0x22, false, timer.ToString());
}
}
private void Reposition_OnTick(Mobile from, Point3D loc, Map map)
{
if (Deleted)
return;
if (InstantExplosion)
Explode(from, true, loc, map);
else
MoveToWorld(loc, map);
}
public void Explode(Mobile from, bool direct, Point3D loc, Map map)
{
if (Deleted)
return;
Consume();
for (var i = 0; Users != null && i < Users.Count; ++i)
{
var m = Users[i];
if (m.Target is ThrowTarget targ && targ.Potion == this)
Target.Cancel(m);
}
if (map == null)
return;
Effects.PlaySound(loc, map, 0x307);
Effects.SendLocationEffect(loc, map, 0x36B0, 9, 10, 0, 0);
var alchemyBonus = 0;
if (direct)
alchemyBonus = (int)(from.Skills.Alchemy.Value / (Core.AOS ? 5 : 10));
var eable = map.GetObjectsInRange(loc, ExplosionRange, LeveledExplosion);
var toDamage = 0;
var toExplode = eable.Where(
o =>
{
if (!(o is Mobile mobile) || @from != null &&
(!SpellHelper.ValidIndirectTarget(@from, mobile) || !@from.CanBeHarmful(mobile, false)))
return o is BaseExplosionPotion && o != this;
++toDamage;
return true;
}
)
.ToList();
eable.Free();
var min = Scale(from, MinDamage);
var max = Scale(from, MaxDamage);
for (var i = 0; i < toExplode.Count; ++i)
{
var o = toExplode[i];
if (o is Mobile m)
{
from?.DoHarmful(m);
var damage = Utility.RandomMinMax(min, max);
damage += alchemyBonus;
if (!Core.AOS && damage > 40)
damage = 40;
else if (Core.AOS && toDamage > 2)
damage /= toDamage - 1;
AOS.Damage(m, from, damage, 0, 100, 0, 0, 0);
}
else if (o is BaseExplosionPotion pot)
{
pot.Explode(from, false, pot.GetWorldLocation(), pot.Map);
}
}
}
private class ThrowTarget : Target
{
public ThrowTarget(BaseExplosionPotion potion) : base(12, true, TargetFlags.None) => Potion = potion;
public BaseExplosionPotion Potion { get; }
protected override void OnTarget(Mobile from, object targeted)
{
if (Potion.Deleted || Potion.Map == Map.Internal)
return;
if (!(targeted is IPoint3D p))
return;
var map = from.Map;
if (map == null)
return;
SpellHelper.GetSurfaceTop(ref p);
from.RevealingAction();
IEntity to = new Entity(Serial.Zero, new Point3D(p), map);
if (p is Mobile m)
{
if (!RelativeLocation) // explosion location = current mob location.
p = m.Location;
else
to = m;
}
Effects.SendMovingEffect(from, to, Potion.ItemID, 7, 0, false, false, Potion.Hue);
if (Potion.Amount > 1) Mobile.LiftItemDupe(Potion, 1);
Potion.Internalize();
Timer.DelayCall(TimeSpan.FromSeconds(1.0), Potion.Reposition_OnTick, from, new Point3D(p), map);
}
}
}
}
}

View file

@ -1,31 +1,31 @@
namespace Server.Items
{
public class ExplosionPotion : BaseExplosionPotion
{
[Constructible]
public ExplosionPotion() : base(PotionEffect.Explosion)
public class ExplosionPotion : BaseExplosionPotion
{
[Constructible]
public ExplosionPotion() : base(PotionEffect.Explosion)
{
}
public ExplosionPotion(Serial serial) : base(serial)
{
}
public override int MinDamage => 10;
public override int MaxDamage => 20;
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 ExplosionPotion(Serial serial) : base(serial)
{
}
public override int MinDamage => 10;
public override int MaxDamage => 20;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
}

View file

@ -1,31 +1,31 @@
namespace Server.Items
{
public class GreaterExplosionPotion : BaseExplosionPotion
{
[Constructible]
public GreaterExplosionPotion() : base(PotionEffect.ExplosionGreater)
public class GreaterExplosionPotion : BaseExplosionPotion
{
[Constructible]
public GreaterExplosionPotion() : base(PotionEffect.ExplosionGreater)
{
}
public GreaterExplosionPotion(Serial serial) : base(serial)
{
}
public override int MinDamage => Core.AOS ? 20 : 15;
public override int MaxDamage => Core.AOS ? 40 : 30;
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 GreaterExplosionPotion(Serial serial) : base(serial)
{
}
public override int MinDamage => Core.AOS ? 20 : 15;
public override int MaxDamage => Core.AOS ? 40 : 30;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
}

View file

@ -1,31 +1,31 @@
namespace Server.Items
{
public class LesserExplosionPotion : BaseExplosionPotion
{
[Constructible]
public LesserExplosionPotion() : base(PotionEffect.ExplosionLesser)
public class LesserExplosionPotion : BaseExplosionPotion
{
[Constructible]
public LesserExplosionPotion() : base(PotionEffect.ExplosionLesser)
{
}
public LesserExplosionPotion(Serial serial) : base(serial)
{
}
public override int MinDamage => 5;
public override int MaxDamage => 10;
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 LesserExplosionPotion(Serial serial) : base(serial)
{
}
public override int MinDamage => 5;
public override int MaxDamage => 10;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
}

View file

@ -4,76 +4,83 @@ using Server.Network;
namespace Server.Items
{
public abstract class BaseHealPotion : BasePotion
{
public BaseHealPotion(PotionEffect effect) : base(0xF0C, effect)
public abstract class BaseHealPotion : BasePotion
{
}
public BaseHealPotion(Serial serial) : base(serial)
{
}
public abstract int MinHeal { get; }
public abstract int MaxHeal { get; }
public abstract double Delay { get; }
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
public void DoHeal(Mobile from)
{
int min = Scale(from, MinHeal);
int max = Scale(from, MaxHeal);
from.Heal(Utility.RandomMinMax(min, max));
}
public override void Drink(Mobile from)
{
if (from.Hits < from.HitsMax)
{
if (from.Poisoned || MortalStrike.IsWounded(from))
public BaseHealPotion(PotionEffect effect) : base(0xF0C, effect)
{
from.LocalOverheadMessage(MessageType.Regular, 0x22,
1005000); // You can not heal yourself in your current state.
}
else
public BaseHealPotion(Serial serial) : base(serial)
{
if (from.BeginAction<BaseHealPotion>())
{
DoHeal(from);
PlayDrinkEffect(from);
if (!DuelContext.IsFreeConsume(from))
Consume();
Timer.DelayCall(TimeSpan.FromSeconds(Delay), from.EndAction<BaseHealPotion>);
}
else
{
from.LocalOverheadMessage(MessageType.Regular, 0x22,
500235); // You must wait 10 seconds before using another healing potion.
}
}
}
else
{
from.SendLocalizedMessage(
1049547); // You decide against drinking this potion, as you are already at full health.
}
public abstract int MinHeal { get; }
public abstract int MaxHeal { get; }
public abstract double Delay { get; }
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 void DoHeal(Mobile from)
{
var min = Scale(from, MinHeal);
var max = Scale(from, MaxHeal);
from.Heal(Utility.RandomMinMax(min, max));
}
public override void Drink(Mobile from)
{
if (from.Hits < from.HitsMax)
{
if (from.Poisoned || MortalStrike.IsWounded(from))
{
from.LocalOverheadMessage(
MessageType.Regular,
0x22,
1005000
); // You can not heal yourself in your current state.
}
else
{
if (from.BeginAction<BaseHealPotion>())
{
DoHeal(from);
PlayDrinkEffect(from);
if (!DuelContext.IsFreeConsume(from))
Consume();
Timer.DelayCall(TimeSpan.FromSeconds(Delay), from.EndAction<BaseHealPotion>);
}
else
{
from.LocalOverheadMessage(
MessageType.Regular,
0x22,
500235
); // You must wait 10 seconds before using another healing potion.
}
}
}
else
{
from.SendLocalizedMessage(
1049547
); // You decide against drinking this potion, as you are already at full health.
}
}
}
}
}
}

View file

@ -1,32 +1,32 @@
namespace Server.Items
{
public class GreaterHealPotion : BaseHealPotion
{
[Constructible]
public GreaterHealPotion() : base(PotionEffect.HealGreater)
public class GreaterHealPotion : BaseHealPotion
{
[Constructible]
public GreaterHealPotion() : base(PotionEffect.HealGreater)
{
}
public GreaterHealPotion(Serial serial) : base(serial)
{
}
public override int MinHeal => Core.AOS ? 20 : 9;
public override int MaxHeal => Core.AOS ? 25 : 30;
public override double Delay => 10.0;
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 GreaterHealPotion(Serial serial) : base(serial)
{
}
public override int MinHeal => Core.AOS ? 20 : 9;
public override int MaxHeal => Core.AOS ? 25 : 30;
public override double Delay => 10.0;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
}

View file

@ -1,32 +1,32 @@
namespace Server.Items
{
public class HealPotion : BaseHealPotion
{
[Constructible]
public HealPotion() : base(PotionEffect.Heal)
public class HealPotion : BaseHealPotion
{
[Constructible]
public HealPotion() : base(PotionEffect.Heal)
{
}
public HealPotion(Serial serial) : base(serial)
{
}
public override int MinHeal => Core.AOS ? 13 : 6;
public override int MaxHeal => Core.AOS ? 16 : 20;
public override double Delay => Core.AOS ? 8.0 : 10.0;
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 HealPotion(Serial serial) : base(serial)
{
}
public override int MinHeal => Core.AOS ? 13 : 6;
public override int MaxHeal => Core.AOS ? 16 : 20;
public override double Delay => Core.AOS ? 8.0 : 10.0;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
}

View file

@ -1,32 +1,32 @@
namespace Server.Items
{
public class LesserHealPotion : BaseHealPotion
{
[Constructible]
public LesserHealPotion() : base(PotionEffect.HealLesser)
public class LesserHealPotion : BaseHealPotion
{
[Constructible]
public LesserHealPotion() : base(PotionEffect.HealLesser)
{
}
public LesserHealPotion(Serial serial) : base(serial)
{
}
public override int MinHeal => Core.AOS ? 6 : 3;
public override int MaxHeal => Core.AOS ? 8 : 10;
public override double Delay => Core.AOS ? 3.0 : 10.0;
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 LesserHealPotion(Serial serial) : base(serial)
{
}
public override int MinHeal => Core.AOS ? 6 : 3;
public override int MaxHeal => Core.AOS ? 8 : 10;
public override double Delay => Core.AOS ? 3.0 : 10.0;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
}

View file

@ -3,85 +3,90 @@ using System.Collections.Generic;
namespace Server.Items
{
public class InvisibilityPotion : BasePotion
{
private static readonly Dictionary<Mobile, Timer> m_Table = new Dictionary<Mobile, Timer>();
[Constructible]
public InvisibilityPotion() : base(0xF0A, PotionEffect.Invisibility) => Hue = 0x48D;
public InvisibilityPotion(Serial serial) : base(serial)
public class InvisibilityPotion : BasePotion
{
private static readonly Dictionary<Mobile, Timer> m_Table = new Dictionary<Mobile, Timer>();
[Constructible]
public InvisibilityPotion() : base(0xF0A, PotionEffect.Invisibility) => Hue = 0x48D;
public InvisibilityPotion(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1072941; // Potion of Invisibility
public override void Drink(Mobile from)
{
if (from.Hidden)
{
from.SendLocalizedMessage(1073185); // You are already unseen.
return;
}
if (HasTimer(from))
{
from.SendLocalizedMessage(1073186); // An invisibility potion is already taking effect on your person.
return;
}
Consume();
m_Table[from] = Timer.DelayCall(TimeSpan.FromSeconds(2), Hide, from);
PlayDrinkEffect(from);
}
public static void Hide(Mobile m)
{
Effects.SendLocationParticles(
EffectItem.Create(new Point3D(m.X, m.Y, m.Z + 16), m.Map, EffectItem.DefaultDuration),
0x376A,
10,
15,
5045
);
m.PlaySound(0x3C4);
m.Hidden = true;
BuffInfo.RemoveBuff(m, BuffIcon.HidingAndOrStealth);
BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Invisibility, 1075825)); // Invisibility/Invisible
RemoveTimer(m);
Timer.DelayCall(TimeSpan.FromSeconds(30), EndHide, m);
}
public static void EndHide(Mobile m)
{
m.RevealingAction();
RemoveTimer(m);
}
public static bool HasTimer(Mobile m) => m_Table.ContainsKey(m);
public static void RemoveTimer(Mobile m, bool interrupted = false)
{
if (m_Table.TryGetValue(m, out var timer))
{
if (interrupted)
m.SendLocalizedMessage(1073187); // The invisibility effect is interrupted.
timer.Stop();
m_Table.Remove(m);
}
}
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 int LabelNumber => 1072941; // Potion of Invisibility
public override void Drink(Mobile from)
{
if (from.Hidden)
{
from.SendLocalizedMessage(1073185); // You are already unseen.
return;
}
if (HasTimer(from))
{
from.SendLocalizedMessage(1073186); // An invisibility potion is already taking effect on your person.
return;
}
Consume();
m_Table[from] = Timer.DelayCall(TimeSpan.FromSeconds(2), Hide, from);
PlayDrinkEffect(from);
}
public static void Hide(Mobile m)
{
Effects.SendLocationParticles(
EffectItem.Create(new Point3D(m.X, m.Y, m.Z + 16), m.Map, EffectItem.DefaultDuration), 0x376A, 10, 15, 5045);
m.PlaySound(0x3C4);
m.Hidden = true;
BuffInfo.RemoveBuff(m, BuffIcon.HidingAndOrStealth);
BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Invisibility, 1075825)); // Invisibility/Invisible
RemoveTimer(m);
Timer.DelayCall(TimeSpan.FromSeconds(30), EndHide, m);
}
public static void EndHide(Mobile m)
{
m.RevealingAction();
RemoveTimer(m);
}
public static bool HasTimer(Mobile m) => m_Table.ContainsKey(m);
public static void RemoveTimer(Mobile m, bool interrupted = false)
{
if (m_Table.TryGetValue(m, out Timer timer))
{
if (interrupted)
m.SendLocalizedMessage(1073187); // The invisibility effect is interrupted.
timer.Stop();
m_Table.Remove(m);
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -2,50 +2,50 @@ using Server.Engines.ConPVP;
namespace Server.Items
{
public class NightSightPotion : BasePotion
{
[Constructible]
public NightSightPotion() : base(0xF06, PotionEffect.Nightsight)
public class NightSightPotion : BasePotion
{
[Constructible]
public NightSightPotion() : base(0xF06, PotionEffect.Nightsight)
{
}
public NightSightPotion(Serial serial) : base(serial)
{
}
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 void Drink(Mobile from)
{
if (from.BeginAction<LightCycle>())
{
new LightCycle.NightSightTimer(from).Start();
from.LightLevel = LightCycle.DungeonLevel / 2;
from.FixedParticles(0x376A, 9, 32, 5007, EffectLayer.Waist);
from.PlaySound(0x1E3);
PlayDrinkEffect(from);
if (!DuelContext.IsFreeConsume(from))
Consume();
}
else
{
from.SendMessage("You already have nightsight.");
}
}
}
public NightSightPotion(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
public override void Drink(Mobile from)
{
if (from.BeginAction<LightCycle>())
{
new LightCycle.NightSightTimer(from).Start();
from.LightLevel = LightCycle.DungeonLevel / 2;
from.FixedParticles(0x376A, 9, 32, 5007, EffectLayer.Waist);
from.PlaySound(0x1E3);
PlayDrinkEffect(from);
if (!DuelContext.IsFreeConsume(from))
Consume();
}
else
{
from.SendMessage("You already have nightsight.");
}
}
}
}
}

View file

@ -1,34 +1,34 @@
namespace Server.Items
{
public class ParasiticPotion : BasePoisonPotion
{
[Constructible]
public ParasiticPotion() : base(PotionEffect.Parasitic) => Hue = 0x17C;
public ParasiticPotion(Serial serial) : base(serial)
public class ParasiticPotion : BasePoisonPotion
{
[Constructible]
public ParasiticPotion() : base(PotionEffect.Parasitic) => Hue = 0x17C;
public ParasiticPotion(Serial serial) : base(serial)
{
}
/* public override Poison Poison => Poison.Darkglow; MUST be restored when prerequisites are done */
public override Poison Poison => Poison.Greater;
public override double MinPoisoningSkill => 95.0;
public override double MaxPoisoningSkill => 100.0;
public override int LabelNumber => 1072848; // Parasitic Poison
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 Poison Poison => Poison.Darkglow; MUST be restored when prerequisites are done */
public override Poison Poison => Poison.Greater;
public override double MinPoisoningSkill => 95.0;
public override double MaxPoisoningSkill => 100.0;
public override int LabelNumber => 1072848; // Parasitic Poison
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
}

View file

@ -2,48 +2,48 @@ using Server.Engines.ConPVP;
namespace Server.Items
{
public abstract class BasePoisonPotion : BasePotion
{
public BasePoisonPotion(PotionEffect effect) : base(0xF0A, effect)
public abstract class BasePoisonPotion : BasePotion
{
public BasePoisonPotion(PotionEffect effect) : base(0xF0A, effect)
{
}
public BasePoisonPotion(Serial serial) : base(serial)
{
}
public abstract Poison Poison { get; }
public abstract double MinPoisoningSkill { get; }
public abstract double MaxPoisoningSkill { get; }
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 void DoPoison(Mobile from)
{
from.ApplyPoison(from, Poison);
}
public override void Drink(Mobile from)
{
DoPoison(from);
PlayDrinkEffect(from);
if (!DuelContext.IsFreeConsume(from))
Consume();
}
}
public BasePoisonPotion(Serial serial) : base(serial)
{
}
public abstract Poison Poison { get; }
public abstract double MinPoisoningSkill { get; }
public abstract double MaxPoisoningSkill { get; }
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
public void DoPoison(Mobile from)
{
from.ApplyPoison(from, Poison);
}
public override void Drink(Mobile from)
{
DoPoison(from);
PlayDrinkEffect(from);
if (!DuelContext.IsFreeConsume(from))
Consume();
}
}
}
}

View file

@ -1,33 +1,33 @@
namespace Server.Items
{
public class DeadlyPoisonPotion : BasePoisonPotion
{
[Constructible]
public DeadlyPoisonPotion() : base(PotionEffect.PoisonDeadly)
public class DeadlyPoisonPotion : BasePoisonPotion
{
[Constructible]
public DeadlyPoisonPotion() : base(PotionEffect.PoisonDeadly)
{
}
public DeadlyPoisonPotion(Serial serial) : base(serial)
{
}
public override Poison Poison => Poison.Deadly;
public override double MinPoisoningSkill => 95.0;
public override double MaxPoisoningSkill => 100.0;
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 DeadlyPoisonPotion(Serial serial) : base(serial)
{
}
public override Poison Poison => Poison.Deadly;
public override double MinPoisoningSkill => 95.0;
public override double MaxPoisoningSkill => 100.0;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
}

View file

@ -1,33 +1,33 @@
namespace Server.Items
{
public class GreaterPoisonPotion : BasePoisonPotion
{
[Constructible]
public GreaterPoisonPotion() : base(PotionEffect.PoisonGreater)
public class GreaterPoisonPotion : BasePoisonPotion
{
[Constructible]
public GreaterPoisonPotion() : base(PotionEffect.PoisonGreater)
{
}
public GreaterPoisonPotion(Serial serial) : base(serial)
{
}
public override Poison Poison => Poison.Greater;
public override double MinPoisoningSkill => 60.0;
public override double MaxPoisoningSkill => 100.0;
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 GreaterPoisonPotion(Serial serial) : base(serial)
{
}
public override Poison Poison => Poison.Greater;
public override double MinPoisoningSkill => 60.0;
public override double MaxPoisoningSkill => 100.0;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
}

View file

@ -1,33 +1,33 @@
namespace Server.Items
{
public class LesserPoisonPotion : BasePoisonPotion
{
[Constructible]
public LesserPoisonPotion() : base(PotionEffect.PoisonLesser)
public class LesserPoisonPotion : BasePoisonPotion
{
[Constructible]
public LesserPoisonPotion() : base(PotionEffect.PoisonLesser)
{
}
public LesserPoisonPotion(Serial serial) : base(serial)
{
}
public override Poison Poison => Poison.Lesser;
public override double MinPoisoningSkill => 0.0;
public override double MaxPoisoningSkill => 60.0;
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 LesserPoisonPotion(Serial serial) : base(serial)
{
}
public override Poison Poison => Poison.Lesser;
public override double MinPoisoningSkill => 0.0;
public override double MaxPoisoningSkill => 60.0;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
}

View file

@ -1,33 +1,33 @@
namespace Server.Items
{
public class PoisonPotion : BasePoisonPotion
{
[Constructible]
public PoisonPotion() : base(PotionEffect.Poison)
public class PoisonPotion : BasePoisonPotion
{
[Constructible]
public PoisonPotion() : base(PotionEffect.Poison)
{
}
public PoisonPotion(Serial serial) : base(serial)
{
}
public override Poison Poison => Poison.Regular;
public override double MinPoisoningSkill => 30.0;
public override double MaxPoisoningSkill => 70.0;
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 PoisonPotion(Serial serial) : base(serial)
{
}
public override Poison Poison => Poison.Regular;
public override double MinPoisoningSkill => 30.0;
public override double MaxPoisoningSkill => 70.0;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
}

View file

@ -2,47 +2,47 @@ using Server.Engines.ConPVP;
namespace Server.Items
{
public abstract class BaseRefreshPotion : BasePotion
{
public BaseRefreshPotion(PotionEffect effect) : base(0xF0B, effect)
public abstract class BaseRefreshPotion : BasePotion
{
public BaseRefreshPotion(PotionEffect effect) : base(0xF0B, effect)
{
}
public BaseRefreshPotion(Serial serial) : base(serial)
{
}
public abstract double Refresh { get; }
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 void Drink(Mobile from)
{
if (from.Stam < from.StamMax)
{
from.Stam += Scale(from, (int)(Refresh * from.StamMax));
PlayDrinkEffect(from);
if (!DuelContext.IsFreeConsume(from))
Consume();
}
else
{
from.SendMessage("You decide against drinking this potion, as you are already at full stamina.");
}
}
}
public BaseRefreshPotion(Serial serial) : base(serial)
{
}
public abstract double Refresh { get; }
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
public override void Drink(Mobile from)
{
if (from.Stam < from.StamMax)
{
from.Stam += Scale(from, (int)(Refresh * from.StamMax));
PlayDrinkEffect(from);
if (!DuelContext.IsFreeConsume(from))
Consume();
}
else
{
from.SendMessage("You decide against drinking this potion, as you are already at full stamina.");
}
}
}
}
}

View file

@ -1,30 +1,30 @@
namespace Server.Items
{
public class RefreshPotion : BaseRefreshPotion
{
[Constructible]
public RefreshPotion() : base(PotionEffect.Refresh)
public class RefreshPotion : BaseRefreshPotion
{
[Constructible]
public RefreshPotion() : base(PotionEffect.Refresh)
{
}
public RefreshPotion(Serial serial) : base(serial)
{
}
public override double Refresh => 0.25;
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 RefreshPotion(Serial serial) : base(serial)
{
}
public override double Refresh => 0.25;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
}

View file

@ -1,30 +1,30 @@
namespace Server.Items
{
public class TotalRefreshPotion : BaseRefreshPotion
{
[Constructible]
public TotalRefreshPotion() : base(PotionEffect.RefreshTotal)
public class TotalRefreshPotion : BaseRefreshPotion
{
[Constructible]
public TotalRefreshPotion() : base(PotionEffect.RefreshTotal)
{
}
public TotalRefreshPotion(Serial serial) : base(serial)
{
}
public override double Refresh => 1.0;
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 TotalRefreshPotion(Serial serial) : base(serial)
{
}
public override double Refresh => 1.0;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
}

View file

@ -4,56 +4,56 @@ using Server.Spells;
namespace Server.Items
{
public abstract class BaseStrengthPotion : BasePotion
{
public BaseStrengthPotion(PotionEffect effect) : base(0xF09, effect)
public abstract class BaseStrengthPotion : BasePotion
{
public BaseStrengthPotion(PotionEffect effect) : base(0xF09, effect)
{
}
public BaseStrengthPotion(Serial serial) : base(serial)
{
}
public abstract int StrOffset { get; }
public abstract TimeSpan Duration { get; }
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 bool DoStrength(Mobile from)
{
// TODO: Verify scaled; is it offset, duration, or both?
if (SpellHelper.AddStatOffset(from, StatType.Str, Scale(from, StrOffset), Duration))
{
from.FixedEffect(0x375A, 10, 15);
from.PlaySound(0x1E7);
return true;
}
from.SendLocalizedMessage(502173); // You are already under a similar effect.
return false;
}
public override void Drink(Mobile from)
{
if (DoStrength(from))
{
PlayDrinkEffect(from);
if (!DuelContext.IsFreeConsume(from))
Consume();
}
}
}
public BaseStrengthPotion(Serial serial) : base(serial)
{
}
public abstract int StrOffset { get; }
public abstract TimeSpan Duration { get; }
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
public bool DoStrength(Mobile from)
{
// TODO: Verify scaled; is it offset, duration, or both?
if (SpellHelper.AddStatOffset(from, StatType.Str, Scale(from, StrOffset), Duration))
{
from.FixedEffect(0x375A, 10, 15);
from.PlaySound(0x1E7);
return true;
}
from.SendLocalizedMessage(502173); // You are already under a similar effect.
return false;
}
public override void Drink(Mobile from)
{
if (DoStrength(from))
{
PlayDrinkEffect(from);
if (!DuelContext.IsFreeConsume(from))
Consume();
}
}
}
}
}

View file

@ -2,32 +2,32 @@ using System;
namespace Server.Items
{
public class GreaterStrengthPotion : BaseStrengthPotion
{
[Constructible]
public GreaterStrengthPotion() : base(PotionEffect.StrengthGreater)
public class GreaterStrengthPotion : BaseStrengthPotion
{
[Constructible]
public GreaterStrengthPotion() : base(PotionEffect.StrengthGreater)
{
}
public GreaterStrengthPotion(Serial serial) : base(serial)
{
}
public override int StrOffset => 20;
public override TimeSpan Duration => TimeSpan.FromMinutes(2.0);
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 GreaterStrengthPotion(Serial serial) : base(serial)
{
}
public override int StrOffset => 20;
public override TimeSpan Duration => TimeSpan.FromMinutes(2.0);
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
}

View file

@ -2,32 +2,32 @@ using System;
namespace Server.Items
{
public class StrengthPotion : BaseStrengthPotion
{
[Constructible]
public StrengthPotion() : base(PotionEffect.Strength)
public class StrengthPotion : BaseStrengthPotion
{
[Constructible]
public StrengthPotion() : base(PotionEffect.Strength)
{
}
public StrengthPotion(Serial serial) : base(serial)
{
}
public override int StrOffset => 10;
public override TimeSpan Duration => TimeSpan.FromMinutes(2.0);
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 StrengthPotion(Serial serial) : base(serial)
{
}
public override int StrOffset => 10;
public override TimeSpan Duration => TimeSpan.FromMinutes(2.0);
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
}

View file

@ -9,464 +9,466 @@ using Server.Network;
namespace Server.Items
{
public class Runebook : Item, ISecurable, ICraftable
{
public static readonly TimeSpan UseDelay = TimeSpan.FromSeconds(7.0);
private Mobile m_Crafter;
private int m_DefaultIndex;
private string m_Description;
private BookQuality m_Quality;
[Constructible]
public Runebook() : this(Core.SE ? 12 : 6)
public class Runebook : Item, ISecurable, ICraftable
{
}
public static readonly TimeSpan UseDelay = TimeSpan.FromSeconds(7.0);
private Mobile m_Crafter;
private int m_DefaultIndex;
[Constructible]
public Runebook(int maxCharges) : base(Core.AOS ? 0x22C5 : 0xEFA)
{
Weight = Core.SE ? 1.0 : 3.0;
LootType = LootType.Blessed;
Hue = 0x461;
private string m_Description;
Layer = Core.AOS ? Layer.Invalid : Layer.OneHanded;
private BookQuality m_Quality;
Entries = new List<RunebookEntry>();
MaxCharges = maxCharges;
m_DefaultIndex = -1;
Level = SecureLevel.CoOwners;
}
public Runebook(Serial serial) : base(serial)
{
}
[CommandProperty(AccessLevel.GameMaster)]
public BookQuality Quality
{
get => m_Quality;
set
{
m_Quality = value;
InvalidateProperties();
}
}
[CommandProperty(AccessLevel.GameMaster)]
public DateTime NextUse { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public Mobile Crafter
{
get => m_Crafter;
set
{
m_Crafter = value;
InvalidateProperties();
}
}
[CommandProperty(AccessLevel.GameMaster)]
public string Description
{
get => m_Description;
set
{
m_Description = value;
InvalidateProperties();
}
}
[CommandProperty(AccessLevel.GameMaster)]
public int CurCharges { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public int MaxCharges { get; set; }
public List<Mobile> Openers { get; set; } = new List<Mobile>();
public override int LabelNumber => 1041267; // runebook
public List<RunebookEntry> Entries { get; private set; }
public RunebookEntry Default
{
get
{
if (m_DefaultIndex >= 0 && m_DefaultIndex < Entries.Count)
return Entries[m_DefaultIndex];
return null;
}
set
{
if (value == null)
m_DefaultIndex = -1;
else
m_DefaultIndex = Entries.IndexOf(value);
}
}
public override bool DisplayLootType => Core.AOS;
public int OnCraft(int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool,
CraftItem craftItem, int resHue)
{
int charges = 5 + quality + (int)(from.Skills.Inscribe.Value / 30);
if (charges > 10)
charges = 10;
MaxCharges = Core.SE ? charges * 2 : charges;
if (makersMark)
Crafter = from;
m_Quality = (BookQuality)(quality - 1);
return quality;
}
[CommandProperty(AccessLevel.GameMaster)]
public SecureLevel Level { get; set; }
public override bool AllowEquippedCast(Mobile from) => true;
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
SetSecureLevelEntry.AddTo(from, this, list);
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(3);
writer.Write((byte)m_Quality);
writer.Write(m_Crafter);
writer.Write((int)Level);
writer.Write(Entries.Count);
for (int i = 0; i < Entries.Count; ++i)
Entries[i].Serialize(writer);
writer.Write(m_Description);
writer.Write(CurCharges);
writer.Write(MaxCharges);
writer.Write(m_DefaultIndex);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
LootType = LootType.Blessed;
if (Core.SE && Weight == 3.0)
Weight = 1.0;
int version = reader.ReadInt();
switch (version)
{
case 3:
{
m_Quality = (BookQuality)reader.ReadByte();
goto case 2;
}
case 2:
{
m_Crafter = reader.ReadMobile();
goto case 1;
}
case 1:
{
Level = (SecureLevel)reader.ReadInt();
goto case 0;
}
case 0:
{
int count = reader.ReadInt();
Entries = new List<RunebookEntry>(count);
for (int i = 0; i < count; ++i)
Entries.Add(new RunebookEntry(reader));
m_Description = reader.ReadString();
CurCharges = reader.ReadInt();
MaxCharges = reader.ReadInt();
m_DefaultIndex = reader.ReadInt();
break;
}
}
}
public void DropRune(Mobile from, RunebookEntry e, int index)
{
if (m_DefaultIndex > index)
m_DefaultIndex -= 1;
else if (m_DefaultIndex == index)
m_DefaultIndex = -1;
Entries.RemoveAt(index);
RecallRune rune = new RecallRune();
rune.Target = e.Location;
rune.TargetMap = e.Map;
rune.Description = e.Description;
rune.House = e.House;
rune.Marked = true;
from.AddToBackpack(rune);
from.SendLocalizedMessage(502421); // You have removed the rune.
}
public bool IsOpen(Mobile toCheck)
{
NetState ns = toCheck.NetState;
if (ns == null)
return false;
foreach (Gump gump in ns.Gumps)
if (gump is RunebookGump bookGump && bookGump.Book == this)
return true;
return false;
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
if (m_Quality == BookQuality.Exceptional)
list.Add(1063341); // exceptional
if (m_Crafter != null)
list.Add(1050043, m_Crafter.Name); // crafted by ~1_NAME~
if (!string.IsNullOrEmpty(m_Description))
list.Add(m_Description);
}
public override bool OnDragLift(Mobile from)
{
if (from.HasGump<RunebookGump>())
{
from.SendLocalizedMessage(500169); // You cannot pick that up.
return false;
}
foreach (Mobile m in Openers)
if (IsOpen(m))
m.CloseGump<RunebookGump>();
Openers.Clear();
return true;
}
public override void OnSingleClick(Mobile from)
{
if (m_Description?.Length > 0)
LabelTo(from, m_Description);
base.OnSingleClick(from);
if (m_Crafter != null)
LabelTo(from, 1050043, m_Crafter.Name);
}
public override void OnDoubleClick(Mobile from)
{
if (from.InRange(GetWorldLocation(), Core.ML ? 3 : 1) && CheckAccess(from))
{
if (RootParent is BaseCreature)
[Constructible]
public Runebook() : this(Core.SE ? 12 : 6)
{
from.SendLocalizedMessage(502402); // That is inaccessible.
return;
}
if (DateTime.UtcNow < NextUse)
[Constructible]
public Runebook(int maxCharges) : base(Core.AOS ? 0x22C5 : 0xEFA)
{
from.SendLocalizedMessage(502406); // This book needs time to recharge.
return;
Weight = Core.SE ? 1.0 : 3.0;
LootType = LootType.Blessed;
Hue = 0x461;
Layer = Core.AOS ? Layer.Invalid : Layer.OneHanded;
Entries = new List<RunebookEntry>();
MaxCharges = maxCharges;
m_DefaultIndex = -1;
Level = SecureLevel.CoOwners;
}
from.CloseGump<RunebookGump>();
from.SendGump(new RunebookGump(from, this));
Openers.Add(from);
}
}
public virtual void OnTravel()
{
if (!Core.SA)
NextUse = DateTime.UtcNow + UseDelay;
}
public override void OnAfterDuped(Item newItem)
{
if (!(newItem is Runebook book))
return;
book.Entries = new List<RunebookEntry>();
for (int i = 0; i < Entries.Count; i++)
{
RunebookEntry entry = Entries[i];
book.Entries.Add(new RunebookEntry(entry.Location, entry.Map, entry.Description, entry.House));
}
}
public bool CheckAccess(Mobile m)
{
if (!IsLockedDown || m.AccessLevel >= AccessLevel.GameMaster)
return true;
BaseHouse house = BaseHouse.FindHouseAt(this);
return (house?.IsAosRules != true || (house.Public && !house.IsBanned(m)) || house.HasAccess(m)) &&
house?.HasSecureAccess(m, Level) == true;
}
public override bool OnDragDrop(Mobile from, Item dropped)
{
if (dropped is RecallRune rune)
{
if (IsLockedDown && from.AccessLevel < AccessLevel.GameMaster)
public Runebook(Serial serial) : base(serial)
{
from.SendLocalizedMessage(502413, null, 0x35); // That cannot be done while the book is locked down.
}
else if (IsOpen(from))
[CommandProperty(AccessLevel.GameMaster)]
public BookQuality Quality
{
from.SendLocalizedMessage(1005571); // You cannot place objects in the book while viewing the contents.
get => m_Quality;
set
{
m_Quality = value;
InvalidateProperties();
}
}
else if (Entries.Count < 16)
[CommandProperty(AccessLevel.GameMaster)]
public DateTime NextUse { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public Mobile Crafter
{
if (rune.Marked && rune.TargetMap != null)
{
Entries.Add(new RunebookEntry(rune.Target, rune.TargetMap, rune.Description, rune.House));
get => m_Crafter;
set
{
m_Crafter = value;
InvalidateProperties();
}
}
rune.Delete();
[CommandProperty(AccessLevel.GameMaster)]
public string Description
{
get => m_Description;
set
{
m_Description = value;
InvalidateProperties();
}
}
from.Send(new PlaySound(0x42, GetWorldLocation()));
[CommandProperty(AccessLevel.GameMaster)]
public int CurCharges { get; set; }
from.SendMessage(rune.Description?.Trim().IsNullOrDefault("(indescript)"));
[CommandProperty(AccessLevel.GameMaster)]
public int MaxCharges { get; set; }
public List<Mobile> Openers { get; set; } = new List<Mobile>();
public override int LabelNumber => 1041267; // runebook
public List<RunebookEntry> Entries { get; private set; }
public RunebookEntry Default
{
get
{
if (m_DefaultIndex >= 0 && m_DefaultIndex < Entries.Count)
return Entries[m_DefaultIndex];
return null;
}
set
{
if (value == null)
m_DefaultIndex = -1;
else
m_DefaultIndex = Entries.IndexOf(value);
}
}
public override bool DisplayLootType => Core.AOS;
public int OnCraft(
int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool,
CraftItem craftItem, int resHue
)
{
var charges = 5 + quality + (int)(from.Skills.Inscribe.Value / 30);
if (charges > 10)
charges = 10;
MaxCharges = Core.SE ? charges * 2 : charges;
if (makersMark)
Crafter = from;
m_Quality = (BookQuality)(quality - 1);
return quality;
}
[CommandProperty(AccessLevel.GameMaster)]
public SecureLevel Level { get; set; }
public override bool AllowEquippedCast(Mobile from) => true;
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
SetSecureLevelEntry.AddTo(from, this, list);
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(3);
writer.Write((byte)m_Quality);
writer.Write(m_Crafter);
writer.Write((int)Level);
writer.Write(Entries.Count);
for (var i = 0; i < Entries.Count; ++i)
Entries[i].Serialize(writer);
writer.Write(m_Description);
writer.Write(CurCharges);
writer.Write(MaxCharges);
writer.Write(m_DefaultIndex);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
LootType = LootType.Blessed;
if (Core.SE && Weight == 3.0)
Weight = 1.0;
var version = reader.ReadInt();
switch (version)
{
case 3:
{
m_Quality = (BookQuality)reader.ReadByte();
goto case 2;
}
case 2:
{
m_Crafter = reader.ReadMobile();
goto case 1;
}
case 1:
{
Level = (SecureLevel)reader.ReadInt();
goto case 0;
}
case 0:
{
var count = reader.ReadInt();
Entries = new List<RunebookEntry>(count);
for (var i = 0; i < count; ++i)
Entries.Add(new RunebookEntry(reader));
m_Description = reader.ReadString();
CurCharges = reader.ReadInt();
MaxCharges = reader.ReadInt();
m_DefaultIndex = reader.ReadInt();
break;
}
}
}
public void DropRune(Mobile from, RunebookEntry e, int index)
{
if (m_DefaultIndex > index)
m_DefaultIndex -= 1;
else if (m_DefaultIndex == index)
m_DefaultIndex = -1;
Entries.RemoveAt(index);
var rune = new RecallRune();
rune.Target = e.Location;
rune.TargetMap = e.Map;
rune.Description = e.Description;
rune.House = e.House;
rune.Marked = true;
from.AddToBackpack(rune);
from.SendLocalizedMessage(502421); // You have removed the rune.
}
public bool IsOpen(Mobile toCheck)
{
var ns = toCheck.NetState;
if (ns == null)
return false;
foreach (var gump in ns.Gumps)
if (gump is RunebookGump bookGump && bookGump.Book == this)
return true;
return false;
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
if (m_Quality == BookQuality.Exceptional)
list.Add(1063341); // exceptional
if (m_Crafter != null)
list.Add(1050043, m_Crafter.Name); // crafted by ~1_NAME~
if (!string.IsNullOrEmpty(m_Description))
list.Add(m_Description);
}
public override bool OnDragLift(Mobile from)
{
if (from.HasGump<RunebookGump>())
{
from.SendLocalizedMessage(500169); // You cannot pick that up.
return false;
}
foreach (var m in Openers)
if (IsOpen(m))
m.CloseGump<RunebookGump>();
Openers.Clear();
return true;
}
from.SendLocalizedMessage(502409); // This rune does not have a marked location.
}
else
public override void OnSingleClick(Mobile from)
{
from.SendLocalizedMessage(502401); // This runebook is full.
if (m_Description?.Length > 0)
LabelTo(from, m_Description);
base.OnSingleClick(from);
if (m_Crafter != null)
LabelTo(from, 1050043, m_Crafter.Name);
}
}
else if (dropped is RecallScroll)
{
if (CurCharges < MaxCharges)
public override void OnDoubleClick(Mobile from)
{
from.Send(new PlaySound(0x249, GetWorldLocation()));
if (from.InRange(GetWorldLocation(), Core.ML ? 3 : 1) && CheckAccess(from))
{
if (RootParent is BaseCreature)
{
from.SendLocalizedMessage(502402); // That is inaccessible.
return;
}
int amount = dropped.Amount;
if (DateTime.UtcNow < NextUse)
{
from.SendLocalizedMessage(502406); // This book needs time to recharge.
return;
}
if (amount > MaxCharges - CurCharges)
{
dropped.Consume(MaxCharges - CurCharges);
CurCharges = MaxCharges;
}
else
{
CurCharges += amount;
dropped.Delete();
from.CloseGump<RunebookGump>();
from.SendGump(new RunebookGump(from, this));
return true;
}
Openers.Add(from);
}
}
else
public virtual void OnTravel()
{
from.SendLocalizedMessage(502410); // This book already has the maximum amount of charges.
if (!Core.SA)
NextUse = DateTime.UtcNow + UseDelay;
}
}
return false;
public override void OnAfterDuped(Item newItem)
{
if (!(newItem is Runebook book))
return;
book.Entries = new List<RunebookEntry>();
for (var i = 0; i < Entries.Count; i++)
{
var entry = Entries[i];
book.Entries.Add(new RunebookEntry(entry.Location, entry.Map, entry.Description, entry.House));
}
}
public bool CheckAccess(Mobile m)
{
if (!IsLockedDown || m.AccessLevel >= AccessLevel.GameMaster)
return true;
var house = BaseHouse.FindHouseAt(this);
return (house?.IsAosRules != true || house.Public && !house.IsBanned(m) || house.HasAccess(m)) &&
house?.HasSecureAccess(m, Level) == true;
}
public override bool OnDragDrop(Mobile from, Item dropped)
{
if (dropped is RecallRune rune)
{
if (IsLockedDown && from.AccessLevel < AccessLevel.GameMaster)
{
from.SendLocalizedMessage(502413, null, 0x35); // That cannot be done while the book is locked down.
}
else if (IsOpen(from))
{
from.SendLocalizedMessage(1005571); // You cannot place objects in the book while viewing the contents.
}
else if (Entries.Count < 16)
{
if (rune.Marked && rune.TargetMap != null)
{
Entries.Add(new RunebookEntry(rune.Target, rune.TargetMap, rune.Description, rune.House));
rune.Delete();
from.Send(new PlaySound(0x42, GetWorldLocation()));
from.SendMessage(rune.Description?.Trim().IsNullOrDefault("(indescript)"));
return true;
}
from.SendLocalizedMessage(502409); // This rune does not have a marked location.
}
else
{
from.SendLocalizedMessage(502401); // This runebook is full.
}
}
else if (dropped is RecallScroll)
{
if (CurCharges < MaxCharges)
{
from.Send(new PlaySound(0x249, GetWorldLocation()));
var amount = dropped.Amount;
if (amount > MaxCharges - CurCharges)
{
dropped.Consume(MaxCharges - CurCharges);
CurCharges = MaxCharges;
}
else
{
CurCharges += amount;
dropped.Delete();
return true;
}
}
else
{
from.SendLocalizedMessage(502410); // This book already has the maximum amount of charges.
}
}
return false;
}
}
}
public class RunebookEntry
{
public RunebookEntry(Point3D loc, Map map, string desc, BaseHouse house = null)
public class RunebookEntry
{
Location = loc;
Map = map;
Description = desc;
House = house;
public RunebookEntry(Point3D loc, Map map, string desc, BaseHouse house = null)
{
Location = loc;
Map = map;
Description = desc;
House = house;
}
public RunebookEntry(IGenericReader reader)
{
int version = reader.ReadByte();
switch (version)
{
case 1:
{
House = reader.ReadItem() as BaseHouse;
goto case 0;
}
case 0:
{
Location = reader.ReadPoint3D();
Map = reader.ReadMap();
Description = reader.ReadString();
break;
}
}
}
public Point3D Location { get; }
public Map Map { get; }
public string Description { get; }
public BaseHouse House { get; }
public void Serialize(IGenericWriter writer)
{
if (House?.Deleted == false)
{
writer.Write((byte)1); // version
writer.Write(House);
}
else
{
writer.Write((byte)0); // version
}
writer.Write(Location);
writer.Write(Map);
writer.Write(Description);
}
}
public RunebookEntry(IGenericReader reader)
{
int version = reader.ReadByte();
switch (version)
{
case 1:
{
House = reader.ReadItem() as BaseHouse;
goto case 0;
}
case 0:
{
Location = reader.ReadPoint3D();
Map = reader.ReadMap();
Description = reader.ReadString();
break;
}
}
}
public Point3D Location { get; }
public Map Map { get; }
public string Description { get; }
public BaseHouse House { get; }
public void Serialize(IGenericWriter writer)
{
if (House?.Deleted == false)
{
writer.Write((byte)1); // version
writer.Write(House);
}
else
{
writer.Write((byte)0); // version
}
writer.Write(Location);
writer.Write(Map);
writer.Write(Description);
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class EarthquakeScroll : SpellScroll
{
[Constructible]
public EarthquakeScroll(int amount = 1) : base(56, 0x1F65, amount)
public class EarthquakeScroll : SpellScroll
{
[Constructible]
public EarthquakeScroll(int amount = 1) : base(56, 0x1F65, amount)
{
}
public EarthquakeScroll(Serial serial) : base(serial)
{
}
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 EarthquakeScroll(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class EnergyVortexScroll : SpellScroll
{
[Constructible]
public EnergyVortexScroll(int amount = 1) : base(57, 0x1F66, amount)
public class EnergyVortexScroll : SpellScroll
{
[Constructible]
public EnergyVortexScroll(int amount = 1) : base(57, 0x1F66, amount)
{
}
public EnergyVortexScroll(Serial serial) : base(serial)
{
}
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 EnergyVortexScroll(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class ResurrectionScroll : SpellScroll
{
[Constructible]
public ResurrectionScroll(int amount = 1) : base(58, 0x1F67, amount)
public class ResurrectionScroll : SpellScroll
{
[Constructible]
public ResurrectionScroll(int amount = 1) : base(58, 0x1F67, amount)
{
}
public ResurrectionScroll(Serial serial) : base(serial)
{
}
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 ResurrectionScroll(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class SummonAirElementalScroll : SpellScroll
{
[Constructible]
public SummonAirElementalScroll(int amount = 1) : base(59, 0x1F68, amount)
public class SummonAirElementalScroll : SpellScroll
{
[Constructible]
public SummonAirElementalScroll(int amount = 1) : base(59, 0x1F68, amount)
{
}
public SummonAirElementalScroll(Serial serial) : base(serial)
{
}
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 SummonAirElementalScroll(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class SummonDaemonScroll : SpellScroll
{
[Constructible]
public SummonDaemonScroll(int amount = 1) : base(60, 0x1F69, amount)
public class SummonDaemonScroll : SpellScroll
{
[Constructible]
public SummonDaemonScroll(int amount = 1) : base(60, 0x1F69, amount)
{
}
public SummonDaemonScroll(Serial serial) : base(serial)
{
}
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 SummonDaemonScroll(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class SummonEarthElementalScroll : SpellScroll
{
[Constructible]
public SummonEarthElementalScroll(int amount = 1) : base(61, 0x1F6A, amount)
public class SummonEarthElementalScroll : SpellScroll
{
[Constructible]
public SummonEarthElementalScroll(int amount = 1) : base(61, 0x1F6A, amount)
{
}
public SummonEarthElementalScroll(Serial serial) : base(serial)
{
}
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 SummonEarthElementalScroll(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class SummonFireElementalScroll : SpellScroll
{
[Constructible]
public SummonFireElementalScroll(int amount = 1) : base(62, 0x1F6B, amount)
public class SummonFireElementalScroll : SpellScroll
{
[Constructible]
public SummonFireElementalScroll(int amount = 1) : base(62, 0x1F6B, amount)
{
}
public SummonFireElementalScroll(Serial serial) : base(serial)
{
}
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 SummonFireElementalScroll(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class SummonWaterElementalScroll : SpellScroll
{
[Constructible]
public SummonWaterElementalScroll(int amount = 1) : base(63, 0x1F6C, amount)
public class SummonWaterElementalScroll : SpellScroll
{
[Constructible]
public SummonWaterElementalScroll(int amount = 1) : base(63, 0x1F6C, amount)
{
}
public SummonWaterElementalScroll(Serial serial) : base(serial)
{
}
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 SummonWaterElementalScroll(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class BladeSpiritsScroll : SpellScroll
{
[Constructible]
public BladeSpiritsScroll(int amount = 1) : base(32, 0x1F4D, amount)
public class BladeSpiritsScroll : SpellScroll
{
[Constructible]
public BladeSpiritsScroll(int amount = 1) : base(32, 0x1F4D, amount)
{
}
public BladeSpiritsScroll(Serial serial) : base(serial)
{
}
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 BladeSpiritsScroll(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class DispelFieldScroll : SpellScroll
{
[Constructible]
public DispelFieldScroll(int amount = 1) : base(33, 0x1F4E, amount)
public class DispelFieldScroll : SpellScroll
{
[Constructible]
public DispelFieldScroll(int amount = 1) : base(33, 0x1F4E, amount)
{
}
public DispelFieldScroll(Serial serial) : base(serial)
{
}
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 DispelFieldScroll(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class IncognitoScroll : SpellScroll
{
[Constructible]
public IncognitoScroll(int amount = 1) : base(34, 0x1F4F, amount)
public class IncognitoScroll : SpellScroll
{
[Constructible]
public IncognitoScroll(int amount = 1) : base(34, 0x1F4F, amount)
{
}
public IncognitoScroll(Serial serial) : base(serial)
{
}
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 IncognitoScroll(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class MagicReflectScroll : SpellScroll
{
[Constructible]
public MagicReflectScroll(int amount = 1) : base(35, 0x1F50, amount)
public class MagicReflectScroll : SpellScroll
{
[Constructible]
public MagicReflectScroll(int amount = 1) : base(35, 0x1F50, amount)
{
}
public MagicReflectScroll(Serial serial) : base(serial)
{
}
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 MagicReflectScroll(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class MindBlastScroll : SpellScroll
{
[Constructible]
public MindBlastScroll(int amount = 1) : base(36, 0x1F51, amount)
public class MindBlastScroll : SpellScroll
{
[Constructible]
public MindBlastScroll(int amount = 1) : base(36, 0x1F51, amount)
{
}
public MindBlastScroll(Serial serial) : base(serial)
{
}
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 MindBlastScroll(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class ParalyzeScroll : SpellScroll
{
[Constructible]
public ParalyzeScroll(int amount = 1) : base(37, 0x1F52, amount)
public class ParalyzeScroll : SpellScroll
{
[Constructible]
public ParalyzeScroll(int amount = 1) : base(37, 0x1F52, amount)
{
}
public ParalyzeScroll(Serial serial) : base(serial)
{
}
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 ParalyzeScroll(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class PoisonFieldScroll : SpellScroll
{
[Constructible]
public PoisonFieldScroll(int amount = 1) : base(38, 0x1F53, amount)
public class PoisonFieldScroll : SpellScroll
{
[Constructible]
public PoisonFieldScroll(int amount = 1) : base(38, 0x1F53, amount)
{
}
public PoisonFieldScroll(Serial serial) : base(serial)
{
}
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 PoisonFieldScroll(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class SummonCreatureScroll : SpellScroll
{
[Constructible]
public SummonCreatureScroll(int amount = 1) : base(39, 0x1F54, amount)
public class SummonCreatureScroll : SpellScroll
{
[Constructible]
public SummonCreatureScroll(int amount = 1) : base(39, 0x1F54, amount)
{
}
public SummonCreatureScroll(Serial serial) : base(serial)
{
}
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 SummonCreatureScroll(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class ClumsyScroll : SpellScroll
{
[Constructible]
public ClumsyScroll(int amount = 1) : base(0, 0x1F2E, amount)
public class ClumsyScroll : SpellScroll
{
[Constructible]
public ClumsyScroll(int amount = 1) : base(0, 0x1F2E, amount)
{
}
public ClumsyScroll(Serial serial) : base(serial)
{
}
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 ClumsyScroll(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class CreateFoodScroll : SpellScroll
{
[Constructible]
public CreateFoodScroll(int amount = 1) : base(1, 0x1F2F, amount)
public class CreateFoodScroll : SpellScroll
{
[Constructible]
public CreateFoodScroll(int amount = 1) : base(1, 0x1F2F, amount)
{
}
public CreateFoodScroll(Serial serial) : base(serial)
{
}
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 CreateFoodScroll(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class FeeblemindScroll : SpellScroll
{
[Constructible]
public FeeblemindScroll(int amount = 1) : base(2, 0x1F30, amount)
public class FeeblemindScroll : SpellScroll
{
[Constructible]
public FeeblemindScroll(int amount = 1) : base(2, 0x1F30, amount)
{
}
public FeeblemindScroll(Serial serial) : base(serial)
{
}
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 FeeblemindScroll(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class HealScroll : SpellScroll
{
[Constructible]
public HealScroll(int amount = 1) : base(3, 0x1F31, amount)
public class HealScroll : SpellScroll
{
[Constructible]
public HealScroll(int amount = 1) : base(3, 0x1F31, amount)
{
}
public HealScroll(Serial serial) : base(serial)
{
}
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 HealScroll(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class MagicArrowScroll : SpellScroll
{
[Constructible]
public MagicArrowScroll(int amount = 1) : base(4, 0x1F32, amount)
public class MagicArrowScroll : SpellScroll
{
[Constructible]
public MagicArrowScroll(int amount = 1) : base(4, 0x1F32, amount)
{
}
public MagicArrowScroll(Serial serial) : base(serial)
{
}
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 MagicArrowScroll(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class NightSightScroll : SpellScroll
{
[Constructible]
public NightSightScroll(int amount = 1) : base(5, 0x1F33, amount)
public class NightSightScroll : SpellScroll
{
[Constructible]
public NightSightScroll(int amount = 1) : base(5, 0x1F33, amount)
{
}
public NightSightScroll(Serial ser) : base(ser)
{
}
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 NightSightScroll(Serial ser) : base(ser)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class ReactiveArmorScroll : SpellScroll
{
[Constructible]
public ReactiveArmorScroll(int amount = 1) : base(6, 0x1F2D, amount)
public class ReactiveArmorScroll : SpellScroll
{
[Constructible]
public ReactiveArmorScroll(int amount = 1) : base(6, 0x1F2D, amount)
{
}
public ReactiveArmorScroll(Serial ser) : base(ser)
{
}
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 ReactiveArmorScroll(Serial ser) : base(ser)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class WeakenScroll : SpellScroll
{
[Constructible]
public WeakenScroll(int amount = 1) : base(7, 0x1F34, amount)
public class WeakenScroll : SpellScroll
{
[Constructible]
public WeakenScroll(int amount = 1) : base(7, 0x1F34, amount)
{
}
public WeakenScroll(Serial serial) : base(serial)
{
}
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 WeakenScroll(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class ArchProtectionScroll : SpellScroll
{
[Constructible]
public ArchProtectionScroll(int amount = 1) : base(25, 0x1F46, amount)
public class ArchProtectionScroll : SpellScroll
{
[Constructible]
public ArchProtectionScroll(int amount = 1) : base(25, 0x1F46, amount)
{
}
public ArchProtectionScroll(Serial serial) : base(serial)
{
}
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 ArchProtectionScroll(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class ArchCureScroll : SpellScroll
{
[Constructible]
public ArchCureScroll(int amount = 1) : base(24, 0x1F45, amount)
public class ArchCureScroll : SpellScroll
{
[Constructible]
public ArchCureScroll(int amount = 1) : base(24, 0x1F45, amount)
{
}
public ArchCureScroll(Serial serial) : base(serial)
{
}
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 ArchCureScroll(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class CurseScroll : SpellScroll
{
[Constructible]
public CurseScroll(int amount = 1) : base(26, 0x1F47, amount)
public class CurseScroll : SpellScroll
{
[Constructible]
public CurseScroll(int amount = 1) : base(26, 0x1F47, amount)
{
}
public CurseScroll(Serial serial) : base(serial)
{
}
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 CurseScroll(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class FireFieldScroll : SpellScroll
{
[Constructible]
public FireFieldScroll(int amount = 1) : base(27, 0x1F48, amount)
public class FireFieldScroll : SpellScroll
{
[Constructible]
public FireFieldScroll(int amount = 1) : base(27, 0x1F48, amount)
{
}
public FireFieldScroll(Serial serial) : base(serial)
{
}
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 FireFieldScroll(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class GreaterHealScroll : SpellScroll
{
[Constructible]
public GreaterHealScroll(int amount = 1) : base(28, 0x1F49, amount)
public class GreaterHealScroll : SpellScroll
{
[Constructible]
public GreaterHealScroll(int amount = 1) : base(28, 0x1F49, amount)
{
}
public GreaterHealScroll(Serial serial) : base(serial)
{
}
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 GreaterHealScroll(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class LightningScroll : SpellScroll
{
[Constructible]
public LightningScroll(int amount = 1) : base(29, 0x1F4A, amount)
public class LightningScroll : SpellScroll
{
[Constructible]
public LightningScroll(int amount = 1) : base(29, 0x1F4A, amount)
{
}
public LightningScroll(Serial serial) : base(serial)
{
}
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 LightningScroll(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class ManaDrainScroll : SpellScroll
{
[Constructible]
public ManaDrainScroll(int amount = 1) : base(30, 0x1F4B, amount)
public class ManaDrainScroll : SpellScroll
{
[Constructible]
public ManaDrainScroll(int amount = 1) : base(30, 0x1F4B, amount)
{
}
public ManaDrainScroll(Serial serial) : base(serial)
{
}
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 ManaDrainScroll(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,28 @@
namespace Server.Items
{
public class RecallScroll : SpellScroll
{
[Constructible]
public RecallScroll(int amount = 1) : base(31, 0x1F4C, amount)
public class RecallScroll : SpellScroll
{
[Constructible]
public RecallScroll(int amount = 1) : base(31, 0x1F4C, amount)
{
}
public RecallScroll(Serial serial) : base(serial)
{
}
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 RecallScroll(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

Some files were not shown because too many files have changed in this diff Show more