Reorganizes Project (#41)
This commit is contained in:
parent
08bf44af9a
commit
3614a66aee
3499 changed files with 79 additions and 55 deletions
|
|
@ -0,0 +1,61 @@
|
|||
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)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,348 @@
|
|||
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)
|
||||
{
|
||||
Movable = false;
|
||||
|
||||
m_Item = new InternalItem(this);
|
||||
m_Item2 = new InternalItem2(this);
|
||||
}
|
||||
|
||||
public LargeForgeWest(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
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 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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.Write(m_Item);
|
||||
writer.Write(m_Item2);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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 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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.Write(m_Item);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int 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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.Write(m_Item);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.Write(m_Item);
|
||||
writer.Write(m_Item2);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.Write(m_Item);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.Write(m_Item);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
m_Item = reader.ReadItem() as LargeForgeEast;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
130
Projects/Scripts/Items/Skill Items/Camping/Bedroll.cs
Normal file
130
Projects/Scripts/Items/Skill Items/Camping/Bedroll.cs
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
using System;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
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>())
|
||||
{
|
||||
CampfireEntry entry = Campfire.GetEntry(from);
|
||||
|
||||
if (entry?.Safe == true)
|
||||
from.SendGump(new LogoutGump(entry, this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
|
||||
private class LogoutGump : Gump
|
||||
{
|
||||
private Bedroll m_Bedroll;
|
||||
private Timer m_CloseTimer;
|
||||
|
||||
private 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);
|
||||
}
|
||||
|
||||
private void CloseGump()
|
||||
{
|
||||
Campfire.RemoveEntry(m_Entry);
|
||||
m_Entry.Player.CloseGump<LogoutGump>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
199
Projects/Scripts/Items/Skill Items/Camping/Campfire.cs
Normal file
199
Projects/Scripts/Items/Skill Items/Camping/Campfire.cs
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
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 List<CampfireEntry> m_Entries;
|
||||
|
||||
private Timer m_Timer;
|
||||
|
||||
public Campfire() : base(0xDE3)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
public Campfire(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DateTime Created{ get; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public CampfireStatus Status
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (ItemID)
|
||||
{
|
||||
case 0xDE3:
|
||||
return CampfireStatus.Burning;
|
||||
|
||||
case 0xDE9:
|
||||
return CampfireStatus.Extinguishing;
|
||||
|
||||
default:
|
||||
return 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 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))
|
||||
{
|
||||
entry.Safe = true;
|
||||
entry.Player.SendLocalizedMessage(500621); // The camp is now secure.
|
||||
}
|
||||
|
||||
IPooledEnumerable<NetState> eable = GetClientsInRange(SecureRange);
|
||||
|
||||
foreach (NetState state in eable)
|
||||
if (state.Mobile is PlayerMobile pm && GetEntry(pm) == null)
|
||||
{
|
||||
CampfireEntry 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 (CampfireEntry entry in m_Entries.ToList())
|
||||
RemoveEntry(entry);
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
m_Timer?.Stop();
|
||||
|
||||
ClearEntries();
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
112
Projects/Scripts/Items/Skill Items/Camping/Kindling.cs
Normal file
112
Projects/Scripts/Items/Skill Items/Camping/Kindling.cs
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
using System.Collections.Generic;
|
||||
using Server.Network;
|
||||
using Server.Regions;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class Kindling : Item
|
||||
{
|
||||
[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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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;
|
||||
|
||||
int idx = Utility.Random(list.Count);
|
||||
return list[idx];
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
278
Projects/Scripts/Items/Skill Items/Carpenter Items/Board.cs
Normal file
278
Projects/Scripts/Items/Skill Items/Carpenter Items/Board.cs
Normal file
|
|
@ -0,0 +1,278 @@
|
|||
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)
|
||||
{
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
switch (m_Resource)
|
||||
{
|
||||
case CraftResource.Bloodwood: return 1075055;
|
||||
case CraftResource.Frostwood: return 1075056;
|
||||
case CraftResource.Heartwood: return 1075062; //WHY Osi. Why?
|
||||
}
|
||||
|
||||
return LabelNumber;
|
||||
}
|
||||
}
|
||||
|
||||
bool ICommodity.IsDeedable => true;
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
if (!CraftResources.IsStandard(m_Resource))
|
||||
{
|
||||
int num = CraftResources.GetLocalizationNumber(m_Resource);
|
||||
|
||||
if (num > 0)
|
||||
list.Add(num);
|
||||
else
|
||||
list.Add(CraftResources.GetName(m_Resource));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(3);
|
||||
|
||||
writer.Write((int)m_Resource);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class HeartwoodBoard : Board
|
||||
{
|
||||
[Constructible]
|
||||
public HeartwoodBoard(int amount = 1)
|
||||
: base(CraftResource.Heartwood, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public HeartwoodBoard(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,528 @@
|
|||
using System;
|
||||
using Server.Mobiles;
|
||||
using Server.Multis;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
[Flippable(0x1EBA, 0x1EBB)]
|
||||
public class TaxidermyKit : Item
|
||||
{
|
||||
private static TrophyInfo[] m_Table =
|
||||
{
|
||||
new TrophyInfo(typeof(BrownBear), 0x1E60, 1041093, 1041107),
|
||||
new TrophyInfo(typeof(GreatHart), 0x1E61, 1041095, 1041109),
|
||||
new TrophyInfo(typeof(BigFish), 0x1E62, 1041096, 1041110),
|
||||
new TrophyInfo(typeof(Gorilla), 0x1E63, 1041091, 1041105),
|
||||
new TrophyInfo(typeof(Orc), 0x1E64, 1041090, 1041104),
|
||||
new TrophyInfo(typeof(PolarBear), 0x1E65, 1041094, 1041108),
|
||||
new TrophyInfo(typeof(Troll), 0x1E66, 1041092, 1041106)
|
||||
};
|
||||
|
||||
[Constructible]
|
||||
public TaxidermyKit() : base(0x1EBA)
|
||||
{
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
public TaxidermyKit(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1041279; // a taxidermy kit
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
|
||||
}
|
||||
else if (from.Skills.Carpentry.Base < 90.0)
|
||||
{
|
||||
from.SendLocalizedMessage(1042594); // You do not understand how to use this.
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1042595); // Target the corpse to make a trophy out of.
|
||||
from.Target = new CorpseTarget(this);
|
||||
}
|
||||
}
|
||||
|
||||
public class TrophyInfo
|
||||
{
|
||||
public TrophyInfo(Type type, int id, int deedNum, int addonNum)
|
||||
{
|
||||
CreatureType = type;
|
||||
NorthID = id;
|
||||
DeedNumber = deedNum;
|
||||
AddonNumber = addonNum;
|
||||
}
|
||||
|
||||
public Type CreatureType{ get; }
|
||||
|
||||
public int NorthID{ get; }
|
||||
|
||||
public int DeedNumber{ get; }
|
||||
|
||||
public int AddonNumber{ get; }
|
||||
}
|
||||
|
||||
|
||||
private class CorpseTarget : Target
|
||||
{
|
||||
private TaxidermyKit m_Kit;
|
||||
|
||||
public CorpseTarget(TaxidermyKit kit) : base(3, false, TargetFlags.None)
|
||||
{
|
||||
m_Kit = kit;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (m_Kit.Deleted)
|
||||
return;
|
||||
|
||||
Corpse corpse = targeted as Corpse;
|
||||
|
||||
if (!(corpse != null || targeted is BigFish))
|
||||
{
|
||||
from.SendLocalizedMessage(1042600); // That is not a corpse!
|
||||
}
|
||||
else if (corpse?.VisitedByTaxidermist == true)
|
||||
{
|
||||
from.SendLocalizedMessage(1042596); // That corpse seems to have been visited by a taxidermist already.
|
||||
}
|
||||
else if (!m_Kit.IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
|
||||
}
|
||||
else if (from.Skills.Carpentry.Base < 90.0)
|
||||
{
|
||||
from.SendLocalizedMessage(1042603); // You would not understand how to use the kit.
|
||||
}
|
||||
else
|
||||
{
|
||||
object obj = corpse?.Owner ?? targeted;
|
||||
|
||||
foreach (TrophyInfo t in m_Table)
|
||||
{
|
||||
if (t.CreatureType != obj.GetType())
|
||||
continue;
|
||||
|
||||
Container pack = from.Backpack;
|
||||
|
||||
if (pack?.ConsumeTotal(typeof(Board), 10) == true)
|
||||
{
|
||||
from.SendLocalizedMessage(
|
||||
1042278); // You review the corpse and find it worthy of a trophy.
|
||||
from.SendLocalizedMessage(1042602); // You use your kit up making the trophy.
|
||||
|
||||
Mobile hunter = null;
|
||||
int weight = 0;
|
||||
|
||||
if (targeted is BigFish fish)
|
||||
{
|
||||
hunter = fish.Fisher;
|
||||
weight = (int)fish.Weight;
|
||||
|
||||
fish.Consume();
|
||||
}
|
||||
|
||||
|
||||
from.AddToBackpack(new TrophyDeed(t, hunter, weight));
|
||||
|
||||
if (corpse != null)
|
||||
corpse.VisitedByTaxidermist = true;
|
||||
|
||||
m_Kit.Delete();
|
||||
return;
|
||||
}
|
||||
|
||||
from.SendLocalizedMessage(1042598); // You do not have enough boards.
|
||||
return;
|
||||
}
|
||||
|
||||
from.SendLocalizedMessage(1042599); // That does not look like something you want hanging on a wall.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class TrophyAddon : Item, IAddon
|
||||
{
|
||||
private int m_AddonNumber;
|
||||
private int m_AnimalWeight;
|
||||
|
||||
private Mobile m_Hunter;
|
||||
|
||||
public TrophyAddon(Mobile from, int itemID, int westID, int northID, int deedNumber,
|
||||
int addonNumber, Mobile hunter = null, int animalWeight = 0) : base(itemID)
|
||||
{
|
||||
WestID = westID;
|
||||
NorthID = northID;
|
||||
DeedNumber = deedNumber;
|
||||
m_AddonNumber = addonNumber;
|
||||
|
||||
m_Hunter = hunter;
|
||||
m_AnimalWeight = animalWeight;
|
||||
|
||||
Movable = false;
|
||||
|
||||
MoveToWorld(from.Location, from.Map);
|
||||
}
|
||||
|
||||
public TrophyAddon(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool ForceShowProperties => ObjectPropertyList.Enabled;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int WestID{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int NorthID{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int DeedNumber{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int AddonNumber
|
||||
{
|
||||
get => m_AddonNumber;
|
||||
set
|
||||
{
|
||||
m_AddonNumber = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Mobile Hunter
|
||||
{
|
||||
get => m_Hunter;
|
||||
set
|
||||
{
|
||||
m_Hunter = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int AnimalWeight
|
||||
{
|
||||
get => m_AnimalWeight;
|
||||
set
|
||||
{
|
||||
m_AnimalWeight = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public override int LabelNumber => m_AddonNumber;
|
||||
|
||||
public bool CouldFit(IPoint3D p, Map map)
|
||||
{
|
||||
if (!map.CanFit(p.X, p.Y, p.Z, ItemData.Height))
|
||||
return false;
|
||||
|
||||
if (ItemID == NorthID)
|
||||
return BaseAddon.IsWall(p.X, p.Y - 1, p.Z, map); // North wall
|
||||
return BaseAddon.IsWall(p.X - 1, p.Y, p.Z, map); // West wall
|
||||
}
|
||||
|
||||
public Item Deed => new TrophyDeed(WestID, NorthID, DeedNumber, m_AddonNumber, m_Hunter, m_AnimalWeight);
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
if (m_AnimalWeight >= 20)
|
||||
{
|
||||
if (m_Hunter != null)
|
||||
list.Add(1070857, m_Hunter.Name); // Caught by ~1_fisherman~
|
||||
|
||||
list.Add(1070858, m_AnimalWeight.ToString()); // ~1_weight~ stones
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1); // version
|
||||
|
||||
writer.Write(m_Hunter);
|
||||
writer.Write(m_AnimalWeight);
|
||||
|
||||
writer.Write(WestID);
|
||||
writer.Write(NorthID);
|
||||
writer.Write(DeedNumber);
|
||||
writer.Write(m_AddonNumber);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
m_Hunter = reader.ReadMobile();
|
||||
m_AnimalWeight = reader.ReadInt();
|
||||
goto case 0;
|
||||
}
|
||||
case 0:
|
||||
{
|
||||
WestID = reader.ReadInt();
|
||||
NorthID = reader.ReadInt();
|
||||
DeedNumber = reader.ReadInt();
|
||||
m_AddonNumber = reader.ReadInt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Timer.DelayCall(TimeSpan.Zero, FixMovingCrate);
|
||||
}
|
||||
|
||||
private void FixMovingCrate()
|
||||
{
|
||||
if (Deleted)
|
||||
return;
|
||||
|
||||
if (Movable || IsLockedDown)
|
||||
{
|
||||
Item deed = Deed;
|
||||
|
||||
if (Parent is Item item)
|
||||
{
|
||||
item.AddItem(deed);
|
||||
deed.Location = Location;
|
||||
}
|
||||
else
|
||||
{
|
||||
deed.MoveToWorld(Location, Map);
|
||||
}
|
||||
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
BaseHouse house = BaseHouse.FindHouseAt(this);
|
||||
|
||||
if (house?.IsCoOwner(from) == true)
|
||||
{
|
||||
if (from.InRange(GetWorldLocation(), 1))
|
||||
{
|
||||
from.AddToBackpack(Deed);
|
||||
Delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(500295); // You are too far away to do that.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Flippable(0x14F0, 0x14EF)]
|
||||
public class TrophyDeed : Item
|
||||
{
|
||||
private int m_AnimalWeight;
|
||||
private int m_DeedNumber;
|
||||
|
||||
private Mobile m_Hunter;
|
||||
|
||||
public TrophyDeed(int westID, int northID, int deedNumber, int addonNumber,
|
||||
Mobile hunter = null, int animalWeight = 0) : base(0x14F0)
|
||||
{
|
||||
WestID = westID;
|
||||
NorthID = northID;
|
||||
m_DeedNumber = deedNumber;
|
||||
AddonNumber = addonNumber;
|
||||
m_Hunter = hunter;
|
||||
m_AnimalWeight = animalWeight;
|
||||
}
|
||||
|
||||
public TrophyDeed(TaxidermyKit.TrophyInfo info, Mobile hunter, int animalWeight)
|
||||
: this(info.NorthID + 7, info.NorthID, info.DeedNumber, info.AddonNumber, hunter, animalWeight)
|
||||
{
|
||||
}
|
||||
|
||||
public TrophyDeed(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int WestID{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int NorthID{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int DeedNumber
|
||||
{
|
||||
get => m_DeedNumber;
|
||||
set
|
||||
{
|
||||
m_DeedNumber = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int AddonNumber{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Mobile Hunter
|
||||
{
|
||||
get => m_Hunter;
|
||||
set
|
||||
{
|
||||
m_Hunter = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int AnimalWeight
|
||||
{
|
||||
get => m_AnimalWeight;
|
||||
set
|
||||
{
|
||||
m_AnimalWeight = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public override int LabelNumber => m_DeedNumber;
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
if (m_AnimalWeight >= 20)
|
||||
{
|
||||
if (m_Hunter != null)
|
||||
list.Add(1070857, m_Hunter.Name); // Caught by ~1_fisherman~
|
||||
|
||||
list.Add(1070858, m_AnimalWeight.ToString()); // ~1_weight~ stones
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1); // version
|
||||
|
||||
writer.Write(m_Hunter);
|
||||
writer.Write(m_AnimalWeight);
|
||||
|
||||
writer.Write(WestID);
|
||||
writer.Write(NorthID);
|
||||
writer.Write(m_DeedNumber);
|
||||
writer.Write(AddonNumber);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
m_Hunter = reader.ReadMobile();
|
||||
m_AnimalWeight = reader.ReadInt();
|
||||
goto case 0;
|
||||
}
|
||||
case 0:
|
||||
{
|
||||
WestID = reader.ReadInt();
|
||||
NorthID = reader.ReadInt();
|
||||
m_DeedNumber = reader.ReadInt();
|
||||
AddonNumber = reader.ReadInt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (IsChildOf(from.Backpack))
|
||||
{
|
||||
BaseHouse house = BaseHouse.FindHouseAt(from);
|
||||
|
||||
if (house?.IsCoOwner(from) == true)
|
||||
{
|
||||
bool northWall = BaseAddon.IsWall(from.X, from.Y - 1, from.Z, from.Map);
|
||||
bool westWall = BaseAddon.IsWall(from.X - 1, from.Y, from.Z, from.Map);
|
||||
|
||||
if (northWall && westWall)
|
||||
switch (from.Direction & Direction.Mask)
|
||||
{
|
||||
case Direction.North:
|
||||
case Direction.South:
|
||||
westWall = false;
|
||||
break;
|
||||
|
||||
case Direction.East:
|
||||
case Direction.West:
|
||||
northWall = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
from.SendMessage("Turn to face the wall on which to hang this trophy.");
|
||||
return;
|
||||
}
|
||||
|
||||
int itemID = 0;
|
||||
|
||||
if (northWall)
|
||||
itemID = NorthID;
|
||||
else if (westWall)
|
||||
itemID = WestID;
|
||||
else
|
||||
from.SendLocalizedMessage(1042626); // The trophy must be placed next to a wall.
|
||||
|
||||
if (itemID > 0)
|
||||
{
|
||||
house.Addons.Add(new TrophyAddon(from, itemID, WestID, NorthID, m_DeedNumber, AddonNumber, m_Hunter,
|
||||
m_AnimalWeight));
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(502092); // You must be in your house to do this.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
69
Projects/Scripts/Items/Skill Items/Fishing/FishingPole.cs
Normal file
69
Projects/Scripts/Items/Skill Items/Fishing/FishingPole.cs
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
using System.Collections.Generic;
|
||||
using Server.ContextMenus;
|
||||
using Server.Engines.Harvest;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class FishingPole : Item
|
||||
{
|
||||
[Constructible]
|
||||
public FishingPole() : base(0x0DC0)
|
||||
{
|
||||
Layer = Layer.TwoHanded;
|
||||
Weight = 8.0;
|
||||
}
|
||||
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
if (version < 1 && Layer == Layer.OneHanded)
|
||||
Layer = Layer.TwoHanded;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
using System;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class MessageInABottle : Item
|
||||
{
|
||||
private int m_Level;
|
||||
|
||||
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 && 1 > Utility.Random(25))
|
||||
return 4; // ancient
|
||||
|
||||
return Utility.RandomMinMax(1, 3);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(3); // version
|
||||
|
||||
writer.Write(m_Level);
|
||||
|
||||
writer.Write(TargetMap);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
326
Projects/Scripts/Items/Skill Items/Fishing/Misc/SOS.cs
Normal file
326
Projects/Scripts/Items/Skill Items/Fishing/Misc/SOS.cs
Normal file
|
|
@ -0,0 +1,326 @@
|
|||
using System;
|
||||
using Server.Gumps;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
[Flippable(0x14ED, 0x14EE)]
|
||||
public class SOS : Item
|
||||
{
|
||||
public override int LabelNumber
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsAncient)
|
||||
return 1063450; // an ancient SOS
|
||||
|
||||
return 1041081; // a waterstained SOS
|
||||
}
|
||||
}
|
||||
|
||||
private int m_Level;
|
||||
|
||||
[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;
|
||||
}
|
||||
|
||||
[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(GenericWriter 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(GenericReader 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);
|
||||
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.
|
||||
}
|
||||
}
|
||||
|
||||
private static int[] m_WaterTiles =
|
||||
{
|
||||
0x00A8, 0x00AB,
|
||||
0x0136, 0x0137
|
||||
};
|
||||
|
||||
private static Rectangle2D[] m_BritRegions = { new Rectangle2D(0, 0, 5120, 4096) };
|
||||
|
||||
private static Rectangle2D[] m_IlshRegions =
|
||||
{ new Rectangle2D(1472, 272, 304, 240), new Rectangle2D(1240, 1000, 312, 160) };
|
||||
|
||||
private static 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[Utility.Random(regions.Length)];
|
||||
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;
|
||||
}
|
||||
|
||||
#if false
|
||||
private class MessageGump : Gump
|
||||
{
|
||||
public MessageGump( MessageEntry entry, Map map, Point3D loc ) : base( (640 - entry.Width) / 2, (480 - entry.Height) / 2 )
|
||||
{
|
||||
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 =
|
||||
String.Format( "{0}°{1}'{2},{3}°{4}'{5}", yLat, yMins, ySouth ? "S" : "N", xLong, xMins, xEast ? "E" : "W" );
|
||||
else
|
||||
fmt = "?????";
|
||||
|
||||
AddPage( 0 );
|
||||
AddBackground( 0, 0, entry.Width, entry.Height, 2520 );
|
||||
AddHtml( 38, 38, entry.Width - 83, entry.Height - 86, String.Format( entry.Message, fmt ), false, false );
|
||||
}
|
||||
}
|
||||
#else
|
||||
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);
|
||||
|
||||
AddHtmlLocalized(30, 80, 285, 160, 1018326, true,
|
||||
true); /* 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.
|
||||
*/
|
||||
|
||||
AddHtml(35, 240, 230, 20, fmt);
|
||||
|
||||
AddButton(35, 265, 4005, 4007, 0);
|
||||
AddHtmlLocalized(70, 265, 100, 20, 1011036); // OKAY
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
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...")
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
159
Projects/Scripts/Items/Skill Items/Fishing/Misc/Sextant.cs
Normal file
159
Projects/Scripts/Items/Skill Items/Fishing/Misc/Sextant.cs
Normal file
|
|
@ -0,0 +1,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 override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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)
|
||||
{
|
||||
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 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public interface IShipwreckedItem
|
||||
{
|
||||
bool IsShipwreckedItem{ get; set; }
|
||||
}
|
||||
|
||||
public class ShipwreckedItem : Item, IDyable, IShipwreckedItem
|
||||
{
|
||||
public ShipwreckedItem(int itemID) : base(itemID)
|
||||
{
|
||||
int 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;
|
||||
}
|
||||
|
||||
#region IShipwreckedItem Members
|
||||
|
||||
bool IShipwreckedItem.IsShipwreckedItem
|
||||
{
|
||||
get => true;
|
||||
set { }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,424 @@
|
|||
using System;
|
||||
using Server.Mobiles;
|
||||
using Server.Multis;
|
||||
using Server.Spells;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class SpecialFishingNet : Item
|
||||
{
|
||||
private static int[] m_Hues =
|
||||
{
|
||||
0x09B,
|
||||
0x0CD,
|
||||
0x0D3,
|
||||
0x14D,
|
||||
0x1DD,
|
||||
0x1E9,
|
||||
0x1F4,
|
||||
0x373,
|
||||
0x451,
|
||||
0x47F,
|
||||
0x489,
|
||||
0x492,
|
||||
0x4B5,
|
||||
0x8AA
|
||||
};
|
||||
|
||||
private static int[] m_WaterTiles =
|
||||
{
|
||||
0x00A8, 0x00AB,
|
||||
0x0136, 0x0137
|
||||
};
|
||||
|
||||
private static int[] m_UndeepWaterTiles =
|
||||
{
|
||||
0x1797, 0x179C
|
||||
};
|
||||
|
||||
[Constructible]
|
||||
public SpecialFishingNet() : base(0x0DCA)
|
||||
{
|
||||
Weight = 1.0;
|
||||
|
||||
if (0.01 > Utility.RandomDouble())
|
||||
Hue = Utility.RandomList(m_Hues);
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1); // version
|
||||
|
||||
writer.Write(InUse);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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))
|
||||
{
|
||||
x = tx;
|
||||
y = ty;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
spawn.MoveToWorld(new Point3D(x, y, p.Z), map);
|
||||
|
||||
if (spawn is Kraken && 0.2 > Utility.RandomDouble())
|
||||
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)
|
||||
{
|
||||
BaseCreature spawn;
|
||||
|
||||
switch (Utility.Random(4))
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
spawn = new SeaSerpent();
|
||||
break;
|
||||
case 1:
|
||||
spawn = new DeepSeaSerpent();
|
||||
break;
|
||||
case 2:
|
||||
spawn = new WaterElemental();
|
||||
break;
|
||||
case 3:
|
||||
spawn = new Kraken();
|
||||
break;
|
||||
}
|
||||
|
||||
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])
|
||||
{
|
||||
z = target.Z;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
return 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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,256 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.ContextMenus;
|
||||
using Server.Engines.Craft;
|
||||
using Server.Engines.Harvest;
|
||||
using Server.Mobiles;
|
||||
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)
|
||||
{
|
||||
m_UsesRemaining = usesRemaining;
|
||||
m_Quality = ToolQuality.Regular;
|
||||
}
|
||||
|
||||
public BaseHarvestTool(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[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; }
|
||||
|
||||
#region ICraftable Members
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
[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(GenericWriter 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(GenericReader 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 PlayerMobile m_Mobile;
|
||||
private 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)
|
||||
{
|
||||
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!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
using Server.Engines.Harvest;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
if (Hue == 0x973)
|
||||
Hue = 0x0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,177 @@
|
|||
using System;
|
||||
using Server.Engines.Harvest;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class ProspectorsTool : BaseBashing, IUsesRemaining
|
||||
{
|
||||
private int m_UsesRemaining;
|
||||
|
||||
[Constructible]
|
||||
public ProspectorsTool() : base(0xFB4)
|
||||
{
|
||||
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 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)
|
||||
{
|
||||
from.SendLocalizedMessage(1049062); // You have used up your prospector's tool.
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1); // version
|
||||
writer.Write(m_UsesRemaining);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
33
Projects/Scripts/Items/Skill Items/Harvest Tools/Shovel.cs
Normal file
33
Projects/Scripts/Items/Skill Items/Harvest Tools/Shovel.cs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
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 override HarvestSystem HarvestSystem => Mining.System;
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
using Server.Engines.Harvest;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class SturdyPickaxe : BaseAxe, IUsesRemaining
|
||||
{
|
||||
[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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
using Server.Engines.Harvest;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class SturdyShovel : BaseHarvestTool
|
||||
{
|
||||
[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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
334
Projects/Scripts/Items/Skill Items/Lumberjack/Log.cs
Normal file
334
Projects/Scripts/Items/Skill Items/Lumberjack/Log.cs
Normal file
|
|
@ -0,0 +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)
|
||||
{
|
||||
}
|
||||
|
||||
[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))
|
||||
{
|
||||
int num = CraftResources.GetLocalizationNumber(m_Resource);
|
||||
|
||||
if (num > 0)
|
||||
list.Add(num);
|
||||
else
|
||||
list.Add(CraftResources.GetName(m_Resource));
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1); // version
|
||||
|
||||
writer.Write((int)m_Resource);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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;
|
||||
}
|
||||
|
||||
base.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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
36
Projects/Scripts/Items/Skill Items/Magical/BookOfBushido.cs
Normal file
36
Projects/Scripts/Items/Skill Items/Magical/BookOfBushido.cs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
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 override SpellbookType SpellbookType => SpellbookType.Samurai;
|
||||
public override int BookOffset => 400;
|
||||
public override int BookCount => 6;
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
if (version == 0 && Core.ML)
|
||||
Layer = Layer.OneHanded;
|
||||
}
|
||||
}
|
||||
}
|
||||
36
Projects/Scripts/Items/Skill Items/Magical/BookOfChivalry.cs
Normal file
36
Projects/Scripts/Items/Skill Items/Magical/BookOfChivalry.cs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
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 override SpellbookType SpellbookType => SpellbookType.Paladin;
|
||||
public override int BookOffset => 200;
|
||||
public override int BookCount => 10;
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
if (version == 0 && Core.ML)
|
||||
Layer = Layer.OneHanded;
|
||||
}
|
||||
}
|
||||
}
|
||||
36
Projects/Scripts/Items/Skill Items/Magical/BookOfNinjitsu.cs
Normal file
36
Projects/Scripts/Items/Skill Items/Magical/BookOfNinjitsu.cs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
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 override SpellbookType SpellbookType => SpellbookType.Ninja;
|
||||
public override int BookOffset => 500;
|
||||
public override int BookCount => 8;
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
if (version == 0 && Core.ML)
|
||||
Layer = Layer.OneHanded;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class BlankScroll : Item, ICommodity
|
||||
{
|
||||
[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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
35
Projects/Scripts/Items/Skill Items/Magical/Misc/Bottle.cs
Normal file
35
Projects/Scripts/Items/Skill Items/Magical/Misc/Bottle.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class Bottle : Item, ICommodity
|
||||
{
|
||||
[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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
393
Projects/Scripts/Items/Skill Items/Magical/Misc/Moongate.cs
Normal file
393
Projects/Scripts/Items/Skill Items/Magical/Misc/Moongate.cs
Normal file
|
|
@ -0,0 +1,393 @@
|
|||
using System;
|
||||
using Server.Factions;
|
||||
using Server.Gumps;
|
||||
using Server.Misc;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
using Server.Regions;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
[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)
|
||||
{
|
||||
#region Mondain's Legacy
|
||||
|
||||
if (m.Hidden && m.AccessLevel == AccessLevel.Player && Core.ML)
|
||||
m.RevealingAction();
|
||||
|
||||
#endregion
|
||||
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1); // version
|
||||
|
||||
writer.Write(Target);
|
||||
writer.Write(TargetMap);
|
||||
|
||||
// Version 1
|
||||
writer.Write(Dispellable);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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)
|
||||
{
|
||||
return map != null && Region.Find(p, map).GetRegion<GuardedRegion>()?.IsDisabled() == false;
|
||||
}
|
||||
|
||||
private class DelayTimer : Timer
|
||||
{
|
||||
private Mobile m_From;
|
||||
private Moongate m_Gate;
|
||||
private 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 == null ? MessageNumber : (object)MessageString, MessageColor, GumpWidth, GumpHeight,
|
||||
okay => Warning_Callback(from, okay)));
|
||||
}
|
||||
else
|
||||
{
|
||||
base.BeginConfirmation(from);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter 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(GenericReader 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 Mobile m_From;
|
||||
private 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
342
Projects/Scripts/Items/Skill Items/Magical/Misc/PotionKeg.cs
Normal file
342
Projects/Scripts/Items/Skill Items/Magical/Misc/PotionKeg.cs
Normal file
|
|
@ -0,0 +1,342 @@
|
|||
using System;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class PotionKeg : Item
|
||||
{
|
||||
private int m_Held;
|
||||
private PotionEffect m_Type;
|
||||
|
||||
[Constructible]
|
||||
public PotionKeg() : base(0x1940)
|
||||
{
|
||||
UpdateWeight();
|
||||
}
|
||||
|
||||
public PotionKeg(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Held
|
||||
{
|
||||
get => m_Held;
|
||||
set
|
||||
{
|
||||
if (m_Held != value)
|
||||
{
|
||||
m_Held = value;
|
||||
UpdateWeight();
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1); // version
|
||||
|
||||
writer.Write((int)m_Type);
|
||||
writer.Write(m_Held);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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(TimeSpan.Zero, 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)
|
||||
{
|
||||
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))
|
||||
{
|
||||
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.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)
|
||||
{
|
||||
#region Mondain's Legacy
|
||||
|
||||
if ((int)pot.PotionEffect >= (int)PotionEffect.Invisibility)
|
||||
{
|
||||
from.SendLocalizedMessage(502232); // The keg is not designed to hold that type of object.
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
switch (m_Type)
|
||||
{
|
||||
default:
|
||||
case PotionEffect.Nightsight: return new NightSightPotion();
|
||||
|
||||
case PotionEffect.CureLesser: return new LesserCurePotion();
|
||||
case PotionEffect.Cure: return new CurePotion();
|
||||
case PotionEffect.CureGreater: return new GreaterCurePotion();
|
||||
|
||||
case PotionEffect.Agility: return new AgilityPotion();
|
||||
case PotionEffect.AgilityGreater: return new GreaterAgilityPotion();
|
||||
|
||||
case PotionEffect.Strength: return new StrengthPotion();
|
||||
case PotionEffect.StrengthGreater: return new GreaterStrengthPotion();
|
||||
|
||||
case PotionEffect.PoisonLesser: return new LesserPoisonPotion();
|
||||
case PotionEffect.Poison: return new PoisonPotion();
|
||||
case PotionEffect.PoisonGreater: return new GreaterPoisonPotion();
|
||||
case PotionEffect.PoisonDeadly: return new DeadlyPoisonPotion();
|
||||
|
||||
case PotionEffect.Refresh: return new RefreshPotion();
|
||||
case PotionEffect.RefreshTotal: return new TotalRefreshPotion();
|
||||
|
||||
case PotionEffect.HealLesser: return new LesserHealPotion();
|
||||
case PotionEffect.Heal: return new HealPotion();
|
||||
case PotionEffect.HealGreater: return new GreaterHealPotion();
|
||||
|
||||
case PotionEffect.ExplosionLesser: return new LesserExplosionPotion();
|
||||
case PotionEffect.Explosion: return new ExplosionPotion();
|
||||
case PotionEffect.ExplosionGreater: return new GreaterExplosionPotion();
|
||||
|
||||
case PotionEffect.Conflagration: return new ConflagrationPotion();
|
||||
case PotionEffect.ConflagrationGreater: return new GreaterConflagrationPotion();
|
||||
|
||||
case PotionEffect.ConfusionBlast: return new ConfusionBlastPotion();
|
||||
case PotionEffect.ConfusionBlastGreater: return new GreaterConfusionBlastPotion();
|
||||
}
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
TileData.ItemTable[0x1940].Height = 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
308
Projects/Scripts/Items/Skill Items/Magical/Misc/RecallRune.cs
Normal file
308
Projects/Scripts/Items/Skill Items/Magical/Misc/RecallRune.cs
Normal file
|
|
@ -0,0 +1,308 @@
|
|||
using Server.Multis;
|
||||
using Server.Prompts;
|
||||
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)
|
||||
{
|
||||
Weight = 1.0;
|
||||
CalculateHue();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
m_Marked = value;
|
||||
CalculateHue();
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[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)
|
||||
{
|
||||
m_TargetMap = value;
|
||||
CalculateHue();
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter 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(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int 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;
|
||||
|
||||
bool setDesc = false;
|
||||
if (Core.AOS)
|
||||
{
|
||||
m_House = BaseHouse.FindHouseAt(m);
|
||||
|
||||
if (m_House == null)
|
||||
{
|
||||
Target = m.Location;
|
||||
m_TargetMap = m.Map;
|
||||
}
|
||||
else
|
||||
{
|
||||
HouseSign sign = m_House.Sign;
|
||||
|
||||
if (sign != null)
|
||||
m_Description = sign.Name;
|
||||
else
|
||||
m_Description = null;
|
||||
|
||||
if (m_Description == null || (m_Description = m_Description.Trim()).Length == 0)
|
||||
m_Description = "an unnamed house";
|
||||
|
||||
setDesc = true;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
||||
if ((desc = m_Description) == null || (desc = desc.Trim()).Length == 0)
|
||||
desc = "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 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.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
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 override SpellbookType SpellbookType => SpellbookType.Mystic;
|
||||
|
||||
public override int BookOffset => 677;
|
||||
public override int BookCount => 16;
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
/*int version = */
|
||||
reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
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 override SpellbookType SpellbookType => SpellbookType.Necromancer;
|
||||
public override int BookOffset => 100;
|
||||
public override int BookCount => Core.SE ? 17 : 16;
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
if (version == 0 && Core.ML)
|
||||
Layer = Layer.OneHanded;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
using System;
|
||||
using Server.Engines.ConPVP;
|
||||
using Server.Spells;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
263
Projects/Scripts/Items/Skill Items/Magical/Potions/BasePotion.cs
Normal file
263
Projects/Scripts/Items/Skill Items/Magical/Potions/BasePotion.cs
Normal file
|
|
@ -0,0 +1,263 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Engines.ConPVP;
|
||||
using Server.Engines.Craft;
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
#region ICraftable Members
|
||||
|
||||
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)
|
||||
{
|
||||
if ((int)PotionEffect >= (int)PotionEffect.Invisibility)
|
||||
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;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
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))
|
||||
{
|
||||
if (this is BaseExplosionPotion && Amount > 1)
|
||||
{
|
||||
BasePotion pot = (BasePotion)Activator.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
|
||||
{
|
||||
from.SendLocalizedMessage(502138); // That is too far away for you to use
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1); // version
|
||||
|
||||
writer.Write((int)m_PotionEffect);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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);
|
||||
|
||||
#region Dueling
|
||||
|
||||
if (!DuelContext.IsFreeConsume(m))
|
||||
m.AddToBackpack(new Bottle());
|
||||
|
||||
#endregion
|
||||
|
||||
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)
|
||||
{
|
||||
return dropped is BasePotion potion && potion.m_PotionEffect == m_PotionEffect &&
|
||||
base.StackWith(from, potion, playSound);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,307 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Spells;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public abstract class BaseConflagrationPotion : BasePotion
|
||||
{
|
||||
private List<Mobile> m_Users = new List<Mobile>();
|
||||
|
||||
public BaseConflagrationPotion(PotionEffect effect) : base(0xF06, effect)
|
||||
{
|
||||
Hue = 0x489;
|
||||
}
|
||||
|
||||
public BaseConflagrationPotion(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public abstract int MinDamage{ get; }
|
||||
public abstract int MaxDamage{ get; }
|
||||
|
||||
public override bool RequireFreeHand => false;
|
||||
|
||||
public override void Drink(Mobile from)
|
||||
{
|
||||
if (Core.AOS && (from.Paralyzed || from.Frozen || from.Spell != null && from.Spell.IsCasting))
|
||||
{
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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++)
|
||||
{
|
||||
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()
|
||||
{
|
||||
return 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(GenericWriter 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(GenericReader 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;
|
||||
}
|
||||
|
||||
private class InternalTimer : Timer
|
||||
{
|
||||
private DateTime m_End;
|
||||
private 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;
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
from.DoHarmful(m);
|
||||
|
||||
AOS.Damage(m, from, m_Item.GetDamage(), 0, 100, 0, 0, 0);
|
||||
m.PlaySound(0x208);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Delay
|
||||
|
||||
private static 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);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,179 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Misc;
|
||||
using Server.Mobiles;
|
||||
using Server.Spells;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public abstract class BaseConfusionBlastPotion : BasePotion
|
||||
{
|
||||
private List<Mobile> m_Users = new List<Mobile>();
|
||||
|
||||
public BaseConfusionBlastPotion(PotionEffect effect) : base(0xF06, effect)
|
||||
{
|
||||
Hue = 0x48D;
|
||||
}
|
||||
|
||||
public BaseConfusionBlastPotion(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
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 != null && from.Spell.IsCasting))
|
||||
{
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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)
|
||||
{
|
||||
if (mon.Controlled || mon.Summoned)
|
||||
continue;
|
||||
|
||||
mon.Pacify(from, DateTime.UtcNow + TimeSpan.FromSeconds(5.0)); // TODO check
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
#region Effects
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Delay
|
||||
|
||||
private static 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);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
using Server.Engines.ConPVP;
|
||||
using Server.Spells;
|
||||
using Server.Spells.Necromancy;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class CureLevelInfo
|
||||
{
|
||||
public CureLevelInfo(Poison poison, double chance)
|
||||
{
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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())
|
||||
{
|
||||
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.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class CurePotion : BaseCurePotion
|
||||
{
|
||||
private static 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 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)
|
||||
{
|
||||
}
|
||||
|
||||
public CurePotion(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override CureLevelInfo[] LevelInfo => Core.AOS ? m_AosLevelInfo : m_OldLevelInfo;
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class GreaterCurePotion : BaseCurePotion
|
||||
{
|
||||
private static 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 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)
|
||||
{
|
||||
}
|
||||
|
||||
public GreaterCurePotion(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override CureLevelInfo[] LevelInfo => Core.AOS ? m_AosLevelInfo : m_OldLevelInfo;
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class LesserCurePotion : BaseCurePotion
|
||||
{
|
||||
private static 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 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)
|
||||
{
|
||||
}
|
||||
|
||||
public LesserCurePotion(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override CureLevelInfo[] LevelInfo => Core.AOS ? m_AosLevelInfo : m_OldLevelInfo;
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,267 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Server.Network;
|
||||
using Server.Spells;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public abstract class BaseExplosionPotion : BasePotion
|
||||
{
|
||||
private const int ExplosionRange = 2; // How long is the blast radius?
|
||||
|
||||
private static bool LeveledExplosion = false; // Should explosion potions explode other nearby potions?
|
||||
private static bool InstantExplosion = false; // Should explosion potions explode on impact?
|
||||
private static bool RelativeLocation = false; // Is the explosion target location relative for mobiles?
|
||||
|
||||
private Timer m_Timer;
|
||||
|
||||
public BaseExplosionPotion(PotionEffect effect) : base(0xF0D, effect)
|
||||
{
|
||||
}
|
||||
|
||||
public BaseExplosionPotion(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public abstract int MinDamage{ get; }
|
||||
public abstract int MaxDamage{ get; }
|
||||
|
||||
public override bool RequireFreeHand => false;
|
||||
|
||||
public List<Mobile> Users{ get; private set; }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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 != null && from.Spell.IsCasting))
|
||||
{
|
||||
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();
|
||||
|
||||
if (Users == null)
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
if (Potion.Amount > 1) Mobile.LiftItemDupe(Potion, 1);
|
||||
|
||||
Potion.Internalize();
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(1.0), () => Potion.Reposition_OnTick(from, new Point3D(p), map));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
using System;
|
||||
using Server.Engines.ConPVP;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public abstract class BaseHealPotion : BasePotion
|
||||
{
|
||||
public BaseHealPotion(PotionEffect effect) : base(0xF0C, effect)
|
||||
{
|
||||
}
|
||||
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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))
|
||||
{
|
||||
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.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class InvisibilityPotion : BasePotion
|
||||
{
|
||||
private static 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)
|
||||
{
|
||||
return 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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
using Server.Engines.ConPVP;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class NightSightPotion : BasePotion
|
||||
{
|
||||
[Constructible]
|
||||
public NightSightPotion() : base(0xF06, PotionEffect.Nightsight)
|
||||
{
|
||||
}
|
||||
|
||||
public NightSightPotion(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
using Server.Engines.ConPVP;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
using Server.Engines.ConPVP;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
using System;
|
||||
using Server.Engines.ConPVP;
|
||||
using Server.Spells;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
484
Projects/Scripts/Items/Skill Items/Magical/Runebook.cs
Normal file
484
Projects/Scripts/Items/Skill Items/Magical/Runebook.cs
Normal file
|
|
@ -0,0 +1,484 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.ContextMenus;
|
||||
using Server.Engines.Craft;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
using Server.Multis;
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
[Constructible]
|
||||
public Runebook(int maxCharges) : base(Core.AOS ? 0x22C5 : 0xEFA)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
#region ICraftable Members
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public SecureLevel Level{ get; set; }
|
||||
|
||||
public override bool AllowEquippedCast(Mobile from)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
|
||||
{
|
||||
base.GetContextMenuEntries(from, list);
|
||||
SetSecureLevelEntry.AddTo(from, this, list);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter 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(GenericReader 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)
|
||||
{
|
||||
from.SendLocalizedMessage(502402); // That is inaccessible.
|
||||
return;
|
||||
}
|
||||
|
||||
if (DateTime.UtcNow < NextUse)
|
||||
{
|
||||
from.SendLocalizedMessage(502406); // This book needs time to recharge.
|
||||
return;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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()));
|
||||
|
||||
string desc = rune.Description;
|
||||
|
||||
if (desc == null || (desc = desc.Trim()).Length == 0)
|
||||
desc = "(indescript)";
|
||||
|
||||
from.SendMessage(desc);
|
||||
|
||||
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()));
|
||||
|
||||
int 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)
|
||||
{
|
||||
Location = loc;
|
||||
Map = map;
|
||||
Description = desc;
|
||||
House = house;
|
||||
}
|
||||
|
||||
public RunebookEntry(GenericReader 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(GenericWriter 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class EarthquakeScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public EarthquakeScroll(int amount = 1) : base(56, 0x1F65, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public EarthquakeScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class EnergyVortexScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public EnergyVortexScroll(int amount = 1) : base(57, 0x1F66, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public EnergyVortexScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class ResurrectionScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public ResurrectionScroll(int amount = 1) : base(58, 0x1F67, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public ResurrectionScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class SummonAirElementalScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public SummonAirElementalScroll(int amount = 1) : base(59, 0x1F68, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public SummonAirElementalScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class SummonDaemonScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public SummonDaemonScroll(int amount = 1) : base(60, 0x1F69, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public SummonDaemonScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class SummonEarthElementalScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public SummonEarthElementalScroll(int amount = 1) : base(61, 0x1F6A, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public SummonEarthElementalScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class SummonFireElementalScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public SummonFireElementalScroll(int amount = 1) : base(62, 0x1F6B, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public SummonFireElementalScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class SummonWaterElementalScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public SummonWaterElementalScroll(int amount = 1) : base(63, 0x1F6C, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public SummonWaterElementalScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class BladeSpiritsScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public BladeSpiritsScroll(int amount = 1) : base(32, 0x1F4D, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public BladeSpiritsScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class DispelFieldScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public DispelFieldScroll(int amount = 1) : base(33, 0x1F4E, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public DispelFieldScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class IncognitoScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public IncognitoScroll(int amount = 1) : base(34, 0x1F4F, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public IncognitoScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class MagicReflectScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public MagicReflectScroll(int amount = 1) : base(35, 0x1F50, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public MagicReflectScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class MindBlastScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public MindBlastScroll(int amount = 1) : base(36, 0x1F51, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public MindBlastScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class ParalyzeScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public ParalyzeScroll(int amount = 1) : base(37, 0x1F52, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public ParalyzeScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class PoisonFieldScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public PoisonFieldScroll(int amount = 1) : base(38, 0x1F53, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public PoisonFieldScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class SummonCreatureScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public SummonCreatureScroll(int amount = 1) : base(39, 0x1F54, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public SummonCreatureScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class ClumsyScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public ClumsyScroll(int amount = 1) : base(0, 0x1F2E, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public ClumsyScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class CreateFoodScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public CreateFoodScroll(int amount = 1) : base(1, 0x1F2F, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public CreateFoodScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class FeeblemindScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public FeeblemindScroll(int amount = 1) : base(2, 0x1F30, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public FeeblemindScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class HealScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public HealScroll(int amount = 1) : base(3, 0x1F31, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public HealScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class MagicArrowScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public MagicArrowScroll(int amount = 1) : base(4, 0x1F32, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public MagicArrowScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class NightSightScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public NightSightScroll(int amount = 1) : base(5, 0x1F33, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public NightSightScroll(Serial ser) : base(ser)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class ReactiveArmorScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public ReactiveArmorScroll(int amount = 1) : base(6, 0x1F2D, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public ReactiveArmorScroll(Serial ser) : base(ser)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class WeakenScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public WeakenScroll(int amount = 1) : base(7, 0x1F34, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public WeakenScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class ArchProtectionScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public ArchProtectionScroll(int amount = 1) : base(25, 0x1F46, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public ArchProtectionScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class ArchCureScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public ArchCureScroll(int amount = 1) : base(24, 0x1F45, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public ArchCureScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class CurseScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public CurseScroll(int amount = 1) : base(26, 0x1F47, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public CurseScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class FireFieldScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public FireFieldScroll(int amount = 1) : base(27, 0x1F48, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public FireFieldScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class GreaterHealScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public GreaterHealScroll(int amount = 1) : base(28, 0x1F49, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public GreaterHealScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class LightningScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public LightningScroll(int amount = 1) : base(29, 0x1F4A, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public LightningScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class ManaDrainScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public ManaDrainScroll(int amount = 1) : base(30, 0x1F4B, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public ManaDrainScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class RecallScroll : SpellScroll
|
||||
{
|
||||
[Constructible]
|
||||
public RecallScroll(int amount = 1) : base(31, 0x1F4C, amount)
|
||||
{
|
||||
}
|
||||
|
||||
public RecallScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue