Reorganizes Project (#41)

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

View file

@ -0,0 +1,328 @@
using System;
using System.Collections.Generic;
using Server.Events.Halloween;
using Server.Items;
using Server.Mobiles;
using Server.Targeting;
namespace Server.Engines.Events
{
public class TrickOrTreat
{
public static TimeSpan OneSecond = TimeSpan.FromSeconds(1);
public static void Initialize()
{
DateTime now = DateTime.UtcNow;
if (DateTime.UtcNow >= HolidaySettings.StartHalloween && DateTime.UtcNow <= HolidaySettings.FinishHalloween)
EventSink.Speech += EventSink_Speech;
}
private static void EventSink_Speech(SpeechEventArgs e)
{
if (Insensitive.Contains(e.Speech, "trick or treat"))
{
e.Mobile.Target = new TrickOrTreatTarget();
e.Mobile.SendLocalizedMessage(1076764); /* Pick someone to Trick or Treat. */
}
}
public static void Bleeding(Mobile m_From)
{
if (CheckMobile(m_From))
if (m_From.Location != Point3D.Zero)
{
int amount = Utility.RandomMinMax(3, 7);
for (int i = 0; i < amount; i++)
new Blood(Utility.RandomMinMax(0x122C, 0x122F)).MoveToWorld(
RandomPointOneAway(m_From.X, m_From.Y, m_From.Z, m_From.Map), m_From.Map);
}
}
public static void RemoveHueMod(Mobile target)
{
if (target?.Deleted == false)
target.SolidHueOverride = -1;
}
public static void SolidHueMobile(Mobile target)
{
if (CheckMobile(target))
{
target.SolidHueOverride = Utility.RandomMinMax(2501, 2644);
Timer.DelayCall(TimeSpan.FromSeconds(10), RemoveHueMod, target);
}
}
public static void MakeTwin(Mobile m_From)
{
List<Item> m_Items = new List<Item>();
if (CheckMobile(m_From))
{
Mobile twin = new NaughtyTwin(m_From);
if (twin.Deleted)
return;
foreach (Item item in m_From.Items)
if (item.Layer != Layer.Backpack && item.Layer != Layer.Mount && item.Layer != Layer.Bank)
m_Items.Add(item);
if (m_Items.Count > 0)
{
for (int i = 0; i < m_Items.Count; i++) /* dupe exploits start out like this ... */
twin.AddItem(Mobile.LiftItemDupe(m_Items[i], 1));
foreach (Item item in twin.Items) /* ... and end like this */
if (item.Layer != Layer.Backpack && item.Layer != Layer.Mount && item.Layer != Layer.Bank)
item.Movable = false;
}
twin.Hue = m_From.Hue;
twin.BodyValue = m_From.BodyValue;
twin.Kills = m_From.Kills;
Point3D point = RandomPointOneAway(m_From.X, m_From.Y, m_From.Z, m_From.Map);
twin.MoveToWorld(m_From.Map.CanSpawnMobile(point) ? point : m_From.Location, m_From.Map);
Timer.DelayCall(TimeSpan.FromSeconds(5), DeleteTwin, twin);
}
}
public static void DeleteTwin(Mobile m_Twin)
{
if (CheckMobile(m_Twin)) m_Twin.Delete();
}
public static Point3D RandomPointOneAway(int x, int y, int z, Map map)
{
Point3D loc = new Point3D(x + Utility.Random(-1, 3), y + Utility.Random(-1, 3), 0);
loc.Z = map.CanFit(loc, 0) ? map.GetAverageZ(loc.X, loc.Y) : z;
return loc;
}
public static bool CheckMobile(Mobile mobile)
{
return mobile?.Map != null && !mobile.Deleted && mobile.Alive && mobile.Map != Map.Internal;
}
private class TrickOrTreatTarget : Target
{
public TrickOrTreatTarget()
: base(15, false, TargetFlags.None)
{
}
protected override void OnTarget(Mobile from, object targ)
{
if (targ == null || !CheckMobile(from))
return;
if (!(targ is Mobile))
{
from.SendLocalizedMessage(1076781); /* There is little chance of getting candy from that! */
return;
}
BaseVendor begged = targ as BaseVendor;
if (begged?.Deleted != false)
{
from.SendLocalizedMessage(1076765); /* That doesn't look friendly. */
return;
}
DateTime now = DateTime.UtcNow;
if (CheckMobile(begged))
{
if (begged.NextTrickOrTreat > now)
{
from.SendLocalizedMessage(1076767); /* That doesn't appear to have any more candy. */
return;
}
begged.NextTrickOrTreat = now + TimeSpan.FromMinutes(Utility.RandomMinMax(5, 10));
if (from.Backpack?.Deleted != false)
return;
if (Utility.RandomDouble() > .10)
{
switch (Utility.Random(3))
{
case 0:
begged.Say(1076768);
break; /* Oooooh, aren't you cute! */
case 1:
begged.Say(1076779);
break; /* All right...This better not spoil your dinner! */
case 2:
begged.Say(1076778);
break; /* Here you go! Enjoy! */
}
if (Utility.RandomDouble() <= .01 && from.Skills.Begging.Value >= 100)
{
from.AddToBackpack(HolidaySettings.RandomGMBeggerItem);
from.SendLocalizedMessage(1076777); /* You receive a special treat! */
}
else
{
from.AddToBackpack(HolidaySettings.RandomTreat);
from.SendLocalizedMessage(1076769); /* You receive some candy. */
}
}
else
{
begged.Say(1076770); /* TRICK! */
int action = Utility.Random(4);
if (action == 0)
Timer.DelayCall(OneSecond, OneSecond, 10, Bleeding, from);
else if (action == 1)
Timer.DelayCall(TimeSpan.FromSeconds(2), SolidHueMobile, from);
else
Timer.DelayCall(TimeSpan.FromSeconds(2), MakeTwin, from);
}
}
}
}
}
public class NaughtyTwin : BaseCreature
{
private static Point3D[] Felucca_Locations =
{
new Point3D(4467, 1283, 5), // Moonglow
new Point3D(1336, 1997, 5), // Britain
new Point3D(1499, 3771, 5), // Jhelom
new Point3D(771, 752, 5), // Yew
new Point3D(2701, 692, 5), // Minoc
new Point3D(1828, 2948, -20), // Trinsic
new Point3D(643, 2067, 5), // Skara Brae
new Point3D(3563, 2139, Map.Trammel.GetAverageZ(3563, 2139)) // (New) Magincia
};
private static Point3D[] Malas_Locations =
{
new Point3D(1015, 527, -65), // Luna
new Point3D(1997, 1386, -85) // Umbra
};
private static Point3D[] Ilshenar_Locations =
{
new Point3D(1215, 467, -13), // Compassion
new Point3D(722, 1366, -60), // Honesty
new Point3D(744, 724, -28), // Honor
new Point3D(281, 1016, 0), // Humility
new Point3D(987, 1011, -32), // Justice
new Point3D(1174, 1286, -30), // Sacrifice
new Point3D(1532, 1340, -3), // Spirituality
new Point3D(528, 216, -45), // Valor
new Point3D(1721, 218, 96) // Chaos
};
private static Point3D[] Tokuno_Locations =
{
new Point3D(1169, 998, 41), // Isamu-Jima
new Point3D(802, 1204, 25), // Makoto-Jima
new Point3D(270, 628, 15) // Homare-Jima
};
private Mobile m_From;
public NaughtyTwin(Mobile from)
: base(AIType.AI_Melee, FightMode.None, 10, 1, 0.2, 0.4)
{
if (TrickOrTreat.CheckMobile(from))
{
Body = from.Body;
m_From = from;
Name = $"{from.Name}\'s Naughty Twin";
Timer.DelayCall(TrickOrTreat.OneSecond, StealCandyOrGate, m_From);
}
}
public NaughtyTwin(Serial serial)
: base(serial)
{
}
public override void OnThink()
{
if (m_From?.Deleted != false)
Delete();
}
public static Item FindCandyTypes(Mobile target)
{
Type[] types =
{ typeof(WrappedCandy), typeof(Lollipops), typeof(NougatSwirl), typeof(Taffy), typeof(JellyBeans) };
if (TrickOrTreat.CheckMobile(target))
return target.Backpack.FindItemByType(types);
return null;
}
public static void StealCandyOrGate(Mobile target)
{
if (TrickOrTreat.CheckMobile(target))
{
if (Utility.RandomBool())
{
Item item = FindCandyTypes(target);
target.SendLocalizedMessage(1113967); /* Your naughty twin steals some of your candy. */
if (item?.Deleted == false)
item.Delete();
}
else
{
target.SendLocalizedMessage(1113972); /* Your naughty twin teleports you away with a naughty laugh! */
target.MoveToWorld(RandomMoongate(target), target.Map);
}
}
}
public static Point3D RandomMoongate(Mobile target)
{
switch (target.Map.MapID)
{
case 2: return Ilshenar_Locations[Utility.Random(Ilshenar_Locations.Length)];
case 3: return Malas_Locations[Utility.Random(Malas_Locations.Length)];
case 4: return Tokuno_Locations[Utility.Random(Tokuno_Locations.Length)];
default: return Felucca_Locations[Utility.Random(Felucca_Locations.Length)];
}
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,96 @@
using Server.Mobiles;
namespace Server.Items
{
public class HalloweenPumpkin : Item
{
private static readonly string[] m_Staff =
{
"Ryan", "Mark", "Eos", "Athena", "Xavier", "Krrios", "Zippy"
};
[Constructible]
public HalloweenPumpkin()
{
Weight = Utility.RandomMinMax(3, 20);
ItemID = Utility.RandomDouble() <= .02
? Utility.RandomList(0x4694, 0x4698)
: Utility.RandomList(0xc6a, 0xc6b, 0xc6c);
}
public HalloweenPumpkin(Serial serial)
: base(serial)
{
}
public override void OnDoubleClick(Mobile from)
{
if (!from.InRange(GetWorldLocation(), 2))
return;
bool douse = false;
switch (ItemID)
{
case 0x4694:
ItemID = 0x4691;
break;
case 0x4691:
ItemID = 0x4694;
douse = true;
break;
case 0x4698:
ItemID = 0x4695;
break;
case 0x4695:
ItemID = 0x4698;
douse = true;
break;
default: return;
}
from.SendLocalizedMessage(douse ? 1113988 : 1113987); // You extinguish/light the Jack-O-Lantern
Effects.PlaySound(GetWorldLocation(), Map, douse ? 0x3be : 0x47);
}
private void AssignRandomName()
{
Name = $"{m_Staff[Utility.Random(m_Staff.Length)]}'s Jack-O-Lantern";
}
public override bool OnDragLift(Mobile from)
{
if (Name == null && (ItemID == 0x4694 || ItemID == 0x4691 || ItemID == 0x4698 || ItemID == 0x4695))
{
if (Utility.RandomBool())
{
new PumpkinHead().MoveToWorld(GetWorldLocation(), Map);
Delete();
return false;
}
AssignRandomName();
}
return true;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
if (version == 0 && Name == null && ItemID == 0x4698)
AssignRandomName();
}
}
}

View file

@ -0,0 +1,32 @@
namespace Server.Items
{
public class PumpkinScarecrow : Item
{
[Constructible]
public PumpkinScarecrow()
: base(Utility.RandomBool() ? 0x469B : 0x469C)
{
}
public PumpkinScarecrow(Serial serial)
: base(serial)
{
}
public override int LabelNumber => 1096947;
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,32 @@
namespace Server.Items
{
public class RuinedTapestry : Item
{
[Constructible]
public RuinedTapestry()
: base(Utility.RandomBool() ? 0x4699 : 0x469A)
{
}
public RuinedTapestry(Serial serial)
: base(serial)
{
}
public override string DefaultName => "Ruined Tapestry ";
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,44 @@
namespace Server.Items
{
public class TwilightLantern : Lantern
{
[Constructible]
public TwilightLantern()
{
Hue = Utility.RandomBool() ? 244 : 997;
}
public TwilightLantern(Serial serial)
: base(serial)
{
}
public override string DefaultName => "Twilight Lantern";
public override bool AllowEquippedCast(Mobile from)
{
return true;
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
list.Add(1060482); // Spell Channeling
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,61 @@
using System;
using System.Linq;
using Server.Events.Halloween;
using Server.Items;
namespace Server.Engines.Events
{
public class PumpkinPatchSpawner
{
private static Timer m_Timer;
private static Rectangle2D[] m_PumpkinFields =
{
new Rectangle2D(4557, 1471, 20, 10),
new Rectangle2D(796, 2152, 36, 24),
new Rectangle2D(816, 2251, 16, 8),
new Rectangle2D(816, 2261, 16, 8),
new Rectangle2D(816, 2271, 16, 8),
new Rectangle2D(816, 2281, 16, 8),
new Rectangle2D(835, 2344, 16, 16),
new Rectangle2D(816, 2344, 16, 24)
};
public static void Initialize()
{
DateTime now = DateTime.UtcNow;
if (DateTime.UtcNow >= HolidaySettings.StartHalloween && DateTime.UtcNow <= HolidaySettings.FinishHalloween)
m_Timer = Timer.DelayCall(TimeSpan.Zero, TimeSpan.FromMinutes(.50), 0, PumpkinPatchSpawnerCallback);
}
protected static void PumpkinPatchSpawnerCallback()
{
AddPumpkin(Map.Felucca);
AddPumpkin(Map.Trammel);
}
private static void AddPumpkin(Map map)
{
for (int i = 0; i < m_PumpkinFields.Length; i++)
{
Rectangle2D rect = m_PumpkinFields[i];
int spawncount = rect.Height * rect.Width / 20;
int pumpkins = map.GetItemsInBounds(rect).OfType<HalloweenPumpkin>().Count();
if (spawncount > pumpkins)
new HalloweenPumpkin().MoveToWorld(RandomPointIn(rect, map), map);
}
}
private static Point3D RandomPointIn(Rectangle2D rect, Map map)
{
int x = Utility.Random(rect.X, rect.Width);
int y = Utility.Random(rect.Y, rect.Height);
int z = map.GetAverageZ(x, y);
return new Point3D(x, y, z);
}
}
}

View file

@ -0,0 +1,37 @@
namespace Server.Items
{
/*
first seen halloween 2009. subsequently in 2010,
2011 and 2012. GM Beggar-only Semi-Rare Treats
*/
public class CreepyCake : Food
{
[Constructible]
public CreepyCake() : base(0x9e9, 1)
{
Hue = 0x3E4;
}
public CreepyCake(Serial serial)
: base(serial)
{
}
public override string DefaultName => "Creepy Cake";
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,39 @@
namespace Server.Items
{
/*
first seen halloween 2009. subsequently in 2010,
2011 and 2012. GM Beggar-only Semi-Rare Treats
*/
public class HarvestWine : BeverageBottle
{
[Constructible]
public HarvestWine()
: base(BeverageType.Wine)
{
Hue = 0xe0;
}
public HarvestWine(Serial serial)
: base(serial)
{
}
public override string DefaultName => "Harvest Wine";
public override double DefaultWeight => 1;
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,34 @@
namespace Server.Items
{
public class MrPlainsCookies : Food
{
[Constructible]
public MrPlainsCookies() : base(0x160C, 1)
{
Weight = 1.0;
FillFactor = 4;
Hue = 0xF4;
}
public MrPlainsCookies(Serial serial)
: base(serial)
{
}
public override string DefaultName => "Mr Plain's Cookies";
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,42 @@
namespace Server.Items
{
/*
first seen halloween 2009. subsequently in 2010,
2011 and 2012. GM Beggar-only Semi-Rare Treats
*/
public class MurkyMilk : Pitcher
{
[Constructible]
public MurkyMilk()
: base(BeverageType.Milk)
{
Hue = 0x3e5;
Quantity = MaxQuantity;
ItemID = Utility.RandomBool() ? 0x09F0 : 0x09AD;
}
public MurkyMilk(Serial serial)
: base(serial)
{
}
public override string DefaultName => "Murky Milk";
public override int MaxQuantity => 5;
public override double DefaultWeight => 1;
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,37 @@
namespace Server.Items
{
/*
first seen halloween 2009. subsequently in 2010,
2011 and 2012. GM Beggar-only Semi-Rare Treats
*/
public class PumpkinPizza : CheesePizza
{
[Constructible]
public PumpkinPizza()
{
Hue = 0xF3;
}
public PumpkinPizza(Serial serial)
: base(serial)
{
}
public override string DefaultName => "Pumpkin Pizza";
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,37 @@
namespace Server.Items
{
/*
first seen halloween 2009. subsequently in 2010,
2011 and 2012. GM Beggar-only Semi-Rare Treats
*/
public class GrimWarning : Item
{
[Constructible]
public GrimWarning()
: base(0x42BD)
{
}
public GrimWarning(Serial serial)
: base(serial)
{
}
public override double DefaultWeight => 1;
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,37 @@
namespace Server.Items
{
/*
first seen halloween 2009. subsequently in 2010,
2011 and 2012. GM Beggar-only Semi-Rare Treats
*/
public class SkullsOnPike : Item
{
[Constructible]
public SkullsOnPike()
: base(0x42B5)
{
}
public SkullsOnPike(Serial serial)
: base(serial)
{
}
public override double DefaultWeight => 1;
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,32 @@
namespace Server.Items
{
public class ChairInAGhostCostume : Item
{
[Constructible]
public ChairInAGhostCostume()
: base(0x3F26)
{
}
public ChairInAGhostCostume(Serial serial)
: base(serial)
{
}
public override double DefaultWeight => 5;
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,33 @@
namespace Server.Items
{
public class ColoredSmallWebs : Item
{
[Constructible]
public ColoredSmallWebs()
: base(Utility.RandomBool() ? 0x10d6 : 0x10d7)
{
Hue = Utility.RandomBool() ? 0x455 : 0x4E9;
}
public ColoredSmallWebs(Serial serial)
: base(serial)
{
}
public override double DefaultWeight => 5;
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,32 @@
namespace Server.Items
{
public class ExcellentIronMaiden : Item
{
[Constructible]
public ExcellentIronMaiden()
: base(0x3f15)
{
}
public ExcellentIronMaiden(Serial serial)
: base(serial)
{
}
public override double DefaultWeight => 5;
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,31 @@
namespace Server.Items
{
public class HalloweenGuillotine : Item
{
[Constructible]
public HalloweenGuillotine() : base(0x3F27)
{
}
public HalloweenGuillotine(Serial serial)
: base(serial)
{
}
public override double DefaultWeight => 5;
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,65 @@
//using System.Collections.Generic;
namespace Server.Items.Holiday
{
[TypeAlias("Server.Items.ClownMask", "Server.Items.DaemonMask", "Server.Items.PlagueMask")]
public class BasePaintedMask : Item
{
private static string[] m_Staffers =
{
"Ryan",
"Mark",
"Krrios",
"Zippy",
"Athena",
"Eos",
"Xavier"
};
private string m_Staffer;
public BasePaintedMask(int itemid)
: this(m_Staffers[Utility.Random(m_Staffers.Length)], itemid)
{
}
public BasePaintedMask(string staffer, int itemid)
: base(itemid + Utility.Random(2))
{
m_Staffer = staffer;
Utility.Intern(m_Staffer);
}
public BasePaintedMask(Serial serial) : base(serial)
{
}
public override string DefaultName
{
get
{
return m_Staffer != null ? $"{MaskName} hand painted by {m_Staffer}" : MaskName;
}
}
public virtual string MaskName => "A Mask";
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
writer.Write(m_Staffer);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
if (version == 1) m_Staffer = Utility.Intern(reader.ReadString());
}
}
}

View file

@ -0,0 +1,32 @@
namespace Server.Items.Holiday
{
public class PaintedEvilClownMask : BasePaintedMask
{
[Constructible]
public PaintedEvilClownMask()
: base(0x4a90)
{
}
public PaintedEvilClownMask(Serial serial)
: base(serial)
{
}
public override string MaskName => "Evil Clown Mask";
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,32 @@
namespace Server.Items.Holiday
{
public class PaintedDaemonMask : BasePaintedMask
{
[Constructible]
public PaintedDaemonMask()
: base(0x4a92)
{
}
public PaintedDaemonMask(Serial serial)
: base(serial)
{
}
public override string MaskName => "Daemon Mask";
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,32 @@
namespace Server.Items.Holiday
{
public class PaintedPlagueMask : BasePaintedMask
{
[Constructible]
public PaintedPlagueMask()
: base(0x4A8E)
{
}
public PaintedPlagueMask(Serial serial)
: base(serial)
{
}
public override string MaskName => "Plague Mask";
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,129 @@
using System;
using Server.Items;
using Server.Items.Holiday;
namespace Server.Mobiles
{
public class PumpkinHead : BaseCreature
{
[Constructible]
public PumpkinHead()
: base(Utility.RandomBool() ? AIType.AI_Melee : AIType.AI_Mage, FightMode.Closest, 10, 1, 0.05, 0.1)
{
Body = 1246 + Utility.Random(2);
BaseSoundID = 268;
SetStr(350);
SetDex(125);
SetInt(250);
SetHits(500);
SetMana(1000);
SetDamage(10, 15);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 55);
SetResistance(ResistanceType.Fire, 50);
SetResistance(ResistanceType.Cold, 50);
SetResistance(ResistanceType.Poison, 65);
SetResistance(ResistanceType.Energy, 80);
SetSkill(SkillName.DetectHidden, 100.0);
SetSkill(SkillName.Meditation, 120.0);
SetSkill(SkillName.Necromancy, 100.0);
SetSkill(SkillName.SpiritSpeak, 120.0);
SetSkill(SkillName.Magery, 160.0);
SetSkill(SkillName.EvalInt, 100.0);
SetSkill(SkillName.MagicResist, 100.0);
SetSkill(SkillName.Tactics, 100.0);
SetSkill(SkillName.Wrestling, 80.0);
Fame = 5000;
Karma = -5000;
VirtualArmor = 49;
}
public PumpkinHead(Serial serial)
: base(serial)
{
}
public override string CorpseName => "a killer pumpkin corpse";
public override bool AutoDispel => true;
public override bool BardImmune => true;
public override bool Unprovokable => true;
public override bool AreaPeaceImmune => true;
public override string DefaultName => "a killer pumpkin";
public override void GenerateLoot()
{
if (Utility.RandomDouble() < .05)
switch (Utility.Random(5))
{
case 0:
PackItem(new PaintedEvilClownMask());
break;
case 1:
PackItem(new PaintedDaemonMask());
break;
case 2:
PackItem(new PaintedPlagueMask());
break;
case 3:
PackItem(new PaintedEvilJesterMask());
break;
case 4:
PackItem(new PaintedPorcelainMask());
break;
}
PackItem(new WrappedCandy());
AddLoot(LootPack.UltraRich, 2);
}
public virtual void Lifted_Callback(Mobile from)
{
if (from?.Deleted == false && from is PlayerMobile)
{
Combatant = from;
Warmode = true;
}
}
public override Item NewHarmfulItem()
{
Item bad = new AcidSlime(TimeSpan.FromSeconds(10), 25, 30);
bad.Name = "gooey nasty pumpkin hummus";
bad.Hue = 144;
return bad;
}
public override void OnDamage(int amount, Mobile from, bool willKill)
{
if (Utility.RandomBool())
if (from?.Map != null && Map != Map.Internal && Map == from.Map && from.InRange(this, 12))
SpillAcid(willKill ? this : from, willKill ? 3 : 1);
base.OnDamage(amount, from, willKill);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,270 @@
using System;
using Server.Items;
using Server.Mobiles;
using System.Collections.Generic;
using Server.Events.Halloween;
namespace Server.Engines.Events
{
public class HalloweenHauntings
{
public static Dictionary<PlayerMobile, ZombieSkeleton> ReAnimated { get; set; }
private static Timer m_Timer;
private static Timer m_ClearTimer;
private static int m_TotalZombieLimit;
private static int m_DeathQueueLimit;
private static int m_QueueDelaySeconds;
private static int m_QueueClearIntervalSeconds;
private static List<PlayerMobile> m_DeathQueue;
private static Rectangle2D[] m_Cemetaries = {
new Rectangle2D(1272,3712,30,20), // Jhelom
new Rectangle2D(1337,1444,48,52), // Britain
new Rectangle2D(2424,1098,20,28), // Trinsic
new Rectangle2D(2728,840,54,54), // Vesper
new Rectangle2D(4528,1314,20,28), // Moonglow
new Rectangle2D(712,1104,30,22), // Yew
new Rectangle2D(5824,1464,22,6), // Fire Dungeon
new Rectangle2D(5224,3655,14,5), // T2A
new Rectangle2D(1272,3712,20,30), // Jhelom
new Rectangle2D(1337,1444,52,48), // Britain
new Rectangle2D(2424,1098,28,20), // Trinsic
new Rectangle2D(2728,840,54,54), // Vesper
new Rectangle2D(4528,1314,28,20), // Moonglow
new Rectangle2D(712,1104,22,30), // Yew
new Rectangle2D(5824,1464,6,22), // Fire Dungeon
new Rectangle2D(5224,3655,5,14) // T2A
};
public static void Initialize()
{
m_TotalZombieLimit = 200;
m_DeathQueueLimit = 200;
m_QueueDelaySeconds = 120;
m_QueueClearIntervalSeconds = 1800;
DateTime today = DateTime.UtcNow;
TimeSpan tick = TimeSpan.FromSeconds( m_QueueDelaySeconds );
TimeSpan clear = TimeSpan.FromSeconds( m_QueueClearIntervalSeconds );
ReAnimated = new Dictionary<PlayerMobile, ZombieSkeleton>();
m_DeathQueue = new List<PlayerMobile>();
if ( today >= HolidaySettings.StartHalloween && today <= HolidaySettings.FinishHalloween )
{
m_Timer = Timer.DelayCall( tick, tick, Timer_Callback );
m_ClearTimer = Timer.DelayCall( clear, clear, Clear_Callback );
EventSink.PlayerDeath += EventSink_PlayerDeath;
}
}
public static void EventSink_PlayerDeath( PlayerDeathEventArgs e )
{
if ( e.Mobile is PlayerMobile player && !player.Deleted && m_Timer.Running && !m_DeathQueue.Contains( player ) && m_DeathQueue.Count < m_DeathQueueLimit )
m_DeathQueue.Add( player );
}
private static void Clear_Callback()
{
ReAnimated.Clear();
m_DeathQueue.Clear();
if ( DateTime.UtcNow <= HolidaySettings.FinishHalloween )
{
m_ClearTimer.Stop();
}
}
private static void Timer_Callback()
{
PlayerMobile player = null;
if ( DateTime.UtcNow <= HolidaySettings.FinishHalloween )
{
for( int index = 0; m_DeathQueue.Count > 0 && index < m_DeathQueue.Count; index++ )
{
if ( !ReAnimated.ContainsKey( m_DeathQueue[ index ] ) )
{
player = m_DeathQueue[ index ];
break;
}
}
if (player?.Deleted == false && ReAnimated.Count < m_TotalZombieLimit )
{
Map map = Utility.RandomBool() ? Map.Trammel : Map.Felucca;
Point3D home = ( GetRandomPointInRect( m_Cemetaries[ Utility.Random( m_Cemetaries.Length ) ], map ));
if ( map.CanSpawnMobile( home ) )
{
ZombieSkeleton zombieskel = new ZombieSkeleton( player );
ReAnimated.Add( player, zombieskel );
zombieskel.Home = home;
zombieskel.RangeHome = 10;
zombieskel.MoveToWorld( home, map );
m_DeathQueue.Remove( player );
}
}
}
else
{
m_Timer.Stop();
}
}
private static Point3D GetRandomPointInRect( Rectangle2D rect, Map map )
{
int x = Utility.Random( rect.X, rect.Width );
int y = Utility.Random( rect.Y, rect.Height );
return new Point3D( x, y, map.GetAverageZ( x, y ) );
}
}
public class PlayerBones : BaseContainer
{
[Constructible]
public PlayerBones( string name )
: base( Utility.RandomMinMax( 0x0ECA, 0x0ED2 ) )
{
Name = $"{name}'s bones";
switch( Utility.Random( 10 ) )
{
case 0: Hue = 0xa09; break;
case 1: Hue = 0xa93; break;
case 2: Hue = 0xa47; break;
default: break;
}
}
public PlayerBones( Serial serial )
: base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
public class ZombieSkeleton : BaseCreature
{
public override string CorpseName => "a rotting corpse";
private static readonly string m_Name = "Zombie Skeleton";
private PlayerMobile m_DeadPlayer;
public ZombieSkeleton(PlayerMobile player = null)
: base( AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4 )
{
m_DeadPlayer = player;
Name = player != null ? $"{player.Name}'s {m_Name}" : m_Name;
Body = 0x93;
BaseSoundID = 0x1c3;
SetStr( 500 );
SetDex( 500 );
SetInt( 500 );
SetHits( 2500 );
SetMana( 500 );
SetStam( 500 );
SetDamage( 8, 18 );
SetDamageType( ResistanceType.Physical, 40 );
SetDamageType( ResistanceType.Cold, 60 );
SetResistance( ResistanceType.Fire, 50 );
SetResistance( ResistanceType.Energy, 50 );
SetResistance( ResistanceType.Physical, 50 );
SetResistance( ResistanceType.Cold, 50 );
SetResistance( ResistanceType.Poison, 50 );
SetSkill( SkillName.MagicResist, 65.1, 80.0 );
SetSkill( SkillName.Tactics, 95.1, 100 );
SetSkill( SkillName.Wrestling, 85.1, 95 );
Fame = 1000;
Karma = -1000;
VirtualArmor = 18;
}
public override void GenerateLoot()
{
switch( Utility.Random( 10 ) )
{
case 0: PackItem( new LeftArm() ); break;
case 1: PackItem( new RightArm() ); break;
case 2: PackItem( new Torso() ); break;
case 3: PackItem( new Bone() ); break;
case 4: PackItem( new RibCage() ); break;
case 5: if (m_DeadPlayer?.Deleted == false) { PackItem( new PlayerBones( m_DeadPlayer.Name ) ); } break;
default: break;
}
AddLoot( LootPack.Meager );
}
public override bool BleedImmune => true;
public override Poison PoisonImmune => Poison.Regular;
public ZombieSkeleton( Serial serial )
: base( serial )
{
}
public override void OnDelete()
{
if ( HalloweenHauntings.ReAnimated != null )
{
if (m_DeadPlayer?.Deleted == false)
{
if ( HalloweenHauntings.ReAnimated.ContainsKey( m_DeadPlayer ) )
HalloweenHauntings.ReAnimated.Remove( m_DeadPlayer );
}
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
writer.WriteMobile( m_DeadPlayer );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
m_DeadPlayer = reader.ReadMobile<PlayerMobile>();
}
}
}

View file

@ -0,0 +1,32 @@
namespace Server.Items.Holiday
{
public class PaintedEvilJesterMask : BasePaintedMask
{
[Constructible]
public PaintedEvilJesterMask()
: base(0x4BA5)
{
}
public PaintedEvilJesterMask(Serial serial)
: base(serial)
{
}
public override string MaskName => "Evil Jester Mask";
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,32 @@
namespace Server.Items.Holiday
{
public class PaintedPorcelainMask : BasePaintedMask
{
[Constructible]
public PaintedPorcelainMask()
: base(0x4BA7)
{
}
public PaintedPorcelainMask(Serial serial)
: base(serial)
{
}
public override string MaskName => "Porcelain Mask";
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,42 @@
using System;
using Server.Items;
namespace Server.Events.Halloween
{
internal class HolidaySettings
{
private static Type[] m_GMBeggarTreats =
{
typeof(CreepyCake),
typeof(PumpkinPizza),
typeof(GrimWarning),
typeof(HarvestWine),
typeof(MurkyMilk),
typeof(MrPlainsCookies),
typeof(SkullsOnPike),
typeof(ChairInAGhostCostume),
typeof(ExcellentIronMaiden),
typeof(HalloweenGuillotine),
typeof(ColoredSmallWebs)
};
private static Type[] m_Treats =
{
typeof(Lollipops),
typeof(WrappedCandy),
typeof(JellyBeans),
typeof(Taffy),
typeof(NougatSwirl)
};
public static DateTime StartHalloween // YY MM DD
=> new DateTime(2012, 10, 24);
public static DateTime FinishHalloween => new DateTime(2012, 11, 15);
public static Item RandomGMBeggerItem =>
(Item)Activator.CreateInstance(m_GMBeggarTreats[Utility.Random(m_GMBeggarTreats.Length)]);
public static Item RandomTreat => (Item)Activator.CreateInstance(m_Treats[Utility.Random(m_Treats.Length)]);
}
}

View file

@ -0,0 +1,32 @@
namespace Server.Items
{
public class JellyBeans : CandyCane
{
public JellyBeans(int amount = 1)
: base(0x468C)
{
Stackable = true;
}
public JellyBeans(Serial serial)
: base(serial)
{
}
public override int LabelNumber => 1096932; /* jellybeans */
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,32 @@
namespace Server.Items
{
[TypeAlias("Server.Items.Lollipop")]
public class Lollipops : CandyCane
{
[Constructible]
public Lollipops(int amount = 1)
: base(0x468D + Utility.Random(3))
{
Stackable = true;
}
public Lollipops(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,33 @@
namespace Server.Items
{
public class NougatSwirl : CandyCane
{
[Constructible]
public NougatSwirl(int amount = 1)
: base(0x4690)
{
Stackable = true;
}
public NougatSwirl(Serial serial)
: base(serial)
{
}
public override int LabelNumber => 1096936; /* nougat swirl */
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,32 @@
namespace Server.Items
{
public class Taffy : CandyCane
{
public Taffy(int amount = 1)
: base(0x469D)
{
Stackable = true;
}
public Taffy(Serial serial)
: base(serial)
{
}
public override int LabelNumber => 1096949; /* taffy */
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,32 @@
namespace Server.Items
{
public class WrappedCandy : CandyCane
{
public WrappedCandy(int amount = 1)
: base(0x469e)
{
Stackable = true;
}
public WrappedCandy(Serial serial)
: base(serial)
{
}
public override int LabelNumber => 1096950; /* wrapped candy */
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}