Overwrite

Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
Unstable Kitsune
2023-11-28 23:20:26 -05:00
parent 3cd54811de
commit b918192e4e
11608 changed files with 2644205 additions and 47 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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