fix: Codegens gifts. Unifies staff names. Thank you to the community! (#1766)

### Summary
* Adds contributors/sponsors to the "staff" list for holiday items.
* Unifies all of the staff lists
* Moves 2004 winter gifts to the appropriate folder
* Codegens the gift items

## Thank you!
Thank you to the RunUO/ServUO community, Owyn, Jaedan, the Outlands community, and the ModernUO contributors/community. Without all of you, this would not be possible! ❤️
This commit is contained in:
Kamron Batman 2024-05-08 20:44:00 -07:00 committed by GitHub
parent 8efa90b3ce
commit 8fd04ac5aa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 822 additions and 1017 deletions

View file

@ -0,0 +1,28 @@
using ModernUO.Serialization;
namespace Server.Items;
[SerializationGenerator(0, false)]
public partial class DecorativeTopiary : Item
{
[Constructible]
public DecorativeTopiary() : base(0x2378)
{
Weight = 1.0;
LootType = LootType.Blessed;
}
public override void OnSingleClick(Mobile from)
{
base.OnSingleClick(from);
LabelTo(from, 1070880); // Winter 2004
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
list.Add(1070880); // Winter 2004
}
}

View file

@ -0,0 +1,28 @@
using ModernUO.Serialization;
namespace Server.Items;
[SerializationGenerator(0, false)]
public partial class FestiveCactus : Item
{
[Constructible]
public FestiveCactus() : base(0x2376)
{
Weight = 1.0;
LootType = LootType.Blessed;
}
public override void OnSingleClick(Mobile from)
{
base.OnSingleClick(from);
LabelTo(from, 1070880); // Winter 2004
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
list.Add(1070880); // Winter 2004
}
}

View file

@ -0,0 +1,42 @@
using ModernUO.Serialization;
using Server.Misc;
namespace Server.Items;
[Flippable(0x236E, 0x2371)]
[SerializationGenerator(0, false)]
public partial class LightOfTheWinterSolstice : Item
{
[InternString]
[InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private string _dipper;
[Constructible]
public LightOfTheWinterSolstice(string dipper = null) : base(0x236E)
{
_dipper = dipper?.Intern() ?? StaffInfo.GetRandomStaff();
Weight = 1.0;
LootType = LootType.Blessed;
Light = LightType.Circle300;
Hue = Utility.RandomDyedHue();
}
public override void OnSingleClick(Mobile from)
{
base.OnSingleClick(from);
LabelTo(from, 1070881, _dipper); // Hand Dipped by ~1_name~
LabelTo(from, 1070880); // Winter 2004
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
list.Add(1070881, _dipper); // Hand Dipped by ~1_name~
list.Add(1070880); // Winter 2004
}
}

View file

@ -0,0 +1,322 @@
using ModernUO.Serialization;
using Server.Gumps;
using Server.Multis;
using Server.Network;
using Server.Targeting;
namespace Server.Items;
[SerializationGenerator(0, false)]
public partial class MistletoeAddon : Item, IDyable, IAddon
{
[Constructible]
public MistletoeAddon() : this(Utility.RandomDyedHue())
{
}
[Constructible]
public MistletoeAddon(int hue) : base(0x2375)
{
Hue = hue;
Movable = false;
}
public bool CouldFit(IPoint3D p, Map map)
{
if (!map.CanFit(p.X, p.Y, p.Z, ItemData.Height))
{
return false;
}
if (ItemID == 0x2375)
{
return BaseAddon.IsWall(p.X, p.Y - 1, p.Z, map); // North wall
}
return BaseAddon.IsWall(p.X - 1, p.Y, p.Z, map); // West wall
}
public Item Deed => new MistletoeDeed(Hue);
public virtual bool Dye(Mobile from, DyeTub sender)
{
if (Deleted)
{
return false;
}
var house = BaseHouse.FindHouseAt(this);
if (house?.IsCoOwner(from) == true)
{
if (from.InRange(GetWorldLocation(), 1))
{
Hue = sender.DyedHue;
return true;
}
from.SendLocalizedMessage(500295); // You are too far away to do that.
return false;
}
return false;
}
[AfterDeserialization(false)]
private void AfterDeserialization()
{
FixMovingCrate();
}
private void FixMovingCrate()
{
if (Deleted)
{
return;
}
if (Movable || IsLockedDown)
{
var deed = Deed;
if (Parent is Item item)
{
item.AddItem(deed);
deed.Location = Location;
}
else
{
deed.MoveToWorld(Location, Map);
}
Delete();
}
}
public override void OnDoubleClick(Mobile from)
{
var house = BaseHouse.FindHouseAt(this);
if (house?.IsCoOwner(from) != true)
{
return;
}
if (from.InRange(GetWorldLocation(), 3))
{
from.CloseGump<MistletoeAddonGump>();
from.SendGump(new MistletoeAddonGump(from, this));
}
else
{
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
}
}
private class MistletoeAddonGump : Gump
{
private readonly MistletoeAddon _addon;
private readonly Mobile _from;
public MistletoeAddonGump(Mobile from, MistletoeAddon addon) : base(150, 50)
{
_from = from;
_addon = addon;
AddPage(0);
AddBackground(0, 0, 220, 170, 0x13BE);
AddBackground(10, 10, 200, 150, 0xBB8);
AddHtmlLocalized(20, 30, 180, 60, 1062839); // Do you wish to re-deed this decoration?
AddHtmlLocalized(55, 100, 160, 25, 1011011); // CONTINUE
AddButton(20, 100, 0xFA5, 0xFA7, 1);
AddHtmlLocalized(55, 125, 160, 25, 1011012); // CANCEL
AddButton(20, 125, 0xFA5, 0xFA7, 0);
}
public override void OnResponse(NetState sender, in RelayInfo info)
{
if (_addon.Deleted || info.ButtonID != 1)
{
return;
}
if (_from.InRange(_addon.GetWorldLocation(), 3))
{
_from.AddToBackpack(_addon.Deed);
_addon.Delete();
}
else
{
_from.SendLocalizedMessage(500295); // You are too far away to do that.
}
}
}
}
[Flippable(0x14F0, 0x14EF)]
[SerializationGenerator(0, false)]
public partial class MistletoeDeed : Item
{
[Constructible]
public MistletoeDeed(int hue = 0) : base(0x14F0)
{
Hue = hue;
Weight = 1.0;
LootType = LootType.Blessed;
}
public override int LabelNumber => 1070882; // Mistletoe Deed
public override void OnSingleClick(Mobile from)
{
base.OnSingleClick(from);
LabelTo(from, 1070880); // Winter 2004
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
list.Add(1070880); // Winter 2004
}
public override void OnDoubleClick(Mobile from)
{
if (!IsChildOf(from.Backpack))
{
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
return;
}
var house = BaseHouse.FindHouseAt(from);
if (house?.IsCoOwner(from) == true)
{
from.SendLocalizedMessage(1062838); // Where would you like to place this decoration?
from.BeginTarget(-1, true, TargetFlags.None, Placement_OnTarget);
}
else
{
from.SendLocalizedMessage(502092); // You must be in your house to do this.
}
}
public void Placement_OnTarget(Mobile from, object targeted)
{
if (targeted is not IPoint3D p)
{
return;
}
var loc = new Point3D(p);
var house = BaseHouse.FindHouseAt(loc, from.Map, 16);
if (house?.IsCoOwner(from) != true)
{
from.SendLocalizedMessage(1042036); // That location is not in your house.
return;
}
var northWall = BaseAddon.IsWall(loc.X, loc.Y - 1, loc.Z, from.Map);
var westWall = BaseAddon.IsWall(loc.X - 1, loc.Y, loc.Z, from.Map);
if (northWall && westWall)
{
from.SendGump(new MistletoeDeedGump(from, loc, this));
}
else
{
PlaceAddon(from, loc, northWall, westWall);
}
}
private void PlaceAddon(Mobile from, Point3D loc, bool northWall, bool westWall)
{
if (Deleted)
{
return;
}
var house = BaseHouse.FindHouseAt(loc, from.Map, 16);
if (house?.IsCoOwner(from) != true)
{
from.SendLocalizedMessage(1042036); // That location is not in your house.
return;
}
var itemID = 0;
if (northWall)
{
itemID = 0x2374;
}
else if (westWall)
{
itemID = 0x2375;
}
else
{
from.SendLocalizedMessage(1070883); // The mistletoe must be placed next to a wall.
}
if (itemID > 0)
{
Item addon = new MistletoeAddon(Hue);
addon.ItemID = itemID;
addon.MoveToWorld(loc, from.Map);
house.Addons.Add(addon);
Delete();
}
}
private class MistletoeDeedGump : Gump
{
private readonly MistletoeDeed _deed;
private readonly Mobile _from;
private readonly Point3D _loc;
public MistletoeDeedGump(Mobile from, Point3D loc, MistletoeDeed deed) : base(150, 50)
{
_from = from;
_loc = loc;
_deed = deed;
AddBackground(0, 0, 300, 150, 0xA28);
AddPage(0);
AddItem(90, 30, 0x2375);
AddItem(180, 30, 0x2374);
AddButton(50, 35, 0x868, 0x869, 1);
AddButton(145, 35, 0x868, 0x869, 2);
}
public override void OnResponse(NetState sender, in RelayInfo info)
{
if (_deed.Deleted)
{
return;
}
switch (info.ButtonID)
{
case 1:
{
_deed.PlaceAddon(_from, _loc, false, true);
break;
}
case 2:
{
_deed.PlaceAddon(_from, _loc, true, false);
break;
}
}
}
}
}

View file

@ -0,0 +1,50 @@
using ModernUO.Serialization;
namespace Server.Items;
[SerializationGenerator(0, false)]
public partial class PileOfGlacialSnow : Item
{
[Constructible]
public PileOfGlacialSnow() : base(0x913)
{
Hue = 0x480;
Weight = 1.0;
LootType = LootType.Blessed;
}
public override int LabelNumber => 1070874; // a Pile of Glacial Snow
public override void OnSingleClick(Mobile from)
{
base.OnSingleClick(from);
LabelTo(from, 1070880); // Winter 2004
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
list.Add(1070880); // Winter 2004
}
public override void OnDoubleClick(Mobile from)
{
if (!IsChildOf(from.Backpack))
{
from.SendLocalizedMessage(1042010); // You must have the object in your backpack to use it.
}
else if (from.Mounted)
{
from.SendLocalizedMessage(1010097); // You cannot use this while mounted.
}
else if (from.CanBeginAction<SnowPile>())
{
from.SendLocalizedMessage(1005575); // You carefully pack the snow into a ball...
from.Target = new SnowTarget();
}
else
{
from.SendLocalizedMessage(1005574); // The snow is not ready to be packed yet. Keep trying.
}
}
}

View file

@ -0,0 +1,38 @@
using ModernUO.Serialization;
namespace Server.Items;
[SerializationGenerator(0, false)]
public partial class SnowPile : Item
{
[Constructible]
public SnowPile() : base(0x913)
{
Hue = 0x481;
Weight = 1.0;
LootType = LootType.Blessed;
}
public override int LabelNumber => 1005578; // a pile of snow
public override void OnDoubleClick(Mobile from)
{
if (!IsChildOf(from.Backpack))
{
from.SendLocalizedMessage(1042010); // You must have the object in your backpack to use it.
}
else if (from.Mounted)
{
from.SendLocalizedMessage(1010097); // You cannot use this while mounted.
}
else if (from.CanBeginAction<SnowPile>())
{
from.SendLocalizedMessage(1005575); // You carefully pack the snow into a ball...
from.Target = new SnowTarget();
}
else
{
from.SendLocalizedMessage(1005574); // The snow is not ready to be packed yet. Keep trying.
}
}
}

View file

@ -0,0 +1,62 @@
using System;
using Server.Engines.ConPVP;
using Server.Targeting;
namespace Server.Items;
public class SnowTarget : Target
{
private static readonly Type[] _snowPileTypes = [typeof(SnowPile), typeof(PileOfGlacialSnow)];
public SnowTarget() : base(10, false, TargetFlags.None)
{
}
protected override void OnTarget(Mobile from, object target)
{
if (target == from)
{
from.SendLocalizedMessage(1005576); // You can't throw this at yourself.
return;
}
if (target is not Mobile targ)
{
// You can only throw a snowball at something that can throw one back.
from.SendLocalizedMessage(1005577);
return;
}
var pack = targ.Backpack;
if (from.Region.IsPartOf<SafeZone>() || targ.Region.IsPartOf<SafeZone>())
{
from.SendMessage("You may not throw snow here.");
return;
}
if (pack?.FindItemByType(_snowPileTypes) == null)
{
// You can only throw a snowball at something that can throw one back.
from.SendLocalizedMessage(1005577);
return;
}
if (!from.BeginAction<SnowPile>())
{
from.SendLocalizedMessage(1005574); // The snow is not ready to be packed yet. Keep trying.
return;
}
Timer.StartTimer(TimeSpan.FromSeconds(5.0), from.EndAction<SnowPile>);
from.PlaySound(0x145);
from.Animate(9, 1, 1, true, false, 0);
targ.SendLocalizedMessage(1010572); // You have just been hit by a snowball!
from.SendLocalizedMessage(1010573); // You throw the snowball and hit the target!
Effects.SendMovingEffect(from, targ, 0x36E4, 7, 0, false, true, 0x47F);
}
}

View file

@ -0,0 +1,28 @@
using ModernUO.Serialization;
namespace Server.Items;
[SerializationGenerator(0, false)]
public partial class SnowyTree : Item
{
[Constructible]
public SnowyTree() : base(0x2377)
{
Weight = 1.0;
LootType = LootType.Blessed;
}
public override void OnSingleClick(Mobile from)
{
base.OnSingleClick(from);
LabelTo(from, 1070880); // Winter 2004
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
list.Add(1070880); // Winter 2004
}
}

View file

@ -0,0 +1,53 @@
using System;
using Server.Items;
namespace Server.Misc;
public class WinterGiftGiver2004 : GiftGiver
{
public override DateTime Start => new(2004, 12, 24);
public override DateTime Finish => new(2005, 1, 1);
public static void Initialize()
{
GiftGiving.Register(new WinterGiftGiver2004());
}
public override void GiveGift(Mobile mob)
{
var box = new GiftBox();
box.DropItem(new MistletoeDeed());
box.DropItem(new PileOfGlacialSnow());
box.DropItem(new LightOfTheWinterSolstice());
var random = Utility.Random(100);
if (random < 60)
{
box.DropItem(new DecorativeTopiary());
}
else if (random < 84)
{
box.DropItem(new FestiveCactus());
}
else
{
box.DropItem(new SnowyTree());
}
switch (GiveGift(mob, box))
{
case GiftResult.Backpack:
{
mob.SendMessage(0x482, "Happy Holidays from the team! Gift items have been placed in your backpack.");
break;
}
case GiftResult.BankBox:
{
mob.SendMessage(0x482, "Happy Holidays from the team! Gift items have been placed in your bank box.");
break;
}
}
}
}

View file

@ -1,90 +1,64 @@
using ModernUO.Serialization;
using Server.Misc;
using Server.Mobiles;
namespace Server.Items
namespace Server.Items;
[SerializationGenerator(0, false)]
public partial class HalloweenPumpkin : Item
{
[SerializationGenerator(1, false)]
public partial class HalloweenPumpkin : Item
[InternString]
[SerializableField(0)]
private string _staffer;
[Constructible]
public HalloweenPumpkin()
{
private static readonly string[] m_Staff =
Weight = Utility.RandomMinMax(3, 20);
ItemID = Utility.RandomDouble() < 0.02
? Utility.RandomList(0x4694, 0x4698)
: Utility.RandomList(0xc6a, 0xc6b, 0xc6c);
}
public override string DefaultName => _staffer != null ? $"{_staffer}'s Jack-O-Lantern" : "A Jack-O-Lantern";
public override void OnDoubleClick(Mobile from)
{
if (!from.InRange(GetWorldLocation(), 2))
{
"Owyn",
"Luthius",
"Kamron",
"Jaedan",
"Vorspire"
return;
}
var douse = ItemID is 0x4695 or 0x4691;
ItemID = ItemID switch
{
0x4694 => 0x4691,
0x4691 => 0x4694,
0x4698 => 0x4695,
0x4695 => 0x4698,
_ => ItemID
};
[Constructible]
public HalloweenPumpkin()
{
Weight = Utility.RandomMinMax(3, 20);
ItemID = Utility.RandomDouble() < 0.02
? Utility.RandomList(0x4694, 0x4698)
: Utility.RandomList(0xc6a, 0xc6b, 0xc6c);
}
from.SendLocalizedMessage(douse ? 1113988 : 1113987); // You extinguish/light the Jack-O-Lantern
Effects.PlaySound(GetWorldLocation(), Map, douse ? 0x3be : 0x47);
}
public override void OnDoubleClick(Mobile from)
public override bool OnDragLift(Mobile from)
{
if (Name == null && ItemID is 0x4694 or 0x4691 or 0x4698 or 0x4695)
{
if (!from.InRange(GetWorldLocation(), 2))
if (Utility.RandomBool())
{
return;
new PumpkinHead().MoveToWorld(GetWorldLocation(), Map);
Delete();
return false;
}
var 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);
_staffer = StaffInfo.GetRandomStaff();
}
private void AssignRandomName()
{
Name = $"{m_Staff.RandomElement()}'s Jack-O-Lantern";
}
public override bool OnDragLift(Mobile from)
{
if (Name == null && ItemID is 0x4694 or 0x4691 or 0x4698 or 0x4695)
{
if (Utility.RandomBool())
{
new PumpkinHead().MoveToWorld(GetWorldLocation(), Map);
Delete();
return false;
}
AssignRandomName();
}
return true;
}
private void Deserialize(IGenericReader reader, int version)
{
if (version == 0 && Name == null && ItemID == 0x4698)
{
AssignRandomName();
}
}
return true;
}
}

View file

@ -1,33 +1,24 @@
using ModernUO.Serialization;
using Server.Misc;
namespace Server.Items.Holiday
namespace Server.Items.Holiday;
[SerializationGenerator(0, false)]
[TypeAlias("Server.Items.ClownMask", "Server.Items.DaemonMask", "Server.Items.PlagueMask")]
public partial class BasePaintedMask : Item
{
[SerializationGenerator(0, false)]
[TypeAlias("Server.Items.ClownMask", "Server.Items.DaemonMask", "Server.Items.PlagueMask")]
public partial class BasePaintedMask : Item
[InternString]
[SerializableField(0, setter: "private")]
private string _staffer;
public BasePaintedMask(int itemid) : this(StaffInfo.GetRandomStaff(), itemid)
{
private static readonly string[] Staffers =
{
"Owyn",
"Luthius",
"Kamron",
"Jaedan",
"Vorspire"
};
[InternString]
[SerializableField(0, setter: "private")]
private string _staffer;
public BasePaintedMask(int itemid) : this(Staffers.RandomElement(), itemid)
{
}
public BasePaintedMask(string staffer, int itemid) : base(itemid + Utility.Random(2)) =>
_staffer = staffer.Intern();
public override string DefaultName => _staffer != null ? $"{MaskName} hand painted by {_staffer}" : MaskName;
public virtual string MaskName => "A Mask";
}
public BasePaintedMask(string staffer, int itemid) : base(itemid + Utility.Random(2)) =>
_staffer = staffer.Intern();
public override string DefaultName => _staffer != null ? $"{MaskName} hand painted by {_staffer}" : MaskName;
public virtual string MaskName => "A Mask";
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Items.DecorativeTopiary"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Items.FestiveCactus"
}

View file

@ -0,0 +1,14 @@
{
"version": 0,
"type": "Server.Items.HalloweenPumpkin",
"properties": [
{
"name": "Staffer",
"type": "string",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
"InternString"
]
}
]
}

