Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Targeting;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class ThrowableCat : BaseThrowableAtMobile<Mobile>
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableCat()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public ThrowableCat(int amount)
|
||||
: base(8475, amount)
|
||||
{
|
||||
Name = "Snowball";
|
||||
|
||||
Weight = 2.0;
|
||||
Stackable = true;
|
||||
|
||||
Consumable = true;
|
||||
AllowCombat = false;
|
||||
TargetFlags = TargetFlags.None;
|
||||
|
||||
Delivery = ThrowableAtMobileDelivery.None;
|
||||
DismountUser = false;
|
||||
|
||||
ThrowSound = 105;
|
||||
ImpactSound = 676;
|
||||
|
||||
EffectID = ItemID;
|
||||
EffectHue = Hue;
|
||||
|
||||
ThrowRecovery = TimeSpan.Zero;
|
||||
}
|
||||
|
||||
public ThrowableCat(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
protected override void OnThrownAt(Mobile from, Mobile target)
|
||||
{
|
||||
if (from == null || from.Deleted || target == null || target.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var cat = new Cat
|
||||
{
|
||||
Name = "Snowball"
|
||||
};
|
||||
|
||||
var pmTarget = target as PlayerMobile;
|
||||
|
||||
if (pmTarget != null)
|
||||
{
|
||||
if (pmTarget.Followers + cat.ControlSlots <= pmTarget.FollowersMax)
|
||||
{
|
||||
cat.Controlled = true;
|
||||
cat.ControlMaster = pmTarget;
|
||||
cat.ControlTarget = pmTarget;
|
||||
cat.ControlOrder = OrderType.Follow;
|
||||
}
|
||||
}
|
||||
|
||||
cat.MoveToWorld(target.Location, target.Map);
|
||||
|
||||
base.OnThrownAt(from, target);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{ }
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{ }
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
using Server.Items;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public abstract class BaseThrowableBench : ThrowableFurniture
|
||||
{
|
||||
public BaseThrowableBench(int itemID)
|
||||
: base(itemID)
|
||||
{
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
public BaseThrowableBench(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture, Flipable(0xB2D, 0xB2C)]
|
||||
public class ThrowableWoodenBench : BaseThrowableBench
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableWoodenBench()
|
||||
: base(Utility.RandomList(0xB2D, 0xB2C))
|
||||
{ }
|
||||
|
||||
public ThrowableWoodenBench(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,259 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
using Server.Items;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public abstract class BaseThrowableChair : ThrowableFurniture
|
||||
{
|
||||
public BaseThrowableChair(int itemID)
|
||||
: base(itemID)
|
||||
{
|
||||
Weight = 20.0;
|
||||
}
|
||||
|
||||
public BaseThrowableChair(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture, Flipable(0xB4F, 0xB4E, 0xB50, 0xB51)]
|
||||
public abstract class ThrowableFancyWoodenChairCushion : BaseThrowableChair
|
||||
{
|
||||
public ThrowableFancyWoodenChairCushion()
|
||||
: base(Utility.RandomList(0xB4F, 0xB4E, 0xB50, 0xB51))
|
||||
{ }
|
||||
|
||||
public ThrowableFancyWoodenChairCushion(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture, Flipable(0xB53, 0xB52, 0xB54, 0xB55)]
|
||||
public abstract class ThrowableWoodenChairCushion : BaseThrowableChair
|
||||
{
|
||||
public ThrowableWoodenChairCushion()
|
||||
: base(Utility.RandomList(0xB53, 0xB52, 0xB54, 0xB55))
|
||||
{ }
|
||||
|
||||
public ThrowableWoodenChairCushion(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture, Flipable(0xB57, 0xB56, 0xB59, 0xB58)]
|
||||
public class ThrowableWoodenChair : BaseThrowableChair
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableWoodenChair()
|
||||
: base(Utility.RandomList(0xB57, 0xB56, 0xB59, 0xB58))
|
||||
{ }
|
||||
|
||||
public ThrowableWoodenChair(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture, Flipable(0xB5B, 0xB5A, 0xB5C, 0xB5D)]
|
||||
public class ThrowableBambooChair : BaseThrowableChair
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableBambooChair()
|
||||
: base(Utility.RandomList(0xB5B, 0xB5A, 0xB5C, 0xB5D))
|
||||
{ }
|
||||
|
||||
public ThrowableBambooChair(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture, Flipable(0x1218, 0x1219, 0x121A, 0x121B)]
|
||||
public class ThrowableStoneChair : BaseThrowableChair
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableStoneChair()
|
||||
: base(Utility.RandomList(0x1218, 0x1219, 0x121A, 0x121B))
|
||||
{ }
|
||||
|
||||
public ThrowableStoneChair(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture, Flipable(0x2DE3, 0x2DE4, 0x2DE5, 0x2DE6)]
|
||||
public class ThrowableOrnateElvenChair : BaseThrowableChair
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableOrnateElvenChair()
|
||||
: base(Utility.RandomList(0x2DE3, 0x2DE4, 0x2DE5, 0x2DE6))
|
||||
{ }
|
||||
|
||||
public ThrowableOrnateElvenChair(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture, Flipable(0x2DEB, 0x2DEC, 0x2DED, 0x2DEE)]
|
||||
public class ThrowableBigElvenChair : BaseThrowableChair
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableBigElvenChair()
|
||||
: base(Utility.RandomList(0x2DEB, 0x2DEC, 0x2DED, 0x2DEE))
|
||||
{ }
|
||||
|
||||
public ThrowableBigElvenChair(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture, Flipable(0x2DF5, 0x2DF6)]
|
||||
public class ThrowableElvenReadingChair : BaseThrowableChair
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableElvenReadingChair()
|
||||
: base(Utility.RandomList(0x2DF5, 0x2DF6))
|
||||
{ }
|
||||
|
||||
public ThrowableElvenReadingChair(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Targeting;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public abstract class ThrowableFurniture : BaseThrowableAtMobile<Mobile>, IDyable
|
||||
{
|
||||
public ThrowableFurniture(int itemID)
|
||||
: base(itemID, 1)
|
||||
{
|
||||
Weight = 10.0;
|
||||
|
||||
AllowCombat = true;
|
||||
AllowDeadUser = false;
|
||||
Consumable = true;
|
||||
ClearHands = true;
|
||||
DismountUser = true;
|
||||
|
||||
Damages = false;
|
||||
Heals = false;
|
||||
|
||||
ThrowRange = 8;
|
||||
|
||||
ThrowSound = 1491;
|
||||
ImpactSound = 1335;
|
||||
|
||||
RequiredSkillValue = 0.0;
|
||||
|
||||
TargetFlags = TargetFlags.None;
|
||||
|
||||
Delivery = ThrowableAtMobileDelivery.None;
|
||||
|
||||
ThrowRecovery = TimeSpan.Zero;
|
||||
}
|
||||
|
||||
public ThrowableFurniture(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public virtual bool Dye(Mobile m, DyeTub sender)
|
||||
{
|
||||
return m != null && sender is FurnitureDyeTub;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
[Furniture]
|
||||
public abstract class BaseThrowableStool : ThrowableFurniture
|
||||
{
|
||||
public BaseThrowableStool(int itemID)
|
||||
: base(itemID)
|
||||
{
|
||||
Weight = 10.0;
|
||||
}
|
||||
|
||||
public BaseThrowableStool(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture]
|
||||
public class ThrowableStool : BaseThrowableStool
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableStool()
|
||||
: base(0xA2A)
|
||||
{ }
|
||||
|
||||
public ThrowableStool(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture]
|
||||
public class ThrowableFootStool : BaseThrowableStool
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableFootStool()
|
||||
: base(0xB5E)
|
||||
{ }
|
||||
|
||||
public ThrowableFootStool(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
using Server.Items;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public abstract class BaseThrowableTable : ThrowableFurniture
|
||||
{
|
||||
public BaseThrowableTable(int itemID)
|
||||
: base(itemID)
|
||||
{
|
||||
Weight = 10.0;
|
||||
}
|
||||
|
||||
public BaseThrowableTable(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture]
|
||||
public class ThrowableElegantLowTable : BaseThrowableTable
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableElegantLowTable()
|
||||
: base(0x2819)
|
||||
{ }
|
||||
|
||||
public ThrowableElegantLowTable(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture]
|
||||
public class ThrowablePlainLowTable : BaseThrowableTable
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowablePlainLowTable()
|
||||
: base(0x281A)
|
||||
{ }
|
||||
|
||||
public ThrowablePlainLowTable(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture, Flipable(0xB90, 0xB7D)]
|
||||
public class ThrowableLargeTable : BaseThrowableTable
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableLargeTable()
|
||||
: base(Utility.RandomList(0xB90, 0xB7D))
|
||||
{ }
|
||||
|
||||
public ThrowableLargeTable(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture, Flipable(0xB35, 0xB34)]
|
||||
public class ThrowableNightstand : BaseThrowableTable
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableNightstand()
|
||||
: base(Utility.RandomList(0xB35, 0xB34))
|
||||
{ }
|
||||
|
||||
public ThrowableNightstand(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture, Flipable(0xB8F, 0xB7C)]
|
||||
public class ThrowableYewWoodTable : BaseThrowableTable
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableYewWoodTable()
|
||||
: base(Utility.RandomList(0xB8F, 0xB7C))
|
||||
{ }
|
||||
|
||||
public ThrowableYewWoodTable(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
using Server.Items;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public abstract class BaseThrowableThrone : ThrowableFurniture
|
||||
{
|
||||
public BaseThrowableThrone(int itemID)
|
||||
: base(itemID)
|
||||
{
|
||||
Weight = 10.0;
|
||||
}
|
||||
|
||||
public BaseThrowableThrone(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture, Flipable(0xB32, 0xB33)]
|
||||
public class ThrowableThrone : BaseThrowableThrone
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableThrone()
|
||||
: base(Utility.RandomList(0xB32, 0xB33))
|
||||
{ }
|
||||
|
||||
public ThrowableThrone(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture, Flipable(0xB2E, 0xB2F, 0xB31, 0xB30)]
|
||||
public class ThrowableWoodenThrone : BaseThrowableThrone
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableWoodenThrone()
|
||||
: base(Utility.RandomList(0xB2E, 0xB2F, 0xB31, 0xB30))
|
||||
{ }
|
||||
|
||||
public ThrowableWoodenThrone(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,520 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Movement;
|
||||
using Server.Targeting;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class HauntedMomentoEntity : BaseCreature
|
||||
{
|
||||
private HauntedMomento _Momento;
|
||||
|
||||
[CommandProperty(AccessLevel.Counselor, AccessLevel.GameMaster)]
|
||||
public HauntedMomento Momento => _Momento;
|
||||
|
||||
public override bool ClickTitle => false;
|
||||
public override bool AlwaysMurderer => true;
|
||||
public override bool BardImmune => true;
|
||||
public override bool BleedImmune => true;
|
||||
public override bool NoHouseRestrictions => true;
|
||||
public override bool ShowFameTitle => false;
|
||||
public override bool Unprovokable => true;
|
||||
public override bool CanMoveOverObstacles => true;
|
||||
public override bool CanOpenDoors => true;
|
||||
public override bool CanTarget => false;
|
||||
//public override bool CanDrop => false;
|
||||
public override bool Commandable => false;
|
||||
public override bool DeleteCorpseOnDeath => true;
|
||||
public override bool IsScaryToPets => true;
|
||||
public override bool IsDispellable => false;
|
||||
public override bool PlayerRangeSensitive => false;
|
||||
public override bool CanFlee => false;
|
||||
|
||||
public HauntedMomentoEntity(HauntedMomento momento)
|
||||
: base(AIType.AI_Use_Default, FightMode.None, 10, 0, 0.2, 0.2)
|
||||
{
|
||||
_Momento = momento;
|
||||
|
||||
Name = "?";
|
||||
|
||||
Hue = 0x4001;
|
||||
BaseSoundID = 0;
|
||||
|
||||
Hidden = true;
|
||||
Blessed = true;
|
||||
Tamable = false;
|
||||
CanSwim = true;
|
||||
|
||||
Fame = 0;
|
||||
Karma = 0;
|
||||
|
||||
VirtualArmor = 1337;
|
||||
|
||||
SetStr(0);
|
||||
SetDex(0);
|
||||
SetInt(0);
|
||||
SetHits(1);
|
||||
SetDamage(0);
|
||||
|
||||
SetDamageType(ResistanceType.Cold, 0);
|
||||
SetDamageType(ResistanceType.Energy, 0);
|
||||
SetDamageType(ResistanceType.Fire, 0);
|
||||
SetDamageType(ResistanceType.Physical, 0);
|
||||
SetDamageType(ResistanceType.Poison, 0);
|
||||
|
||||
SetResistance(ResistanceType.Cold, 100);
|
||||
SetResistance(ResistanceType.Energy, 100);
|
||||
SetResistance(ResistanceType.Fire, 100);
|
||||
SetResistance(ResistanceType.Physical, 100);
|
||||
SetResistance(ResistanceType.Poison, 100);
|
||||
|
||||
this.SetAllSkills(0, 0);
|
||||
|
||||
ChangeBody();
|
||||
OnThink();
|
||||
}
|
||||
|
||||
public HauntedMomentoEntity(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public static bool IsBeingLookedAt(Direction facing, Direction to)
|
||||
{
|
||||
if (facing.HasFlag(Direction.Running))
|
||||
{
|
||||
facing &= ~Direction.Running;
|
||||
}
|
||||
|
||||
switch (facing)
|
||||
{
|
||||
case Direction.Up:
|
||||
return (to == Direction.Left || to == Direction.West || to == Direction.Up || to == Direction.North ||
|
||||
to == Direction.Right);
|
||||
case Direction.North:
|
||||
return (to == Direction.West || to == Direction.Up || to == Direction.North || to == Direction.Right ||
|
||||
to == Direction.East);
|
||||
case Direction.Right:
|
||||
return (to == Direction.Up || to == Direction.North || to == Direction.Right || to == Direction.East ||
|
||||
to == Direction.Down);
|
||||
case Direction.East:
|
||||
return (to == Direction.North || to == Direction.Right || to == Direction.East || to == Direction.Down ||
|
||||
to == Direction.South);
|
||||
case Direction.Down:
|
||||
return (to == Direction.Right || to == Direction.East || to == Direction.Down || to == Direction.South ||
|
||||
to == Direction.Left);
|
||||
case Direction.South:
|
||||
return (to == Direction.East || to == Direction.Down || to == Direction.South || to == Direction.Left ||
|
||||
to == Direction.West);
|
||||
case Direction.Left:
|
||||
return (to == Direction.Down || to == Direction.South || to == Direction.Left || to == Direction.West ||
|
||||
to == Direction.Up);
|
||||
case Direction.West:
|
||||
return (to == Direction.South || to == Direction.Left || to == Direction.West || to == Direction.Up ||
|
||||
to == Direction.North);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void ChangeBody()
|
||||
{
|
||||
Body = Utility.RandomList(26, 50, 146, 148, 196, 747, 748, 970);
|
||||
|
||||
PlaySound(1383);
|
||||
}
|
||||
|
||||
public override void OnThink()
|
||||
{
|
||||
base.OnThink();
|
||||
|
||||
if (Deleted || _Momento == null || _Momento.Deleted || _Momento.Map == null || _Momento.Map == Map.Internal ||
|
||||
!(_Momento.RootParent is Mobile))
|
||||
{
|
||||
Delete();
|
||||
return;
|
||||
}
|
||||
|
||||
var parent = (Mobile)_Momento.RootParent;
|
||||
|
||||
if (parent.Deleted || parent.Map == null || parent.Map == Map.Internal)
|
||||
{
|
||||
Delete();
|
||||
return;
|
||||
}
|
||||
|
||||
Hidden = true;
|
||||
|
||||
Home = parent.Location;
|
||||
RangeHome = RangePerception;
|
||||
|
||||
var map = parent.Map;
|
||||
|
||||
if (Map == null || Map == Map.Internal || Map != map || !InRange(parent, 20))
|
||||
{
|
||||
MoveToWorld(parent.GetRandomPoint3D(RangeHome + (RangeHome / 2)).GetWorldTop(map), map);
|
||||
|
||||
ChangeBody();
|
||||
}
|
||||
|
||||
var to = parent.GetDirectionTo(this);
|
||||
|
||||
var stop = (parent.InRange(this, RangeHome / 2));
|
||||
|
||||
if (parent is PlayerMobile)
|
||||
{
|
||||
var hide = (IsBeingLookedAt(parent.Direction, to) || !parent.InRange(this, RangeHome + (RangeHome / 2)));
|
||||
|
||||
if (hide)
|
||||
{
|
||||
((PlayerMobile)parent).VisibilityList.Update(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
((PlayerMobile)parent).VisibilityList.Remove(this);
|
||||
}
|
||||
}
|
||||
|
||||
if (stop)
|
||||
{
|
||||
Frozen = true;
|
||||
return;
|
||||
}
|
||||
|
||||
Frozen = false;
|
||||
|
||||
int x = X, y = Y, z = Z;
|
||||
|
||||
Movement.Offset(GetDirectionTo(Home), ref x, ref y);
|
||||
|
||||
var p = new Point3D(x, y, z).GetWorldTop(map);
|
||||
|
||||
if (!map.CanFit(p, 16))
|
||||
{
|
||||
SetLocation(p, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Move(GetDirectionTo(p));
|
||||
}
|
||||
|
||||
Direction = GetDirectionTo(parent);
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
if (_Momento != null)
|
||||
{
|
||||
var parent = _Momento.RootParent as Mobile;
|
||||
|
||||
if (parent is PlayerMobile)
|
||||
{
|
||||
((PlayerMobile)parent).VisibilityList.Remove(this);
|
||||
}
|
||||
|
||||
if (_Momento.Entity == this)
|
||||
{
|
||||
_Momento.Entity = null;
|
||||
}
|
||||
}
|
||||
|
||||
base.OnAfterDelete();
|
||||
}
|
||||
|
||||
public override bool CanBeDamaged()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool CanBeRenamedBy(Mobile from)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool CanBeControlledBy(Mobile m)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool CheckFlee()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override bool OnMove(Direction d)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnMoveOver(Mobile m)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnMoveOff(Mobile m)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool CheckShove(Mobile shoved)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile m)
|
||||
{ }
|
||||
|
||||
public override void OnAosSingleClick(Mobile m)
|
||||
{ }
|
||||
|
||||
public override void OnSingleClick(Mobile m)
|
||||
{ }
|
||||
|
||||
public override bool OnDragDrop(Mobile from, Item dropped)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool OnDragLift(Item item)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void OnStatsQuery(Mobile from)
|
||||
{ }
|
||||
|
||||
public override void AddNameProperties(ObjectPropertyList list)
|
||||
{ }
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{ }
|
||||
|
||||
public override void GenerateLoot()
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(1);
|
||||
|
||||
writer.Write(_Momento);
|
||||
|
||||
if (version < 1)
|
||||
{
|
||||
writer.Write(false);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
_Momento = reader.ReadItem<HauntedMomento>();
|
||||
|
||||
if (version < 1)
|
||||
{
|
||||
reader.ReadBool();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class HauntedMomento : BaseThrowableAtMobile<Mobile>
|
||||
{
|
||||
private static bool _Initialized;
|
||||
|
||||
[CommandProperty(AccessLevel.Counselor, AccessLevel.GameMaster)]
|
||||
public HauntedMomentoEntity Entity { get; set; }
|
||||
|
||||
[Constructable]
|
||||
public HauntedMomento()
|
||||
: base(0x3679, 1)
|
||||
{
|
||||
Name = "Haunted Momento";
|
||||
Token = "Mysterious Energies Surround This Momento";
|
||||
|
||||
Weight = 1.0;
|
||||
Stackable = false;
|
||||
LootType = LootType.Blessed;
|
||||
|
||||
AllowCombat = false;
|
||||
TargetFlags = TargetFlags.None;
|
||||
|
||||
Delivery = ThrowableAtMobileDelivery.AddToPack;
|
||||
DismountUser = false;
|
||||
|
||||
ThrowSound = 0x180;
|
||||
ImpactSound = 0x181;
|
||||
|
||||
EffectID = ItemID;
|
||||
EffectHue = Hue;
|
||||
|
||||
ThrowRecovery = TimeSpan.Zero;
|
||||
}
|
||||
|
||||
public HauntedMomento(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
if (_Initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EventSink.Login += e =>
|
||||
{
|
||||
if (e.Mobile == null || e.Mobile.Deleted || e.Mobile.Backpack == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
VitaNexCore.TryCatch(
|
||||
() =>
|
||||
{
|
||||
var momentos = e.Mobile.Backpack.FindItemsByType<HauntedMomento>(true);
|
||||
|
||||
momentos.ForEach(
|
||||
m =>
|
||||
{
|
||||
if (m != null && !m.Deleted)
|
||||
{
|
||||
m.InvalidateEntity();
|
||||
}
|
||||
});
|
||||
|
||||
momentos.Clear();
|
||||
});
|
||||
};
|
||||
|
||||
_Initialized = true;
|
||||
}
|
||||
|
||||
public override bool CanThrowAt(Mobile from, Mobile target, bool message)
|
||||
{
|
||||
if (!base.CanThrowAt(from, target, message))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!target.Player)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
from.SendMessage(37, "You can only throw the {0} at other players.", Name);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void OnLocationChange(Point3D oldLocation)
|
||||
{
|
||||
base.OnLocationChange(oldLocation);
|
||||
|
||||
InvalidateEntity();
|
||||
}
|
||||
|
||||
protected virtual HauntedMomentoEntity CreateEntity()
|
||||
{
|
||||
return new HauntedMomentoEntity(this);
|
||||
}
|
||||
|
||||
public override void OnMapChange()
|
||||
{
|
||||
base.OnMapChange();
|
||||
|
||||
InvalidateEntity();
|
||||
|
||||
if (Entity != null)
|
||||
{
|
||||
Entity.ChangeBody();
|
||||
}
|
||||
}
|
||||
|
||||
#if NEWPARENT
|
||||
public override void OnAdded(IEntity parent)
|
||||
#else
|
||||
public override void OnAdded(object parent)
|
||||
#endif
|
||||
{
|
||||
base.OnAdded(parent);
|
||||
|
||||
InvalidateEntity();
|
||||
}
|
||||
|
||||
protected virtual void InvalidateEntity()
|
||||
{
|
||||
if (Map == null || Map == Map.Internal || !(RootParent is Mobile) || Parent is BankBox)
|
||||
{
|
||||
if (Entity != null)
|
||||
{
|
||||
Entity.Delete();
|
||||
Entity = null;
|
||||
}
|
||||
}
|
||||
else if (Entity == null || Entity.Deleted)
|
||||
{
|
||||
Entity = CreateEntity();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
if (Entity != null)
|
||||
{
|
||||
Entity.Delete();
|
||||
}
|
||||
|
||||
base.OnAfterDelete();
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
writer.Write(Entity);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
Entity = reader.ReadMobile<HauntedMomentoEntity>();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Targeting;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class ThrowableRat : BaseThrowableAtMobile<Mobile>
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableRat()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public ThrowableRat(int amount)
|
||||
: base(8483, amount)
|
||||
{
|
||||
Name = "Reeking Rat";
|
||||
Weight = 1.0;
|
||||
Token = "Mickey's Ugly Cousin";
|
||||
|
||||
Consumable = true;
|
||||
AllowCombat = false;
|
||||
TargetFlags = TargetFlags.None;
|
||||
|
||||
Delivery = ThrowableAtMobileDelivery.None;
|
||||
DismountUser = false;
|
||||
|
||||
ThrowSound = 206;
|
||||
ImpactSound = 204;
|
||||
|
||||
EffectID = ItemID;
|
||||
EffectHue = Hue;
|
||||
|
||||
ThrowRecovery = TimeSpan.Zero;
|
||||
}
|
||||
|
||||
public ThrowableRat(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
protected override void OnThrownAt(Mobile from, Mobile target)
|
||||
{
|
||||
if (from == null || from.Deleted || target == null || target.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var rat = new Rat
|
||||
{
|
||||
Name = "Reeking Rat"
|
||||
};
|
||||
|
||||
var pmTarget = target as PlayerMobile;
|
||||
|
||||
if (pmTarget != null)
|
||||
{
|
||||
if (pmTarget.Followers + rat.ControlSlots <= pmTarget.FollowersMax)
|
||||
{
|
||||
rat.Controlled = true;
|
||||
rat.ControlMaster = pmTarget;
|
||||
rat.ControlTarget = pmTarget;
|
||||
rat.ControlOrder = OrderType.Follow;
|
||||
}
|
||||
}
|
||||
|
||||
rat.MoveToWorld(target.Location, target.Map);
|
||||
|
||||
base.OnThrownAt(from, target);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
using Server.Targeting;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class ThrowableRock : BaseThrowableAtMobile<Mobile>
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableRock()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public ThrowableRock(int amount)
|
||||
: base(0x11B6, amount)
|
||||
{
|
||||
Name = "Gigantic Boulder";
|
||||
Usage = "Pass The Rock!";
|
||||
Token = "Your Strength Has Increased By Over 9000!";
|
||||
|
||||
Weight = 1.0;
|
||||
Stackable = true;
|
||||
|
||||
AllowCombat = false;
|
||||
TargetFlags = TargetFlags.None;
|
||||
|
||||
Delivery = ThrowableAtMobileDelivery.AddToPack;
|
||||
DismountUser = false;
|
||||
|
||||
ThrowSound = 543;
|
||||
ImpactSound = 1613;
|
||||
|
||||
EffectID = ItemID;
|
||||
EffectHue = Hue;
|
||||
|
||||
ThrowRecovery = TimeSpan.Zero;
|
||||
}
|
||||
|
||||
public ThrowableRock(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{ }
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{ }
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Targeting;
|
||||
|
||||
using VitaNex.FX;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
[Flipable(10248, 10249)]
|
||||
public class ThrowableStinkBomb : BaseThrowableAtMobile<Mobile>
|
||||
{
|
||||
private static readonly PollTimer _InternalTimer;
|
||||
|
||||
public static Dictionary<Mobile, DateTime> Stinky { get; private set; }
|
||||
|
||||
static ThrowableStinkBomb()
|
||||
{
|
||||
Stinky = new Dictionary<Mobile, DateTime>();
|
||||
|
||||
_InternalTimer = PollTimer.FromSeconds(5.0, InternalCallback, () => Stinky.Count > 0);
|
||||
}
|
||||
|
||||
private static void InternalCallback()
|
||||
{
|
||||
Stinky.RemoveKeyRange(m => !CheckStinky(m));
|
||||
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
var e = Enumerable.Empty<Tuple<Mobile, TimeSpan>>();
|
||||
e = Stinky.Aggregate(e, (c, kv) => c.With(DoStinkEffect(kv.Key).Select(t => Tuple.Create(t, kv.Value - now))));
|
||||
|
||||
foreach (var t in e.Where(t => t.Item2.TotalSeconds > 0))
|
||||
{
|
||||
MakeStinky(t.Item1, t.Item2);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool CheckStinky(Mobile m)
|
||||
{
|
||||
return Stinky.ContainsKey(m) && Stinky[m] >= DateTime.UtcNow;
|
||||
}
|
||||
|
||||
public static void MakeStinky(Mobile m, TimeSpan duration)
|
||||
{
|
||||
Stinky[m] = DateTime.UtcNow + duration;
|
||||
}
|
||||
|
||||
public static IEnumerable<Mobile> DoStinkEffect(Mobile m)
|
||||
{
|
||||
if (!CheckStinky(m) || m.Hidden || !m.Alive)
|
||||
{
|
||||
return Enumerable.Empty<Mobile>();
|
||||
}
|
||||
|
||||
Effects.PlaySound(m.Location, m.Map, 1064);
|
||||
|
||||
new PoisonExplodeEffect(m, m.Map, 1)
|
||||
{
|
||||
EffectMutator = e =>
|
||||
{
|
||||
if (e.ProcessIndex == 0)
|
||||
{
|
||||
e.SoundID = 1064;
|
||||
}
|
||||
},
|
||||
EffectHandler = e =>
|
||||
{
|
||||
if (e.ProcessIndex != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var t in e.Source.FindMobilesInRange(e.Map, 0)
|
||||
.Where(t => t != null && !t.Deleted && t != m && !t.Hidden && t.Alive && t.Body.IsHuman))
|
||||
{
|
||||
Effects.PlaySound(t.Location, t.Map, Utility.RandomList(1065, 1066, 1067));
|
||||
}
|
||||
}
|
||||
}.Send();
|
||||
|
||||
return m.FindMobilesInRange(m.Map, 1)
|
||||
.Where(t => t != null && !t.Deleted && t != m && !t.Hidden && t.Alive && t.Body.IsHuman);
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ExplosionRange { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TimeSpan StinkyDuration { get; set; }
|
||||
|
||||
[Constructable]
|
||||
public ThrowableStinkBomb()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public ThrowableStinkBomb(int amount)
|
||||
: base(Utility.RandomList(10248, 10249), amount)
|
||||
{
|
||||
Name = "Stink Bomb";
|
||||
Usage = "Throw To Unleash A Terrible Smell!";
|
||||
Hue = 1270;
|
||||
Weight = 1.0;
|
||||
Stackable = true;
|
||||
|
||||
StinkyDuration = TimeSpan.FromSeconds(30.0);
|
||||
|
||||
TargetFlags = TargetFlags.None;
|
||||
Delivery = ThrowableAtMobileDelivery.None;
|
||||
|
||||
ThrowSound = 1491;
|
||||
ImpactSound = 1064;
|
||||
|
||||
EffectID = ItemID;
|
||||
EffectHue = Hue;
|
||||
|
||||
ThrowRecovery = TimeSpan.FromSeconds(60.0);
|
||||
|
||||
ExplosionRange = 5;
|
||||
|
||||
RequiredSkill = SkillName.Alchemy;
|
||||
RequiredSkillValue = 25.0;
|
||||
}
|
||||
|
||||
public ThrowableStinkBomb(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
protected override void OnThrownAt(Mobile from, Mobile target)
|
||||
{
|
||||
if (from == null || from.Deleted || target == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int layer = 0, range = ExplosionRange; layer < ExplosionRange && range >= 0; layer++, range--)
|
||||
{
|
||||
new PoisonExplodeEffect(target.Clone3D(0, 0, layer * 10), target.Map, range, 0, null, ExplosionStink).Send();
|
||||
}
|
||||
|
||||
base.OnThrownAt(from, target);
|
||||
}
|
||||
|
||||
public virtual void ExplosionStink(EffectInfo info)
|
||||
{
|
||||
Effects.PlaySound(info.Source.Location, info.Map, ImpactSound);
|
||||
|
||||
foreach (var m in info.Source.FindMobilesInRange(info.Map, 0)
|
||||
.Not(t => t == null || t.Deleted || t.Hidden || (!t.Alive && !AllowDeadTarget)))
|
||||
{
|
||||
Effects.PlaySound(m.Location, m.Map, Utility.RandomList(1065, 1066, 1067));
|
||||
|
||||
if (StinkyDuration > TimeSpan.Zero)
|
||||
{
|
||||
MakeStinky(m, StinkyDuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
writer.Write(ExplosionRange);
|
||||
writer.Write(StinkyDuration);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
ExplosionRange = reader.ReadInt();
|
||||
StinkyDuration = reader.ReadTimeSpan();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (StinkyDuration <= TimeSpan.Zero)
|
||||
{
|
||||
StinkyDuration = TimeSpan.FromSeconds(30);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
using Server;
|
||||
using Server.Items;
|
||||
|
||||
using VitaNex.FX;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
[Flipable(8790, 8791)]
|
||||
public class ThrowableCureBomb : BaseThrowableAtMobile<Mobile>
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ExplosionRange { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public override string Usage
|
||||
{
|
||||
get => !String.IsNullOrWhiteSpace(base.Usage)
|
||||
? base.Usage
|
||||
: String.Format(
|
||||
"Cause an explosion at the target which will attempt to cure all allies within {0:#,0} paces.",
|
||||
ExplosionRange);
|
||||
set => base.Usage = value;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public ThrowableCureBomb()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public ThrowableCureBomb(int amount)
|
||||
: base(Utility.RandomList(8790, 8791), amount)
|
||||
{
|
||||
Name = "Curing Bobomb";
|
||||
Usage = String.Empty;
|
||||
Hue = 74;
|
||||
Weight = 10.0;
|
||||
Stackable = true;
|
||||
|
||||
Delivery = ThrowableAtMobileDelivery.None;
|
||||
|
||||
ThrowSound = 1491;
|
||||
ImpactSound = Utility.RandomList(776, 777);
|
||||
|
||||
EffectID = ItemID;
|
||||
EffectHue = Hue;
|
||||
|
||||
ThrowRecovery = TimeSpan.FromSeconds(60.0);
|
||||
|
||||
ExplosionRange = 5;
|
||||
|
||||
RequiredSkillValue = 100.0;
|
||||
}
|
||||
|
||||
public ThrowableCureBomb(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
protected override void OnThrownAt(Mobile from, Mobile target)
|
||||
{
|
||||
if (from == null || from.Deleted || target == null || target.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var fx = new PoisonExplodeEffect(target, target.Map, ExplosionRange)
|
||||
{
|
||||
EffectHandler = e =>
|
||||
{
|
||||
if (e.ProcessIndex != 0)
|
||||
{
|
||||
ExplosionCure(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
fx.Send();
|
||||
|
||||
base.OnThrownAt(from, target);
|
||||
}
|
||||
|
||||
public virtual void ExplosionCure(EffectInfo info)
|
||||
{
|
||||
Effects.PlaySound(info.Source.Location, info.Map, ImpactSound);
|
||||
|
||||
var targets = info.Source.Location.GetMobilesInRange(info.Map, 0);
|
||||
|
||||
foreach (var m in targets.Where(m => m != null && !m.Deleted && User.CanBeBeneficial(m, false, false)))
|
||||
{
|
||||
m.PlaySound(ImpactSound);
|
||||
m.CurePoison(User);
|
||||
}
|
||||
|
||||
targets.Free(true);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
writer.Write(ExplosionRange);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
ExplosionRange = reader.ReadInt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
using Server;
|
||||
using Server.Items;
|
||||
|
||||
using VitaNex.FX;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
[Flipable(8790, 8791)]
|
||||
public class ThrowableHealBomb : BaseThrowableAtMobile<Mobile>
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ExplosionRange { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public override string Usage
|
||||
{
|
||||
get => !String.IsNullOrWhiteSpace(base.Usage)
|
||||
? base.Usage
|
||||
: String.Format(
|
||||
"Cause an explosion at the target which will replenish {0:#,0} to {1:#,0} health for all allies within {2:#,0} paces.",
|
||||
HealMin,
|
||||
HealMax,
|
||||
ExplosionRange);
|
||||
set => base.Usage = value;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public ThrowableHealBomb()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public ThrowableHealBomb(int amount)
|
||||
: base(Utility.RandomList(8790, 8791), amount)
|
||||
{
|
||||
Name = "Healing Bobomb";
|
||||
Usage = String.Empty;
|
||||
Hue = 55;
|
||||
Weight = 10.0;
|
||||
Stackable = true;
|
||||
|
||||
Delivery = ThrowableAtMobileDelivery.None;
|
||||
|
||||
Heals = true;
|
||||
HealMin = 25;
|
||||
HealMax = 100;
|
||||
|
||||
ThrowSound = 1491;
|
||||
ImpactSound = Utility.RandomList(776, 777);
|
||||
|
||||
EffectID = ItemID;
|
||||
EffectHue = Hue;
|
||||
|
||||
ThrowRecovery = TimeSpan.FromSeconds(60.0);
|
||||
|
||||
ExplosionRange = 5;
|
||||
|
||||
RequiredSkillValue = 100.0;
|
||||
}
|
||||
|
||||
public ThrowableHealBomb(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
protected override void OnThrownAt(Mobile from, Mobile target)
|
||||
{
|
||||
if (from == null || from.Deleted || target == null || target.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var fx = new EnergyExplodeEffect(target, target.Map, ExplosionRange)
|
||||
{
|
||||
EffectHandler = e =>
|
||||
{
|
||||
if (e.ProcessIndex != 0)
|
||||
{
|
||||
ExplosionHeal(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
fx.Send();
|
||||
|
||||
base.OnThrownAt(from, target);
|
||||
}
|
||||
|
||||
public virtual void ExplosionHeal(EffectInfo info)
|
||||
{
|
||||
Effects.PlaySound(info.Source.Location, info.Map, ImpactSound);
|
||||
|
||||
var targets = info.Source.Location.GetMobilesInRange(info.Map, 0);
|
||||
|
||||
foreach (var m in targets.Where(m => m != null && !m.Deleted && User.CanBeBeneficial(m, false, false)))
|
||||
{
|
||||
m.PlaySound(ImpactSound);
|
||||
m.Heal(Utility.RandomMinMax(HealMin, HealMax), User, true);
|
||||
}
|
||||
|
||||
targets.Free(true);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
writer.Write(ExplosionRange);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
ExplosionRange = reader.ReadInt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
using Server;
|
||||
using Server.Items;
|
||||
|
||||
using VitaNex.FX;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
[Flipable(8790, 8791)]
|
||||
public class ThrowableManaBomb : BaseThrowableAtMobile<Mobile>
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ExplosionRange { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public override string Usage
|
||||
{
|
||||
get => !String.IsNullOrWhiteSpace(base.Usage)
|
||||
? base.Usage
|
||||
: String.Format(
|
||||
"Cause an explosion at the target which will replenish {0:#,0} to {1:#,0} mana for all allies within {2:#,0} paces.",
|
||||
HealMin,
|
||||
HealMax,
|
||||
ExplosionRange);
|
||||
set => base.Usage = value;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public ThrowableManaBomb()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public ThrowableManaBomb(int amount)
|
||||
: base(Utility.RandomList(8790, 8791), amount)
|
||||
{
|
||||
Name = "Mana Bobomb";
|
||||
Usage = String.Empty;
|
||||
Hue = 2;
|
||||
Weight = 10.0;
|
||||
Stackable = true;
|
||||
|
||||
Delivery = ThrowableAtMobileDelivery.None;
|
||||
|
||||
HealMin = 25;
|
||||
HealMax = 100;
|
||||
|
||||
ThrowSound = 1491;
|
||||
ImpactSound = Utility.RandomList(776, 777);
|
||||
|
||||
EffectID = ItemID;
|
||||
EffectHue = Hue;
|
||||
|
||||
ThrowRecovery = TimeSpan.FromSeconds(60.0);
|
||||
|
||||
ExplosionRange = 5;
|
||||
|
||||
RequiredSkillValue = 100.0;
|
||||
}
|
||||
|
||||
public ThrowableManaBomb(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
protected override void OnThrownAt(Mobile from, Mobile target)
|
||||
{
|
||||
if (from == null || from.Deleted || target == null || target.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var fx = new EnergyExplodeEffect(target, target.Map, ExplosionRange)
|
||||
{
|
||||
EffectHandler = e =>
|
||||
{
|
||||
if (e.ProcessIndex != 0)
|
||||
{
|
||||
ExplosionMana(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
fx.Send();
|
||||
|
||||
base.OnThrownAt(from, target);
|
||||
}
|
||||
|
||||
public virtual void ExplosionMana(EffectInfo info)
|
||||
{
|
||||
Effects.PlaySound(info.Source.Location, info.Map, ImpactSound);
|
||||
|
||||
var targets = info.Source.Location.GetMobilesInRange(info.Map, 0);
|
||||
|
||||
foreach (var m in targets.Where(m => m != null && !m.Deleted && User.CanBeBeneficial(m, false, false)))
|
||||
{
|
||||
m.PlaySound(ImpactSound);
|
||||
m.Mana += Utility.RandomMinMax(HealMin, HealMax);
|
||||
}
|
||||
|
||||
targets.Free(true);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
writer.Write(ExplosionRange);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
ExplosionRange = reader.ReadInt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
using Server.Network;
|
||||
using Server.Targeting;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class ThrowableAxe : BaseThrowableAtMobile<Mobile>
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool InstantKillForced { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int InstantKillChance { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool InstantKillHead { get; set; }
|
||||
|
||||
[Constructable]
|
||||
public ThrowableAxe()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public ThrowableAxe(int amount)
|
||||
: base(0x255D, amount)
|
||||
{
|
||||
InstantKillForced = false;
|
||||
InstantKillChance = 1;
|
||||
|
||||
Name = "Throwing Axe";
|
||||
Usage = "When thrown, has a slight chance to decapitate the target.";
|
||||
Token = "BOOM! Head Shot!";
|
||||
|
||||
Weight = 10.0;
|
||||
Stackable = true;
|
||||
Consumable = true;
|
||||
AllowCombat = true;
|
||||
|
||||
TargetFlags = TargetFlags.Harmful;
|
||||
|
||||
Delivery = ThrowableAtMobileDelivery.MoveToWorld;
|
||||
DismountUser = true;
|
||||
|
||||
Damages = true;
|
||||
DamageMin = 30;
|
||||
DamageMax = 50;
|
||||
|
||||
ThrowSound = 513;
|
||||
ImpactSound = 1310;
|
||||
|
||||
EffectID = ItemID;
|
||||
EffectHue = Hue;
|
||||
|
||||
ThrowRecovery = TimeSpan.FromMinutes(2.0);
|
||||
|
||||
RequiredSkill = SkillName.Tactics;
|
||||
RequiredSkillValue = 50.0;
|
||||
}
|
||||
|
||||
public ThrowableAxe(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
protected virtual SeveredHead CreateHead(Mobile target)
|
||||
{
|
||||
return !InstantKillHead || target == null || !target.Body.IsHuman || target.Blessed ? null : new SeveredHead(target);
|
||||
}
|
||||
|
||||
protected override void OnThrownAt(Mobile m, Mobile target)
|
||||
{
|
||||
if (m != null && target != null && (InstantKillForced || Utility.RandomDouble() < InstantKillChance / 100.0))
|
||||
{
|
||||
SeveredHead.Decapitate(m, target, CreateHead);
|
||||
m.PublicOverheadMessage(MessageType.Yell, 37, true, "BOOM! Head Shot!");
|
||||
}
|
||||
|
||||
base.OnThrownAt(m, target);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(2);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 2:
|
||||
case 1:
|
||||
writer.Write(InstantKillHead);
|
||||
goto case 0;
|
||||
case 0:
|
||||
{
|
||||
writer.Write(InstantKillForced);
|
||||
writer.Write(InstantKillChance);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 2:
|
||||
case 1:
|
||||
InstantKillHead = reader.ReadBool();
|
||||
goto case 0;
|
||||
case 0:
|
||||
{
|
||||
InstantKillForced = reader.ReadBool();
|
||||
InstantKillChance = version < 2 ? (int)reader.ReadDouble() : reader.ReadInt();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
using Server;
|
||||
using Server.Items;
|
||||
|
||||
using VitaNex.FX;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
[Flipable(8790, 8791)]
|
||||
public class ThrowableBomb : BaseThrowableAtMobile<Mobile>
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ExplosionRange { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public override string Usage
|
||||
{
|
||||
get => !String.IsNullOrWhiteSpace(base.Usage)
|
||||
? base.Usage
|
||||
: String.Format(
|
||||
"Cause an explosion at the target which will deal {0:#,0} to {1:#,0} damage to all enemies within {2:#,0} paces.",
|
||||
DamageMin,
|
||||
DamageMax,
|
||||
ExplosionRange);
|
||||
set => base.Usage = value;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public ThrowableBomb()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public ThrowableBomb(int amount)
|
||||
: base(Utility.RandomList(8790, 8791), amount)
|
||||
{
|
||||
Name = "Bobomb";
|
||||
Token = "A.C.M.E";
|
||||
Hue = 2104;
|
||||
Weight = 10.0;
|
||||
Stackable = true;
|
||||
|
||||
Delivery = ThrowableAtMobileDelivery.None;
|
||||
|
||||
Damages = true;
|
||||
DamageMin = 25;
|
||||
DamageMax = 50;
|
||||
|
||||
ThrowSound = 1491;
|
||||
ImpactSound = Utility.RandomList(776, 777);
|
||||
|
||||
EffectID = ItemID;
|
||||
EffectHue = Hue;
|
||||
|
||||
ThrowRecovery = TimeSpan.FromSeconds(60.0);
|
||||
|
||||
ExplosionRange = 5;
|
||||
|
||||
RequiredSkillValue = 100.0;
|
||||
}
|
||||
|
||||
public ThrowableBomb(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
protected override void OnThrownAt(Mobile from, Mobile target)
|
||||
{
|
||||
if (from == null || from.Deleted || target == null || target.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var fx = new FireExplodeEffect(target, target.Map, ExplosionRange)
|
||||
{
|
||||
EffectHandler = e =>
|
||||
{
|
||||
if (e.ProcessIndex != 0)
|
||||
{
|
||||
ExplosionDamage(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
fx.Send();
|
||||
|
||||
base.OnThrownAt(from, target);
|
||||
}
|
||||
|
||||
public virtual void ExplosionDamage(EffectInfo info)
|
||||
{
|
||||
Effects.PlaySound(info.Source.Location, info.Map, ImpactSound);
|
||||
|
||||
foreach (var m in info.Source.Location.GetMobilesInRange(info.Map, 0)
|
||||
.Where(m => m != null && !m.Deleted && User.CanBeHarmful(m, false, true)))
|
||||
{
|
||||
m.PlaySound(ImpactSound);
|
||||
m.Damage(Utility.RandomMinMax(DamageMin, DamageMax), User, true);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(1);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
case 0:
|
||||
writer.Write(ExplosionRange);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
case 0:
|
||||
{
|
||||
ExplosionRange = reader.ReadInt();
|
||||
|
||||
if (version < 1)
|
||||
{
|
||||
reader.ReadInt();
|
||||
reader.ReadInt();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Targeting;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class ThrowableTrainingDagger : ThrowableDagger
|
||||
{
|
||||
private PollTimer TrainingTimer { get; set; }
|
||||
private Point3D TrainingLocation { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public double SkillGainChance { get; set; }
|
||||
|
||||
[Constructable]
|
||||
public ThrowableTrainingDagger()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public ThrowableTrainingDagger(int amount)
|
||||
: base(amount)
|
||||
{
|
||||
SkillGainChance = 25.0;
|
||||
|
||||
Name = "Throwing Training Dagger";
|
||||
Usage = "Throw at a target to train your Throwing skill.";
|
||||
|
||||
Hue = 2020;
|
||||
Layer = Layer.OneHanded;
|
||||
Weight = 1.0;
|
||||
Stackable = true;
|
||||
|
||||
TargetFlags = TargetFlags.None;
|
||||
|
||||
Consumable = false;
|
||||
Delivery = ThrowableAtMobileDelivery.None;
|
||||
DismountUser = false;
|
||||
|
||||
Damages = false;
|
||||
DamageMin = 0;
|
||||
DamageMax = 0;
|
||||
|
||||
ThrowRecovery = TimeSpan.Zero;
|
||||
|
||||
RequiredSkillValue = 0;
|
||||
}
|
||||
|
||||
public ThrowableTrainingDagger(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
protected override void OnThrownAt(Mobile from, Mobile target)
|
||||
{
|
||||
base.OnThrownAt(from, target);
|
||||
|
||||
if (Utility.RandomDouble() * 100 <= SkillGainChance)
|
||||
{
|
||||
from.Skills[RequiredSkill].IncreaseBase(Utility.RandomDouble());
|
||||
}
|
||||
|
||||
CheckTraining(from, target);
|
||||
}
|
||||
|
||||
public virtual void CheckTraining(Mobile from, Mobile target)
|
||||
{
|
||||
if (from == null || from.Deleted || target == null || target.Deleted)
|
||||
{
|
||||
if (TrainingTimer != null)
|
||||
{
|
||||
TrainingTimer.Stop();
|
||||
TrainingTimer = null;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (TrainingTimer == null)
|
||||
{
|
||||
TrainingLocation = from.Location;
|
||||
|
||||
TrainingTimer = PollTimer.CreateInstance(
|
||||
TimeSpan.FromSeconds(1.0),
|
||||
() =>
|
||||
{
|
||||
if (from.Location != TrainingLocation)
|
||||
{
|
||||
TrainingTimer.Stop();
|
||||
TrainingTimer = null;
|
||||
return;
|
||||
}
|
||||
|
||||
BeginThrow(from, target);
|
||||
});
|
||||
}
|
||||
else if (from.Location != TrainingLocation)
|
||||
{
|
||||
TrainingTimer.Stop();
|
||||
TrainingTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
writer.Write(SkillGainChance);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
SkillGainChance = reader.ReadDouble();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Flipable(3921, 3922)]
|
||||
public class ThrowableDagger : BaseThrowableAtMobile<Mobile>
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableDagger()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public ThrowableDagger(int amount)
|
||||
: base(Utility.RandomList(3921, 3922), amount)
|
||||
{
|
||||
Name = "Throwing Dagger";
|
||||
|
||||
Layer = Layer.OneHanded;
|
||||
Weight = 1.0;
|
||||
Stackable = true;
|
||||
|
||||
TargetFlags = TargetFlags.Harmful;
|
||||
|
||||
Delivery = ThrowableAtMobileDelivery.AddToPack;
|
||||
DismountUser = false;
|
||||
|
||||
Damages = true;
|
||||
DamageMin = 20;
|
||||
DamageMax = 40;
|
||||
|
||||
ThrowSound = 1492;
|
||||
ImpactSound = 903;
|
||||
|
||||
EffectID = ItemID;
|
||||
EffectHue = Hue;
|
||||
|
||||
ThrowRecovery = TimeSpan.FromSeconds(60.0);
|
||||
RequiredSkillValue = 60.0;
|
||||
}
|
||||
|
||||
public ThrowableDagger(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{ }
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{ }
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public abstract class BaseDazingThrowable<TMobile> : BaseThrowableAtMobile<TMobile>
|
||||
where TMobile : Mobile
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual TimeSpan MountRecovery { get; set; }
|
||||
|
||||
public BaseDazingThrowable(int itemID, int amount = 1)
|
||||
: base(itemID, amount)
|
||||
{
|
||||
MountRecovery = TimeSpan.FromSeconds(3.0);
|
||||
}
|
||||
|
||||
public BaseDazingThrowable(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override bool CanThrowAt(Mobile from, TMobile target, bool message)
|
||||
{
|
||||
if (!base.CanThrowAt(from, target, message))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!target.Mounted)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
from.SendMessage(37, "Your target is not mounted.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void OnThrownAt(Mobile from, TMobile target)
|
||||
{
|
||||
base.OnThrownAt(from, target);
|
||||
|
||||
var mounted = target.Mounted;
|
||||
|
||||
if (target is PlayerMobile)
|
||||
{
|
||||
var pm = target as PlayerMobile;
|
||||
|
||||
pm.SetMountBlock(BlockMountType.Dazed, MountRecovery, mounted);
|
||||
}
|
||||
|
||||
if (!mounted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BaseMount.Dismount(target);
|
||||
OnTargetDismounted(from, target, true);
|
||||
}
|
||||
|
||||
protected virtual void OnTargetDismounted(Mobile from, TMobile target, bool message)
|
||||
{
|
||||
if (from == null || from.Deleted || target == null || target.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (message)
|
||||
{
|
||||
target.SendMessage(37, "{0} has brought you down with the {1}!", from.RawName, Name);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
writer.Write(MountRecovery);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
MountRecovery = reader.ReadTimeSpan();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,633 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
using Server.Spells;
|
||||
using Server.Targeting;
|
||||
|
||||
using VitaNex.FX;
|
||||
using VitaNex.Network;
|
||||
using VitaNex.Targets;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public abstract class BaseThrowable<TEntity> : Item, IBaseThrowable
|
||||
where TEntity : IEntity
|
||||
{
|
||||
public PollTimer UpdateTimer { get; protected set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual bool Silent { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual string Usage { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual string Token { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual bool AllowNoOwner { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual bool AllowCombat { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual bool AllowDeadUser { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual bool Consumable { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual bool ClearHands { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual bool DismountUser { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual int EffectID { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual int EffectHue { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual int EffectSpeed { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual EffectRender EffectRender { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual TargetFlags TargetFlags { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual int ThrowSound { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual int ImpactSound { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual int ThrowRange { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual TimeSpan ThrowRecovery { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual DateTime ThrownLast { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual SkillName RequiredSkill { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual double RequiredSkillValue { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual Mobile User { get; set; }
|
||||
|
||||
public BaseThrowable(int itemID)
|
||||
: this(itemID, 1)
|
||||
{ }
|
||||
|
||||
public BaseThrowable(int itemID, int amount)
|
||||
: base(itemID)
|
||||
{
|
||||
Stackable = true;
|
||||
Amount = amount;
|
||||
Weight = 1.0;
|
||||
|
||||
Usage = "Throw Me!";
|
||||
AllowNoOwner = false;
|
||||
AllowCombat = true;
|
||||
AllowDeadUser = false;
|
||||
Consumable = true;
|
||||
ClearHands = true;
|
||||
DismountUser = true;
|
||||
EffectID = 0;
|
||||
EffectHue = 0;
|
||||
EffectRender = EffectRender.Normal;
|
||||
EffectSpeed = 10;
|
||||
ThrowSound = -1;
|
||||
ImpactSound = -1;
|
||||
ThrowRecovery = TimeSpan.FromSeconds(60.0);
|
||||
ThrowRange = 12;
|
||||
RequiredSkill = SkillName.Throwing;
|
||||
RequiredSkillValue = 0;
|
||||
}
|
||||
|
||||
public BaseThrowable(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void OnAfterDuped(Item newItem)
|
||||
{
|
||||
base.OnAfterDuped(newItem);
|
||||
|
||||
var t = newItem as BaseThrowable<TEntity>;
|
||||
|
||||
if (t != null)
|
||||
{
|
||||
t.UpdateTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
base.OnAfterDelete();
|
||||
|
||||
if (UpdateTimer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateTimer.Running = false;
|
||||
UpdateTimer = null;
|
||||
}
|
||||
|
||||
public virtual bool CanThrow(Mobile m, bool message)
|
||||
{
|
||||
if (m == null || m.Deleted)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m.AccessLevel >= AccessLevel.GameMaster)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!AllowNoOwner && RootParent != m)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage(37, "You must own the {0} before you can throw it!", this.ResolveName(m));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m.Alive && !AllowDeadUser)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage(37, "You can't throw the {0} while dead.", this.ResolveName(m));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (RequiredSkillValue > 0 && m.Skills[RequiredSkill].Value < RequiredSkillValue)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage(37, "You do not have the skill required to throw the {0}.", this.ResolveName(m));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m.CanBeginAction(GetType()))
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage(37, "Your arms are tired, you must wait to throw another {0}!", this.ResolveName(m));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!AllowCombat && SpellHelper.CheckCombat(m))
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage(37, "You can't throw the {0} while in combat!", this.ResolveName(m));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m.BodyMod > 0 && !m.BodyMod.IsHuman)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage(37, "How are you supposed to throw the {0} with no hands, beast?", this.ResolveName(m));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual bool CanThrowAt(Mobile m, TEntity target, bool message)
|
||||
{
|
||||
if (m == null || m.Deleted || target == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m == target as Mobile)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage(37, "You can't throw the {0} at yourself!", this.ResolveName(m));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m.AccessLevel >= AccessLevel.GameMaster)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!m.CanSee(target) || !m.InLOS(target))
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage(37, "You can't aim at something you can't see!");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void BeginThrow(Mobile m, TEntity target)
|
||||
{
|
||||
if (m == null || m.Deleted || target == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CanThrow(m, true) || !CanThrowAt(m, target, true) ||
|
||||
(m.AccessLevel < AccessLevel.GameMaster && !m.BeginAction(GetType())))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
User = m;
|
||||
|
||||
OnBeforeThrownAt(m, target);
|
||||
|
||||
var effect = EffectID > 0 ? EffectID : ItemID;
|
||||
var hue = EffectHue > 0 ? EffectHue : Hue;
|
||||
|
||||
new MovingEffectInfo(m, target, target.Map, effect, hue, EffectSpeed, EffectRender).MovingImpact(
|
||||
() => FinishThrow(m, target));
|
||||
}
|
||||
|
||||
public virtual void FinishThrow(Mobile m, TEntity target)
|
||||
{
|
||||
if (m != null && !m.Deleted && target != null)
|
||||
{
|
||||
OnThrownAt(m, target);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual Target BeginTarget(Mobile m)
|
||||
{
|
||||
return new GenericSelectTarget<TEntity>(BeginThrow, t => { }, ThrowRange, false, TargetFlags);
|
||||
}
|
||||
|
||||
protected virtual void OnBeginTarget(Mobile m, bool message)
|
||||
{
|
||||
if (m == null || m.Deleted || !message || Silent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m.LocalOverheadMessage(
|
||||
MessageType.Emote,
|
||||
0x55,
|
||||
true,
|
||||
String.Format("You begin to swing the {0}...", this.ResolveName(m)));
|
||||
m.NonlocalOverheadMessage(
|
||||
MessageType.Emote,
|
||||
0x55,
|
||||
true,
|
||||
String.Format("{0} begins to swing the {1}...", m.RawName, this.ResolveName(m)));
|
||||
}
|
||||
|
||||
protected virtual void OnBeforeThrownAt(Mobile m, TEntity target)
|
||||
{
|
||||
if (m == null || m.Deleted || target == null || !CanThrowAt(m, target, false))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m.Spell != null)
|
||||
{
|
||||
m.Spell.OnCasterUsingObject(this);
|
||||
}
|
||||
|
||||
if (DismountUser)
|
||||
{
|
||||
EtherealMount.StopMounting(m);
|
||||
}
|
||||
|
||||
if (ClearHands)
|
||||
{
|
||||
m.ClearHands();
|
||||
}
|
||||
|
||||
if (DismountUser && m.Mounted)
|
||||
{
|
||||
BaseMount.Dismount(m);
|
||||
}
|
||||
|
||||
if ((m.Direction & Direction.Running) != Direction.Running)
|
||||
{
|
||||
m.Direction = m.GetDirectionTo(target.Location);
|
||||
}
|
||||
|
||||
m.Animate(11, 5, 1, true, false, 0);
|
||||
|
||||
if (ThrowSound >= 0)
|
||||
{
|
||||
m.PlaySound(ThrowSound);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnThrownAt(Mobile m, TEntity target)
|
||||
{
|
||||
if (m == null || m.Deleted || target == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ImpactSound >= 0)
|
||||
{
|
||||
Effects.PlaySound(target.Location, target.Map, ImpactSound);
|
||||
}
|
||||
|
||||
ThrownLast = DateTime.UtcNow;
|
||||
|
||||
if (Consumable)
|
||||
{
|
||||
Consume();
|
||||
}
|
||||
|
||||
if (ThrowRecovery > TimeSpan.Zero)
|
||||
{
|
||||
if (UpdateTimer == null)
|
||||
{
|
||||
UpdateTimer = PollTimer.FromSeconds(
|
||||
1.0,
|
||||
() =>
|
||||
{
|
||||
ClearProperties();
|
||||
Delta(ItemDelta.Properties);
|
||||
|
||||
var readyWhen = ThrownLast + ThrowRecovery;
|
||||
|
||||
if (DateTime.UtcNow < readyWhen)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m.EndAction(GetType());
|
||||
|
||||
if (UpdateTimer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateTimer.Running = false;
|
||||
UpdateTimer = null;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateTimer.Running = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (UpdateTimer != null)
|
||||
{
|
||||
UpdateTimer.Running = false;
|
||||
UpdateTimer = null;
|
||||
}
|
||||
|
||||
ClearProperties();
|
||||
Delta(ItemDelta.Properties);
|
||||
m.EndAction(GetType());
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
base.OnDelete();
|
||||
|
||||
if (UpdateTimer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateTimer.Running = false;
|
||||
UpdateTimer = null;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile m)
|
||||
{
|
||||
if (m == null || m.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CanThrow(m, true))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m.Spell != null)
|
||||
{
|
||||
m.Spell.OnCasterUsingObject(this);
|
||||
}
|
||||
|
||||
if (ClearHands)
|
||||
{
|
||||
m.ClearHands();
|
||||
}
|
||||
|
||||
if (DismountUser)
|
||||
{
|
||||
EtherealMount.StopMounting(m);
|
||||
}
|
||||
|
||||
if (DismountUser && m.Mounted)
|
||||
{
|
||||
BaseMount.Dismount(m);
|
||||
}
|
||||
|
||||
m.Target = BeginTarget(m);
|
||||
OnBeginTarget(m, true);
|
||||
}
|
||||
|
||||
public override void OnAosSingleClick(Mobile from)
|
||||
{
|
||||
OnSingleClick(from);
|
||||
}
|
||||
|
||||
public override void OnSingleClick(Mobile from)
|
||||
{
|
||||
base.OnSingleClick(from);
|
||||
|
||||
DateTime now = DateTime.UtcNow, readyWhen = ThrownLast + ThrowRecovery;
|
||||
var diff = TimeSpan.Zero;
|
||||
|
||||
if (readyWhen > now)
|
||||
{
|
||||
diff = readyWhen - now;
|
||||
}
|
||||
|
||||
if (diff > TimeSpan.Zero)
|
||||
{
|
||||
var time = String.Format("{0:D2}:{1:D2}:{2:D2}", diff.Hours, diff.Minutes, diff.Seconds);
|
||||
LabelTo(from, "Use: {0}", time);
|
||||
}
|
||||
else if (!String.IsNullOrWhiteSpace(Usage))
|
||||
{
|
||||
LabelTo(from, "Use: {0}", Usage);
|
||||
}
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(Token))
|
||||
{
|
||||
LabelTo(from, "\"{0}\"", Token);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(2);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 3:
|
||||
writer.Write(AllowNoOwner);
|
||||
goto case 2;
|
||||
case 2:
|
||||
case 1:
|
||||
writer.Write(Silent);
|
||||
goto case 0;
|
||||
case 0:
|
||||
{
|
||||
writer.Write(Usage);
|
||||
writer.Write(Token);
|
||||
writer.Write(AllowCombat);
|
||||
writer.Write(AllowDeadUser);
|
||||
writer.Write(Consumable);
|
||||
writer.Write(ClearHands);
|
||||
writer.Write(DismountUser);
|
||||
writer.Write(EffectID);
|
||||
writer.Write(EffectHue);
|
||||
writer.Write(EffectSpeed);
|
||||
|
||||
if (version < 2)
|
||||
{
|
||||
writer.Write((short)EffectRender);
|
||||
writer.Write((byte)TargetFlags);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteFlag(EffectRender);
|
||||
writer.WriteFlag(TargetFlags);
|
||||
}
|
||||
|
||||
writer.Write(ThrowSound);
|
||||
writer.Write(ImpactSound);
|
||||
writer.Write(ThrowRange);
|
||||
writer.Write(ThrowRecovery);
|
||||
writer.Write(ThrownLast);
|
||||
|
||||
if (version < 2)
|
||||
{
|
||||
writer.Write((short)RequiredSkill);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteFlag(RequiredSkill);
|
||||
}
|
||||
|
||||
writer.Write(RequiredSkillValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 3:
|
||||
AllowNoOwner = reader.ReadBool();
|
||||
goto case 2;
|
||||
case 2:
|
||||
case 1:
|
||||
Silent = reader.ReadBool();
|
||||
goto case 0;
|
||||
case 0:
|
||||
{
|
||||
Usage = reader.ReadString();
|
||||
Token = reader.ReadString();
|
||||
AllowCombat = reader.ReadBool();
|
||||
AllowDeadUser = reader.ReadBool();
|
||||
Consumable = reader.ReadBool();
|
||||
ClearHands = reader.ReadBool();
|
||||
DismountUser = reader.ReadBool();
|
||||
EffectID = reader.ReadInt();
|
||||
EffectHue = reader.ReadInt();
|
||||
EffectSpeed = reader.ReadInt();
|
||||
|
||||
if (version < 2)
|
||||
{
|
||||
EffectRender = (EffectRender)reader.ReadShort();
|
||||
TargetFlags = (TargetFlags)reader.ReadByte();
|
||||
}
|
||||
else
|
||||
{
|
||||
EffectRender = reader.ReadFlag<EffectRender>();
|
||||
TargetFlags = reader.ReadFlag<TargetFlags>();
|
||||
}
|
||||
|
||||
ThrowSound = reader.ReadInt();
|
||||
ImpactSound = reader.ReadInt();
|
||||
ThrowRange = reader.ReadInt();
|
||||
ThrowRecovery = reader.ReadTimeSpan();
|
||||
ThrownLast = reader.ReadDateTime();
|
||||
|
||||
if (version < 2)
|
||||
{
|
||||
RequiredSkill = (SkillName)reader.ReadShort();
|
||||
}
|
||||
else
|
||||
{
|
||||
RequiredSkill = reader.ReadFlag<SkillName>();
|
||||
}
|
||||
|
||||
RequiredSkillValue = reader.ReadDouble();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
using Server.Targeting;
|
||||
|
||||
using VitaNex.Targets;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public enum ThrowableAtMobileDelivery : byte
|
||||
{
|
||||
None = 0x00,
|
||||
MoveToWorld = 0x01,
|
||||
AddToPack = 0x02
|
||||
}
|
||||
|
||||
public abstract class BaseThrowableAtMobile<TMobile> : BaseThrowable<TMobile>
|
||||
where TMobile : Mobile
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual bool AllowDeadTarget { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual ThrowableAtMobileDelivery Delivery { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual bool Damages { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual int DamageMin { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual int DamageMax { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual bool Heals { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual int HealMin { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual int HealMax { get; set; }
|
||||
|
||||
public BaseThrowableAtMobile(int itemID)
|
||||
: this(itemID, 1)
|
||||
{ }
|
||||
|
||||
public BaseThrowableAtMobile(int itemID, int amount)
|
||||
: base(itemID, amount)
|
||||
{
|
||||
AllowDeadTarget = false;
|
||||
Delivery = ThrowableAtMobileDelivery.MoveToWorld;
|
||||
Damages = false;
|
||||
DamageMin = 0;
|
||||
DamageMax = 0;
|
||||
Heals = false;
|
||||
HealMin = 0;
|
||||
HealMax = 0;
|
||||
}
|
||||
|
||||
public BaseThrowableAtMobile(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override bool CanThrowAt(Mobile from, TMobile target, bool message)
|
||||
{
|
||||
if (from == null || from.Deleted || target == null || target.Deleted || !base.CanThrowAt(from, target, message))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!target.Alive && !AllowDeadTarget)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
from.SendMessage(37, "You can't throw the {0} at the dead.", Name);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (target.Alive && Damages && !from.CanBeHarmful(target, false, true))
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
from.SendMessage(37, "You can't harm them.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (target.Alive && Heals && !from.CanBeBeneficial(target, false, true))
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
from.SendMessage(37, "You can't heal them.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void OnBeforeThrownAt(Mobile from, TMobile target)
|
||||
{
|
||||
if (from == null || from.Deleted || target == null || target.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (target.Alive && Heals)
|
||||
{
|
||||
from.DoBeneficial(target);
|
||||
}
|
||||
|
||||
if (target.Alive && Damages)
|
||||
{
|
||||
from.DoHarmful(target);
|
||||
}
|
||||
|
||||
base.OnBeforeThrownAt(from, target);
|
||||
}
|
||||
|
||||
protected override void OnThrownAt(Mobile from, TMobile target)
|
||||
{
|
||||
if (from == null || from.Deleted || target == null || target.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (target.Alive && Damages)
|
||||
{
|
||||
target.Damage(Utility.RandomMinMax(DamageMin, DamageMax), from);
|
||||
}
|
||||
|
||||
if (target.Alive && Heals)
|
||||
{
|
||||
target.Heal(Utility.RandomMinMax(HealMin, HealMax), from);
|
||||
}
|
||||
|
||||
if (Delivery != ThrowableAtMobileDelivery.None)
|
||||
{
|
||||
var instance = VitaNexCore.TryCatchGet(() => GetType().CreateInstance<BaseThrowableAtMobile<TMobile>>());
|
||||
|
||||
if (instance != null)
|
||||
{
|
||||
switch (Delivery)
|
||||
{
|
||||
case ThrowableAtMobileDelivery.MoveToWorld:
|
||||
instance.MoveToWorld(target.Location, target.Map);
|
||||
break;
|
||||
case ThrowableAtMobileDelivery.AddToPack:
|
||||
{
|
||||
if (!target.AddToBackpack(instance))
|
||||
{
|
||||
instance.MoveToWorld(target.Location, target.Map);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
instance.Delete();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base.OnThrownAt(from, target);
|
||||
}
|
||||
|
||||
public override Target BeginTarget(Mobile from)
|
||||
{
|
||||
return new MobileSelectTarget<TMobile>(BeginThrow, src => { }, ThrowRange, false, TargetFlags);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(1);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
case 0:
|
||||
{
|
||||
writer.Write(AllowDeadTarget);
|
||||
|
||||
if (version < 1)
|
||||
{
|
||||
writer.Write((byte)Delivery);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteFlag(Delivery);
|
||||
}
|
||||
|
||||
writer.Write(Damages);
|
||||
writer.Write(DamageMin);
|
||||
writer.Write(DamageMax);
|
||||
writer.Write(Heals);
|
||||
writer.Write(HealMin);
|
||||
writer.Write(HealMax);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
case 0:
|
||||
{
|
||||
AllowDeadTarget = reader.ReadBool();
|
||||
|
||||
if (version < 1)
|
||||
{
|
||||
Delivery = (ThrowableAtMobileDelivery)reader.ReadByte();
|
||||
}
|
||||
else
|
||||
{
|
||||
Delivery = reader.ReadFlag<ThrowableAtMobileDelivery>();
|
||||
}
|
||||
|
||||
Damages = reader.ReadBool();
|
||||
DamageMin = reader.ReadInt();
|
||||
DamageMax = reader.ReadInt();
|
||||
Heals = reader.ReadBool();
|
||||
HealMin = reader.ReadInt();
|
||||
HealMax = reader.ReadInt();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
|
||||
using Server;
|
||||
|
||||
using VitaNex.Network;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public static class BaseThrowableOPL
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
ExtendedOPL.OnItemOPLRequest += OnItemOPLRequest;
|
||||
}
|
||||
|
||||
private static void OnItemOPLRequest(Item item, Mobile viewer, ExtendedOPL list)
|
||||
{
|
||||
if (item == null || list == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (viewer == null && item.Parent is Mobile)
|
||||
{
|
||||
viewer = (Mobile)item.Parent;
|
||||
}
|
||||
|
||||
if (viewer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var throwable = item as IBaseThrowable;
|
||||
|
||||
if (throwable == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GetProperties(throwable, viewer, list);
|
||||
}
|
||||
|
||||
public static void GetProperties(IBaseThrowable throwable, Mobile viewer, ExtendedOPL list)
|
||||
{
|
||||
if (throwable == null || list == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var lines = new List<string>();
|
||||
|
||||
if (throwable.Consumable)
|
||||
{
|
||||
lines.Add("Consumable");
|
||||
}
|
||||
|
||||
if (throwable.ClearHands)
|
||||
{
|
||||
lines.Add("Clears Hands");
|
||||
}
|
||||
|
||||
if (!throwable.AllowCombat)
|
||||
{
|
||||
lines.Add("Non-Combat");
|
||||
}
|
||||
|
||||
if (lines.Count > 0)
|
||||
{
|
||||
list.Add(String.Join(", ", lines).WrapUOHtmlColor(Color.Orange));
|
||||
lines.Clear();
|
||||
}
|
||||
|
||||
if (throwable.RequiredSkillValue > 0)
|
||||
{
|
||||
list.Add("Required Skill: {0} - {1:F2}%", throwable.RequiredSkill, throwable.RequiredSkillValue);
|
||||
}
|
||||
|
||||
DateTime now = DateTime.UtcNow, readyWhen = (throwable.ThrownLast + throwable.ThrowRecovery);
|
||||
var diff = TimeSpan.Zero;
|
||||
|
||||
if (readyWhen > now)
|
||||
{
|
||||
diff = readyWhen - now;
|
||||
}
|
||||
|
||||
if (diff > TimeSpan.Zero)
|
||||
{
|
||||
list.Add("Use: {0:D2}:{1:D2}:{2:D2}".WrapUOHtmlColor(Color.LimeGreen), diff.Hours, diff.Minutes, diff.Seconds);
|
||||
}
|
||||
else if (!String.IsNullOrWhiteSpace(throwable.Usage))
|
||||
{
|
||||
list.Add("Use: {0}".WrapUOHtmlColor(Color.Cyan), throwable.Usage);
|
||||
}
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(throwable.Token))
|
||||
{
|
||||
list.Add("\"{0}\"".WrapUOHtmlColor(Color.Gold), throwable.Token);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
using Server.Targeting;
|
||||
|
||||
using VitaNex.Network;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public interface IBaseThrowable
|
||||
{
|
||||
string Token { get; set; }
|
||||
string Usage { get; set; }
|
||||
|
||||
bool AllowCombat { get; set; }
|
||||
bool AllowDeadUser { get; set; }
|
||||
bool ClearHands { get; set; }
|
||||
bool Consumable { get; set; }
|
||||
bool DismountUser { get; set; }
|
||||
|
||||
int EffectHue { get; set; }
|
||||
int EffectID { get; set; }
|
||||
int EffectSpeed { get; set; }
|
||||
EffectRender EffectRender { get; set; }
|
||||
|
||||
int ThrowSound { get; set; }
|
||||
int ImpactSound { get; set; }
|
||||
|
||||
SkillName RequiredSkill { get; set; }
|
||||
double RequiredSkillValue { get; set; }
|
||||
|
||||
TargetFlags TargetFlags { get; set; }
|
||||
DateTime ThrownLast { get; set; }
|
||||
TimeSpan ThrowRecovery { get; set; }
|
||||
int ThrowRange { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user