Reorganizes Project (#41)

This commit is contained in:
Kamron Batman 2019-08-02 18:13:40 -07:00 committed by GitHub
parent 08bf44af9a
commit 3614a66aee
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3499 changed files with 79 additions and 55 deletions

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

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

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

View file

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

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

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

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

View 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.
}
}
}
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -0,0 +1,31 @@
namespace Server.Items
{
public class AnimatedWeaponScroll : SpellScroll
{
[Constructible]
public AnimatedWeaponScroll(int amount = 1)
: base(683, 0x2DA4, amount)
{
}
public AnimatedWeaponScroll(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();
}
}
}

View file

@ -0,0 +1,31 @@
namespace Server.Items
{
public class BombardScroll : SpellScroll
{
[Constructible]
public BombardScroll(int amount = 1)
: base(688, 0x2DA9, amount)
{
}
public BombardScroll(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();
}
}
}

View file

@ -0,0 +1,31 @@
namespace Server.Items
{
public class CleansingWindsScroll : SpellScroll
{
[Constructible]
public CleansingWindsScroll(int amount = 1)
: base(687, 0x2DA8, amount)
{
}
public CleansingWindsScroll(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();
}
}
}

View file

@ -0,0 +1,31 @@
namespace Server.Items
{
public class EagleStrikeScroll : SpellScroll
{
[Constructible]
public EagleStrikeScroll(int amount = 1)
: base(682, 0x2DA3, amount)
{
}
public EagleStrikeScroll(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();
}
}
}

View file

@ -0,0 +1,31 @@
namespace Server.Items
{
public class EnchantScroll : SpellScroll
{
[Constructible]
public EnchantScroll(int amount = 1)
: base(680, 0x2DA1, amount)
{
}
public EnchantScroll(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();
}
}
}

View file

@ -0,0 +1,31 @@
namespace Server.Items
{
public class HailStormScroll : SpellScroll
{
[Constructible]
public HailStormScroll(int amount = 1)
: base(690, 0x2DAB, amount)
{
}
public HailStormScroll(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();
}
}
}

View file

@ -0,0 +1,31 @@
namespace Server.Items
{
public class HealingStoneScroll : SpellScroll
{
[Constructible]
public HealingStoneScroll(int amount = 1)
: base(678, 0x2D9F, amount)
{
}
public HealingStoneScroll(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();
}
}
}

View file

@ -0,0 +1,31 @@
namespace Server.Items
{
public class MassSleepScroll : SpellScroll
{
[Constructible]
public MassSleepScroll(int amount = 1)
: base(686, 0x2DA7, amount)
{
}
public MassSleepScroll(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();
}
}
}

View file

@ -0,0 +1,31 @@
namespace Server.Items
{
public class NetherBoltScroll : SpellScroll
{
[Constructible]
public NetherBoltScroll(int amount = 1)
: base(677, 0x2D9E, amount)
{
}
public NetherBoltScroll(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();
}
}
}

View file

@ -0,0 +1,31 @@
namespace Server.Items
{
public class NetherCycloneScroll : SpellScroll
{
[Constructible]
public NetherCycloneScroll(int amount = 1)
: base(691, 0x2DAC, amount)
{
}
public NetherCycloneScroll(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();
}
}
}

View file

@ -0,0 +1,31 @@
namespace Server.Items
{
public class PurgeMagicScroll : SpellScroll
{
[Constructible]
public PurgeMagicScroll(int amount = 1)
: base(679, 0x2DA0, amount)
{
}
public PurgeMagicScroll(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();
}
}
}

View file

@ -0,0 +1,31 @@
namespace Server.Items
{
public class RisingColossusScroll : SpellScroll
{
[Constructible]
public RisingColossusScroll(int amount = 1)
: base(692, 0x2DAD, amount)
{
}
public RisingColossusScroll(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();
}
}
}

View file

@ -0,0 +1,31 @@
namespace Server.Items
{
public class SleepScroll : SpellScroll
{
[Constructible]
public SleepScroll(int amount = 1)
: base(681, 0x2DA2, amount)
{
}
public SleepScroll(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();
}
}
}

View file

@ -0,0 +1,31 @@
namespace Server.Items
{
public class SpellPlagueScroll : SpellScroll
{
[Constructible]
public SpellPlagueScroll(int amount = 1)
: base(689, 0x2DAA, amount)
{
}
public SpellPlagueScroll(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();
}
}
}

View file

@ -0,0 +1,31 @@
namespace Server.Items
{
public class SpellTriggerScroll : SpellScroll
{
[Constructible]
public SpellTriggerScroll(int amount = 1)
: base(685, 0x2DA6, amount)
{
}
public SpellTriggerScroll(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();
}
}
}

View file

@ -0,0 +1,31 @@
namespace Server.Items
{
public class StoneFormScroll : SpellScroll
{
[Constructible]
public StoneFormScroll(int amount = 1)
: base(684, 0x2DA5, amount)
{
}
public StoneFormScroll(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();
}
}
}

View file

@ -0,0 +1,28 @@
namespace Server.Items
{
public class AnimateDeadScroll : SpellScroll
{
[Constructible]
public AnimateDeadScroll(int amount = 1) : base(100, 0x2260, amount)
{
}
public AnimateDeadScroll(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();
}
}
}

View file

@ -0,0 +1,28 @@
namespace Server.Items
{
public class BloodOathScroll : SpellScroll
{
[Constructible]
public BloodOathScroll(int amount = 1) : base(101, 0x2261, amount)
{
}
public BloodOathScroll(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();
}
}
}

View file

@ -0,0 +1,28 @@
namespace Server.Items
{
public class CorpseSkinScroll : SpellScroll
{
[Constructible]
public CorpseSkinScroll(int amount = 1) : base(102, 0x2262, amount)
{
}
public CorpseSkinScroll(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();
}
}
}

View file

@ -0,0 +1,28 @@
namespace Server.Items
{
public class CurseWeaponScroll : SpellScroll
{
[Constructible]
public CurseWeaponScroll(int amount = 1) : base(103, 0x2263, amount)
{
}
public CurseWeaponScroll(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