View file

@ -1,4 +0,0 @@
{
"version": 1,
"type": "Server.Items.HalloweenPumpkin"
}

View file

@ -0,0 +1,14 @@
{
"version": 0,
"type": "Server.Items.LightOfTheWinterSolstice",
"properties": [
{
"name": "Dipper",
"type": "string",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
"InternString"
]
}
]
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Items.MistletoeAddon"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Items.MistletoeDeed"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Items.PileOfGlacialSnow"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Items.SnowPile"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Items.SnowyTree"
}

View file

@ -1,44 +0,0 @@
namespace Server.Items
{
public class DecorativeTopiary : Item
{
[Constructible]
public DecorativeTopiary() : base(0x2378)
{
Weight = 1.0;
LootType = LootType.Blessed;
}
public DecorativeTopiary(Serial serial) : base(serial)
{
}
public override void OnSingleClick(Mobile from)
{
base.OnSingleClick(from);
LabelTo(from, 1070880); // Winter 2004
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
list.Add(1070880); // Winter 2004
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,44 +0,0 @@
namespace Server.Items
{
public class FestiveCactus : Item
{
[Constructible]
public FestiveCactus() : base(0x2376)
{
Weight = 1.0;
LootType = LootType.Blessed;
}
public FestiveCactus(Serial serial) : base(serial)
{
}
public override void OnSingleClick(Mobile from)
{
base.OnSingleClick(from);
LabelTo(from, 1070880); // Winter 2004
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
list.Add(1070880); // Winter 2004
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,95 +0,0 @@
namespace Server.Items
{
[Flippable(0x236E, 0x2371)]
public class LightOfTheWinterSolstice : Item
{
private static readonly string[] m_StaffNames =
{
"Aenima",
"Alkiser",
"ASayre",
"David",
"Krrios",
"Mark",
"Merlin",
"Merlix", // LordMerlix
"Phantom",
"Phenos",
"psz",
"Ryan",
"Quantos",
"Outkast", // TheOutkastDev
"V", // Admin_V
"Zippy"
};
[Constructible]
public LightOfTheWinterSolstice(string dipper = null) : base(0x236E)
{
Dipper = dipper ?? m_StaffNames.RandomElement();
Weight = 1.0;
LootType = LootType.Blessed;
Light = LightType.Circle300;
Hue = Utility.RandomDyedHue();
}
public LightOfTheWinterSolstice(Serial serial) : base(serial)
{
}
[CommandProperty(AccessLevel.GameMaster)]
public string Dipper { get; set; }
public override void OnSingleClick(Mobile from)
{
base.OnSingleClick(from);
LabelTo(from, 1070881, Dipper); // Hand Dipped by ~1_name~
LabelTo(from, 1070880); // Winter 2004
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
list.Add(1070881, Dipper); // Hand Dipped by ~1_name~
list.Add(1070880); // Winter 2004
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
writer.Write(Dipper);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
switch (version)
{
case 1:
{
Dipper = reader.ReadString();
break;
}
case 0:
{
Dipper = m_StaffNames.RandomElement();
break;
}
}
if (Dipper != null)
{
Dipper = string.Intern(Dipper);
}
}
}
}

View file

@ -1,348 +0,0 @@
using Server.Gumps;
using Server.Multis;
using Server.Network;
using Server.Targeting;
namespace Server.Items
{
public class MistletoeAddon : Item, IDyable, IAddon
{
[Constructible]
public MistletoeAddon() : this(Utility.RandomDyedHue())
{
}
[Constructible]
public MistletoeAddon(int hue) : base(0x2375)
{
Hue = hue;
Movable = false;
}
public MistletoeAddon(Serial serial) : base(serial)
{
}
public bool CouldFit(IPoint3D p, Map map)
{
if (!map.CanFit(p.X, p.Y, p.Z, ItemData.Height))
{
return false;
}
if (ItemID == 0x2375)
{
return BaseAddon.IsWall(p.X, p.Y - 1, p.Z, map); // North wall
}
return BaseAddon.IsWall(p.X - 1, p.Y, p.Z, map); // West wall
}
public Item Deed => new MistletoeDeed(Hue);
public virtual bool Dye(Mobile from, DyeTub sender)
{
if (Deleted)
{
return false;
}
var house = BaseHouse.FindHouseAt(this);
if (house?.IsCoOwner(from) == true)
{
if (from.InRange(GetWorldLocation(), 1))
{
Hue = sender.DyedHue;
return true;
}
from.SendLocalizedMessage(500295); // You are too far away to do that.
return false;
}
return false;
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
Timer.StartTimer(FixMovingCrate);
}
private void FixMovingCrate()
{
if (Deleted)
{
return;
}
if (Movable || IsLockedDown)
{
var deed = Deed;
if (Parent is Item item)
{
item.AddItem(deed);
deed.Location = Location;
}
else
{
deed.MoveToWorld(Location, Map);
}
Delete();
}
}
public override void OnDoubleClick(Mobile from)
{
var house = BaseHouse.FindHouseAt(this);
if (house?.IsCoOwner(from) == true)
{
if (from.InRange(GetWorldLocation(), 3))
{
from.CloseGump<MistletoeAddonGump>();
from.SendGump(new MistletoeAddonGump(from, this));
}
else
{
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
}
}
}
private class MistletoeAddonGump : Gump
{
private readonly MistletoeAddon m_Addon;
private readonly Mobile m_From;
public MistletoeAddonGump(Mobile from, MistletoeAddon addon) : base(150, 50)
{
m_From = from;
m_Addon = addon;
AddPage(0);
AddBackground(0, 0, 220, 170, 0x13BE);
AddBackground(10, 10, 200, 150, 0xBB8);
AddHtmlLocalized(20, 30, 180, 60, 1062839); // Do you wish to re-deed this decoration?
AddHtmlLocalized(55, 100, 160, 25, 1011011); // CONTINUE
AddButton(20, 100, 0xFA5, 0xFA7, 1);
AddHtmlLocalized(55, 125, 160, 25, 1011012); // CANCEL
AddButton(20, 125, 0xFA5, 0xFA7, 0);
}
public override void OnResponse(NetState sender, in RelayInfo info)
{
if (m_Addon.Deleted || info.ButtonID != 1)
{
return;
}
if (m_From.InRange(m_Addon.GetWorldLocation(), 3))
{
m_From.AddToBackpack(m_Addon.Deed);
m_Addon.Delete();
}
else
{
m_From.SendLocalizedMessage(500295); // You are too far away to do that.
}
}
}
}
[Flippable(0x14F0, 0x14EF)]
public class MistletoeDeed : Item
{
[Constructible]
public MistletoeDeed(int hue = 0) : base(0x14F0)
{
Hue = hue;
Weight = 1.0;
LootType = LootType.Blessed;
}
public MistletoeDeed(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1070882; // Mistletoe Deed
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
public override void OnSingleClick(Mobile from)
{
base.OnSingleClick(from);
LabelTo(from, 1070880); // Winter 2004
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
list.Add(1070880); // Winter 2004
}
public override void OnDoubleClick(Mobile from)
{
if (IsChildOf(from.Backpack))
{
var house = BaseHouse.FindHouseAt(from);
if (house?.IsCoOwner(from) == true)
{
from.SendLocalizedMessage(1062838); // Where would you like to place this decoration?
from.BeginTarget(-1, true, TargetFlags.None, Placement_OnTarget);
}
else
{
from.SendLocalizedMessage(502092); // You must be in your house to do this.
}
}
else
{
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
}
}
public void Placement_OnTarget(Mobile from, object targeted)
{
if (targeted is not IPoint3D p)
{
return;
}
var loc = new Point3D(p);
var house = BaseHouse.FindHouseAt(loc, from.Map, 16);
if (house?.IsCoOwner(from) == true)
{
var northWall = BaseAddon.IsWall(loc.X, loc.Y - 1, loc.Z, from.Map);
var westWall = BaseAddon.IsWall(loc.X - 1, loc.Y, loc.Z, from.Map);
if (northWall && westWall)
{
from.SendGump(new MistletoeDeedGump(from, loc, this));
}
else
{
PlaceAddon(from, loc, northWall, westWall);
}
}
else
{
from.SendLocalizedMessage(1042036); // That location is not in your house.
}
}
private void PlaceAddon(Mobile from, Point3D loc, bool northWall, bool westWall)
{
if (Deleted)
{
return;
}
var house = BaseHouse.FindHouseAt(loc, from.Map, 16);
if (house?.IsCoOwner(from) != true)
{
from.SendLocalizedMessage(1042036); // That location is not in your house.
return;
}
var itemID = 0;
if (northWall)
{
itemID = 0x2374;
}
else if (westWall)
{
itemID = 0x2375;
}
else
{
from.SendLocalizedMessage(1070883); // The mistletoe must be placed next to a wall.
}
if (itemID > 0)
{
Item addon = new MistletoeAddon(Hue);
addon.ItemID = itemID;
addon.MoveToWorld(loc, from.Map);
house.Addons.Add(addon);
Delete();
}
}
private class MistletoeDeedGump : Gump
{
private readonly MistletoeDeed m_Deed;
private readonly Mobile m_From;
private readonly Point3D m_Loc;
public MistletoeDeedGump(Mobile from, Point3D loc, MistletoeDeed deed) : base(150, 50)
{
m_From = from;
m_Loc = loc;
m_Deed = deed;
AddBackground(0, 0, 300, 150, 0xA28);
AddPage(0);
AddItem(90, 30, 0x2375);
AddItem(180, 30, 0x2374);
AddButton(50, 35, 0x868, 0x869, 1);
AddButton(145, 35, 0x868, 0x869, 2);
}
public override void OnResponse(NetState sender, in RelayInfo info)
{
if (m_Deed.Deleted)
{
return;
}
switch (info.ButtonID)
{
case 1:
m_Deed.PlaceAddon(m_From, m_Loc, false, true);
break;
case 2:
m_Deed.PlaceAddon(m_From, m_Loc, true, false);
break;
}
}
}
}
}

View file

@ -1,151 +0,0 @@
using System;
using Server.Engines.ConPVP;
using Server.Targeting;
namespace Server.Items
{
public class PileOfGlacialSnow : Item
{
private static Type[] _snowPileTypes = { typeof(SnowPile), typeof(PileOfGlacialSnow) };
[Constructible]
public PileOfGlacialSnow() : base(0x913)
{
Hue = 0x480;
Weight = 1.0;
LootType = LootType.Blessed;
}
public PileOfGlacialSnow(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1070874; // a Pile of Glacial Snow
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
if (version == 0)
{
Weight = 1.0;
LootType = LootType.Blessed;
}
}
public override void OnSingleClick(Mobile from)
{
base.OnSingleClick(from);
LabelTo(from, 1070880); // Winter 2004
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
list.Add(1070880); // Winter 2004
}
public override void OnDoubleClick(Mobile from)
{
if (!IsChildOf(from.Backpack))
{
from.SendLocalizedMessage(1042010); // You must have the object in your backpack to use it.
}
else if (from.Mounted)
{
from.SendLocalizedMessage(1010097); // You cannot use this while mounted.
}
else if (from.CanBeginAction<SnowPile>())
{
from.SendLocalizedMessage(1005575); // You carefully pack the snow into a ball...
from.Target = new SnowTarget(from, this);
}
else
{
from.SendLocalizedMessage(1005574); // The snow is not ready to be packed yet. Keep trying.
}
}
private class InternalTimer : Timer
{
private readonly Mobile m_From;
public InternalTimer(Mobile from) : base(TimeSpan.FromSeconds(5.0)) => m_From = from;
protected override void OnTick()
{
m_From.EndAction<SnowPile>();
}
}
private class SnowTarget : Target
{
private Item m_Snow;
private Mobile m_Thrower;
public SnowTarget(Mobile thrower, Item snow) : base(10, false, TargetFlags.None)
{
m_Thrower = thrower;
m_Snow = snow;
}
protected override void OnTarget(Mobile from, object target)
{
if (target == from)
{
from.SendLocalizedMessage(1005576); // You can't throw this at yourself.
}
else if (target is Mobile targ)
{
var pack = targ.Backpack;
if (from.Region.IsPartOf<SafeZone>() || targ.Region.IsPartOf<SafeZone>())
{
from.SendMessage("You may not throw snow here.");
}
else if (pack?.FindItemByType(_snowPileTypes) != null)
{
if (from.BeginAction<SnowPile>())
{
new InternalTimer(from).Start();
from.PlaySound(0x145);
from.Animate(9, 1, 1, true, false, 0);
targ.SendLocalizedMessage(1010572); // You have just been hit by a snowball!
from.SendLocalizedMessage(1010573); // You throw the snowball and hit the target!
Effects.SendMovingEffect(from, targ, 0x36E4, 7, 0, false, true, 0x47F);
}
else
{
from.SendLocalizedMessage(1005574); // The snow is not ready to be packed yet. Keep trying.
}
}
else
{
// You can only throw a snowball at something that can throw one back.
from.SendLocalizedMessage(1005577);
}
}
else
{
// You can only throw a snowball at something that can throw one back.
from.SendLocalizedMessage(1005577);
}
}
}
}
}

View file

@ -1,137 +0,0 @@
using System;
using Server.Engines.ConPVP;
using Server.Targeting;
namespace Server.Items
{
public class SnowPile : Item
{
[Constructible]
public SnowPile() : base(0x913)
{
Hue = 0x481;
Weight = 1.0;
LootType = LootType.Blessed;
}
public SnowPile(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1005578; // a pile of snow
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
if (version == 0)
{
Weight = 1.0;
LootType = LootType.Blessed;
}
}
public override void OnDoubleClick(Mobile from)
{
if (!IsChildOf(from.Backpack))
{
from.SendLocalizedMessage(1042010); // You must have the object in your backpack to use it.
}
else if (from.Mounted)
{
from.SendLocalizedMessage(1010097); // You cannot use this while mounted.
}
else if (from.CanBeginAction<SnowPile>())
{
from.SendLocalizedMessage(1005575); // You carefully pack the snow into a ball...
from.Target = new SnowTarget(from, this);
}
else
{
from.SendLocalizedMessage(1005574); // The snow is not ready to be packed yet. Keep trying.
}
}
private class InternalTimer : Timer
{
private readonly Mobile m_From;
public InternalTimer(Mobile from) : base(TimeSpan.FromSeconds(5.0)) => m_From = from;
protected override void OnTick()
{
m_From.EndAction<SnowPile>();
}
}
private class SnowTarget : Target
{
private Item m_Snow;
private Mobile m_Thrower;
public SnowTarget(Mobile thrower, Item snow) : base(10, false, TargetFlags.None)
{
m_Thrower = thrower;
m_Snow = snow;
}
protected override void OnTarget(Mobile from, object target)
{
if (target == from)
{
from.SendLocalizedMessage(1005576); // You can't throw this at yourself.
}
else if (target is Mobile targ)
{
var pack = targ.Backpack;
if (from.Region.IsPartOf<SafeZone>() || targ.Region.IsPartOf<SafeZone>())
{
from.SendMessage("You may not throw snow here.");
}
else if (pack?.FindItemByType(new[] { typeof(SnowPile), typeof(PileOfGlacialSnow) }) != null)
{
if (from.BeginAction<SnowPile>())
{
new InternalTimer(from).Start();
from.PlaySound(0x145);
from.Animate(9, 1, 1, true, false, 0);
targ.SendLocalizedMessage(1010572); // You have just been hit by a snowball!
from.SendLocalizedMessage(1010573); // You throw the snowball and hit the target!
Effects.SendMovingEffect(from, targ, 0x36E4, 7, 0, false, true, 0x480);
}
else
{
from.SendLocalizedMessage(1005574); // The snow is not ready to be packed yet. Keep trying.
}
}
else
{
from.SendLocalizedMessage(
1005577
); // You can only throw a snowball at something that can throw one back.
}
}
else
{
from.SendLocalizedMessage(
1005577
); // You can only throw a snowball at something that can throw one back.
}
}
}
}
}

View file

@ -1,44 +0,0 @@
namespace Server.Items
{
public class SnowyTree : Item
{
[Constructible]
public SnowyTree() : base(0x2377)
{
Weight = 1.0;
LootType = LootType.Blessed;
}
public SnowyTree(Serial serial) : base(serial)
{
}
public override void OnSingleClick(Mobile from)
{
base.OnSingleClick(from);
LabelTo(from, 1070880); // Winter 2004
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
list.Add(1070880); // Winter 2004
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,50 +0,0 @@
using System;
using Server.Items;
namespace Server.Misc
{
public class WinterGiftGiver2004 : GiftGiver
{
public override DateTime Start => new(2004, 12, 24);
public override DateTime Finish => new(2005, 1, 1);
public static void Initialize()
{
GiftGiving.Register(new WinterGiftGiver2004());
}
public override void GiveGift(Mobile mob)
{
var box = new GiftBox();
box.DropItem(new MistletoeDeed());
box.DropItem(new PileOfGlacialSnow());
box.DropItem(new LightOfTheWinterSolstice());
var random = Utility.Random(100);
if (random < 60)
{
box.DropItem(new DecorativeTopiary());
}
else if (random < 84)
{
box.DropItem(new FestiveCactus());
}
else
{
box.DropItem(new SnowyTree());
}
switch (GiveGift(mob, box))
{
case GiftResult.Backpack:
mob.SendMessage(0x482, "Happy Holidays from the team! Gift items have been placed in your backpack.");
break;
case GiftResult.BankBox:
mob.SendMessage(0x482, "Happy Holidays from the team! Gift items have been placed in your bank box.");
break;
}
}
}
}

View file

@ -0,0 +1,50 @@
namespace Server.Misc;
public static class StaffInfo
{
private static readonly string[] _staff =
{
// ModernUO Sponsors
"Prayer",
"Arch Lich Oro",
"Tamashii",
// ModernUO Contributors
"nibbio",
"what the moose",
// RunUO Contributors
"Aenima",
"Alkiser",
"ASayre",
"David",
"Krrios",
"Mark",
"Merlin",
"Merlix", //LordMerlix
"nerun",
"Outkast", //TheOutkastDev
"Phantom",
"Phenos",
"psz",
"Quantos",
"Ryan",
"Sp1der", // Kamron
"V", //Admin_V
"Zippy",
// ServUO Contributors
"Vorspire",
"kevin-10",
"Argalep",
"dmurphy22",
"qbradq",
// Outlands Staff
"Owyn",
"Luthius",
"Jaedan"
};
public static string GetRandomStaff() => _staff.RandomElement();
}