fix: Fixes veteran rewards (#1374)

### Summary
- [X] Fixes a bug in wall banner East setter: [[ServerUO#5046]](https://github.com/ServUO/ServUO/pull/5046)
- [X] Eliminates the timer in tree stump.
- [X] Codegens the rewards
This commit is contained in:
Kamron Batman 2023-03-12 17:28:51 -07:00 committed by GitHub
parent e797ec7f53
commit 127ca5e51e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
62 changed files with 4065 additions and 4653 deletions

View file

@ -193,12 +193,12 @@ namespace Server.Engines.VeteranRewards
return true;
}
// Your account is not old enough to use this item. Months until you can use this item :
from.SendLocalizedMessage(
1008126,
true,
Math.Ceiling(ts.TotalDays / 30.0)
.ToString()
); // Your account is not old enough to use this item. Months until you can use this item :
Math.Ceiling(ts.TotalDays / 30.0).ToString()
);
return false;
}
@ -221,12 +221,12 @@ namespace Server.Engines.VeteranRewards
return true;
}
// Your account is not old enough to use this item. Months until you can use this item :
from.SendLocalizedMessage(
1008126,
true,
Math.Ceiling(ts.TotalDays / 30.0)
.ToString()
); // Your account is not old enough to use this item. Months until you can use this item :
Math.Ceiling(ts.TotalDays / 30.0).ToString()
);
return false;
}
}

View file

@ -3,55 +3,37 @@
* Adding it with no params or false will create an empty box.
*/
namespace Server.Items
using ModernUO.Serialization;
namespace Server.Items;
[SerializationGenerator(0, false)]
public partial class RedVelvetGiftBox : BaseContainer
{
public class RedVelvetGiftBox : BaseContainer
[Constructible]
public RedVelvetGiftBox(bool fill = false) : base(0xE7A)
{
[Constructible]
public RedVelvetGiftBox(bool fill = false)
: base(0xE7A)
{
Hue = 0x20;
Hue = 0x20;
if (fill)
if (fill)
{
for (var i = 0; i < 5; i++)
{
for (var i = 0; i < 5; i++)
{
AddToBox(new ValentinesCardSouth(), new Point3D(60 + i * 10, 47, 0));
AddToBox(new ValentinesCardEast(), new Point3D(20 + i * 10, 72, 0));
}
AddToBox(new Bacon(), new Point3D(90, 85, 0));
AddToBox(new RoseInAVase(), new Point3D(130, 55, 0));
AddToBox(new ValentinesCardSouth(), new Point3D(60 + i * 10, 47, 0));
AddToBox(new ValentinesCardEast(), new Point3D(20 + i * 10, 72, 0));
}
}
public RedVelvetGiftBox(Serial serial)
: base(serial)
{
}
public override int DefaultGumpID => 0x3f;
public override int LabelNumber => 1077596; // A Red Velvet Box
public virtual void AddToBox(Item item, Point3D loc)
{
DropItem(item);
item.Location = loc;
}
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();
AddToBox(new Bacon(), new Point3D(90, 85, 0));
AddToBox(new RoseInAVase(), new Point3D(130, 55, 0));
}
}
public override int DefaultGumpID => 0x3f;
public override int LabelNumber => 1077596; // A Red Velvet Box
public void AddToBox(Item item, Point3D loc)
{
DropItem(item);
item.Location = loc;
}
}

View file

@ -1,34 +1,16 @@
namespace Server.Items
using ModernUO.Serialization;
namespace Server.Items;
[SerializationGenerator(0, false)]
public partial class RoseInAVase : Item /* TODO: when dye tub changes are implemented, furny dyable this */
{
public class RoseInAVase : Item /* TODO: when dye tub changes are implemented, furny dyable this */
[Constructible]
public RoseInAVase() : base(0x0EB0)
{
[Constructible]
public RoseInAVase()
: base(0x0EB0)
{
Hue = 0x20;
LootType = LootType.Blessed;
}
public RoseInAVase(Serial serial)
: base(serial)
{
}
public override int LabelNumber => 1023760; // A Rose in a Vase 1023760
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();
}
Hue = 0x20;
LootType = LootType.Blessed;
}
public override int LabelNumber => 1023760; // A Rose in a Vase 1023760
}

View file

@ -1,201 +1,130 @@
using Server.Mobiles;
using ModernUO.Serialization;
using Server.Mobiles;
using Server.Targeting;
namespace Server.Items
namespace Server.Items;
[SerializationGenerator(0, false)]
public partial class ValentinesCard : Item
{
public class ValentinesCard : Item
private const string Unsigned = "___";
[SerializableField(0, getter: "private", setter: "private")]
private int _labelNumber;
[InvalidateProperties]
[SerializableField(1)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private string _from;
[InvalidateProperties]
[SerializableField(2)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private string _to;
[Constructible]
public ValentinesCard(int itemid) : base(itemid)
{
private static readonly string Unsigned = "___";
private string m_From;
LootType = LootType.Blessed;
Hue = Utility.RandomDouble() < .001 ? 0x47E : 0xE8;
_labelNumber = Utility.Random(1077589, 5);
}
private int m_LabelNumber;
private string m_To;
public override string DefaultName => "a Valentine's card";
[Constructible]
public ValentinesCard(int itemid)
: base(itemid)
/*
* Five possible messages:
* To my one true love, ~1_target_player~. Signed: ~2_player~ 1077589
* Youve pwnd my heart, ~1_target_player~. Signed: ~2_player~ 1077590
* Happy Valentines Day, ~1_target_player~. Signed: ~2_player~ 1077591
* Blackrock has driven me crazy... for ~1_target_player~! Signed: ~2_player~ 1077592
* You light my Candle of Love, ~1_target_player~! Signed: ~2_player~ 1077593
*
*/
public override void AddNameProperty(IPropertyList list)
{
list.Add(_labelNumber, $"{_to ?? Unsigned}\t{_from ?? Unsigned}");
}
public override void OnSingleClick(Mobile from)
{
base.OnSingleClick(from);
LabelTo(from, _labelNumber, $"{_to ?? Unsigned}\t{_from ?? Unsigned}");
}
public override void OnDoubleClick(Mobile from)
{
if (_to == null)
{
LootType = LootType.Blessed;
Hue = Utility.RandomDouble() < .001 ? 0x47E : 0xE8;
m_LabelNumber = Utility.Random(1077589, 5);
}
public ValentinesCard(Serial serial)
: base(serial)
{
}
public override string DefaultName => "a Valentine's card";
[CommandProperty(AccessLevel.GameMaster)]
public virtual string From
{
get => m_From;
set => m_From = value;
}
[CommandProperty(AccessLevel.GameMaster)]
public virtual string To
{
get => m_To;
set => m_To = value;
}
/*
* Five possible messages to be signed:
*
* To my one true love, ~1_target_player~. Signed: ~2_player~ 1077589
* Youve pwnd my heart, ~1_target_player~. Signed: ~2_player~ 1077590
* Happy Valentines Day, ~1_target_player~. Signed: ~2_player~ 1077591
* Blackrock has driven me crazy... for ~1_target_player~! Signed: ~2_player~ 1077592
* You light my Candle of Love, ~1_target_player~! Signed: ~2_player~ 1077593
*
*/
public override void AddNameProperty(IPropertyList list)
{
list.Add(m_LabelNumber, $"{m_To ?? Unsigned}\t{m_From ?? Unsigned}");
}
public override void OnSingleClick(Mobile from)
{
base.OnSingleClick(from);
LabelTo(
from,
m_LabelNumber,
$"{m_To ?? Unsigned}\t{m_From ?? Unsigned}"
);
}
public override void OnDoubleClick(Mobile from)
{
if (m_To == null)
if (IsChildOf(from))
{
if (IsChildOf(from))
{
from.BeginTarget(10, false, TargetFlags.None, OnTarget);
from.BeginTarget(10, false, TargetFlags.None, OnTarget);
from.SendLocalizedMessage(1077497); // To whom do you wish to give this card?
}
else
{
from.SendLocalizedMessage(1080063); // This must be in your backpack to use it.
}
from.SendLocalizedMessage(1077497); // To whom do you wish to give this card?
}
}
public virtual void OnTarget(Mobile from, object targeted)
{
if (!Deleted)
else
{
if (targeted is Mobile to)
{
if (to is PlayerMobile)
{
if (to != from)
{
m_From = from.Name;
m_To = to.Name;
from.SendLocalizedMessage(
1077498
); // You fill out the card. Hopefully the other person actually likes you...
InvalidateProperties();
}
else
{
from.SendLocalizedMessage(1077495); // You can't give yourself a card, silly!
}
}
else
{
from.SendLocalizedMessage(1077496); // You can't possibly be THAT lonely!
}
}
else
{
from.SendLocalizedMessage(1077488); // That's not another player!
}
from.SendLocalizedMessage(1080063); // This must be in your backpack to use it.
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
writer.Write(m_LabelNumber);
writer.Write(m_From);
writer.Write(m_To);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
m_LabelNumber = reader.ReadInt();
m_From = reader.ReadString();
m_To = reader.ReadString();
Utility.Intern(ref m_From);
Utility.Intern(ref m_To);
}
}
public class ValentinesCardSouth : ValentinesCard
public virtual void OnTarget(Mobile from, object targeted)
{
[Constructible]
public ValentinesCardSouth()
: base(0x0EBD)
if (Deleted)
{
return;
}
public ValentinesCardSouth(Serial serial)
: base(serial)
if (targeted is not Mobile to)
{
from.SendLocalizedMessage(1077488); // That's not another player!
return;
}
public override void Serialize(IGenericWriter writer)
if (to is not PlayerMobile)
{
base.Serialize(writer);
writer.Write(0); // version
from.SendLocalizedMessage(1077496); // You can't possibly be THAT lonely!
return;
}
public override void Deserialize(IGenericReader reader)
if (to == from)
{
base.Deserialize(reader);
var version = reader.ReadInt();
from.SendLocalizedMessage(1077495); // You can't give yourself a card, silly!
return;
}
From = from.Name;
To = to.Name;
// You fill out the card. Hopefully the other person actually likes you...
from.SendLocalizedMessage(1077498);
}
public class ValentinesCardEast : ValentinesCard
[AfterDeserialization]
private void AfterDeserialization()
{
Utility.Intern(ref _from);
Utility.Intern(ref _to);
}
}
[SerializationGenerator(0, false)]
public partial class ValentinesCardSouth : ValentinesCard
{
[Constructible]
public ValentinesCardSouth() : base(0x0EBD)
{
}
}
[SerializationGenerator(0, false)]
public partial class ValentinesCardEast : ValentinesCard
{
[Constructible]
public ValentinesCardEast() : base(0x0EBE)
{
[Constructible]
public ValentinesCardEast()
: base(0x0EBE)
{
}
public ValentinesCardEast(Serial serial)
: base(serial)
{
}
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,369 +1,276 @@
using System;
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.ContextMenus;
using Server.Engines.VeteranRewards;
using Server.Gumps;
using Server.Mobiles;
using Server.Network;
namespace Server.Items
namespace Server.Items;
[SerializationGenerator(0, false)]
public partial class AnkhOfSacrificeComponent : AddonComponent
{
public class AnkhOfSacrificeComponent : AddonComponent
public AnkhOfSacrificeComponent(int itemID) : base(itemID)
{
public AnkhOfSacrificeComponent(int itemID) : base(itemID)
}
public override bool ForceShowProperties => ObjectPropertyList.Enabled;
public override int LabelNumber => 1027772; // Ankh of Sacrifice
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
if (from is PlayerMobile mobile)
{
list.Add(new LockKarmaEntry(mobile, Addon as AnkhOfSacrificeAddon));
}
public AnkhOfSacrificeComponent(Serial serial) : base(serial)
list.Add(new ResurrectEntry(from, Addon as AnkhOfSacrificeAddon));
}
public static void Resurrect(PlayerMobile m, AnkhOfSacrificeAddon ankh)
{
if (m == null)
{
}
public override bool ForceShowProperties => ObjectPropertyList.Enabled;
public override int LabelNumber => 1027772; // Ankh of Sacrifice
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
else if (!m.InRange(ankh.GetWorldLocation(), 2))
{
base.GetContextMenuEntries(from, list);
if (from is PlayerMobile mobile)
{
list.Add(new LockKarmaEntry(mobile, Addon as AnkhOfSacrificeAddon));
}
list.Add(new ResurrectEntry(from, Addon as AnkhOfSacrificeAddon));
m.SendLocalizedMessage(500446); // That is too far away.
}
public override void Serialize(IGenericWriter writer)
else if (m.Alive)
{
base.Serialize(writer);
writer.Write(0); // version
m.SendLocalizedMessage(1060197); // You are not dead, and thus cannot be resurrected!
}
public override void Deserialize(IGenericReader reader)
else if (m.AnkhNextUse > Core.Now)
{
base.Deserialize(reader);
var delay = m.AnkhNextUse - Core.Now;
var version = reader.ReadInt();
}
public static void Resurrect(PlayerMobile m, AnkhOfSacrificeAddon ankh)
{
if (m == null)
if (delay.TotalMinutes > 0)
{
}
else if (!m.InRange(ankh.GetWorldLocation(), 2))
{
m.SendLocalizedMessage(500446); // That is too far away.
}
else if (m.Alive)
{
m.SendLocalizedMessage(1060197); // You are not dead, and thus cannot be resurrected!
}
else if (m.AnkhNextUse > Core.Now)
{
var delay = m.AnkhNextUse - Core.Now;
if (delay.TotalMinutes > 0)
{
m.SendLocalizedMessage(
1079265,
Math.Round(delay.TotalMinutes)
.ToString()
); // You must wait ~1_minutes~ minutes before you can use this item.
}
else
{
m.SendLocalizedMessage(
1079263,
Math.Round(delay.TotalSeconds)
.ToString()
); // You must wait ~1_seconds~ seconds before you can use this item.
}
// You must wait ~1_minutes~ minutes before you can use this item.
m.SendLocalizedMessage(1079265, Math.Round(delay.TotalMinutes).ToString());
}
else
{
m.CloseGump<AnkhResurrectGump>();
m.SendGump(new AnkhResurrectGump(m, ResurrectMessage.VirtueShrine));
// You must wait ~1_seconds~ seconds before you can use this item.
m.SendLocalizedMessage(1079263, Math.Round(delay.TotalSeconds).ToString());
}
}
private class ResurrectEntry : ContextMenuEntry
else
{
private readonly AnkhOfSacrificeAddon m_Ankh;
private readonly Mobile m_Mobile;
public ResurrectEntry(Mobile mobile, AnkhOfSacrificeAddon ankh) : base(6195, 2)
{
m_Mobile = mobile;
m_Ankh = ankh;
}
public override void OnClick()
{
if (m_Ankh?.Deleted != false)
{
return;
}
Resurrect(m_Mobile as PlayerMobile, m_Ankh);
}
}
private class LockKarmaEntry : ContextMenuEntry
{
private readonly AnkhOfSacrificeAddon m_Ankh;
private readonly PlayerMobile m_Mobile;
public LockKarmaEntry(PlayerMobile mobile, AnkhOfSacrificeAddon ankh) : base(mobile.KarmaLocked ? 6197 : 6196, 2)
{
m_Mobile = mobile;
m_Ankh = ankh;
}
public override void OnClick()
{
if (!m_Mobile.InRange(m_Ankh.GetWorldLocation(), 2))
{
m_Mobile.SendLocalizedMessage(500446); // That is too far away.
}
else
{
m_Mobile.KarmaLocked = !m_Mobile.KarmaLocked;
if (m_Mobile.KarmaLocked)
{
m_Mobile.SendLocalizedMessage(
1060192
); // Your karma has been locked. Your karma can no longer be raised.
}
else
{
m_Mobile.SendLocalizedMessage(
1060191
); // Your karma has been unlocked. Your karma can be raised again.
}
}
}
}
private class AnkhResurrectGump : ResurrectGump
{
public AnkhResurrectGump(Mobile owner, ResurrectMessage msg) : base(owner, owner, msg)
{
}
public override void OnResponse(NetState state, RelayInfo info)
{
var from = state.Mobile;
if (info.ButtonID is 1 or 2)
{
if (from.Map?.CanFit(from.Location, 16, false, false) != true)
{
from.SendLocalizedMessage(502391); // Thou can not be resurrected there!
return;
}
if (from is PlayerMobile mobile)
{
mobile.AnkhNextUse = Core.Now + TimeSpan.FromHours(1);
}
base.OnResponse(state, info);
}
}
m.CloseGump<AnkhResurrectGump>();
m.SendGump(new AnkhResurrectGump(m, ResurrectMessage.VirtueShrine));
}
}
public class AnkhOfSacrificeAddon : BaseAddon, IRewardItem
private class ResurrectEntry : ContextMenuEntry
{
private bool m_IsRewardItem;
private readonly AnkhOfSacrificeAddon _ankh;
private readonly Mobile _mobile;
[Constructible]
public AnkhOfSacrificeAddon(bool east)
public ResurrectEntry(Mobile mobile, AnkhOfSacrificeAddon ankh) : base(6195, 2)
{
if (east)
{
AddComponent(new AnkhOfSacrificeComponent(0x1D98), 0, 0, 0);
AddComponent(new AnkhOfSacrificeComponent(0x1D97), 0, 1, 0);
AddComponent(new AnkhOfSacrificeComponent(0x1CD6), 1, 0, 0);
AddComponent(new AnkhOfSacrificeComponent(0x1CD4), 1, 1, 0);
AddComponent(new AnkhOfSacrificeComponent(0x1CD0), 2, 0, 0);
AddComponent(new AnkhOfSacrificeComponent(0x1CCE), 2, 1, 0);
}
else
{
AddComponent(new AnkhOfSacrificeComponent(0x1E5D), 0, 0, 0);
AddComponent(new AnkhOfSacrificeComponent(0x1E5C), 1, 0, 0);
AddComponent(new AnkhOfSacrificeComponent(0x1CD2), 0, 1, 0);
AddComponent(new AnkhOfSacrificeComponent(0x1CD8), 1, 1, 0);
AddComponent(new AnkhOfSacrificeComponent(0x1CCD), 0, 2, 0);
AddComponent(new AnkhOfSacrificeComponent(0x1CCE), 1, 2, 0);
}
_mobile = mobile;
_ankh = ankh;
}
public AnkhOfSacrificeAddon(Serial serial) : base(serial)
public override void OnClick()
{
}
public override bool HandlesOnMovement => true;
public override BaseAddonDeed Deed
{
get
{
var deed = new AnkhOfSacrificeDeed();
deed.IsRewardItem = m_IsRewardItem;
return deed;
}
}
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
{
get => m_IsRewardItem;
set
{
m_IsRewardItem = value;
InvalidateProperties();
}
}
public override void OnMovement(Mobile m, Point3D oldLocation)
{
if (!m.Alive && Utility.InRange(Location, m.Location, 1) && !Utility.InRange(Location, oldLocation, 1))
{
AnkhOfSacrificeComponent.Resurrect(m as PlayerMobile, this);
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
writer.Write(m_IsRewardItem);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_IsRewardItem = reader.ReadBool();
}
}
public class AnkhOfSacrificeDeed : BaseAddonDeed, IRewardItem, IRewardOption
{
private bool m_East;
private bool m_IsRewardItem;
[Constructible]
public AnkhOfSacrificeDeed(bool isRewardItem = false)
{
LootType = LootType.Blessed;
m_IsRewardItem = isRewardItem;
}
public AnkhOfSacrificeDeed(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1080397; // Deed For An Ankh Of Sacrifice
public override BaseAddon Addon
{
get
{
var addon = new AnkhOfSacrificeAddon(m_East);
addon.IsRewardItem = m_IsRewardItem;
return addon;
}
}
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
{
get => m_IsRewardItem;
set
{
m_IsRewardItem = value;
InvalidateProperties();
}
}
public void GetOptions(RewardOptionList list)
{
list.Add(1, 1080398); // Ankh of Sacrifice South
list.Add(2, 1080399); // Ankh of Sacrifice East
}
public void OnOptionSelected(Mobile from, int option)
{
m_East = option switch
{
1 => false,
2 => true,
_ => m_East
};
if (!Deleted)
{
base.OnDoubleClick(from);
}
}
public override void OnDoubleClick(Mobile from)
{
if (m_IsRewardItem && !RewardSystem.CheckIsUsableBy(from, this))
if (_ankh?.Deleted != false)
{
return;
}
if (IsChildOf(from.Backpack))
Resurrect(_mobile as PlayerMobile, _ankh);
}
}
private class LockKarmaEntry : ContextMenuEntry
{
private readonly AnkhOfSacrificeAddon _ankh;
private readonly PlayerMobile _mobile;
public LockKarmaEntry(PlayerMobile mobile, AnkhOfSacrificeAddon ankh) : base(mobile.KarmaLocked ? 6197 : 6196, 2)
{
_mobile = mobile;
_ankh = ankh;
}
public override void OnClick()
{
if (!_mobile.InRange(_ankh.GetWorldLocation(), 2))
{
from.CloseGump<RewardOptionGump>();
from.SendGump(new RewardOptionGump(this));
_mobile.SendLocalizedMessage(500446); // That is too far away.
}
else
{
from.SendLocalizedMessage(1062334); // This item must be in your backpack to be used.
_mobile.KarmaLocked = !_mobile.KarmaLocked;
if (_mobile.KarmaLocked)
{
// Your karma has been locked. Your karma can no longer be raised.
_mobile.SendLocalizedMessage(1060192);
}
else
{
// Your karma has been unlocked. Your karma can be raised again.
_mobile.SendLocalizedMessage(1060191);
}
}
}
}
public override void GetProperties(IPropertyList list)
private class AnkhResurrectGump : ResurrectGump
{
public AnkhResurrectGump(Mobile owner, ResurrectMessage msg) : base(owner, owner, msg)
{
base.GetProperties(list);
}
if (m_IsRewardItem)
public override void OnResponse(NetState state, RelayInfo info)
{
var from = state.Mobile;
if (info.ButtonID is 1 or 2)
{
list.Add(1080457); // 10th Year Veteran Reward
if (from.Map?.CanFit(from.Location, 16, false, false) != true)
{
from.SendLocalizedMessage(502391); // Thou can not be resurrected there!
return;
}
if (from is PlayerMobile mobile)
{
mobile.AnkhNextUse = Core.Now + TimeSpan.FromHours(1);
}
base.OnResponse(state, info);
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
writer.Write(m_IsRewardItem);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_IsRewardItem = reader.ReadBool();
}
}
}
[SerializationGenerator(0)]
public partial class AnkhOfSacrificeAddon : BaseAddon, IRewardItem
{
[InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _isRewardItem;
[Constructible]
public AnkhOfSacrificeAddon(bool east)
{
if (east)
{
AddComponent(new AnkhOfSacrificeComponent(0x1D98), 0, 0, 0);
AddComponent(new AnkhOfSacrificeComponent(0x1D97), 0, 1, 0);
AddComponent(new AnkhOfSacrificeComponent(0x1CD6), 1, 0, 0);
AddComponent(new AnkhOfSacrificeComponent(0x1CD4), 1, 1, 0);
AddComponent(new AnkhOfSacrificeComponent(0x1CD0), 2, 0, 0);
AddComponent(new AnkhOfSacrificeComponent(0x1CCE), 2, 1, 0);
}
else
{
AddComponent(new AnkhOfSacrificeComponent(0x1E5D), 0, 0, 0);
AddComponent(new AnkhOfSacrificeComponent(0x1E5C), 1, 0, 0);
AddComponent(new AnkhOfSacrificeComponent(0x1CD2), 0, 1, 0);
AddComponent(new AnkhOfSacrificeComponent(0x1CD8), 1, 1, 0);
AddComponent(new AnkhOfSacrificeComponent(0x1CCD), 0, 2, 0);
AddComponent(new AnkhOfSacrificeComponent(0x1CCE), 1, 2, 0);
}
}
public override bool HandlesOnMovement => true;
public override BaseAddonDeed Deed =>
new AnkhOfSacrificeDeed
{
IsRewardItem = _isRewardItem
};
public override void OnMovement(Mobile m, Point3D oldLocation)
{
if (!m.Alive && Utility.InRange(Location, m.Location, 1) && !Utility.InRange(Location, oldLocation, 1))
{
AnkhOfSacrificeComponent.Resurrect(m as PlayerMobile, this);
}
}
}
[SerializationGenerator(0)]
public partial class AnkhOfSacrificeDeed : BaseAddonDeed, IRewardItem, IRewardOption
{
private bool _east;
[InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _isRewardItem;
[Constructible]
public AnkhOfSacrificeDeed(bool isRewardItem = false)
{
LootType = LootType.Blessed;
_isRewardItem = isRewardItem;
}
public override int LabelNumber => 1080397; // Deed For An Ankh Of Sacrifice
public override BaseAddon Addon =>
new AnkhOfSacrificeAddon(_east)
{
IsRewardItem = _isRewardItem
};
public void GetOptions(RewardOptionList list)
{
list.Add(1, 1080398); // Ankh of Sacrifice South
list.Add(2, 1080399); // Ankh of Sacrifice East
}
public void OnOptionSelected(Mobile from, int option)
{
_east = option switch
{
1 => false,
2 => true,
_ => _east
};
if (!Deleted)
{
base.OnDoubleClick(from);
}
}
public override void OnDoubleClick(Mobile from)
{
if (_isRewardItem && !RewardSystem.CheckIsUsableBy(from, this))
{
return;
}
if (IsChildOf(from.Backpack))
{
from.CloseGump<RewardOptionGump>();
from.SendGump(new RewardOptionGump(this));
}
else
{
from.SendLocalizedMessage(1062334); // This item must be in your backpack to be used.
}
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (_isRewardItem)
{
list.Add(1080457); // 10th Year Veteran Reward
}
}
}

View file

@ -1,185 +1,320 @@
using ModernUO.Serialization;
using Server.Engines.VeteranRewards;
using Server.Gumps;
using Server.Multis;
using Server.Network;
using Server.Targeting;
namespace Server.Items
namespace Server.Items;
[SerializationGenerator(0)]
public partial class Banner : Item, IAddon, IDyable, IRewardItem
{
public class Banner : Item, IAddon, IDyable, IRewardItem
[InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _isRewardItem;
[Constructible]
public Banner(int itemID) : base(itemID)
{
private bool m_IsRewardItem;
LootType = LootType.Blessed;
Movable = false;
}
[Constructible]
public Banner(int itemID) : base(itemID)
public override bool ForceShowProperties => ObjectPropertyList.Enabled;
public bool FacingSouth => (ItemID & 0x1) == 0;
public Item Deed =>
new BannerDeed
{
LootType = LootType.Blessed;
Movable = false;
IsRewardItem = _isRewardItem
};
public bool CouldFit(IPoint3D p, Map map)
{
if (map?.CanFit(p.X, p.Y, p.Z, ItemData.Height) != true)
{
return false;
}
public Banner(Serial serial) : base(serial)
if (FacingSouth)
{
return BaseAddon.IsWall(p.X, p.Y - 1, p.Z, map); // north wall
}
public override bool ForceShowProperties => ObjectPropertyList.Enabled;
return BaseAddon.IsWall(p.X - 1, p.Y, p.Z, map); // west wall
}
public bool FacingSouth => (ItemID & 0x1) == 0;
public Item Deed
public bool Dye(Mobile from, DyeTub sender)
{
if (Deleted)
{
get
{
var deed = new BannerDeed();
deed.IsRewardItem = m_IsRewardItem;
return deed;
}
return false;
}
public bool CouldFit(IPoint3D p, Map map)
Hue = sender.DyedHue;
return true;
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (Core.ML && _isRewardItem)
{
if (map?.CanFit(p.X, p.Y, p.Z, ItemData.Height) != true)
{
return false;
}
if (FacingSouth)
{
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 bool Dye(Mobile from, DyeTub sender)
{
if (Deleted)
{
return false;
}
Hue = sender.DyedHue;
return true;
}
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
{
get => m_IsRewardItem;
set
{
m_IsRewardItem = value;
InvalidateProperties();
}
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (Core.ML && m_IsRewardItem)
{
list.Add(1076218); // 2nd Year Veteran Reward
}
}
public override void OnDoubleClick(Mobile from)
{
if (from.InRange(Location, 2))
{
var house = BaseHouse.FindHouseAt(this);
if (house?.IsOwner(from) == true)
{
from.CloseGump<RewardDemolitionGump>();
from.SendGump(new RewardDemolitionGump(this, 1018318)); // Do you wish to re-deed this banner?
}
else
{
from.SendLocalizedMessage(
1018330
); // You can only re-deed a banner if you placed it or you are the owner of the house.
}
}
else
{
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
writer.Write(m_IsRewardItem);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_IsRewardItem = reader.ReadBool();
list.Add(1076218); // 2nd Year Veteran Reward
}
}
public class BannerDeed : Item, IRewardItem
public override void OnDoubleClick(Mobile from)
{
private bool m_IsRewardItem;
[Constructible]
public BannerDeed() : base(0x14F0)
if (from.InRange(Location, 2))
{
LootType = LootType.Blessed;
Weight = 1.0;
}
var house = BaseHouse.FindHouseAt(this);
public BannerDeed(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1041007; // a banner deed
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
{
get => m_IsRewardItem;
set
if (house?.IsOwner(from) == true)
{
m_IsRewardItem = value;
InvalidateProperties();
from.CloseGump<RewardDemolitionGump>();
from.SendGump(new RewardDemolitionGump(this, 1018318)); // Do you wish to re-deed this banner?
}
else
{
// You can only re-deed a banner if you placed it or you are the owner of the house.
from.SendLocalizedMessage(1018330);
}
}
else
{
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
}
}
}
public class BannerDeed : Item, IRewardItem
{
private bool m_IsRewardItem;
[Constructible]
public BannerDeed() : base(0x14F0)
{
LootType = LootType.Blessed;
Weight = 1.0;
}
public BannerDeed(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1041007; // a banner deed
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
{
get => m_IsRewardItem;
set
{
m_IsRewardItem = value;
InvalidateProperties();
}
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (m_IsRewardItem)
{
list.Add(1076218); // 2nd Year Veteran Reward
}
}
public override void OnDoubleClick(Mobile from)
{
if (m_IsRewardItem && !RewardSystem.CheckIsUsableBy(from, this))
{
return;
}
if (IsChildOf(from.Backpack))
{
var house = BaseHouse.FindHouseAt(from);
if (house?.IsOwner(from) == true)
{
from.CloseGump<InternalGump>();
from.SendGump(new InternalGump(this));
}
else
{
from.SendLocalizedMessage(502092); // You must be in your house to do this.
}
}
else
{
from.SendLocalizedMessage(1042038); // You must have the object in your backpack to use it.
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
writer.Write(m_IsRewardItem);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_IsRewardItem = reader.ReadBool();
}
private class InternalGump : Gump
{
public const int Start = 0x15AE;
public const int End = 0x15F4;
private readonly BannerDeed m_Banner;
public InternalGump(BannerDeed banner) : base(100, 200)
{
m_Banner = banner;
Closable = true;
Disposable = true;
Draggable = true;
Resizable = false;
AddPage(0);
AddBackground(25, 0, 520, 230, 0xA28);
// TODO: Use 1152360 - <CENTER>Choose a banner:</CENTER>
AddLabel(70, 12, 0x3E3, "Choose a Banner:");
var itemID = Start;
for (var i = 1; i <= 4; i++)
{
AddPage(i);
for (var j = 0; j < 8; j++, itemID += 2)
{
AddItem(50 + 60 * j, 70, itemID);
AddButton(50 + 60 * j, 50, 0x845, 0x846, itemID);
}
if (i > 1)
{
AddButton(75, 198, 0x8AF, 0x8AF, 0, GumpButtonType.Page, i - 1);
}
if (i < 4)
{
AddButton(475, 198, 0x8B0, 0x8B0, 0, GumpButtonType.Page, i + 1);
}
}
}
public override void GetProperties(IPropertyList list)
public override void OnResponse(NetState sender, RelayInfo info)
{
base.GetProperties(list);
if (m_IsRewardItem)
{
list.Add(1076218); // 2nd Year Veteran Reward
}
}
public override void OnDoubleClick(Mobile from)
{
if (m_IsRewardItem && !RewardSystem.CheckIsUsableBy(from, this))
if (m_Banner?.Deleted != false)
{
return;
}
if (IsChildOf(from.Backpack))
var m = sender.Mobile;
if (info.ButtonID is < Start or > End || (info.ButtonID & 0x1) != 0)
{
return;
}
m.SendLocalizedMessage(1042037); // Where would you like to place this banner?
m.Target = new InternalTarget(m_Banner, info.ButtonID);
}
}
private class InternalTarget : Target
{
private readonly BannerDeed m_Banner;
private readonly int m_ItemID;
public InternalTarget(BannerDeed banner, int itemID) : base(-1, true, TargetFlags.None)
{
m_Banner = banner;
m_ItemID = itemID;
}
protected override void OnTarget(Mobile from, object targeted)
{
if (m_Banner?.Deleted != false)
{
return;
}
if (m_Banner.IsChildOf(from.Backpack))
{
var house = BaseHouse.FindHouseAt(from);
if (house?.IsOwner(from) == true)
{
from.CloseGump<InternalGump>();
from.SendGump(new InternalGump(this));
var p = targeted as IPoint3D;
var map = from.Map;
if (p == null || map == null)
{
return;
}
var p3d = new Point3D(p);
var id = TileData.ItemTable[m_ItemID & TileData.MaxItemValue];
if (map.CanFit(p3d, id.Height))
{
house = BaseHouse.FindHouseAt(p3d, map, id.Height);
if (house?.IsOwner(from) == true)
{
var north = BaseAddon.IsWall(p3d.X, p3d.Y - 1, p3d.Z, map);
var west = BaseAddon.IsWall(p3d.X - 1, p3d.Y, p3d.Z, map);
if (north && west)
{
from.CloseGump<FacingGump>();
from.SendGump(new FacingGump(m_Banner, m_ItemID, p3d, house));
}
else if (north || west)
{
var banner = new Banner(m_ItemID + (west ? 0 : 1));
house.Addons.Add(banner);
banner.IsRewardItem = m_Banner.IsRewardItem;
banner.MoveToWorld(p3d, map);
m_Banner.Delete();
}
else
{
from.SendLocalizedMessage(1042039); // The banner must be placed next to a wall.
}
}
else
{
from.SendLocalizedMessage(1042036); // That location is not in your house.
}
}
else
{
from.SendLocalizedMessage(500269); // You cannot build that there.
}
}
else
{
@ -192,34 +327,19 @@ namespace Server.Items
}
}
public override void Serialize(IGenericWriter writer)
private class FacingGump : Gump
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
writer.Write(m_IsRewardItem);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_IsRewardItem = reader.ReadBool();
}
private class InternalGump : Gump
{
public const int Start = 0x15AE;
public const int End = 0x15F4;
private readonly BannerDeed m_Banner;
private readonly BaseHouse m_House;
private readonly int m_ItemID;
private readonly Point3D m_Location;
public InternalGump(BannerDeed banner) : base(100, 200)
public FacingGump(BannerDeed banner, int itemID, Point3D location, BaseHouse house) : base(150, 50)
{
m_Banner = banner;
m_ItemID = itemID;
m_Location = location;
m_House = house;
Closable = true;
Disposable = true;
@ -228,203 +348,49 @@ namespace Server.Items
AddPage(0);
AddBackground(25, 0, 520, 230, 0xA28);
AddLabel(70, 12, 0x3E3, "Choose a Banner:");
AddBackground(0, 0, 300, 150, 0xA28);
var itemID = Start;
AddItem(90, 30, itemID + 1);
AddItem(180, 30, itemID);
for (var i = 1; i <= 4; i++)
{
AddPage(i);
for (var j = 0; j < 8; j++, itemID += 2)
{
AddItem(50 + 60 * j, 70, itemID);
AddButton(50 + 60 * j, 50, 0x845, 0x846, itemID);
}
if (i > 1)
{
AddButton(75, 198, 0x8AF, 0x8AF, 0, GumpButtonType.Page, i - 1);
}
if (i < 4)
{
AddButton(475, 198, 0x8B0, 0x8B0, 0, GumpButtonType.Page, i + 1);
}
}
AddButton(50, 35, 0x868, 0x869, (int)Buttons.East);
AddButton(145, 35, 0x868, 0x869, (int)Buttons.South);
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if (m_Banner?.Deleted != false)
if (m_Banner?.Deleted != false || m_House == null)
{
return;
}
var m = sender.Mobile;
Banner banner = null;
if (info.ButtonID is < Start or > End || (info.ButtonID & 0x1) != 0)
if (info.ButtonID == (int)Buttons.East)
{
return;
banner = new Banner(m_ItemID + 1);
}
else if (info.ButtonID == (int)Buttons.South)
{
banner = new Banner(m_ItemID);
}
m.SendLocalizedMessage(1042037); // Where would you like to place this banner?
m.Target = new InternalTarget(m_Banner, info.ButtonID);
}
}
private class InternalTarget : Target
{
private readonly BannerDeed m_Banner;
private readonly int m_ItemID;
public InternalTarget(BannerDeed banner, int itemID) : base(-1, true, TargetFlags.None)
{
m_Banner = banner;
m_ItemID = itemID;
}
protected override void OnTarget(Mobile from, object targeted)
{
if (m_Banner?.Deleted != false)
if (banner != null)
{
return;
}
m_House.Addons.Add(banner);
if (m_Banner.IsChildOf(from.Backpack))
{
var house = BaseHouse.FindHouseAt(from);
banner.IsRewardItem = m_Banner.IsRewardItem;
banner.MoveToWorld(m_Location, sender.Mobile.Map);
if (house?.IsOwner(from) == true)
{
var p = targeted as IPoint3D;
var map = from.Map;
if (p == null || map == null)
{
return;
}
var p3d = new Point3D(p);
var id = TileData.ItemTable[m_ItemID & TileData.MaxItemValue];
if (map.CanFit(p3d, id.Height))
{
house = BaseHouse.FindHouseAt(p3d, map, id.Height);
if (house?.IsOwner(from) == true)
{
var north = BaseAddon.IsWall(p3d.X, p3d.Y - 1, p3d.Z, map);
var west = BaseAddon.IsWall(p3d.X - 1, p3d.Y, p3d.Z, map);
if (north && west)
{
from.CloseGump<FacingGump>();
from.SendGump(new FacingGump(m_Banner, m_ItemID, p3d, house));
}
else if (north || west)
{
var banner = new Banner(m_ItemID + (west ? 0 : 1));
house.Addons.Add(banner);
banner.IsRewardItem = m_Banner.IsRewardItem;
banner.MoveToWorld(p3d, map);
m_Banner.Delete();
}
else
{
from.SendLocalizedMessage(1042039); // The banner must be placed next to a wall.
}
}
else
{
from.SendLocalizedMessage(1042036); // That location is not in your house.
}
}
else
{
from.SendLocalizedMessage(500269); // You cannot build that there.
}
}
else
{
from.SendLocalizedMessage(502092); // You must be in your house to do this.
}
}
else
{
from.SendLocalizedMessage(1042038); // You must have the object in your backpack to use it.
m_Banner.Delete();
}
}
private class FacingGump : Gump
private enum Buttons
{
private readonly BannerDeed m_Banner;
private readonly BaseHouse m_House;
private readonly int m_ItemID;
private readonly Point3D m_Location;
public FacingGump(BannerDeed banner, int itemID, Point3D location, BaseHouse house) : base(150, 50)
{
m_Banner = banner;
m_ItemID = itemID;
m_Location = location;
m_House = house;
Closable = true;
Disposable = true;
Draggable = true;
Resizable = false;
AddPage(0);
AddBackground(0, 0, 300, 150, 0xA28);
AddItem(90, 30, itemID + 1);
AddItem(180, 30, itemID);
AddButton(50, 35, 0x868, 0x869, (int)Buttons.East);
AddButton(145, 35, 0x868, 0x869, (int)Buttons.South);
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if (m_Banner?.Deleted != false || m_House == null)
{
return;
}
Banner banner = null;
if (info.ButtonID == (int)Buttons.East)
{
banner = new Banner(m_ItemID + 1);
}
else if (info.ButtonID == (int)Buttons.South)
{
banner = new Banner(m_ItemID);
}
if (banner != null)
{
m_House.Addons.Add(banner);
banner.IsRewardItem = m_Banner.IsRewardItem;
banner.MoveToWorld(m_Location, sender.Mobile.Map);
m_Banner.Delete();
}
}
private enum Buttons
{
Cancel,
East,
South
}
Cancel,
East,
South
}
}
}

View file

@ -1,199 +1,114 @@
using ModernUO.Serialization;
using Server.Engines.VeteranRewards;
namespace Server.Items
namespace Server.Items;
[SerializationGenerator(0)]
public partial class BloodyPentagramComponent : AddonComponent
{
public class BloodyPentagramComponent : AddonComponent
public BloodyPentagramComponent(int itemID) : base(itemID)
{
public BloodyPentagramComponent(int itemID) : base(itemID)
{
}
public BloodyPentagramComponent(Serial serial) : base(serial)
{
}
public override bool DisplayWeight => false;
public override int LabelNumber => 1080279; // Bloody Pentagram
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
}
}
public class BloodyPentagramAddon : BaseAddon, IRewardItem
public override bool DisplayWeight => false;
public override int LabelNumber => 1080279; // Bloody Pentagram
}
[SerializationGenerator(0)]
public partial class BloodyPentagramAddon : BaseAddon, IRewardItem
{
[InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _isRewardItem;
[Constructible]
public BloodyPentagramAddon()
{
private bool m_IsRewardItem;
AddComponent(new BloodyPentagramComponent(0x1CF9), 0, 1, 0);
AddComponent(new BloodyPentagramComponent(0x1CF8), 0, 2, 0);
AddComponent(new BloodyPentagramComponent(0x1CF7), 0, 3, 0);
AddComponent(new BloodyPentagramComponent(0x1CF6), 0, 4, 0);
AddComponent(new BloodyPentagramComponent(0x1CF5), 0, 5, 0);
[Constructible]
public BloodyPentagramAddon()
{
AddComponent(new BloodyPentagramComponent(0x1CF9), 0, 1, 0);
AddComponent(new BloodyPentagramComponent(0x1CF8), 0, 2, 0);
AddComponent(new BloodyPentagramComponent(0x1CF7), 0, 3, 0);
AddComponent(new BloodyPentagramComponent(0x1CF6), 0, 4, 0);
AddComponent(new BloodyPentagramComponent(0x1CF5), 0, 5, 0);
AddComponent(new BloodyPentagramComponent(0x1CFB), 1, 0, 0);
AddComponent(new BloodyPentagramComponent(0x1CFA), 1, 1, 0);
AddComponent(new BloodyPentagramComponent(0x1D09), 1, 2, 0);
AddComponent(new BloodyPentagramComponent(0x1D08), 1, 3, 0);
AddComponent(new BloodyPentagramComponent(0x1D07), 1, 4, 0);
AddComponent(new BloodyPentagramComponent(0x1CF4), 1, 5, 0);
AddComponent(new BloodyPentagramComponent(0x1CFB), 1, 0, 0);
AddComponent(new BloodyPentagramComponent(0x1CFA), 1, 1, 0);
AddComponent(new BloodyPentagramComponent(0x1D09), 1, 2, 0);
AddComponent(new BloodyPentagramComponent(0x1D08), 1, 3, 0);
AddComponent(new BloodyPentagramComponent(0x1D07), 1, 4, 0);
AddComponent(new BloodyPentagramComponent(0x1CF4), 1, 5, 0);
AddComponent(new BloodyPentagramComponent(0x1CFC), 2, 0, 0);
AddComponent(new BloodyPentagramComponent(0x1D0A), 2, 1, 0);
AddComponent(new BloodyPentagramComponent(0x1D11), 2, 2, 0);
AddComponent(new BloodyPentagramComponent(0x1D10), 2, 3, 0);
AddComponent(new BloodyPentagramComponent(0x1D06), 2, 4, 0);
AddComponent(new BloodyPentagramComponent(0x1CF3), 2, 5, 0);
AddComponent(new BloodyPentagramComponent(0x1CFC), 2, 0, 0);
AddComponent(new BloodyPentagramComponent(0x1D0A), 2, 1, 0);
AddComponent(new BloodyPentagramComponent(0x1D11), 2, 2, 0);
AddComponent(new BloodyPentagramComponent(0x1D10), 2, 3, 0);
AddComponent(new BloodyPentagramComponent(0x1D06), 2, 4, 0);
AddComponent(new BloodyPentagramComponent(0x1CF3), 2, 5, 0);
AddComponent(new BloodyPentagramComponent(0x1CFD), 3, 0, 0);
AddComponent(new BloodyPentagramComponent(0x1D0B), 3, 1, 0);
AddComponent(new BloodyPentagramComponent(0x1D12), 3, 2, 0);
AddComponent(new BloodyPentagramComponent(0x1D0F), 3, 3, 0);
AddComponent(new BloodyPentagramComponent(0x1D05), 3, 4, 0);
AddComponent(new BloodyPentagramComponent(0x1CF2), 3, 5, 0);
AddComponent(new BloodyPentagramComponent(0x1CFD), 3, 0, 0);
AddComponent(new BloodyPentagramComponent(0x1D0B), 3, 1, 0);
AddComponent(new BloodyPentagramComponent(0x1D12), 3, 2, 0);
AddComponent(new BloodyPentagramComponent(0x1D0F), 3, 3, 0);
AddComponent(new BloodyPentagramComponent(0x1D05), 3, 4, 0);
AddComponent(new BloodyPentagramComponent(0x1CF2), 3, 5, 0);
AddComponent(new BloodyPentagramComponent(0x1CFE), 4, 0, 0);
AddComponent(new BloodyPentagramComponent(0x1D0C), 4, 1, 0);
AddComponent(new BloodyPentagramComponent(0x1D0D), 4, 2, 0);
AddComponent(new BloodyPentagramComponent(0x1D0E), 4, 3, 0);
AddComponent(new BloodyPentagramComponent(0x1D04), 4, 4, 0);
AddComponent(new BloodyPentagramComponent(0x1CF1), 4, 5, 0);
AddComponent(new BloodyPentagramComponent(0x1CFE), 4, 0, 0);
AddComponent(new BloodyPentagramComponent(0x1D0C), 4, 1, 0);
AddComponent(new BloodyPentagramComponent(0x1D0D), 4, 2, 0);
AddComponent(new BloodyPentagramComponent(0x1D0E), 4, 3, 0);
AddComponent(new BloodyPentagramComponent(0x1D04), 4, 4, 0);
AddComponent(new BloodyPentagramComponent(0x1CF1), 4, 5, 0);
AddComponent(new BloodyPentagramComponent(0x1CFF), 5, 0, 0);
AddComponent(new BloodyPentagramComponent(0x1D00), 5, 1, 0);
AddComponent(new BloodyPentagramComponent(0x1D01), 5, 2, 0);
AddComponent(new BloodyPentagramComponent(0x1D02), 5, 3, 0);
AddComponent(new BloodyPentagramComponent(0x1D03), 5, 4, 0);
}
public BloodyPentagramAddon(Serial serial) : base(serial)
{
}
public override BaseAddonDeed Deed
{
get
{
var deed = new BloodyPentagramDeed();
deed.IsRewardItem = m_IsRewardItem;
return deed;
}
}
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
{
get => m_IsRewardItem;
set
{
m_IsRewardItem = value;
InvalidateProperties();
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
writer.Write(m_IsRewardItem);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_IsRewardItem = reader.ReadBool();
}
AddComponent(new BloodyPentagramComponent(0x1CFF), 5, 0, 0);
AddComponent(new BloodyPentagramComponent(0x1D00), 5, 1, 0);
AddComponent(new BloodyPentagramComponent(0x1D01), 5, 2, 0);
AddComponent(new BloodyPentagramComponent(0x1D02), 5, 3, 0);
AddComponent(new BloodyPentagramComponent(0x1D03), 5, 4, 0);
}
public class BloodyPentagramDeed : BaseAddonDeed, IRewardItem
public override BaseAddonDeed Deed =>
new BloodyPentagramDeed
{
IsRewardItem = _isRewardItem
};
}
[SerializationGenerator(0)]
public partial class BloodyPentagramDeed : BaseAddonDeed, IRewardItem
{
[InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _isRewardItem;
[Constructible]
public BloodyPentagramDeed() => LootType = LootType.Blessed;
public override int LabelNumber => 1080384; // Bloody Pentagram
public override BaseAddon Addon =>
new BloodyPentagramAddon
{
IsRewardItem = _isRewardItem
};
public override void OnDoubleClick(Mobile from)
{
private bool m_IsRewardItem;
[Constructible]
public BloodyPentagramDeed() => LootType = LootType.Blessed;
public BloodyPentagramDeed(Serial serial) : base(serial)
if (_isRewardItem && !RewardSystem.CheckIsUsableBy(from, this))
{
return;
}
public override int LabelNumber => 1080384; // Bloody Pentagram
base.OnDoubleClick(from);
}
public override BaseAddon Addon
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (_isRewardItem)
{
get
{
var addon = new BloodyPentagramAddon();
addon.IsRewardItem = m_IsRewardItem;
return addon;
}
}
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
{
get => m_IsRewardItem;
set
{
m_IsRewardItem = value;
InvalidateProperties();
}
}
public override void OnDoubleClick(Mobile from)
{
if (m_IsRewardItem && !RewardSystem.CheckIsUsableBy(from, this))
{
return;
}
base.OnDoubleClick(from);
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (m_IsRewardItem)
{
list.Add(1076221); // 5th Year Veteran Reward
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
writer.Write(m_IsRewardItem);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_IsRewardItem = reader.ReadBool();
list.Add(1076221); // 5th Year Veteran Reward
}
}
}

View file

@ -1,268 +1,205 @@
using ModernUO.Serialization;
using Server.Engines.VeteranRewards;
using Server.Gumps;
using Server.Multis;
using Server.Network;
namespace Server.Items
namespace Server.Items;
[SerializationGenerator(0)]
public partial class RewardBrazier : Item, IRewardItem
{
public class RewardBrazier : Item, IRewardItem
private static readonly int[] _art = { 0x19AA, 0x19BB };
[InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _isRewardItem;
[SerializableField(1, getter: "private", setter: "private")]
private Item _fire;
[Constructible]
public RewardBrazier() : this(_art.RandomElement())
{
private static readonly int[] m_Art =
}
[Constructible]
public RewardBrazier(int itemID) : base(itemID)
{
LootType = LootType.Blessed;
Weight = 10.0;
}
public override bool ForceShowProperties => ObjectPropertyList.Enabled;
public override void OnDelete()
{
TurnOff();
base.OnDelete();
}
public void TurnOff()
{
if (_fire != null)
{
0x19AA, 0x19BB
};
private Item m_Fire;
private bool m_IsRewardItem;
[Constructible]
public RewardBrazier() : this(m_Art.RandomElement())
{
}
[Constructible]
public RewardBrazier(int itemID) : base(itemID)
{
LootType = LootType.Blessed;
Weight = 10.0;
}
public RewardBrazier(Serial serial) : base(serial)
{
}
public override bool ForceShowProperties => ObjectPropertyList.Enabled;
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
{
get => m_IsRewardItem;
set
{
m_IsRewardItem = value;
InvalidateProperties();
}
}
public override void OnDelete()
{
TurnOff();
base.OnDelete();
}
public void TurnOff()
{
if (m_Fire != null)
{
m_Fire.Delete();
m_Fire = null;
}
}
public void TurnOn()
{
m_Fire ??= new Item();
m_Fire.ItemID = 0x19AB;
m_Fire.Movable = false;
m_Fire.MoveToWorld(new Point3D(X, Y, Z + ItemData.Height + 2), Map);
}
public override void OnDoubleClick(Mobile from)
{
if (!from.InRange(GetWorldLocation(), 2))
{
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
}
else if (IsLockedDown)
{
var house = BaseHouse.FindHouseAt(from);
if (house?.IsCoOwner(from) == true)
{
if (m_Fire != null)
{
TurnOff();
}
else
{
TurnOn();
}
}
else
{
from.SendLocalizedMessage(502436); // That is not accessible.
}
}
else
{
from.SendLocalizedMessage(502692); // This must be in a house and be locked down to work.
}
}
public override void OnLocationChange(Point3D old)
{
m_Fire?.MoveToWorld(new Point3D(X, Y, Z + ItemData.Height), Map);
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (m_IsRewardItem)
{
list.Add(1076222); // 6th Year Veteran Reward
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
writer.Write(m_IsRewardItem);
writer.Write(m_Fire);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_IsRewardItem = reader.ReadBool();
m_Fire = reader.ReadEntity<Item>();
_fire.Delete();
Fire = null;
}
}
public class RewardBrazierDeed : Item, IRewardItem
public void TurnOn()
{
private bool m_IsRewardItem;
Fire ??= new Item();
[Constructible]
public RewardBrazierDeed() : base(0x14F0)
_fire.ItemID = 0x19AB;
_fire.Movable = false;
_fire.MoveToWorld(new Point3D(X, Y, Z + ItemData.Height + 2), Map);
}
public override void OnDoubleClick(Mobile from)
{
if (!from.InRange(GetWorldLocation(), 2))
{
LootType = LootType.Blessed;
Weight = 1.0;
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
return;
}
public RewardBrazierDeed(Serial serial) : base(serial)
if (!IsLockedDown)
{
from.SendLocalizedMessage(502692); // This must be in a house and be locked down to work.
return;
}
public override int LabelNumber => 1080527; // Brazier Deed
var house = BaseHouse.FindHouseAt(from);
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
if (house?.IsCoOwner(from) != true)
{
get => m_IsRewardItem;
set
{
m_IsRewardItem = value;
InvalidateProperties();
}
from.SendLocalizedMessage(502436); // That is not accessible.
return;
}
public override void OnDoubleClick(Mobile from)
if (_fire != null)
{
if (m_IsRewardItem && !RewardSystem.CheckIsUsableBy(from, this))
TurnOff();
}
else
{
TurnOn();
}
}
public override void OnLocationChange(Point3D old)
{
_fire?.MoveToWorld(new Point3D(X, Y, Z + ItemData.Height), Map);
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (_isRewardItem)
{
list.Add(1076222); // 6th Year Veteran Reward
}
}
}
[SerializationGenerator(0)]
public partial class RewardBrazierDeed : Item, IRewardItem
{
[InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _isRewardItem;
[Constructible]
public RewardBrazierDeed() : base(0x14F0)
{
LootType = LootType.Blessed;
Weight = 1.0;
}
public override int LabelNumber => 1080527; // Brazier Deed
public override void OnDoubleClick(Mobile from)
{
if (_isRewardItem && !RewardSystem.CheckIsUsableBy(from, this))
{
return;
}
if (!IsChildOf(from.Backpack))
{
from.SendLocalizedMessage(1042038); // You must have the object in your backpack to use it.
return;
}
from.CloseGump<InternalGump>();
from.SendGump(new InternalGump(this));
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (_isRewardItem)
{
list.Add(1076222); // 6th Year Veteran Reward
}
}
private class InternalGump : Gump
{
private readonly RewardBrazierDeed _brazier;
public InternalGump(RewardBrazierDeed brazier) : base(100, 200)
{
_brazier = brazier;
Closable = true;
Disposable = true;
Draggable = true;
Resizable = false;
AddPage(0);
AddBackground(0, 0, 200, 200, 2600);
AddPage(1);
AddLabel(45, 15, 0, "Choose a Brazier:");
AddItem(40, 75, 0x19AA);
AddButton(55, 50, 0x845, 0x846, 0x19AA);
AddItem(100, 75, 0x19BB);
AddButton(115, 50, 0x845, 0x846, 0x19BB);
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if (_brazier?.Deleted != false)
{
return;
}
if (IsChildOf(from.Backpack))
var m = sender.Mobile;
if (info.ButtonID != 0x19AA && info.ButtonID != 0x19BB)
{
from.CloseGump<InternalGump>();
from.SendGump(new InternalGump(this));
return;
}
var brazier = new RewardBrazier(info.ButtonID) { IsRewardItem = _brazier.IsRewardItem };
if (!m.PlaceInBackpack(brazier))
{
brazier.Delete();
m.SendLocalizedMessage(1078837); // Your backpack is full! Please make room and try again.
}
else
{
from.SendLocalizedMessage(1042038); // You must have the object in your backpack to use it.
}
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (m_IsRewardItem)
{
list.Add(1076222); // 6th Year Veteran Reward
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
writer.Write(m_IsRewardItem);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_IsRewardItem = reader.ReadBool();
}
private class InternalGump : Gump
{
private readonly RewardBrazierDeed m_Brazier;
public InternalGump(RewardBrazierDeed brazier) : base(100, 200)
{
m_Brazier = brazier;
Closable = true;
Disposable = true;
Draggable = true;
Resizable = false;
AddPage(0);
AddBackground(0, 0, 200, 200, 2600);
AddPage(1);
AddLabel(45, 15, 0, "Choose a Brazier:");
AddItem(40, 75, 0x19AA);
AddButton(55, 50, 0x845, 0x846, 0x19AA);
AddItem(100, 75, 0x19BB);
AddButton(115, 50, 0x845, 0x846, 0x19BB);
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if (m_Brazier?.Deleted != false)
{
return;
}
var m = sender.Mobile;
if (info.ButtonID != 0x19AA && info.ButtonID != 0x19BB)
{
return;
}
var brazier = new RewardBrazier(info.ButtonID) { IsRewardItem = m_Brazier.IsRewardItem };
if (!m.PlaceInBackpack(brazier))
{
brazier.Delete();
m.SendLocalizedMessage(1078837); // Your backpack is full! Please make room and try again.
}
else
{
m_Brazier.Delete();
}
_brazier.Delete();
}
}
}

View file

@ -1,515 +1,431 @@
using ModernUO.Serialization;
using Server.Engines.Quests.Haven;
using Server.Engines.VeteranRewards;
using Server.Gumps;
using Server.Network;
using Server.Targeting;
namespace Server.Items
namespace Server.Items;
[SerializationGenerator(0, false)]
public partial class CannonAddonComponent : AddonComponent
{
public class CannonAddonComponent : AddonComponent
public CannonAddonComponent(int itemID) : base(itemID) => LootType = LootType.Blessed;
public override int LabelNumber => 1076157; // Decorative Cannon
public override void GetProperties(IPropertyList list)
{
public CannonAddonComponent(int itemID) : base(itemID) => LootType = LootType.Blessed;
base.GetProperties(list);
public CannonAddonComponent(Serial serial) : base(serial)
if (Addon is CannonAddon addon)
{
}
public override int LabelNumber => 1076157; // Decorative Cannon
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (Addon is CannonAddon addon)
if (addon.IsRewardItem)
{
if (addon.IsRewardItem)
{
list.Add(1076223); // 7th Year Veteran Reward
}
list.Add(1076207, addon.Charges); // Remaining Charges: ~1_val~
list.Add(1076223); // 7th Year Veteran Reward
}
list.Add(1076207, addon.Charges); // Remaining Charges: ~1_val~
}
}
}
public override void Serialize(IGenericWriter writer)
[SerializationGenerator(1)]
public partial class CannonAddon : BaseAddon
{
private static readonly int[] m_Effects = { 0x36B0, 0x3728, 0x3709, 0x36FE };
[SerializableField(0, setter: "private")]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private CannonDirection _cannonDirection;
[Constructible]
public CannonAddon(CannonDirection direction)
{
CannonDirection = direction;
switch (direction)
{
base.Serialize(writer);
case CannonDirection.North:
{
AddComponent(new CannonAddonComponent(0xE8D), 0, 0, 0);
AddComponent(new CannonAddonComponent(0xE8C), 0, 1, 0);
AddComponent(new CannonAddonComponent(0xE8B), 0, 2, 0);
writer.Write(0); // version
}
break;
}
case CannonDirection.East:
{
AddComponent(new CannonAddonComponent(0xE96), 0, 0, 0);
AddComponent(new CannonAddonComponent(0xE95), -1, 0, 0);
AddComponent(new CannonAddonComponent(0xE94), -2, 0, 0);
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
break;
}
case CannonDirection.South:
{
AddComponent(new CannonAddonComponent(0xE91), 0, 0, 0);
AddComponent(new CannonAddonComponent(0xE92), 0, -1, 0);
AddComponent(new CannonAddonComponent(0xE93), 0, -2, 0);
var version = reader.ReadInt();
break;
}
default:
{
AddComponent(new CannonAddonComponent(0xE8E), 0, 0, 0);
AddComponent(new CannonAddonComponent(0xE8F), 1, 0, 0);
AddComponent(new CannonAddonComponent(0xE90), 2, 0, 0);
break;
}
}
}
public class CannonAddon : BaseAddon
{
private static readonly int[] m_Effects =
public override BaseAddonDeed Deed =>
new CannonDeed
{
0x36B0, 0x3728, 0x3709, 0x36FE
Charges = _charges,
IsRewardItem = _isRewardItem
};
private int m_Charges;
private bool m_IsRewardItem;
[Constructible]
public CannonAddon(CannonDirection direction)
[SerializableProperty(1)]
[CommandProperty(AccessLevel.GameMaster)]
public int Charges
{
get => _charges;
set
{
CannonDirection = direction;
_charges = value;
switch (direction)
foreach (var c in Components)
{
c.InvalidateProperties();
}
this.MarkDirty();
}
}
[SerializableProperty(2)]
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
{
get => _isRewardItem;
set
{
_isRewardItem = value;
foreach (var c in Components)
{
c.InvalidateProperties();
}
this.MarkDirty();
}
}
public override void OnComponentUsed(AddonComponent c, Mobile from)
{
if (!from.InRange(Location, 2))
{
from.SendLocalizedMessage(1076766); // That is too far away.
return;
}
if (_charges > 0)
{
from.Target = new InternalTarget(this);
}
else if (from.Backpack != null)
{
var keg = from.Backpack.FindItemByType<PotionKeg>();
if (Validate(keg) > 0)
{
from.SendGump(new InternalGump(this, keg));
}
else
{
// You do not have a full keg of explosion potions needed to recharge the cannon.
from.SendLocalizedMessage(1076198);
}
}
}
public int Validate(PotionKeg keg)
{
if (keg?.Deleted != false || keg.Held != 100)
{
return 0;
}
return keg.Type switch
{
PotionEffect.ExplosionLesser => 5,
PotionEffect.Explosion => 10,
PotionEffect.ExplosionGreater => 15,
_ => 0
};
}
public void Fill(Mobile from, PotionKeg keg)
{
Charges = Validate(keg);
if (_charges > 0)
{
keg.Delete();
from.SendLocalizedMessage(1076199); // Your cannon is recharged.
}
else
{
// You do not have a full keg of explosion potions needed to recharge the cannon.
from.SendLocalizedMessage(1076198);
}
}
public void DoFireEffect(Point3D target)
{
var map = Map;
if (map == null)
{
return;
}
Effects.PlaySound(target, map, Utility.RandomList(0x11B, 0x11C, 0x11D));
Effects.SendLocationEffect(target, map, m_Effects.RandomElement(), 16, 1);
for (var count = Utility.Random(3); count > 0; count--)
{
Point3D location = new Point3D(
target.X + Utility.RandomMinMax(-1, 1),
target.Y + Utility.RandomMinMax(-1, 1),
target.Z
);
Effects.SendLocationEffect(location, map, m_Effects.RandomElement(), 16, 1);
}
Charges -= 1;
}
private void Deserialize(IGenericReader reader, int version)
{
_cannonDirection = (CannonDirection)reader.ReadInt();
_charges = reader.ReadInt();
_isRewardItem = reader.ReadBool();
}
private class InternalTarget : Target
{
private readonly CannonAddon _cannon;
public InternalTarget(CannonAddon cannon) : base(12, true, TargetFlags.None) => _cannon = cannon;
protected override void OnTarget(Mobile from, object targeted)
{
if (_cannon?.Deleted != false)
{
return;
}
if (targeted is not IPoint3D p)
{
return;
}
if (!from.InLOS(new Point3D(p)))
{
from.SendLocalizedMessage(1049630); // You cannot see that target!
return;
}
if (Utility.InRange(new Point3D(p), _cannon.Location, 2))
{
from.SendLocalizedMessage(1076215); // Cannon must be aimed farther away.
return;
}
var allow = false;
var x = p.X - _cannon.X;
var y = p.Y - _cannon.Y;
switch (_cannon.CannonDirection)
{
case CannonDirection.North:
{
AddComponent(new CannonAddonComponent(0xE8D), 0, 0, 0);
AddComponent(new CannonAddonComponent(0xE8C), 0, 1, 0);
AddComponent(new CannonAddonComponent(0xE8B), 0, 2, 0);
if (y < 0 && x.Abs() <= -y / 3)
{
allow = true;
}
break;
}
case CannonDirection.East:
{
AddComponent(new CannonAddonComponent(0xE96), 0, 0, 0);
AddComponent(new CannonAddonComponent(0xE95), -1, 0, 0);
AddComponent(new CannonAddonComponent(0xE94), -2, 0, 0);
if (x > 0 && y.Abs() <= x / 3)
{
allow = true;
}
break;
}
case CannonDirection.South:
{
AddComponent(new CannonAddonComponent(0xE91), 0, 0, 0);
AddComponent(new CannonAddonComponent(0xE92), 0, -1, 0);
AddComponent(new CannonAddonComponent(0xE93), 0, -2, 0);
if (y > 0 && x.Abs() <= y / 3)
{
allow = true;
}
break;
}
default:
case CannonDirection.West:
{
AddComponent(new CannonAddonComponent(0xE8E), 0, 0, 0);
AddComponent(new CannonAddonComponent(0xE8F), 1, 0, 0);
AddComponent(new CannonAddonComponent(0xE90), 2, 0, 0);
if (x < 0 && y.Abs() <= -x / 3)
{
allow = true;
}
break;
}
}
}
public CannonAddon(Serial serial) : base(serial)
{
}
var loc = new Point3D(p);
public override BaseAddonDeed Deed
{
get
if (allow && Utility.InRange(loc, _cannon.Location, 14))
{
var deed = new CannonDeed();
deed.Charges = m_Charges;
deed.IsRewardItem = m_IsRewardItem;
return deed;
}
}
[CommandProperty(AccessLevel.GameMaster)]
public CannonDirection CannonDirection { get; private set; }
[CommandProperty(AccessLevel.GameMaster)]
public int Charges
{
get => m_Charges;
set
{
m_Charges = value;
foreach (var c in Components)
{
c.InvalidateProperties();
}
}
}
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
{
get => m_IsRewardItem;
set
{
m_IsRewardItem = value;
foreach (var c in Components)
{
c.InvalidateProperties();
}
}
}
public override void OnComponentUsed(AddonComponent c, Mobile from)
{
if (from.InRange(Location, 2))
{
if (m_Charges > 0)
{
from.Target = new InternalTarget(this);
}
else
{
if (from.Backpack != null)
{
var keg = from.Backpack.FindItemByType<PotionKeg>();
if (Validate(keg) > 0)
{
from.SendGump(new InternalGump(this, keg));
}
else
{
from.SendLocalizedMessage(
1076198
); // You do not have a full keg of explosion potions needed to recharge the cannon.
}
}
}
_cannon.DoFireEffect(loc);
}
else
{
from.SendLocalizedMessage(1076766); // That is too far away.
}
}
public int Validate(PotionKeg keg)
{
if (keg?.Deleted != false || keg.Held != 100)
{
return 0;
}
return keg.Type switch
{
PotionEffect.ExplosionLesser => 5,
PotionEffect.Explosion => 10,
PotionEffect.ExplosionGreater => 15,
_ => 0
};
}
public void Fill(Mobile from, PotionKeg keg)
{
Charges = Validate(keg);
if (Charges > 0)
{
keg.Delete();
from.SendLocalizedMessage(1076199); // Your cannon is recharged.
}
else
{
from.SendLocalizedMessage(
1076198
); // You do not have a full keg of explosion potions needed to recharge the cannon.
}
}
public void DoFireEffect(Point3D target)
{
var map = Map;
if (map == null)
{
return;
}
Effects.PlaySound(target, map, Utility.RandomList(0x11B, 0x11C, 0x11D));
Effects.SendLocationEffect(target, map, m_Effects.RandomElement(), 16, 1);
for (var count = Utility.Random(3); count > 0; count--)
{
Point3D location = new Point3D(
target.X + Utility.RandomMinMax(-1, 1),
target.Y + Utility.RandomMinMax(-1, 1),
target.Z
);
Effects.SendLocationEffect(location, map, m_Effects.RandomElement(), 16, 1);
}
Charges -= 1;
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
writer.Write((int)CannonDirection);
writer.Write(m_Charges);
writer.Write(m_IsRewardItem);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
CannonDirection = (CannonDirection)reader.ReadInt();
m_Charges = reader.ReadInt();
m_IsRewardItem = reader.ReadBool();
}
private class InternalTarget : Target
{
private readonly CannonAddon m_Cannon;
public InternalTarget(CannonAddon cannon) : base(12, true, TargetFlags.None) => m_Cannon = cannon;
protected override void OnTarget(Mobile from, object targeted)
{
if (m_Cannon?.Deleted != false)
{
return;
}
if (targeted is not IPoint3D p)
{
return;
}
if (from.InLOS(new Point3D(p)))
{
if (!Utility.InRange(new Point3D(p), m_Cannon.Location, 2))
{
var allow = false;
var x = p.X - m_Cannon.X;
var y = p.Y - m_Cannon.Y;
switch (m_Cannon.CannonDirection)
{
case CannonDirection.North:
if (y < 0 && x.Abs() <= -y / 3)
{
allow = true;
}
break;
case CannonDirection.East:
if (x > 0 && y.Abs() <= x / 3)
{
allow = true;
}
break;
case CannonDirection.South:
if (y > 0 && x.Abs() <= y / 3)
{
allow = true;
}
break;
case CannonDirection.West:
if (x < 0 && y.Abs() <= -x / 3)
{
allow = true;
}
break;
}
var loc = new Point3D(p);
if (allow && Utility.InRange(loc, m_Cannon.Location, 14))
{
m_Cannon.DoFireEffect(loc);
}
else
{
from.SendLocalizedMessage(1076203); // Target out of range.
}
}
else
{
from.SendLocalizedMessage(1076215); // Cannon must be aimed farther away.
}
}
else
{
from.SendLocalizedMessage(1049630); // You cannot see that target!
}
}
protected override void OnTargetOutOfRange(Mobile from, object targeted)
{
from.SendLocalizedMessage(1076203); // Target out of range.
}
}
private class InternalGump : Gump
protected override void OnTargetOutOfRange(Mobile from, object targeted)
{
private readonly CannonAddon m_Cannon;
private readonly PotionKeg m_Keg;
public InternalGump(CannonAddon cannon, PotionKeg keg) : base(50, 50)
{
m_Cannon = cannon;
m_Keg = keg;
Closable = true;
Disposable = true;
Draggable = true;
Resizable = false;
AddPage(0);
AddBackground(0, 0, 291, 133, 0x13BE);
AddImageTiled(5, 5, 280, 100, 0xA40);
AddHtmlLocalized(
9,
9,
272,
100,
1076196,
cannon.Validate(keg).ToString(),
0x7FFF
); // You will need a full keg of explosion potions to recharge the cannon. Your keg will provide ~1_CHARGES~ charges.
AddButton(5, 107, 0xFB1, 0xFB2, (int)Buttons.Cancel);
AddHtmlLocalized(40, 109, 100, 20, 1060051, 0x7FFF); // CANCEL
AddButton(160, 107, 0xFB7, 0xFB8, (int)Buttons.Recharge);
AddHtmlLocalized(195, 109, 120, 20, 1076197, 0x7FFF); // Recharge
}
public override void OnResponse(NetState state, RelayInfo info)
{
if (m_Cannon?.Deleted == false && info.ButtonID == (int)Buttons.Recharge)
{
m_Cannon.Fill(state.Mobile, m_Keg);
}
}
private enum Buttons
{
Cancel,
Recharge
}
from.SendLocalizedMessage(1076203); // Target out of range.
}
}
public class CannonDeed : BaseAddonDeed, IRewardItem, IRewardOption
private class InternalGump : Gump
{
private int m_Charges;
private readonly CannonAddon _cannon;
private readonly PotionKeg _keg;
private CannonDirection m_Direction;
private bool m_IsRewardItem;
[Constructible]
public CannonDeed() => LootType = LootType.Blessed;
public CannonDeed(Serial serial) : base(serial)
public InternalGump(CannonAddon cannon, PotionKeg keg) : base(50, 50)
{
_cannon = cannon;
_keg = keg;
Closable = true;
Disposable = true;
Draggable = true;
Resizable = false;
AddPage(0);
AddBackground(0, 0, 291, 133, 0x13BE);
AddImageTiled(5, 5, 280, 100, 0xA40);
// You will need a full keg of explosion potions to recharge the cannon. Your keg will provide ~1_CHARGES~ charges.
AddHtmlLocalized(9, 9, 272, 100, 1076196, cannon.Validate(keg).ToString(), 0x7FFF);
AddButton(5, 107, 0xFB1, 0xFB2, (int)Buttons.Cancel);
AddHtmlLocalized(40, 109, 100, 20, 1060051, 0x7FFF); // CANCEL
AddButton(160, 107, 0xFB7, 0xFB8, (int)Buttons.Recharge);
AddHtmlLocalized(195, 109, 120, 20, 1076197, 0x7FFF); // Recharge
}
public override int LabelNumber => 1076195; // A deed for a cannon
public override BaseAddon Addon => new CannonAddon(m_Direction)
public override void OnResponse(NetState state, RelayInfo info)
{
Charges = m_Charges,
IsRewardItem = m_IsRewardItem
};
[CommandProperty(AccessLevel.GameMaster)]
public int Charges
{
get => m_Charges;
set
if (_cannon?.Deleted == false && info.ButtonID == (int)Buttons.Recharge)
{
m_Charges = value;
InvalidateProperties();
_cannon.Fill(state.Mobile, _keg);
}
}
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
private enum Buttons
{
get => m_IsRewardItem;
set
{
m_IsRewardItem = value;
InvalidateProperties();
}
}
public void GetOptions(RewardOptionList list)
{
list.Add((int)CannonDirection.South, 1075386); // South
list.Add((int)CannonDirection.East, 1075387); // East
list.Add((int)CannonDirection.North, 1075389); // North
list.Add((int)CannonDirection.West, 1075390); // West
}
public void OnOptionSelected(Mobile from, int option)
{
m_Direction = (CannonDirection)option;
if (!Deleted)
{
base.OnDoubleClick(from);
}
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (m_IsRewardItem)
{
list.Add(1076223); // 7th Year Veteran Reward
}
list.Add(1076207, m_Charges); // Remaining Charges: ~1_val~
}
public override void OnDoubleClick(Mobile from)
{
if (m_IsRewardItem && !RewardSystem.CheckIsUsableBy(from, this))
{
return;
}
if (IsChildOf(from.Backpack))
{
from.CloseGump<RewardOptionGump>();
from.SendGump(new RewardOptionGump(this));
}
else
{
from.SendLocalizedMessage(1042038); // You must have the object in your backpack to use it.
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
writer.Write(m_Charges);
writer.Write(m_IsRewardItem);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_Charges = reader.ReadInt();
m_IsRewardItem = reader.ReadBool();
Cancel,
Recharge
}
}
}
[SerializationGenerator(0)]
public partial class CannonDeed : BaseAddonDeed, IRewardItem, IRewardOption
{
[InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private int _charges;
[InvalidateProperties]
[SerializableField(1)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _isRewardItem;
private CannonDirection _direction;
[Constructible]
public CannonDeed() => LootType = LootType.Blessed;
public override int LabelNumber => 1076195; // A deed for a cannon
public override BaseAddon Addon => new CannonAddon(_direction)
{
Charges = _charges,
IsRewardItem = _isRewardItem
};
public void GetOptions(RewardOptionList list)
{
list.Add((int)CannonDirection.South, 1075386); // South
list.Add((int)CannonDirection.East, 1075387); // East
list.Add((int)CannonDirection.North, 1075389); // North
list.Add((int)CannonDirection.West, 1075390); // West
}
public void OnOptionSelected(Mobile from, int option)
{
_direction = (CannonDirection)option;
if (!Deleted)
{
base.OnDoubleClick(from);
}
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (_isRewardItem)
{
list.Add(1076223); // 7th Year Veteran Reward
}
list.Add(1076207, _charges); // Remaining Charges: ~1_val~
}
public override void OnDoubleClick(Mobile from)
{
if (_isRewardItem && !RewardSystem.CheckIsUsableBy(from, this))
{
return;
}
if (IsChildOf(from.Backpack))
{
from.CloseGump<RewardOptionGump>();
from.SendGump(new RewardOptionGump(this));
}
else
{
from.SendLocalizedMessage(1042038); // You must have the object in your backpack to use it.
}
}
}

View file

@ -1,75 +1,46 @@
using ModernUO.Serialization;
using Server.Engines.VeteranRewards;
namespace Server.Items
namespace Server.Items;
[Furniture]
[SerializationGenerator(0)]
public partial class CommodityDeedBox : BaseContainer, IRewardItem
{
[Furniture]
public class CommodityDeedBox : BaseContainer, IRewardItem
[InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _isRewardItem;
[Constructible]
public CommodityDeedBox() : base(0x9AA)
{
private bool m_IsRewardItem;
Hue = 0x47;
Weight = 4.0;
}
[Constructible]
public CommodityDeedBox() : base(0x9AA)
public override int LabelNumber => 1080523; // Commodity Deed Box
public override int DefaultGumpID => 0x43;
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (_isRewardItem)
{
Hue = 0x47;
Weight = 4.0;
}
public CommodityDeedBox(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1080523; // Commodity Deed Box
public override int DefaultGumpID => 0x43;
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
{
get => m_IsRewardItem;
set
{
m_IsRewardItem = value;
InvalidateProperties();
}
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (m_IsRewardItem)
{
list.Add(1076217); // 1st Year Veteran Reward
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
writer.Write(m_IsRewardItem);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_IsRewardItem = reader.ReadBool();
}
public static CommodityDeedBox Find(Item deed)
{
var parent = deed;
while (parent != null && parent is not CommodityDeedBox)
{
parent = parent.Parent as Item;
}
return parent as CommodityDeedBox;
list.Add(1076217); // 1st Year Veteran Reward
}
}
public static CommodityDeedBox Find(Item deed)
{
var parent = deed;
while (parent != null && parent is not CommodityDeedBox)
{
parent = parent.Parent as Item;
}
return parent as CommodityDeedBox;
}
}

View file

@ -1,142 +1,74 @@
using ModernUO.Serialization;
using Server.Engines.VeteranRewards;
namespace Server.Items
namespace Server.Items;
[SerializationGenerator(0)]
public partial class ContestMiniHouse : MiniHouseAddon
{
public class ContestMiniHouse : MiniHouseAddon
[InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _isRewardItem;
[Constructible]
public ContestMiniHouse() : base(MiniHouseType.MalasMountainPass)
{
private bool m_IsRewardItem;
[Constructible]
public ContestMiniHouse() : base(MiniHouseType.MalasMountainPass)
{
}
[Constructible]
public ContestMiniHouse(MiniHouseType type) : base(type)
{
}
public ContestMiniHouse(Serial serial) : base(serial)
{
}
public override BaseAddonDeed Deed
{
get
{
var deed = new ContestMiniHouseDeed(Type);
deed.IsRewardItem = m_IsRewardItem;
return deed;
}
}
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
{
get => m_IsRewardItem;
set
{
m_IsRewardItem = value;
InvalidateProperties();
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
writer.Write(m_IsRewardItem);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_IsRewardItem = reader.ReadBool();
}
}
public class ContestMiniHouseDeed : MiniHouseDeed, IRewardItem
[Constructible]
public ContestMiniHouse(MiniHouseType type) : base(type)
{
private bool m_IsRewardItem;
}
[Constructible]
public ContestMiniHouseDeed() : base(MiniHouseType.MalasMountainPass)
public override BaseAddonDeed Deed =>
new ContestMiniHouseDeed(Type)
{
IsRewardItem = _isRewardItem
};
}
[SerializationGenerator(0)]
public partial class ContestMiniHouseDeed : MiniHouseDeed, IRewardItem
{
[InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _isRewardItem;
[Constructible]
public ContestMiniHouseDeed() : base(MiniHouseType.MalasMountainPass)
{
}
[Constructible]
public ContestMiniHouseDeed(MiniHouseType type) : base(type)
{
}
public override BaseAddon Addon =>
new ContestMiniHouse(Type)
{
IsRewardItem = _isRewardItem
};
public override void OnDoubleClick(Mobile from)
{
if (_isRewardItem && !RewardSystem.CheckIsUsableBy(from, this, new object[] { Type }))
{
return;
}
[Constructible]
public ContestMiniHouseDeed(MiniHouseType type) : base(type)
base.OnDoubleClick(from);
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (Core.ML && _isRewardItem)
{
}
public ContestMiniHouseDeed(Serial serial) : base(serial)
{
}
public override BaseAddon Addon
{
get
{
var addon = new ContestMiniHouse(Type);
addon.IsRewardItem = m_IsRewardItem;
return addon;
}
}
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
{
get => m_IsRewardItem;
set
{
m_IsRewardItem = value;
InvalidateProperties();
}
}
public override void OnDoubleClick(Mobile from)
{
if (m_IsRewardItem && !RewardSystem.CheckIsUsableBy(from, this, new object[] { Type }))
{
return;
}
base.OnDoubleClick(from);
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (Core.ML && m_IsRewardItem)
{
list.Add(1076217); // 1st Year Veteran Reward
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
writer.Write(m_IsRewardItem);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_IsRewardItem = reader.ReadBool();
list.Add(1076217); // 1st Year Veteran Reward
}
}
}

View file

@ -1,215 +1,305 @@
using ModernUO.Serialization;
using Server.Engines.VeteranRewards;
using Server.Gumps;
using Server.Multis;
using Server.Network;
using Server.Targeting;
namespace Server.Items
namespace Server.Items;
[SerializationGenerator(0)]
public partial class DecorativeShield : Item, IAddon, IRewardItem
{
public class DecorativeShield : Item, IAddon, IRewardItem
[InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _isRewardItem;
[Constructible]
public DecorativeShield(int itemID = 0x156C) : base(itemID) => Movable = false;
public override bool ForceShowProperties => ObjectPropertyList.Enabled;
public bool FacingSouth
{
private bool m_IsRewardItem;
[Constructible]
public DecorativeShield(int itemID = 0x156C) : base(itemID) => Movable = false;
public DecorativeShield(Serial serial) : base(serial)
get
{
}
public override bool ForceShowProperties => ObjectPropertyList.Enabled;
public bool FacingSouth
{
get
if (ItemID < 0x1582)
{
if (ItemID < 0x1582)
{
return (ItemID & 0x1) == 0;
}
return ItemID <= 0x1585;
return (ItemID & 0x1) == 0;
}
}
public Item Deed
{
get
{
var deed = new DecorativeShieldDeed();
deed.IsRewardItem = m_IsRewardItem;
return deed;
}
}
public bool CouldFit(IPoint3D p, Map map) =>
map?.CanFit(p.X, p.Y, p.Z, ItemData.Height) == true && (FacingSouth
&& BaseAddon.IsWall(p.X, p.Y - 1, p.Z, map)
|| BaseAddon.IsWall(p.X - 1, p.Y, p.Z, map));
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
{
get => m_IsRewardItem;
set
{
m_IsRewardItem = value;
InvalidateProperties();
}
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (Core.ML && m_IsRewardItem)
{
list.Add(1076220); // 4th Year Veteran Reward
}
}
public override void OnDoubleClick(Mobile from)
{
if (from.InRange(Location, 2))
{
var house = BaseHouse.FindHouseAt(this);
if (house?.IsOwner(from) == true)
{
from.CloseGump<RewardDemolitionGump>();
from.SendGump(new RewardDemolitionGump(this, 1049783)); // Do you wish to re-deed this decoration?
}
else
{
from.SendLocalizedMessage(
1049784
); // You can only re-deed this decoration if you are the house owner or originally placed the decoration.
}
}
else
{
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
writer.Write(m_IsRewardItem);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_IsRewardItem = reader.ReadBool();
return ItemID <= 0x1585;
}
}
public class DecorativeShieldDeed : Item, IRewardItem
public Item Deed =>
new DecorativeShieldDeed
{
IsRewardItem = _isRewardItem
};
public bool CouldFit(IPoint3D p, Map map) =>
map?.CanFit(p.X, p.Y, p.Z, ItemData.Height) == true &&
(FacingSouth && BaseAddon.IsWall(p.X, p.Y - 1, p.Z, map) || BaseAddon.IsWall(p.X - 1, p.Y, p.Z, map));
public override void GetProperties(IPropertyList list)
{
private bool m_IsRewardItem;
base.GetProperties(list);
[Constructible]
public DecorativeShieldDeed() : base(0x14F0)
if (Core.ML && _isRewardItem)
{
LootType = LootType.Blessed;
Weight = 1.0;
list.Add(1076220); // 4th Year Veteran Reward
}
}
public DecorativeShieldDeed(Serial serial) : base(serial)
public override void OnDoubleClick(Mobile from)
{
if (from.InRange(Location, 2))
{
}
var house = BaseHouse.FindHouseAt(this);
public override int LabelNumber => 1049771; // deed for a decorative shield wall hanging
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
{
get => m_IsRewardItem;
set
if (house?.IsOwner(from) == true)
{
m_IsRewardItem = value;
InvalidateProperties();
from.CloseGump<RewardDemolitionGump>();
from.SendGump(new RewardDemolitionGump(this, 1049783)); // Do you wish to re-deed this decoration?
}
else
{
// You can only re-deed this decoration if you are the house owner or originally placed the decoration.
from.SendLocalizedMessage(1049784);
}
}
else
{
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
}
}
}
[SerializationGenerator(0)]
public partial class DecorativeShieldDeed : Item, IRewardItem
{
[InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _isRewardItem;
[Constructible]
public DecorativeShieldDeed() : base(0x14F0)
{
LootType = LootType.Blessed;
Weight = 1.0;
}
public override int LabelNumber => 1049771; // deed for a decorative shield wall hanging
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (_isRewardItem)
{
list.Add(1076220); // 4th Year Veteran Reward
}
}
public override void OnDoubleClick(Mobile from)
{
if (_isRewardItem && !RewardSystem.CheckIsUsableBy(from, this))
{
return;
}
if (IsChildOf(from.Backpack))
{
from.CloseGump<InternalGump>();
from.SendGump(new InternalGump(this));
}
else
{
from.SendLocalizedMessage(1042038); // You must have the object in your backpack to use it.
}
}
public static int GetWestItemID(int east)
{
return east switch
{
0x1582 => 0x1635,
0x1583 => 0x1634,
0x1584 => 0x1637,
0x1585 => 0x1636,
_ => east + 1
};
}
private class InternalGump : Gump
{
public const int Start = 0x156C;
public const int End = 0x1585;
private readonly DecorativeShieldDeed _shield;
public InternalGump(DecorativeShieldDeed shield) : base(150, 50)
{
_shield = shield;
Closable = true;
Disposable = true;
Draggable = true;
Resizable = false;
AddPage(0);
AddBackground(25, 0, 500, 230, 0xA28);
var itemID = Start;
for (var i = 1; i <= 2; i++)
{
AddPage(i);
for (var j = 0; j < 9 - i; j++)
{
AddItem(40 + j * 60, 70, itemID);
AddButton(60 + j * 60, 50, 0x845, 0x846, itemID);
if (itemID < 0x1582)
{
itemID += 2;
}
else
{
itemID += 1;
}
}
switch (i)
{
case 1:
{
AddButton(455, 198, 0x8B0, 0x8B0, 0, GumpButtonType.Page, 2);
break;
}
case 2:
{
AddButton(70, 198, 0x8AF, 0x8AF, 0, GumpButtonType.Page, 1);
break;
}
}
}
}
public override void GetProperties(IPropertyList list)
public override void OnResponse(NetState sender, RelayInfo info)
{
base.GetProperties(list);
if (m_IsRewardItem)
{
list.Add(1076220); // 4th Year Veteran Reward
}
}
public override void OnDoubleClick(Mobile from)
{
if (m_IsRewardItem && !RewardSystem.CheckIsUsableBy(from, this))
if (_shield?.Deleted != false ||
info.ButtonID is < Start or > End ||
((info.ButtonID & 0x1) != 0 || info.ButtonID >= 0x1582) && info.ButtonID is < 0x1582 or > 0x1585)
{
return;
}
if (IsChildOf(from.Backpack))
sender.Mobile.SendLocalizedMessage(1049780); // Where would you like to place this decoration?
sender.Mobile.Target = new InternalTarget(_shield, info.ButtonID);
}
}
private class InternalTarget : Target
{
private readonly int _itemID;
private readonly DecorativeShieldDeed _shield;
public InternalTarget(DecorativeShieldDeed shield, int itemID) : base(-1, true, TargetFlags.None)
{
_shield = shield;
_itemID = itemID;
}
protected override void OnTarget(Mobile from, object targeted)
{
if (_shield?.Deleted != false)
{
from.CloseGump<InternalGump>();
from.SendGump(new InternalGump(this));
return;
}
if (!_shield.IsChildOf(from.Backpack))
{
from.SendLocalizedMessage(1042038); // You must have the object in your backpack to use it.
return;
}
var house = BaseHouse.FindHouseAt(from);
if (house?.IsOwner(from) != true)
{
from.SendLocalizedMessage(502092); // You must be in your house to do this.
return;
}
var p = targeted as IPoint3D;
var map = from.Map;
if (p == null || map == null)
{
return;
}
var p3d = new Point3D(p);
var id = TileData.ItemTable[_itemID & TileData.MaxItemValue];
if (!map.CanFit(p3d, id.Height))
{
from.SendLocalizedMessage(500269); // You cannot build that there.
return;
}
house = BaseHouse.FindHouseAt(p3d, map, id.Height);
if (house?.IsOwner(from) != true)
{
from.SendLocalizedMessage(1042036); // That location is not in your house.
return;
}
var north = BaseAddon.IsWall(p3d.X, p3d.Y - 1, p3d.Z, map);
var west = BaseAddon.IsWall(p3d.X - 1, p3d.Y, p3d.Z, map);
if (north && west)
{
from.CloseGump<FacingGump>();
from.SendGump(new FacingGump(_shield, _itemID, p3d, house));
}
else if (north || west)
{
var shield = new DecorativeShield(west ? GetWestItemID(_itemID) : _itemID);
house.Addons.Add(shield);
shield.IsRewardItem = _shield.IsRewardItem;
shield.MoveToWorld(p3d, map);
_shield.Delete();
}
else
{
from.SendLocalizedMessage(1042038); // You must have the object in your backpack to use it.
from.SendLocalizedMessage(1049781); // This decoration must be placed next to a wall.
}
}
public override void Serialize(IGenericWriter writer)
private class FacingGump : Gump
{
base.Serialize(writer);
private readonly BaseHouse _house;
private readonly int _itemID;
private readonly Point3D _location;
private readonly DecorativeShieldDeed _shield;
writer.WriteEncodedInt(0); // version
writer.Write(m_IsRewardItem);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_IsRewardItem = reader.ReadBool();
}
public static int GetWestItemID(int east)
{
return east switch
public FacingGump(DecorativeShieldDeed shield, int itemID, Point3D location, BaseHouse house) : base(150, 50)
{
0x1582 => 0x1635,
0x1583 => 0x1634,
0x1584 => 0x1637,
0x1585 => 0x1636,
_ => east + 1
};
}
private class InternalGump : Gump
{
public const int Start = 0x156C;
public const int End = 0x1585;
private readonly DecorativeShieldDeed m_Shield;
private int m_Page;
public InternalGump(DecorativeShieldDeed shield, int page = 1) : base(150, 50)
{
m_Shield = shield;
m_Page = page;
_shield = shield;
_itemID = itemID;
_location = location;
_house = house;
Closable = true;
Disposable = true;
@ -217,202 +307,50 @@ namespace Server.Items
Resizable = false;
AddPage(0);
AddBackground(0, 0, 300, 150, 0xA28);
AddBackground(25, 0, 500, 230, 0xA28);
AddItem(90, 30, GetWestItemID(itemID));
AddItem(180, 30, itemID);
var itemID = Start;
for (var i = 1; i <= 2; i++)
{
AddPage(i);
for (var j = 0; j < 9 - i; j++)
{
AddItem(40 + j * 60, 70, itemID);
AddButton(60 + j * 60, 50, 0x845, 0x846, itemID);
if (itemID < 0x1582)
{
itemID += 2;
}
else
{
itemID += 1;
}
}
switch (i)
{
case 1:
AddButton(455, 198, 0x8B0, 0x8B0, 0, GumpButtonType.Page, 2);
break;
case 2:
AddButton(70, 198, 0x8AF, 0x8AF, 0, GumpButtonType.Page, 1);
break;
}
}
AddButton(50, 35, 0x867, 0x869, (int)Buttons.East);
AddButton(145, 35, 0x867, 0x869, (int)Buttons.South);
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if (m_Shield?.Deleted != false || info.ButtonID is < Start or > End || ((info.ButtonID & 0x1) != 0 || info.ButtonID >= 0x1582) &&
info.ButtonID is < 0x1582 or > 0x1585)
if (_shield?.Deleted != false || _house == null)
{
return;
}
sender.Mobile.SendLocalizedMessage(1049780); // Where would you like to place this decoration?
sender.Mobile.Target = new InternalTarget(m_Shield, info.ButtonID);
}
}
DecorativeShield shield = null;
private class InternalTarget : Target
{
private readonly int m_ItemID;
private readonly DecorativeShieldDeed m_Shield;
public InternalTarget(DecorativeShieldDeed shield, int itemID) : base(-1, true, TargetFlags.None)
{
m_Shield = shield;
m_ItemID = itemID;
}
protected override void OnTarget(Mobile from, object targeted)
{
if (m_Shield?.Deleted != false)
if (info.ButtonID == (int)Buttons.East)
{
return;
shield = new DecorativeShield(GetWestItemID(_itemID));
}
if (!m_Shield.IsChildOf(from.Backpack))
if (info.ButtonID == (int)Buttons.South)
{
from.SendLocalizedMessage(1042038); // You must have the object in your backpack to use it.
return;
shield = new DecorativeShield(_itemID);
}
var house = BaseHouse.FindHouseAt(from);
if (house?.IsOwner(from) != true)
if (shield != null)
{
from.SendLocalizedMessage(502092); // You must be in your house to do this.
return;
}
_house.Addons.Add(shield);
var p = targeted as IPoint3D;
var map = from.Map;
shield.IsRewardItem = _shield.IsRewardItem;
shield.MoveToWorld(_location, sender.Mobile.Map);
if (p == null || map == null)
{
return;
}
var p3d = new Point3D(p);
var id = TileData.ItemTable[m_ItemID & TileData.MaxItemValue];
if (!map.CanFit(p3d, id.Height))
{
from.SendLocalizedMessage(500269); // You cannot build that there.
return;
}
house = BaseHouse.FindHouseAt(p3d, map, id.Height);
if (house?.IsOwner(from) != true)
{
from.SendLocalizedMessage(1042036); // That location is not in your house.
return;
}
var north = BaseAddon.IsWall(p3d.X, p3d.Y - 1, p3d.Z, map);
var west = BaseAddon.IsWall(p3d.X - 1, p3d.Y, p3d.Z, map);
if (north && west)
{
from.CloseGump<FacingGump>();
from.SendGump(new FacingGump(m_Shield, m_ItemID, p3d, house));
}
else if (north || west)
{
var shield = new DecorativeShield(west ? GetWestItemID(m_ItemID) : m_ItemID);
house.Addons.Add(shield);
shield.IsRewardItem = m_Shield.IsRewardItem;
shield.MoveToWorld(p3d, map);
m_Shield.Delete();
}
else
{
from.SendLocalizedMessage(1049781); // This decoration must be placed next to a wall.
_shield.Delete();
}
}
private class FacingGump : Gump
private enum Buttons
{
private readonly BaseHouse m_House;
private readonly int m_ItemID;
private readonly Point3D m_Location;
private readonly DecorativeShieldDeed m_Shield;
public FacingGump(DecorativeShieldDeed shield, int itemID, Point3D location, BaseHouse house) : base(150, 50)
{
m_Shield = shield;
m_ItemID = itemID;
m_Location = location;
m_House = house;
Closable = true;
Disposable = true;
Draggable = true;
Resizable = false;
AddPage(0);
AddBackground(0, 0, 300, 150, 0xA28);
AddItem(90, 30, GetWestItemID(itemID));
AddItem(180, 30, itemID);
AddButton(50, 35, 0x867, 0x869, (int)Buttons.East);
AddButton(145, 35, 0x867, 0x869, (int)Buttons.South);
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if (m_Shield?.Deleted != false || m_House == null)
{
return;
}
DecorativeShield shield = null;
if (info.ButtonID == (int)Buttons.East)
{
shield = new DecorativeShield(GetWestItemID(m_ItemID));
}
if (info.ButtonID == (int)Buttons.South)
{
shield = new DecorativeShield(m_ItemID);
}
if (shield != null)
{
m_House.Addons.Add(shield);
shield.IsRewardItem = m_Shield.IsRewardItem;
shield.MoveToWorld(m_Location, sender.Mobile.Map);
m_Shield.Delete();
}
}
private enum Buttons
{
Cancel,
South,
East
}
Cancel,
South,
East
}
}
}

View file

@ -1,297 +1,227 @@
using ModernUO.Serialization;
using Server.Engines.VeteranRewards;
using Server.Gumps;
using Server.Multis;
using Server.Targeting;
namespace Server.Items
namespace Server.Items;
[SerializationGenerator(0)]
public partial class FlamingHead : StoneFaceTrapNoDamage, IAddon, IRewardItem
{
public class FlamingHead : StoneFaceTrapNoDamage, IAddon, IRewardItem
[InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _isRewardItem;
[Constructible]
public FlamingHead(StoneFaceTrapType type = StoneFaceTrapType.NorthWall)
{
private bool m_IsRewardItem;
LootType = LootType.Blessed;
Movable = false;
Type = type;
}
[Constructible]
public FlamingHead(StoneFaceTrapType type = StoneFaceTrapType.NorthWall)
public override int LabelNumber => 1041266; // Flaming Head
public override bool ForceShowProperties => ObjectPropertyList.Enabled;
public Item Deed =>
new FlamingHeadDeed
{
LootType = LootType.Blessed;
Movable = false;
Type = type;
}
IsRewardItem = _isRewardItem
};
public FlamingHead(Serial serial) : base(serial)
public bool CouldFit(IPoint3D p, Map map)
{
if (map?.CanFit(p.X, p.Y, p.Z, ItemData.Height) != true)
{
}
public override int LabelNumber => 1041266; // Flaming Head
public override bool ForceShowProperties => ObjectPropertyList.Enabled;
public Item Deed
{
get
{
var deed = new FlamingHeadDeed();
deed.IsRewardItem = m_IsRewardItem;
return deed;
}
}
public bool CouldFit(IPoint3D p, Map map)
{
if (map?.CanFit(p.X, p.Y, p.Z, ItemData.Height) != true)
{
return false;
}
if (Type == StoneFaceTrapType.NorthWestWall)
{
return BaseAddon.IsWall(p.X, p.Y - 1, p.Z, map) &&
BaseAddon.IsWall(p.X - 1, p.Y, p.Z, map); // north and west wall
}
if (Type == StoneFaceTrapType.NorthWall)
{
return BaseAddon.IsWall(p.X, p.Y - 1, p.Z, map); // north wall
}
if (Type == StoneFaceTrapType.WestWall)
{
return BaseAddon.IsWall(p.X - 1, p.Y, p.Z, map); // west wall
}
return false;
}
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
if (Type == StoneFaceTrapType.NorthWestWall)
{
get => m_IsRewardItem;
set
{
m_IsRewardItem = value;
InvalidateProperties();
}
return BaseAddon.IsWall(p.X, p.Y - 1, p.Z, map) &&
BaseAddon.IsWall(p.X - 1, p.Y, p.Z, map); // north and west wall
}
public override void GetProperties(IPropertyList list)
if (Type == StoneFaceTrapType.NorthWall)
{
base.GetProperties(list);
if (Core.ML && m_IsRewardItem)
{
list.Add(1076218); // 2nd Year Veteran Reward
}
return BaseAddon.IsWall(p.X, p.Y - 1, p.Z, map); // north wall
}
public override void OnDoubleClick(Mobile from)
if (Type == StoneFaceTrapType.WestWall)
{
if (from.InRange(Location, 2))
{
var house = BaseHouse.FindHouseAt(this);
if (house?.IsOwner(from) == true)
{
from.CloseGump<RewardDemolitionGump>();
from.SendGump(new RewardDemolitionGump(this, 1018329)); // Do you wish to re-deed this skull?
}
else
{
from.SendLocalizedMessage(
1018328
); // You can only re-deed a skull if you placed it or you are the owner of the house.
}
}
else
{
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
}
return BaseAddon.IsWall(p.X - 1, p.Y, p.Z, map); // west wall
}
public override void Serialize(IGenericWriter writer)
return false;
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (Core.ML && _isRewardItem)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
writer.Write(m_IsRewardItem);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_IsRewardItem = reader.ReadBool();
list.Add(1076218); // 2nd Year Veteran Reward
}
}
public class FlamingHeadDeed : Item, IRewardItem
public override void OnDoubleClick(Mobile from)
{
private bool m_IsRewardItem;
[Constructible]
public FlamingHeadDeed() : base(0x14F0)
if (from.InRange(Location, 2))
{
LootType = LootType.Blessed;
Weight = 1.0;
}
var house = BaseHouse.FindHouseAt(this);
public FlamingHeadDeed(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1041050; // a flaming head deed
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
{
get => m_IsRewardItem;
set
if (house?.IsOwner(from) == true)
{
m_IsRewardItem = value;
InvalidateProperties();
from.CloseGump<RewardDemolitionGump>();
from.SendGump(new RewardDemolitionGump(this, 1018329)); // Do you wish to re-deed this skull?
}
else
{
// You can only re-deed a skull if you placed it or you are the owner of the house.
from.SendLocalizedMessage(1018328);
}
}
public override void GetProperties(IPropertyList list)
else
{
base.GetProperties(list);
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
}
}
}
if (m_IsRewardItem)
{
list.Add(1076218); // 2nd Year Veteran Reward
}
[SerializationGenerator(0)]
public partial class FlamingHeadDeed : Item, IRewardItem
{
[InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _isRewardItem;
[Constructible]
public FlamingHeadDeed() : base(0x14F0)
{
LootType = LootType.Blessed;
Weight = 1.0;
}
public override int LabelNumber => 1041050; // a flaming head deed
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (_isRewardItem)
{
list.Add(1076218); // 2nd Year Veteran Reward
}
}
public override void OnDoubleClick(Mobile from)
{
if (_isRewardItem && !RewardSystem.CheckIsUsableBy(from, this))
{
return;
}
public override void OnDoubleClick(Mobile from)
if (IsChildOf(from.Backpack))
{
if (m_IsRewardItem && !RewardSystem.CheckIsUsableBy(from, this))
var house = BaseHouse.FindHouseAt(from);
if (house?.IsOwner(from) == true)
{
from.SendLocalizedMessage(1042264); // Where would you like to place this head?
from.Target = new InternalTarget(this);
}
else
{
from.SendLocalizedMessage(502115); // You must be in your house to do this.
}
}
else
{
from.SendLocalizedMessage(1042038); // You must have the object in your backpack to use it.
}
}
private class InternalTarget : Target
{
private readonly FlamingHeadDeed _deed;
public InternalTarget(FlamingHeadDeed deed) : base(-1, true, TargetFlags.None) => _deed = deed;
protected override void OnTarget(Mobile from, object targeted)
{
if (_deed?.Deleted != false)
{
return;
}
if (IsChildOf(from.Backpack))
{
var house = BaseHouse.FindHouseAt(from);
if (house?.IsOwner(from) == true)
{
from.SendLocalizedMessage(1042264); // Where would you like to place this head?
from.Target = new InternalTarget(this);
}
else
{
from.SendLocalizedMessage(502115); // You must be in your house to do this.
}
}
else
if (!_deed.IsChildOf(from.Backpack))
{
from.SendLocalizedMessage(1042038); // You must have the object in your backpack to use it.
return;
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
var house = BaseHouse.FindHouseAt(from);
writer.WriteEncodedInt(0); // version
writer.Write(m_IsRewardItem);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_IsRewardItem = reader.ReadBool();
}
private class InternalTarget : Target
{
private readonly FlamingHeadDeed m_Head;
public InternalTarget(FlamingHeadDeed head) : base(-1, true, TargetFlags.None) => m_Head = head;
protected override void OnTarget(Mobile from, object targeted)
if (house?.IsOwner(from) != true)
{
if (m_Head?.Deleted != false)
{
return;
}
if (!m_Head.IsChildOf(from.Backpack))
{
from.SendLocalizedMessage(1042038); // You must have the object in your backpack to use it.
return;
}
var house = BaseHouse.FindHouseAt(from);
if (house?.IsOwner(from) != true)
{
from.SendLocalizedMessage(502115); // You must be in your house to do this.
return;
}
var p = targeted as IPoint3D;
var map = from.Map;
if (p == null || map == null)
{
return;
}
var p3d = new Point3D(p);
var id = TileData.ItemTable[0x10F5];
house = BaseHouse.FindHouseAt(p3d, map, id.Height);
if (house?.IsOwner(from) != true)
{
from.SendLocalizedMessage(1042036); // That location is not in your house.
return;
}
if (!map.CanFit(p3d, id.Height))
{
from.SendLocalizedMessage(1042266); // The head must be placed next to a wall.
return;
}
var north = BaseAddon.IsWall(p3d.X, p3d.Y - 1, p3d.Z, map);
var west = BaseAddon.IsWall(p3d.X - 1, p3d.Y, p3d.Z, map);
FlamingHead head = null;
if (north && west)
{
head = new FlamingHead(StoneFaceTrapType.NorthWestWall);
}
else if (north)
{
head = new FlamingHead();
}
else if (west)
{
head = new FlamingHead(StoneFaceTrapType.WestWall);
}
if (north || west)
{
house.Addons.Add(head);
head.IsRewardItem = m_Head.IsRewardItem;
head.MoveToWorld(p3d, map);
m_Head.Delete();
}
else
{
from.SendLocalizedMessage(1042266); // The head must be placed next to a wall.
}
from.SendLocalizedMessage(502115); // You must be in your house to do this.
return;
}
var p = targeted as IPoint3D;
var map = from.Map;
if (p == null || map == null)
{
return;
}
var p3d = new Point3D(p);
var id = TileData.ItemTable[0x10F5];
house = BaseHouse.FindHouseAt(p3d, map, id.Height);
if (house?.IsOwner(from) != true)
{
from.SendLocalizedMessage(1042036); // That location is not in your house.
return;
}
if (!map.CanFit(p3d, id.Height))
{
from.SendLocalizedMessage(1042266); // The head must be placed next to a wall.
return;
}
var north = BaseAddon.IsWall(p3d.X, p3d.Y - 1, p3d.Z, map);
var west = BaseAddon.IsWall(p3d.X - 1, p3d.Y, p3d.Z, map);
if (!(north || west))
{
from.SendLocalizedMessage(1042266); // The head must be placed next to a wall.
return;
}
var facing = north switch
{
true when west => StoneFaceTrapType.NorthWestWall,
true => StoneFaceTrapType.NorthWall,
_ => StoneFaceTrapType.WestWall
};
var head = new FlamingHead(facing)
{
IsRewardItem = _deed.IsRewardItem
};
_deed.Delete();
house.Addons.Add(head);
head.MoveToWorld(p3d, map);
}
}
}

View file

@ -1,231 +1,291 @@
using ModernUO.Serialization;
using Server.Engines.VeteranRewards;
using Server.Gumps;
using Server.Multis;
using Server.Network;
using Server.Targeting;
namespace Server.Items
namespace Server.Items;
[SerializationGenerator(0)]
public partial class HangingSkeleton : Item, IAddon, IRewardItem
{
public class HangingSkeleton : Item, IAddon, IRewardItem
[InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _isRewardItem;
[Constructible]
public HangingSkeleton(int itemID = 0x1596) : base(itemID)
{
private bool m_IsRewardItem;
LootType = LootType.Blessed;
Movable = false;
}
[Constructible]
public HangingSkeleton(int itemID = 0x1596) : base(itemID)
public override bool ForceShowProperties => ObjectPropertyList.Enabled;
public bool FacingSouth => ItemID is 0x1A03 or 0x1A05 or 0x1A09 or 0x1B1E or 0x1B7F;
public Item Deed =>
new HangingSkeletonDeed
{
LootType = LootType.Blessed;
Movable = false;
IsRewardItem = _isRewardItem
};
public bool CouldFit(IPoint3D p, Map map)
{
if (map?.CanFit(p.X, p.Y, p.Z, ItemData.Height) != true)
{
return false;
}
public HangingSkeleton(Serial serial) : base(serial)
if (FacingSouth)
{
return BaseAddon.IsWall(p.X, p.Y - 1, p.Z, map); // north wall
}
public override bool ForceShowProperties => ObjectPropertyList.Enabled;
return BaseAddon.IsWall(p.X - 1, p.Y, p.Z, map); // west wall
}
public bool FacingSouth
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (Core.ML && _isRewardItem)
{
get
{
if (ItemID is 0x1A03 or 0x1A05 or 0x1A09 or 0x1B1E or 0x1B7F)
{
return true;
}
return false;
}
}
public Item Deed
{
get
{
var deed = new HangingSkeletonDeed();
deed.IsRewardItem = m_IsRewardItem;
return deed;
}
}
public bool CouldFit(IPoint3D p, Map map)
{
if (map?.CanFit(p.X, p.Y, p.Z, ItemData.Height) != true)
{
return false;
}
if (FacingSouth)
{
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
}
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
{
get => m_IsRewardItem;
set
{
m_IsRewardItem = value;
InvalidateProperties();
}
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (Core.ML && m_IsRewardItem)
{
list.Add(1076220); // 4th Year Veteran Reward
}
}
public override void OnDoubleClick(Mobile from)
{
if (from.InRange(Location, 3))
{
var house = BaseHouse.FindHouseAt(this);
if (house?.IsOwner(from) == true)
{
from.CloseGump<RewardDemolitionGump>();
from.SendGump(new RewardDemolitionGump(this, 1049783)); // Do you wish to re-deed this decoration?
}
else
{
from.SendLocalizedMessage(
1049784
); // You can only re-deed this decoration if you are the house owner or originally placed the decoration.
}
}
else
{
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
writer.Write(m_IsRewardItem);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_IsRewardItem = reader.ReadBool();
list.Add(1076220); // 4th Year Veteran Reward
}
}
public class HangingSkeletonDeed : Item, IRewardItem
public override void OnDoubleClick(Mobile from)
{
private bool m_IsRewardItem;
[Constructible]
public HangingSkeletonDeed() : base(0x14F0)
if (from.InRange(Location, 3))
{
LootType = LootType.Blessed;
Weight = 1.0;
}
var house = BaseHouse.FindHouseAt(this);
public HangingSkeletonDeed(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1049772; // deed for a hanging skeleton decoration
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
{
get => m_IsRewardItem;
set
if (house?.IsOwner(from) == true)
{
m_IsRewardItem = value;
InvalidateProperties();
from.CloseGump<RewardDemolitionGump>();
from.SendGump(new RewardDemolitionGump(this, 1049783)); // Do you wish to re-deed this decoration?
}
else
{
// You can only re-deed this decoration if you are the house owner or originally placed the decoration.
from.SendLocalizedMessage(1049784);
}
}
public override void GetProperties(IPropertyList list)
else
{
base.GetProperties(list);
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
}
}
}
if (m_IsRewardItem)
{
list.Add(1076220); // 4th Year Veteran Reward
}
[SerializationGenerator(0)]
public partial class HangingSkeletonDeed : Item, IRewardItem
{
[InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _isRewardItem;
[Constructible]
public HangingSkeletonDeed() : base(0x14F0)
{
LootType = LootType.Blessed;
Weight = 1.0;
}
public override int LabelNumber => 1049772; // deed for a hanging skeleton decoration
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (_isRewardItem)
{
list.Add(1076220); // 4th Year Veteran Reward
}
}
public override void OnDoubleClick(Mobile from)
{
if (_isRewardItem && !RewardSystem.CheckIsUsableBy(from, this))
{
return;
}
public override void OnDoubleClick(Mobile from)
if (!IsChildOf(from.Backpack))
{
if (m_IsRewardItem && !RewardSystem.CheckIsUsableBy(from, this))
from.SendLocalizedMessage(1042038); // You must have the object in your backpack to use it.
return;
}
var house = BaseHouse.FindHouseAt(from);
if (house?.IsOwner(from) != true)
{
from.SendLocalizedMessage(502092); // You must be in your house to do this.
return;
}
from.CloseGump<InternalGump>();
from.SendGump(new InternalGump(this));
}
public static int GetWestItemID(int south)
{
return south switch
{
0x1B1E => 0x1B1D,
0x1B7F => 0x1B7C,
_ => south + 1
};
}
private class InternalGump : Gump
{
private readonly HangingSkeletonDeed _deed;
public InternalGump(HangingSkeletonDeed skeleton) : base(100, 200)
{
_deed = skeleton;
Closable = true;
Disposable = true;
Draggable = true;
Resizable = false;
AddPage(0);
AddBackground(25, 0, 500, 230, 0xA28);
AddPage(1);
AddItem(130, 70, 0x1A03);
AddButton(150, 50, 0x845, 0x846, 0x1A03);
AddItem(190, 70, 0x1A05);
AddButton(210, 50, 0x845, 0x846, 0x1A05);
AddItem(250, 70, 0x1A09);
AddButton(270, 50, 0x845, 0x846, 0x1A09);
AddItem(310, 70, 0x1B1E);
AddButton(330, 50, 0x845, 0x846, 0x1B1E);
AddItem(370, 70, 0x1B7F);
AddButton(390, 50, 0x845, 0x846, 0x1B7F);
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if (_deed?.Deleted != false || info.ButtonID != 0x1A03 && info.ButtonID != 0x1A05 &&
info.ButtonID != 0x1A09 && info.ButtonID != 0x1B1E && info.ButtonID != 0x1B7F)
{
return;
}
if (IsChildOf(from.Backpack))
{
var house = BaseHouse.FindHouseAt(from);
sender.Mobile.SendLocalizedMessage(1049780); // Where would you like to place this decoration?
sender.Mobile.Target = new InternalTarget(_deed, info.ButtonID);
}
}
if (house?.IsOwner(from) == true)
{
from.CloseGump<InternalGump>();
from.SendGump(new InternalGump(this));
}
else
{
from.SendLocalizedMessage(502092); // You must be in your house to do this.
}
private class InternalTarget : Target
{
private readonly int _itemID;
private readonly HangingSkeletonDeed _deed;
public InternalTarget(HangingSkeletonDeed deed, int itemID) : base(-1, true, TargetFlags.None)
{
_deed = deed;
_itemID = itemID;
}
protected override void OnTarget(Mobile from, object targeted)
{
if (_deed?.Deleted != false)
{
return;
}
if (!_deed.IsChildOf(from.Backpack))
{
from.SendLocalizedMessage(1042038); // You must have the object in your backpack to use it.
return;
}
var house = BaseHouse.FindHouseAt(from);
if (house?.IsOwner(from) != true)
{
from.SendLocalizedMessage(502092); // You must be in your house to do this.
return;
}
var p = targeted as IPoint3D;
var map = from.Map;
if (p == null || map == null)
{
return;
}
var p3d = new Point3D(p);
var id = TileData.ItemTable[_itemID & TileData.MaxItemValue];
if (!map.CanFit(p3d, id.Height))
{
from.SendLocalizedMessage(500269); // You cannot build that there.
return;
}
house = BaseHouse.FindHouseAt(p3d, map, id.Height);
if (house?.IsOwner(from) != true)
{
from.SendLocalizedMessage(1042036); // That location is not in your house.
return;
}
var north = BaseAddon.IsWall(p3d.X, p3d.Y - 1, p3d.Z, map);
var west = BaseAddon.IsWall(p3d.X - 1, p3d.Y, p3d.Z, map);
if (north && west)
{
from.CloseGump<FacingGump>();
from.SendGump(new FacingGump(_deed, _itemID, p3d, house));
}
else if (north || west)
{
var banner = new HangingSkeleton(west ? GetWestItemID(_itemID) : _itemID);
house.Addons.Add(banner);
banner.IsRewardItem = _deed.IsRewardItem;
banner.MoveToWorld(p3d, map);
_deed.Delete();
}
else
{
from.SendLocalizedMessage(1042038); // You must have the object in your backpack to use it.
from.SendLocalizedMessage(1042039); // The banner must be placed next to a wall.
}
}
public override void Serialize(IGenericWriter writer)
private class FacingGump : Gump
{
base.Serialize(writer);
private readonly BaseHouse _house;
private readonly int _itemID;
private readonly Point3D _location;
private readonly HangingSkeletonDeed _skeleton;
writer.WriteEncodedInt(0); // version
writer.Write(m_IsRewardItem);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_IsRewardItem = reader.ReadBool();
}
public static int GetWestItemID(int south)
{
return south switch
public FacingGump(HangingSkeletonDeed banner, int itemID, Point3D location, BaseHouse house) : base(150, 50)
{
0x1B1E => 0x1B1D,
0x1B7F => 0x1B7C,
_ => south + 1
};
}
private class InternalGump : Gump
{
private readonly HangingSkeletonDeed m_Skeleton;
public InternalGump(HangingSkeletonDeed skeleton) : base(100, 200)
{
m_Skeleton = skeleton;
_skeleton = banner;
_itemID = itemID;
_location = location;
_house = house;
Closable = true;
Disposable = true;
@ -234,187 +294,50 @@ namespace Server.Items
AddPage(0);
AddBackground(25, 0, 500, 230, 0xA28);
AddBackground(0, 0, 300, 150, 0xA28);
AddPage(1);
AddItem(90, 30, GetWestItemID(itemID));
AddItem(180, 30, itemID);
AddItem(130, 70, 0x1A03);
AddButton(150, 50, 0x845, 0x846, 0x1A03);
AddItem(190, 70, 0x1A05);
AddButton(210, 50, 0x845, 0x846, 0x1A05);
AddItem(250, 70, 0x1A09);
AddButton(270, 50, 0x845, 0x846, 0x1A09);
AddItem(310, 70, 0x1B1E);
AddButton(330, 50, 0x845, 0x846, 0x1B1E);
AddItem(370, 70, 0x1B7F);
AddButton(390, 50, 0x845, 0x846, 0x1B7F);
AddButton(50, 35, 0x868, 0x869, (int)Buttons.East);
AddButton(145, 35, 0x868, 0x869, (int)Buttons.South);
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if (m_Skeleton?.Deleted != false || info.ButtonID != 0x1A03 && info.ButtonID != 0x1A05 &&
info.ButtonID != 0x1A09 && info.ButtonID != 0x1B1E && info.ButtonID != 0x1B7F)
if (_skeleton?.Deleted != false || _house == null)
{
return;
}
sender.Mobile.SendLocalizedMessage(1049780); // Where would you like to place this decoration?
sender.Mobile.Target = new InternalTarget(m_Skeleton, info.ButtonID);
}
}
HangingSkeleton banner = null;
private class InternalTarget : Target
{
private readonly int m_ItemID;
private readonly HangingSkeletonDeed m_Skeleton;
public InternalTarget(HangingSkeletonDeed banner, int itemID) : base(-1, true, TargetFlags.None)
{
m_Skeleton = banner;
m_ItemID = itemID;
}
protected override void OnTarget(Mobile from, object targeted)
{
if (m_Skeleton?.Deleted != false)
if (info.ButtonID == (int)Buttons.East)
{
return;
banner = new HangingSkeleton(GetWestItemID(_itemID));
}
if (!m_Skeleton.IsChildOf(from.Backpack))
if (info.ButtonID == (int)Buttons.South)
{
from.SendLocalizedMessage(1042038); // You must have the object in your backpack to use it.
return;
banner = new HangingSkeleton(_itemID);
}
var house = BaseHouse.FindHouseAt(from);
if (house?.IsOwner(from) != true)
if (banner != null)
{
from.SendLocalizedMessage(502092); // You must be in your house to do this.
return;
}
_house.Addons.Add(banner);
var p = targeted as IPoint3D;
var map = from.Map;
banner.IsRewardItem = _skeleton.IsRewardItem;
banner.MoveToWorld(_location, sender.Mobile.Map);
if (p == null || map == null)
{
return;
}
var p3d = new Point3D(p);
var id = TileData.ItemTable[m_ItemID & TileData.MaxItemValue];
if (!map.CanFit(p3d, id.Height))
{
from.SendLocalizedMessage(500269); // You cannot build that there.
return;
}
house = BaseHouse.FindHouseAt(p3d, map, id.Height);
if (house?.IsOwner(from) != true)
{
from.SendLocalizedMessage(1042036); // That location is not in your house.
return;
}
var north = BaseAddon.IsWall(p3d.X, p3d.Y - 1, p3d.Z, map);
var west = BaseAddon.IsWall(p3d.X - 1, p3d.Y, p3d.Z, map);
if (north && west)
{
from.CloseGump<FacingGump>();
from.SendGump(new FacingGump(m_Skeleton, m_ItemID, p3d, house));
}
else if (north || west)
{
var banner = new HangingSkeleton(west ? GetWestItemID(m_ItemID) : m_ItemID);
house.Addons.Add(banner);
banner.IsRewardItem = m_Skeleton.IsRewardItem;
banner.MoveToWorld(p3d, map);
m_Skeleton.Delete();
}
else
{
from.SendLocalizedMessage(1042039); // The banner must be placed next to a wall.
_skeleton.Delete();
}
}
private class FacingGump : Gump
private enum Buttons
{
private readonly BaseHouse m_House;
private readonly int m_ItemID;
private readonly Point3D m_Location;
private readonly HangingSkeletonDeed m_Skeleton;
public FacingGump(HangingSkeletonDeed banner, int itemID, Point3D location, BaseHouse house) : base(150, 50)
{
m_Skeleton = banner;
m_ItemID = itemID;
m_Location = location;
m_House = house;
Closable = true;
Disposable = true;
Draggable = true;
Resizable = false;
AddPage(0);
AddBackground(0, 0, 300, 150, 0xA28);
AddItem(90, 30, GetWestItemID(itemID));
AddItem(180, 30, itemID);
AddButton(50, 35, 0x868, 0x869, (int)Buttons.East);
AddButton(145, 35, 0x868, 0x869, (int)Buttons.South);
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if (m_Skeleton?.Deleted != false || m_House == null)
{
return;
}
HangingSkeleton banner = null;
if (info.ButtonID == (int)Buttons.East)
{
banner = new HangingSkeleton(GetWestItemID(m_ItemID));
}
if (info.ButtonID == (int)Buttons.South)
{
banner = new HangingSkeleton(m_ItemID);
}
if (banner != null)
{
m_House.Addons.Add(banner);
banner.IsRewardItem = m_Skeleton.IsRewardItem;
banner.MoveToWorld(m_Location, sender.Mobile.Map);
m_Skeleton.Delete();
}
}
private enum Buttons
{
Cancel,
South,
East
}
Cancel,
South,
East
}
}
}

View file

@ -1,38 +1,57 @@
using System;
using ModernUO.Serialization;
using Server.Engines.VeteranRewards;
using Server.Gumps;
using Server.Multis;
namespace Server.Items
namespace Server.Items;
public enum MiningCartType
{
public enum MiningCartType
{
OreSouth = 100,
OreEast = 101,
GemSouth = 102,
GemEast = 103
}
OreSouth = 100,
OreEast = 101,
GemSouth = 102,
GemEast = 103
}
public class MiningCart : BaseAddon, IRewardItem
[SerializationGenerator(3)]
public partial class MiningCart : BaseAddon, IRewardItem
{
[SerializableField(0, setter: "private")]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private MiningCartType _cartType;
[InvalidateProperties]
[SerializableField(1)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _isRewardItem;
[SerializableField(4, getter: "private", setter: "private")]
private DateTime _lastResourceTime;
[Constructible]
public MiningCart(MiningCartType type)
{
[Constructible]
public MiningCart(MiningCartType type)
_cartType = type;
switch (type)
{
CartType = type;
switch (type)
{
case MiningCartType.OreSouth:
case MiningCartType.OreSouth:
{
AddComponent(new AddonComponent(0x1A83), 0, 0, 0);
AddComponent(new AddonComponent(0x1A82), 0, 1, 0);
AddComponent(new AddonComponent(0x1A86), 0, -1, 0);
break;
case MiningCartType.OreEast:
}
case MiningCartType.OreEast:
{
AddComponent(new AddonComponent(0x1A88), 0, 0, 0);
AddComponent(new AddonComponent(0x1A87), 1, 0, 0);
AddComponent(new AddonComponent(0x1A8B), -1, 0, 0);
break;
case MiningCartType.GemSouth:
}
case MiningCartType.GemSouth:
{
AddComponent(new LocalizedAddonComponent(0x1A83, 1080388), 0, 0, 0);
AddComponent(new LocalizedAddonComponent(0x1A82, 1080388), 0, 1, 0);
AddComponent(new LocalizedAddonComponent(0x1A86, 1080388), 0, -1, 0);
@ -47,7 +66,9 @@ namespace Server.Items
AddComponent(new AddonComponent(0xF27), 0, 0, 3);
AddComponent(new AddonComponent(0xF29), 0, 0, 0);
break;
case MiningCartType.GemEast:
}
case MiningCartType.GemEast:
{
AddComponent(new LocalizedAddonComponent(0x1A88, 1080388), 0, 0, 0);
AddComponent(new LocalizedAddonComponent(0x1A87, 1080388), 1, 0, 0);
AddComponent(new LocalizedAddonComponent(0x1A8B, 1080388), -1, 0, 0);
@ -62,122 +83,122 @@ namespace Server.Items
AddComponent(new AddonComponent(0xF23), 0, 0, 3);
AddComponent(new AddonComponent(0xF27), 0, 0, 3);
break;
}
_lastResourceTime = Core.Now;
}
}
public MiningCart(Serial serial) : base(serial)
_lastResourceTime = Core.Now;
}
public override BaseAddonDeed Deed
{
get
{
GiveResources();
return new MiningCartDeed { IsRewardItem = IsRewardItem, Gems = _gems, Ore = _ore };
}
}
[SerializableProperty(2)]
[CommandProperty(AccessLevel.GameMaster)]
public int Gems
{
get
{
GiveResources();
return _gems;
}
set
{
_gems = value;
this.MarkDirty();
}
}
[SerializableProperty(3)]
[CommandProperty(AccessLevel.GameMaster)]
public int Ore
{
get
{
GiveResources();
return _ore;
}
set
{
_ore = value;
this.MarkDirty();
}
}
private void GiveResources()
{
var amount = (Core.Now - _lastResourceTime).Days;
if (amount <= 0)
{
return;
}
public override BaseAddonDeed Deed
switch (_cartType)
{
get
{
GiveResources();
return new MiningCartDeed { IsRewardItem = IsRewardItem, Gems = _gems, Ore = _ore };
}
}
[CommandProperty(AccessLevel.GameMaster)]
public MiningCartType CartType { get; private set; }
private int _gems;
[CommandProperty(AccessLevel.GameMaster)]
public int Gems
{
get
{
GiveResources();
return _gems;
}
set => _gems = value;
}
private int _ore;
[CommandProperty(AccessLevel.GameMaster)]
public int Ore
{
get
{
GiveResources();
return _ore;
}
set => _ore = value;
}
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem { get; set; }
private void GiveResources()
{
var amount = (Core.Now - _lastResourceTime).Days;
if (amount <= 0)
{
return;
}
switch (CartType)
{
case MiningCartType.OreSouth:
case MiningCartType.OreEast:
case MiningCartType.OreSouth:
case MiningCartType.OreEast:
{
_ore = Math.Min(100, _ore + amount * 10);
break;
case MiningCartType.GemSouth:
case MiningCartType.GemEast:
}
case MiningCartType.GemSouth:
case MiningCartType.GemEast:
{
_gems = Math.Min(50, _gems + amount * 5);
break;
}
_lastResourceTime += TimeSpan.FromDays(amount);
}
}
private DateTime _lastResourceTime;
_lastResourceTime += TimeSpan.FromDays(amount);
}
public override void OnComponentUsed(AddonComponent c, Mobile from)
public override void OnComponentUsed(AddonComponent c, Mobile from)
{
var house = BaseHouse.FindHouseAt(this);
/*
* Unique problems have unique solutions. OSI does not have a problem with 1000s of mining carts
* due to the fact that they have only a miniscule fraction of the number of 10 year vets that a
* typical RunUO shard will have (RunUO's scaled down account aging system makes this a unique problem),
* and the "freeness" of free accounts. We also dont have mitigating factors like inactive (unpaid)
* accounts not gaining veteran time.
*
* The lack of high end vets and vet rewards on OSI has made testing the *exact* ranging/stacking
* behavior of these things all but impossible, so either way its just an estimation.
*
* If youd like your shard's carts/stumps to work the way they did before, simply replace the check
* below with this line of code:
*
* if (!from.InRange(GetWorldLocation(), 2)
*
* However, I am sure these checks are more accurate to OSI than the former version was.
*
*/
if (!from.InRange(GetWorldLocation(), 2) || !from.InLOS(this) || !(from.Z - Z > -3 && from.Z - Z < 3))
{
var house = BaseHouse.FindHouseAt(this);
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
return;
}
/*
* Unique problems have unique solutions. OSI does not have a problem with 1000s of mining carts
* due to the fact that they have only a miniscule fraction of the number of 10 year vets that a
* typical RunUO shard will have (RunUO's scaled down account aging system makes this a unique problem),
* and the "freeness" of free accounts. We also dont have mitigating factors like inactive (unpaid)
* accounts not gaining veteran time.
*
* The lack of high end vets and vet rewards on OSI has made testing the *exact* ranging/stacking
* behavior of these things all but impossible, so either way its just an estimation.
*
* If youd like your shard's carts/stumps to work the way they did before, simply replace the check
* below with this line of code:
*
* if (!from.InRange(GetWorldLocation(), 2)
*
* However, I am sure these checks are more accurate to OSI than the former version was.
*
*/
if (house?.HasSecureAccess(from, SecureLevel.Friends) != true)
{
from.SendLocalizedMessage(1061637); // You are not allowed to access this.
return;
}
if (!from.InRange(GetWorldLocation(), 2) || !from.InLOS(this) || !(from.Z - Z > -3 && from.Z - Z < 3))
{
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
return;
}
GiveResources();
if (house?.HasSecureAccess(from, SecureLevel.Friends) != true)
{
from.SendLocalizedMessage(1061637); // You are not allowed to access this.
return;
}
GiveResources();
switch (CartType)
{
case MiningCartType.OreSouth:
case MiningCartType.OreEast:
switch (CartType)
{
case MiningCartType.OreSouth:
case MiningCartType.OreEast:
{
if (_ore > 0)
{
var ingots = Utility.Random(9) switch
@ -199,9 +220,8 @@ namespace Server.Items
if (!from.PlaceInBackpack(ingots))
{
ingots.Delete();
from.SendLocalizedMessage(
1078837
); // Your backpack is full! Please make room and try again.
// Your backpack is full! Please make room and try again.
from.SendLocalizedMessage(1078837);
}
else
{
@ -215,8 +235,10 @@ namespace Server.Items
}
break;
case MiningCartType.GemSouth:
case MiningCartType.GemEast:
}
case MiningCartType.GemSouth:
case MiningCartType.GemEast:
{
if (_gems > 0)
{
Item gems = Utility.Random(15) switch
@ -246,9 +268,8 @@ namespace Server.Items
if (!from.PlaceInBackpack(gems))
{
gems.Delete();
from.SendLocalizedMessage(
1078837 // Your backpack is full! Please make room and try again.
);
// Your backpack is full! Please make room and try again.
from.SendLocalizedMessage(1078837);
}
else
{
@ -262,150 +283,97 @@ namespace Server.Items
}
break;
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(2); // version
writer.Write((int)CartType);
writer.Write(IsRewardItem);
writer.Write(_gems);
writer.Write(_ore);
writer.Write(_lastResourceTime);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
switch (version)
{
case 2:
case 1:
CartType = (MiningCartType)reader.ReadInt();
goto case 0;
case 0:
IsRewardItem = reader.ReadBool();
_gems = reader.ReadInt();
_ore = reader.ReadInt();
_lastResourceTime = reader.ReadDateTime() - (version < 2 ? TimeSpan.FromDays(1.0) : TimeSpan.Zero);
break;
}
GiveResources();
}
}
}
public class MiningCartDeed : BaseAddonDeed, IRewardItem, IRewardOption
private void Deserialize(IGenericReader reader, int version)
{
private MiningCartType m_CartType;
_cartType = (MiningCartType)reader.ReadInt();
private bool m_IsRewardItem;
_isRewardItem = reader.ReadBool();
_gems = reader.ReadInt();
_ore = reader.ReadInt();
[Constructible]
public MiningCartDeed() => LootType = LootType.Blessed;
_lastResourceTime = reader.ReadDateTime();
}
public MiningCartDeed(Serial serial) : base(serial)
[AfterDeserialization]
private void AfterDeserialization()
{
GiveResources();
}
}
[SerializationGenerator(0)]
public partial class MiningCartDeed : BaseAddonDeed, IRewardItem, IRewardOption
{
[InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _isRewardItem;
[SerializableField(1)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private int _gems;
[SerializableField(2)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private int _ore;
private MiningCartType _cartType;
[Constructible]
public MiningCartDeed() => LootType = LootType.Blessed;
public override int LabelNumber => 1080385; // deed for a mining cart decoration
public override BaseAddon Addon =>
new MiningCart(_cartType) { IsRewardItem = _isRewardItem, Gems = Gems, Ore = Ore };
public void GetOptions(RewardOptionList list)
{
list.Add((int)MiningCartType.OreSouth, 1080391);
list.Add((int)MiningCartType.OreEast, 1080390);
list.Add((int)MiningCartType.GemSouth, 1080500);
list.Add((int)MiningCartType.GemEast, 1080499);
}
public void OnOptionSelected(Mobile from, int choice)
{
_cartType = (MiningCartType)choice;
if (!Deleted)
{
base.OnDoubleClick(from);
}
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (_isRewardItem)
{
list.Add(1080457); // 10th Year Veteran Reward
}
}
public override void OnDoubleClick(Mobile from)
{
if (_isRewardItem && !RewardSystem.CheckIsUsableBy(from, this))
{
return;
}
public override int LabelNumber => 1080385; // deed for a mining cart decoration
public override BaseAddon Addon =>
new MiningCart(m_CartType) { IsRewardItem = m_IsRewardItem, Gems = Gems, Ore = Ore };
[CommandProperty(AccessLevel.GameMaster)]
public int Gems { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public int Ore { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
if (IsChildOf(from.Backpack))
{
get => m_IsRewardItem;
set
{
m_IsRewardItem = value;
InvalidateProperties();
}
from.CloseGump<RewardOptionGump>();
from.SendGump(new RewardOptionGump(this));
}
public void GetOptions(RewardOptionList list)
else
{
list.Add((int)MiningCartType.OreSouth, 1080391);
list.Add((int)MiningCartType.OreEast, 1080390);
list.Add((int)MiningCartType.GemSouth, 1080500);
list.Add((int)MiningCartType.GemEast, 1080499);
}
public void OnOptionSelected(Mobile from, int choice)
{
m_CartType = (MiningCartType)choice;
if (!Deleted)
{
base.OnDoubleClick(from);
}
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (m_IsRewardItem)
{
list.Add(1080457); // 10th Year Veteran Reward
}
}
public override void OnDoubleClick(Mobile from)
{
if (m_IsRewardItem && !RewardSystem.CheckIsUsableBy(from, this))
{
return;
}
if (IsChildOf(from.Backpack))
{
from.CloseGump<RewardOptionGump>();
from.SendGump(new RewardOptionGump(this));
}
else
{
from.SendLocalizedMessage(1062334); // This item must be in your backpack to be used.
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
writer.Write(m_IsRewardItem);
writer.Write(Gems);
writer.Write(Ore);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_IsRewardItem = reader.ReadBool();
Gems = reader.ReadInt();
Ore = reader.ReadInt();
from.SendLocalizedMessage(1062334); // This item must be in your backpack to be used.
}
}
}

View file

@ -1,191 +1,131 @@
using ModernUO.Serialization;
using Server.Engines.VeteranRewards;
using Server.Gumps;
namespace Server.Items
namespace Server.Items;
public enum MinotaurStatueType
{
public enum MinotaurStatueType
{
AttackSouth = 100,
AttackEast = 101,
DefendSouth = 102,
DefendEast = 103
}
AttackSouth = 100,
AttackEast = 101,
DefendSouth = 102,
DefendEast = 103
}
public class MinotaurStatue : BaseAddon, IRewardItem
{
private bool m_IsRewardItem;
[SerializationGenerator(0)]
public partial class MinotaurStatue : BaseAddon, IRewardItem
{
[InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _isRewardItem;
[Constructible]
public MinotaurStatue(MinotaurStatueType type)
[Constructible]
public MinotaurStatue(MinotaurStatueType type)
{
switch (type)
{
switch (type)
{
case MinotaurStatueType.AttackSouth:
case MinotaurStatueType.AttackSouth:
{
AddComponent(new AddonComponent(0x306C), 0, 0, 0);
AddComponent(new AddonComponent(0x306D), -1, 0, 0);
AddComponent(new AddonComponent(0x306E), 0, -1, 0);
break;
case MinotaurStatueType.AttackEast:
}
case MinotaurStatueType.AttackEast:
{
AddComponent(new AddonComponent(0x3074), 0, 0, 0);
AddComponent(new AddonComponent(0x3075), -1, 0, 0);
AddComponent(new AddonComponent(0x3076), 0, -1, 0);
break;
case MinotaurStatueType.DefendSouth:
}
case MinotaurStatueType.DefendSouth:
{
AddComponent(new AddonComponent(0x3072), 0, 0, 0);
AddComponent(new AddonComponent(0x3073), 0, -1, 0);
break;
case MinotaurStatueType.DefendEast:
}
case MinotaurStatueType.DefendEast:
{
AddComponent(new AddonComponent(0x306F), 0, 0, 0);
AddComponent(new AddonComponent(0x3070), -1, 0, 0);
AddComponent(new AddonComponent(0x3071), 0, -1, 0);
break;
}
}
public MinotaurStatue(Serial serial) : base(serial)
{
}
public override BaseAddonDeed Deed
{
get
{
var deed = new MinotaurStatueDeed();
deed.IsRewardItem = m_IsRewardItem;
return deed;
}
}
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
{
get => m_IsRewardItem;
set
{
m_IsRewardItem = value;
InvalidateProperties();
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
writer.Write(m_IsRewardItem);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_IsRewardItem = reader.ReadBool();
}
}
}
public class MinotaurStatueDeed : BaseAddonDeed, IRewardItem, IRewardOption
public override BaseAddonDeed Deed =>
new MinotaurStatueDeed
{
IsRewardItem = _isRewardItem
};
}
[SerializationGenerator(0)]
public partial class MinotaurStatueDeed : BaseAddonDeed, IRewardItem, IRewardOption
{
[InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _isRewardItem;
private MinotaurStatueType _statueType;
[Constructible]
public MinotaurStatueDeed() => LootType = LootType.Blessed;
public override int LabelNumber => 1080409; // Minotaur Statue Deed
public override BaseAddon Addon =>
new MinotaurStatue(_statueType)
{
IsRewardItem = _isRewardItem
};
public void GetOptions(RewardOptionList list)
{
private bool m_IsRewardItem;
list.Add((int)MinotaurStatueType.AttackSouth, 1080410); // Minotaur Attack South
list.Add((int)MinotaurStatueType.AttackEast, 1080411); // Minotaur Attack East
list.Add((int)MinotaurStatueType.DefendSouth, 1080412); // Minotaur Defend South
list.Add((int)MinotaurStatueType.DefendEast, 1080413); // Minotaur Defend East
}
private MinotaurStatueType m_StatueType;
public void OnOptionSelected(Mobile from, int option)
{
_statueType = (MinotaurStatueType)option;
[Constructible]
public MinotaurStatueDeed() => LootType = LootType.Blessed;
public MinotaurStatueDeed(Serial serial) : base(serial)
if (!Deleted)
{
base.OnDoubleClick(from);
}
}
public override void OnDoubleClick(Mobile from)
{
if (_isRewardItem && !RewardSystem.CheckIsUsableBy(from, this))
{
return;
}
public override int LabelNumber => 1080409; // Minotaur Statue Deed
public override BaseAddon Addon
if (IsChildOf(from.Backpack))
{
get
{
var addon = new MinotaurStatue(m_StatueType);
addon.IsRewardItem = m_IsRewardItem;
return addon;
}
from.CloseGump<RewardOptionGump>();
from.SendGump(new RewardOptionGump(this));
}
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
else
{
get => m_IsRewardItem;
set
{
m_IsRewardItem = value;
InvalidateProperties();
}
from.SendLocalizedMessage(1062334); // This item must be in your backpack to be used.
}
}
public void GetOptions(RewardOptionList list)
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (_isRewardItem)
{
list.Add((int)MinotaurStatueType.AttackSouth, 1080410); // Minotaur Attack South
list.Add((int)MinotaurStatueType.AttackEast, 1080411); // Minotaur Attack East
list.Add((int)MinotaurStatueType.DefendSouth, 1080412); // Minotaur Defend South
list.Add((int)MinotaurStatueType.DefendEast, 1080413); // Minotaur Defend East
}
public void OnOptionSelected(Mobile from, int option)
{
m_StatueType = (MinotaurStatueType)option;
if (!Deleted)
{
base.OnDoubleClick(from);
}
}
public override void OnDoubleClick(Mobile from)
{
if (m_IsRewardItem && !RewardSystem.CheckIsUsableBy(from, this))
{
return;
}
if (IsChildOf(from.Backpack))
{
from.CloseGump<RewardOptionGump>();
from.SendGump(new RewardOptionGump(this));
}
else
{
from.SendLocalizedMessage(1062334); // This item must be in your backpack to be used.
}
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (m_IsRewardItem)
{
list.Add(1076218); // 2nd Year Veteran Reward
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
writer.Write(m_IsRewardItem);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_IsRewardItem = reader.ReadBool();
list.Add(1076218); // 2nd Year Veteran Reward
}
}
}

View file

@ -1,194 +1,132 @@
using ModernUO.Serialization;
using Server.Engines.VeteranRewards;
using Server.Gumps;
using Server.Network;
namespace Server.Items
namespace Server.Items;
[SerializationGenerator(0)]
public partial class RewardPottedCactus : Item, IRewardItem
{
public class RewardPottedCactus : Item, IRewardItem
[InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _isRewardItem;
[Constructible]
public RewardPottedCactus() : this(Utility.RandomMinMax(0x1E0F, 0x1E14))
{
private bool m_IsRewardItem;
}
[Constructible]
public RewardPottedCactus() : this(Utility.RandomMinMax(0x1E0F, 0x1E14))
[Constructible]
public RewardPottedCactus(int itemID) : base(itemID) => Weight = 5.0;
public override bool ForceShowProperties => ObjectPropertyList.Enabled;
}
[SerializationGenerator(0)]
public partial class PottedCactusDeed : Item, IRewardItem
{
[InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _isRewardItem;
[Constructible]
public PottedCactusDeed() : base(0x14F0)
{
LootType = LootType.Blessed;
Weight = 1.0;
}
public override int LabelNumber => 1080407; // Potted Cactus Deed
public override void OnDoubleClick(Mobile from)
{
if (_isRewardItem && !RewardSystem.CheckIsUsableBy(from, this))
{
return;
}
[Constructible]
public RewardPottedCactus(int itemID) : base(itemID) => Weight = 5.0;
public RewardPottedCactus(Serial serial) : base(serial)
if (IsChildOf(from.Backpack))
{
from.CloseGump<InternalGump>();
from.SendGump(new InternalGump(this));
}
public override bool ForceShowProperties => ObjectPropertyList.Enabled;
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
else
{
get => m_IsRewardItem;
set
{
m_IsRewardItem = value;
InvalidateProperties();
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(1); // version
writer.Write(m_IsRewardItem);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_IsRewardItem = version switch
{
1 => reader.ReadBool(),
_ => m_IsRewardItem
};
from.SendLocalizedMessage(1042038); // You must have the object in your backpack to use it.
}
}
public class PottedCactusDeed : Item, IRewardItem
public override void GetProperties(IPropertyList list)
{
private bool m_IsRewardItem;
base.GetProperties(list);
[Constructible]
public PottedCactusDeed() : base(0x14F0)
if (_isRewardItem)
{
LootType = LootType.Blessed;
Weight = 1.0;
list.Add(1076219); // 3rd Year Veteran Reward
}
}
private class InternalGump : Gump
{
private readonly PottedCactusDeed _deed;
public InternalGump(PottedCactusDeed cactus) : base(100, 200)
{
_deed = cactus;
Closable = true;
Disposable = true;
Draggable = true;
Resizable = false;
AddPage(0);
AddBackground(0, 0, 425, 250, 0xA28);
AddPage(1);
AddLabel(45, 15, 0, "Choose a Potted Cactus:");
AddItem(45, 75, 0x1E0F);
AddButton(55, 50, 0x845, 0x846, 0x1E0F);
AddItem(105, 75, 0x1E10);
AddButton(115, 50, 0x845, 0x846, 0x1E10);
AddItem(160, 75, 0x1E14);
AddButton(175, 50, 0x845, 0x846, 0x1E14);
AddItem(220, 75, 0x1E11);
AddButton(235, 50, 0x845, 0x846, 0x1E11);
AddItem(280, 75, 0x1E12);
AddButton(295, 50, 0x845, 0x846, 0x1E12);
AddItem(340, 75, 0x1E13);
AddButton(355, 50, 0x845, 0x846, 0x1E13);
}
public PottedCactusDeed(Serial serial) : base(serial)
public override void OnResponse(NetState sender, RelayInfo info)
{
}
public override int LabelNumber => 1080407; // Potted Cactus Deed
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
{
get => m_IsRewardItem;
set
{
m_IsRewardItem = value;
InvalidateProperties();
}
}
public override void OnDoubleClick(Mobile from)
{
if (m_IsRewardItem && !RewardSystem.CheckIsUsableBy(from, this))
if (_deed?.Deleted != false || info.ButtonID is < 0x1E0F or > 0x1E14)
{
return;
}
if (IsChildOf(from.Backpack))
var cactus = new RewardPottedCactus(info.ButtonID)
{
from.CloseGump<InternalGump>();
from.SendGump(new InternalGump(this));
IsRewardItem = _deed.IsRewardItem
};
if (!sender.Mobile.PlaceInBackpack(cactus))
{
cactus.Delete();
sender.Mobile.SendLocalizedMessage(1078837); // Your backpack is full! Please make room and try again.
}
else
{
from.SendLocalizedMessage(1042038); // You must have the object in your backpack to use it.
}
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (m_IsRewardItem)
{
list.Add(1076219); // 3rd Year Veteran Reward
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
writer.Write(m_IsRewardItem);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_IsRewardItem = reader.ReadBool();
}
private class InternalGump : Gump
{
private readonly PottedCactusDeed m_Cactus;
public InternalGump(PottedCactusDeed cactus) : base(100, 200)
{
m_Cactus = cactus;
Closable = true;
Disposable = true;
Draggable = true;
Resizable = false;
AddPage(0);
AddBackground(0, 0, 425, 250, 0xA28);
AddPage(1);
AddLabel(45, 15, 0, "Choose a Potted Cactus:");
AddItem(45, 75, 0x1E0F);
AddButton(55, 50, 0x845, 0x846, 0x1E0F);
AddItem(105, 75, 0x1E10);
AddButton(115, 50, 0x845, 0x846, 0x1E10);
AddItem(160, 75, 0x1E14);
AddButton(175, 50, 0x845, 0x846, 0x1E14);
AddItem(220, 75, 0x1E11);
AddButton(235, 50, 0x845, 0x846, 0x1E11);
AddItem(280, 75, 0x1E12);
AddButton(295, 50, 0x845, 0x846, 0x1E12);
AddItem(340, 75, 0x1E13);
AddButton(355, 50, 0x845, 0x846, 0x1E13);
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if (m_Cactus?.Deleted != false || info.ButtonID is < 0x1E0F or > 0x1E14)
{
return;
}
var cactus = new RewardPottedCactus(info.ButtonID)
{
IsRewardItem = m_Cactus.IsRewardItem
};
if (!sender.Mobile.PlaceInBackpack(cactus))
{
cactus.Delete();
sender.Mobile.SendLocalizedMessage(1078837); // Your backpack is full! Please make room and try again.
}
else
{
m_Cactus.Delete();
}
_deed.Delete();
}
}
}

View file

@ -1,278 +1,197 @@
using ModernUO.Serialization;
using Server.Engines.VeteranRewards;
using Server.Gumps;
using Server.Multis;
using Server.Network;
namespace Server.Items
namespace Server.Items;
[SerializationGenerator(0)]
public partial class StoneAnkhComponent : AddonComponent
{
public class StoneAnkhComponent : AddonComponent
public StoneAnkhComponent(int itemID) : base(itemID) => Weight = 1.0;
public override bool ForceShowProperties => ObjectPropertyList.Enabled;
public override void GetProperties(IPropertyList list)
{
public StoneAnkhComponent(int itemID) : base(itemID) => Weight = 1.0;
base.GetProperties(list);
public StoneAnkhComponent(Serial serial) : base(serial)
if (Addon is StoneAnkh { IsRewardItem: true })
{
list.Add(1076221); // 5th Year Veteran Reward
}
}
}
public override bool ForceShowProperties => ObjectPropertyList.Enabled;
[SerializationGenerator(0)]
public partial class StoneAnkh : BaseAddon, IRewardItem
{
[InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _isRewardItem;
public override void GetProperties(IPropertyList list)
[Constructible]
public StoneAnkh(bool east = true)
{
if (east)
{
base.GetProperties(list);
if (Addon is StoneAnkh ankh && ankh.IsRewardItem)
{
list.Add(1076221); // 5th Year Veteran Reward
}
AddComponent(new StoneAnkhComponent(0x2), 0, 0, 0);
AddComponent(new StoneAnkhComponent(0x3), 0, -1, 0);
}
public override void Serialize(IGenericWriter writer)
else
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
AddComponent(new StoneAnkhComponent(0x5), 0, 0, 0);
AddComponent(new StoneAnkhComponent(0x4), -1, 0, 0);
}
}
public class StoneAnkh : BaseAddon, IRewardItem
public StoneAnkh(Serial serial) : base(serial)
{
private bool m_IsRewardItem;
}
[Constructible]
public StoneAnkh(bool east = true)
public override BaseAddonDeed Deed =>
new StoneAnkhDeed
{
if (east)
{
AddComponent(new StoneAnkhComponent(0x2), 0, 0, 0);
AddComponent(new StoneAnkhComponent(0x3), 0, -1, 0);
}
else
{
AddComponent(new StoneAnkhComponent(0x5), 0, 0, 0);
AddComponent(new StoneAnkhComponent(0x4), -1, 0, 0);
}
}
IsRewardItem = _isRewardItem
};
public StoneAnkh(Serial serial) : base(serial)
public override void OnChop(Mobile from)
{
from.SendLocalizedMessage(500489); // You can't use an axe on that.
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (Core.ML && _isRewardItem)
{
}
public override BaseAddonDeed Deed
{
get
{
var deed = new StoneAnkhDeed();
deed.IsRewardItem = m_IsRewardItem;
return deed;
}
}
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
{
get => m_IsRewardItem;
set
{
m_IsRewardItem = value;
InvalidateProperties();
}
}
public override void OnChop(Mobile from)
{
from.SendLocalizedMessage(500489); // You can't use an axe on that.
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (Core.ML && m_IsRewardItem)
{
list.Add(1076221); // 5th Year Veteran Reward
}
}
public override void OnComponentUsed(AddonComponent c, Mobile from)
{
if (from.InRange(Location, 2))
{
var house = BaseHouse.FindHouseAt(this);
if (house?.IsOwner(from) == true)
{
from.CloseGump<RewardDemolitionGump>();
from.SendGump(new RewardDemolitionGump(this, 1049783)); // Do you wish to re-deed this decoration?
}
else
{
from.SendLocalizedMessage(
1049784
); // You can only re-deed this decoration if you are the house owner or originally placed the decoration.
}
}
else
{
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
writer.Write(m_IsRewardItem);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_IsRewardItem = reader.ReadBool();
list.Add(1076221); // 5th Year Veteran Reward
}
}
public class StoneAnkhDeed : BaseAddonDeed, IRewardItem
public override void OnComponentUsed(AddonComponent c, Mobile from)
{
private bool m_East;
private bool m_IsRewardItem;
[Constructible]
public StoneAnkhDeed() => LootType = LootType.Blessed;
public StoneAnkhDeed(Serial serial) : base(serial)
if (from.InRange(Location, 2))
{
}
var house = BaseHouse.FindHouseAt(this);
public override int LabelNumber => 1049773; // deed for a stone ankh
public override BaseAddon Addon
{
get
if (house?.IsOwner(from) == true)
{
var addon = new StoneAnkh(m_East);
addon.IsRewardItem = m_IsRewardItem;
return addon;
from.CloseGump<RewardDemolitionGump>();
from.SendGump(new RewardDemolitionGump(this, 1049783)); // Do you wish to re-deed this decoration?
}
else
{
// You can only re-deed this decoration if you are the house owner or originally placed the decoration.
from.SendLocalizedMessage(1049784);
}
}
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
else
{
get => m_IsRewardItem;
set
{
m_IsRewardItem = value;
InvalidateProperties();
}
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
}
}
}
[SerializationGenerator(0)]
public partial class StoneAnkhDeed : BaseAddonDeed, IRewardItem
{
[InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _isRewardItem;
private bool _east;
[Constructible]
public StoneAnkhDeed() => LootType = LootType.Blessed;
public override int LabelNumber => 1049773; // deed for a stone ankh
public override BaseAddon Addon =>
new StoneAnkh(_east)
{
IsRewardItem = _isRewardItem
};
public override void OnDoubleClick(Mobile from)
{
if (_isRewardItem && !RewardSystem.CheckIsUsableBy(from, this))
{
return;
}
public override void OnDoubleClick(Mobile from)
if (IsChildOf(from.Backpack))
{
if (m_IsRewardItem && !RewardSystem.CheckIsUsableBy(from, this))
from.CloseGump<InternalGump>();
from.SendGump(new InternalGump(this));
}
else
{
from.SendLocalizedMessage(1042038); // You must have the object in your backpack to use it.
}
}
private void SendTarget(Mobile m)
{
base.OnDoubleClick(m);
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (_isRewardItem)
{
list.Add(1076221); // 5th Year Veteran Reward
}
}
private class InternalGump : Gump
{
private readonly StoneAnkhDeed _deed;
public InternalGump(StoneAnkhDeed deed) : base(150, 50)
{
_deed = deed;
Closable = true;
Disposable = true;
Draggable = true;
Resizable = false;
AddPage(0);
AddBackground(0, 0, 300, 150, 0xA28);
AddItem(90, 30, 0x4);
AddItem(112, 30, 0x5);
AddButton(50, 35, 0x867, 0x869, (int)Buttons.South); // South
AddItem(170, 30, 0x2);
AddItem(192, 30, 0x3);
AddButton(145, 35, 0x867, 0x869, (int)Buttons.East); // East
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if (_deed?.Deleted != false || info.ButtonID == (int)Buttons.Cancel)
{
return;
}
if (IsChildOf(from.Backpack))
{
from.CloseGump<InternalGump>();
from.SendGump(new InternalGump(this));
}
else
{
from.SendLocalizedMessage(1042038); // You must have the object in your backpack to use it.
}
_deed._east = info.ButtonID == (int)Buttons.East;
_deed.SendTarget(sender.Mobile);
}
private void SendTarget(Mobile m)
private enum Buttons
{
base.OnDoubleClick(m);
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (m_IsRewardItem)
{
list.Add(1076221); // 5th Year Veteran Reward
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
writer.Write(m_IsRewardItem);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_IsRewardItem = reader.ReadBool();
}
private class InternalGump : Gump
{
private readonly StoneAnkhDeed m_Deed;
public InternalGump(StoneAnkhDeed deed) : base(150, 50)
{
m_Deed = deed;
Closable = true;
Disposable = true;
Draggable = true;
Resizable = false;
AddPage(0);
AddBackground(0, 0, 300, 150, 0xA28);
AddItem(90, 30, 0x4);
AddItem(112, 30, 0x5);
AddButton(50, 35, 0x867, 0x869, (int)Buttons.South); // South
AddItem(170, 30, 0x2);
AddItem(192, 30, 0x3);
AddButton(145, 35, 0x867, 0x869, (int)Buttons.East); // East
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if (m_Deed?.Deleted != false || info.ButtonID == (int)Buttons.Cancel)
{
return;
}
m_Deed.m_East = info.ButtonID == (int)Buttons.East;
m_Deed.SendTarget(sender.Mobile);
}
private enum Buttons
{
Cancel,
South,
East
}
Cancel,
South,
East
}
}
}

View file

@ -1,300 +1,214 @@
using System;
using System.Runtime.CompilerServices;
using ModernUO.Serialization;
using Server.Engines.VeteranRewards;
using Server.Gumps;
using Server.Multis;
namespace Server.Items
namespace Server.Items;
[SerializationGenerator(1)]
public partial class TreeStump : BaseAddon, IRewardItem
{
public class TreeStump : BaseAddon, IRewardItem
[InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _isRewardItem;
[InvalidateProperties]
[SerializableField(1)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private int _logs;
[SerializableField(2)]
[SerializedCommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)]
private DateTime _lastChecked;
[Constructible]
public TreeStump(int itemID)
{
private bool m_IsRewardItem;
private int m_Logs;
private TimerExecutionToken _timerToken;
AddComponent(new AddonComponent(itemID), 0, 0, 0);
_lastChecked = Core.Now;
}
[Constructible]
public TreeStump(int itemID)
public override BaseAddonDeed Deed =>
new TreeStumpDeed
{
AddComponent(new AddonComponent(itemID), 0, 0, 0);
IsRewardItem = _isRewardItem,
Logs = _logs
};
Timer.StartTimer(TimeSpan.FromDays(1), TimeSpan.FromDays(1), GiveLogs, out _timerToken);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void UpdateLogs()
{
var now = Core.Now;
var daysSince = (now - _lastChecked).Days;
_logs = Math.Min(100, _logs + daysSince * 10);
_lastChecked = now;
}
public override void OnComponentUsed(AddonComponent c, Mobile from)
{
var house = BaseHouse.FindHouseAt(this);
/*
* Unique problems have unique solutions. OSI does not have a problem with 1000s of mining carts
* due to the fact that they have only a miniscule fraction of the number of 10 year vets that a
* typical RunUO shard will have (RunUO's scaled down account aging system makes this a unique problem),
* and the "freeness" of free accounts. We also dont have mitigating factors like inactive (unpaid)
* accounts not gaining veteran time.
*
* The lack of high end vets and vet rewards on OSI has made testing the *exact* ranging/stacking
* behavior of these things all but impossible, so either way its just an estimation.
*
* If youd like your shard's carts/stumps to work the way they did before, simply replace the check
* below with this line of code:
*
* if (!from.InRange(GetWorldLocation(), 2)
*
* However, I am sure these checks are more accurate to OSI than the former version was.
*
*/
if (!from.InRange(GetWorldLocation(), 2) || !from.InLOS(this) || !(from.Z - Z > -3 && from.Z - Z < 3))
{
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
return;
}
public TreeStump(Serial serial) : base(serial)
if (house?.HasSecureAccess(from, SecureLevel.Friends) != true)
{
from.SendLocalizedMessage(1061637); // You are not allowed to access this.
return;
}
public override BaseAddonDeed Deed
{
get
{
var deed = new TreeStumpDeed();
deed.IsRewardItem = m_IsRewardItem;
deed.Logs = m_Logs;
UpdateLogs();
return deed;
}
if (_logs <= 0)
{
from.SendLocalizedMessage(1094720); // There are no more logs available.
return;
}
[CommandProperty(AccessLevel.GameMaster)]
public int Logs
var logs = Utility.Random(7) switch
{
get => m_Logs;
set
{
m_Logs = value;
InvalidateProperties();
}
0 => new Log(),
1 => new AshLog(),
2 => new OakLog(),
3 => new YewLog(),
4 => new HeartwoodLog(),
5 => new BloodwoodLog(),
_ => new FrostwoodLog()
};
var amount = Math.Min(10, _logs);
logs.Amount = amount;
if (!from.PlaceInBackpack(logs))
{
logs.Delete();
from.SendLocalizedMessage(1078837); // Your backpack is full! Please make room and try again.
}
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
else
{
get => m_IsRewardItem;
set
{
m_IsRewardItem = value;
InvalidateProperties();
}
}
private void GiveLogs()
{
m_Logs = Math.Min(100, m_Logs + 10);
}
public override void OnAfterDelete()
{
_timerToken.Cancel();
}
public override void OnComponentUsed(AddonComponent c, Mobile from)
{
var house = BaseHouse.FindHouseAt(this);
/*
* Unique problems have unique solutions. OSI does not have a problem with 1000s of mining carts
* due to the fact that they have only a miniscule fraction of the number of 10 year vets that a
* typical RunUO shard will have (RunUO's scaled down account aging system makes this a unique problem),
* and the "freeness" of free accounts. We also dont have mitigating factors like inactive (unpaid)
* accounts not gaining veteran time.
*
* The lack of high end vets and vet rewards on OSI has made testing the *exact* ranging/stacking
* behavior of these things all but impossible, so either way its just an estimation.
*
* If youd like your shard's carts/stumps to work the way they did before, simply replace the check
* below with this line of code:
*
* if (!from.InRange(GetWorldLocation(), 2)
*
* However, I am sure these checks are more accurate to OSI than the former version was.
*
*/
if (!from.InRange(GetWorldLocation(), 2) || !from.InLOS(this) || !(from.Z - Z > -3 && from.Z - Z < 3))
{
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
}
else if (house?.HasSecureAccess(from, SecureLevel.Friends) == true)
{
if (m_Logs > 0)
{
var logs = Utility.Random(7) switch
{
0 => new Log(),
1 => new AshLog(),
2 => new OakLog(),
3 => new YewLog(),
4 => new HeartwoodLog(),
5 => new BloodwoodLog(),
_ => new FrostwoodLog()
};
var amount = Math.Min(10, m_Logs);
logs.Amount = amount;
if (!from.PlaceInBackpack(logs))
{
logs.Delete();
from.SendLocalizedMessage(1078837); // Your backpack is full! Please make room and try again.
}
else
{
m_Logs -= amount;
PublicOverheadMessage(MessageType.Regular, 0, 1094719, m_Logs.ToString()); // Logs: ~1_COUNT~
}
}
else
{
from.SendLocalizedMessage(1094720); // There are no more logs available.
}
}
else
{
from.SendLocalizedMessage(1061637); // You are not allowed to access this.
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
writer.Write(m_IsRewardItem);
writer.Write(m_Logs);
if (_timerToken.Running)
{
writer.Write(_timerToken.Next);
}
else
{
writer.Write(Core.Now + TimeSpan.FromDays(1));
}
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_IsRewardItem = reader.ReadBool();
m_Logs = reader.ReadInt();
var next = reader.ReadDateTime();
if (next < Core.Now)
{
next = Core.Now;
}
Timer.StartTimer(next - Core.Now, TimeSpan.FromDays(1), GiveLogs, out _timerToken);
_logs -= amount;
PublicOverheadMessage(MessageType.Regular, 0, 1094719, _logs.ToString()); // Logs: ~1_COUNT~
}
}
public class TreeStumpDeed : BaseAddonDeed, IRewardItem, IRewardOption
private void Deserialize(IGenericReader reader, int version)
{
private bool m_IsRewardItem;
_isRewardItem = reader.ReadBool();
_logs = reader.ReadInt();
private int m_ItemID;
var next = reader.ReadDateTime();
private int m_Logs;
[Constructible]
public TreeStumpDeed() => LootType = LootType.Blessed;
public TreeStumpDeed(Serial serial) : base(serial)
if (next < Core.Now)
{
next = Core.Now;
}
public override int LabelNumber => 1080406; // a deed for a tree stump decoration
_lastChecked = next - TimeSpan.FromDays(1);
}
}
public override BaseAddon Addon
[SerializationGenerator(0)]
public partial class TreeStumpDeed : BaseAddonDeed, IRewardItem, IRewardOption
{
[InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _isRewardItem;
[InvalidateProperties]
[SerializableField(1)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private int _logs;
private int _itemID;
[Constructible]
public TreeStumpDeed() => LootType = LootType.Blessed;
public override int LabelNumber => 1080406; // a deed for a tree stump decoration
public override BaseAddon Addon =>
new TreeStump(_itemID)
{
get
{
var addon = new TreeStump(m_ItemID);
addon.IsRewardItem = m_IsRewardItem;
addon.Logs = m_Logs;
IsRewardItem = _isRewardItem,
Logs = _logs
};
return addon;
}
public void GetOptions(RewardOptionList list)
{
list.Add(1, 1080403); // Tree Stump with Axe West
list.Add(2, 1080404); // Tree Stump with Axe North
list.Add(3, 1080401); // Tree Stump East
list.Add(4, 1080402); // Tree Stump South
}
public void OnOptionSelected(Mobile from, int option)
{
_itemID = option switch
{
1 => 0xE56,
2 => 0xE58,
3 => 0xE57,
4 => 0xE59,
_ => _itemID
};
if (!Deleted)
{
base.OnDoubleClick(from);
}
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (_isRewardItem)
{
list.Add(1076223); // 7th Year Veteran Reward
}
}
public override void OnDoubleClick(Mobile from)
{
if (_isRewardItem && !RewardSystem.CheckIsUsableBy(from, this))
{
return;
}
[CommandProperty(AccessLevel.GameMaster)]
public int Logs
if (IsChildOf(from.Backpack))
{
get => m_Logs;
set
{
m_Logs = value;
InvalidateProperties();
}
from.CloseGump<RewardOptionGump>();
from.SendGump(new RewardOptionGump(this));
}
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
else
{
get => m_IsRewardItem;
set
{
m_IsRewardItem = value;
InvalidateProperties();
}
}
public void GetOptions(RewardOptionList list)
{
list.Add(1, 1080403); // Tree Stump with Axe West
list.Add(2, 1080404); // Tree Stump with Axe North
list.Add(3, 1080401); // Tree Stump East
list.Add(4, 1080402); // Tree Stump South
}
public void OnOptionSelected(Mobile from, int option)
{
m_ItemID = option switch
{
1 => 0xE56,
2 => 0xE58,
3 => 0xE57,
4 => 0xE59,
_ => m_ItemID
};
if (!Deleted)
{
base.OnDoubleClick(from);
}
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (m_IsRewardItem)
{
list.Add(1076223); // 7th Year Veteran Reward
}
}
public override void OnDoubleClick(Mobile from)
{
if (m_IsRewardItem && !RewardSystem.CheckIsUsableBy(from, this))
{
return;
}
if (IsChildOf(from.Backpack))
{
from.CloseGump<RewardOptionGump>();
from.SendGump(new RewardOptionGump(this));
}
else
{
from.SendLocalizedMessage(1062334); // This item must be in your backpack to be used.
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
writer.Write(m_IsRewardItem);
writer.Write(m_Logs);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_IsRewardItem = reader.ReadBool();
m_Logs = reader.ReadInt();
from.SendLocalizedMessage(1062334); // This item must be in your backpack to be used.
}
}
}

View file

@ -1,515 +1,479 @@
using ModernUO.Serialization;
using Server.Engines.VeteranRewards;
using Server.Gumps;
using Server.Network;
namespace Server.Items
namespace Server.Items;
[SerializationGenerator(0)]
public partial class WallBannerComponent : AddonComponent, IDyable
{
public class WallBannerComponent : AddonComponent, IDyable
public WallBannerComponent(int itemID) : base(itemID)
{
public WallBannerComponent(int itemID) : base(itemID)
{
}
public WallBannerComponent(Serial serial) : base(serial)
{
}
public override bool NeedsWall => true;
public override Point3D WallPosition => East ? new Point3D(-1, 0, 0) : new Point3D(0, -1, 0);
public bool East => ((WallBanner)Addon).East;
public bool Dye(Mobile from, DyeTub sender)
{
if (Deleted)
{
return false;
}
if (Addon != null)
{
Addon.Hue = sender.DyedHue;
}
return true;
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
}
}
public class WallBanner : BaseAddon, IRewardItem
public override bool NeedsWall => true;
public override Point3D WallPosition => East ? new Point3D(-1, 0, 0) : new Point3D(0, -1, 0);
public bool East => ((WallBanner)Addon).East;
public bool Dye(Mobile from, DyeTub sender)
{
private bool m_East;
private bool m_IsRewardItem;
[Constructible]
public WallBanner(int bannerID)
if (Deleted)
{
m_East = bannerID % 2 == 1;
return false;
}
switch (bannerID)
{
case 1:
if (Addon != null)
{
Addon.Hue = sender.DyedHue;
}
return true;
}
}
[SerializationGenerator(0)]
public partial class WallBanner : BaseAddon, IRewardItem
{
[InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _east;
[InvalidateProperties]
[SerializableField(1)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _isRewardItem;
[Constructible]
public WallBanner(int bannerID)
{
switch (bannerID)
{
case 1:
{
AddComponent(new WallBannerComponent(0x161F), 0, 0, 0);
AddComponent(new WallBannerComponent(0x161E), 0, 1, 0);
AddComponent(new WallBannerComponent(0x161D), 0, 2, 0);
break;
case 2:
}
case 2:
{
AddComponent(new WallBannerComponent(0x1586), 0, 0, 0);
AddComponent(new WallBannerComponent(0x1587), 1, 0, 0);
AddComponent(new WallBannerComponent(0x1588), 2, 0, 0);
break;
case 3:
}
case 3:
{
AddComponent(new WallBannerComponent(0x1622), 0, 0, 0);
AddComponent(new WallBannerComponent(0x1621), 0, 1, 0);
AddComponent(new WallBannerComponent(0x1620), 0, 2, 0);
break;
case 4:
}
case 4:
{
AddComponent(new WallBannerComponent(0x1589), 0, 0, 0);
AddComponent(new WallBannerComponent(0x158A), 1, 0, 0);
AddComponent(new WallBannerComponent(0x158B), 2, 0, 0);
break;
case 5:
}
case 5:
{
AddComponent(new WallBannerComponent(0x1625), 0, 0, 0);
AddComponent(new WallBannerComponent(0x1624), 0, 1, 0);
AddComponent(new WallBannerComponent(0x1623), 0, 2, 0);
break;
case 6:
}
case 6:
{
AddComponent(new WallBannerComponent(0x158C), 0, 0, 0);
AddComponent(new WallBannerComponent(0x158D), 1, 0, 0);
AddComponent(new WallBannerComponent(0x158E), 2, 0, 0);
break;
case 7:
}
case 7:
{
AddComponent(new WallBannerComponent(0x1628), 0, 0, 0);
AddComponent(new WallBannerComponent(0x1627), 0, 1, 0);
AddComponent(new WallBannerComponent(0x1626), 0, 2, 0);
break;
case 8:
}
case 8:
{
AddComponent(new WallBannerComponent(0x1590), 0, 0, 0);
AddComponent(new WallBannerComponent(0x1591), 1, 0, 0);
AddComponent(new WallBannerComponent(0x158F), 2, 0, 0);
break;
case 9:
}
case 9:
{
AddComponent(new WallBannerComponent(0x162A), 0, 0, 0);
AddComponent(new WallBannerComponent(0x1629), 0, 1, 0);
AddComponent(new WallBannerComponent(0x1626), 0, 2, 0);
break;
case 10:
}
case 10:
{
AddComponent(new WallBannerComponent(0x1592), 0, 0, 0);
AddComponent(new WallBannerComponent(0x1593), 1, 0, 0);
AddComponent(new WallBannerComponent(0x158F), 2, 0, 0);
break;
case 11:
}
case 11:
{
AddComponent(new WallBannerComponent(0x162D), 0, 0, 0);
AddComponent(new WallBannerComponent(0x162C), 0, 1, 0);
AddComponent(new WallBannerComponent(0x162B), 0, 2, 0);
break;
case 12:
}
case 12:
{
AddComponent(new WallBannerComponent(0x1594), 0, 0, 0);
AddComponent(new WallBannerComponent(0x1595), 1, 0, 0);
AddComponent(new WallBannerComponent(0x1596), 2, 0, 0);
break;
case 13:
}
case 13:
{
AddComponent(new WallBannerComponent(0x1632), 0, 0, 0);
AddComponent(new WallBannerComponent(0x1631), 0, 1, 0);
AddComponent(new WallBannerComponent(0x162E), 0, 2, 0);
break;
case 14:
}
case 14:
{
AddComponent(new WallBannerComponent(0x1598), 0, 0, 0);
AddComponent(new WallBannerComponent(0x159B), 1, 0, 0);
AddComponent(new WallBannerComponent(0x159C), 2, 0, 0);
break;
case 15:
}
case 15:
{
AddComponent(new WallBannerComponent(0x1633), 0, 0, 0);
AddComponent(new WallBannerComponent(0x1630), 0, 1, 0);
AddComponent(new WallBannerComponent(0x162F), 0, 2, 0);
break;
case 16:
}
case 16:
{
AddComponent(new WallBannerComponent(0x1599), 0, 0, 0);
AddComponent(new WallBannerComponent(0x159A), 1, 0, 0);
AddComponent(new WallBannerComponent(0x159D), 2, 0, 0);
break;
}
case 17:
case 17:
{
AddComponent(new WallBannerComponent(0x1610), 0, 0, 0);
AddComponent(new WallBannerComponent(0x160F), 0, 1, 0);
break;
case 18:
}
case 18:
{
AddComponent(new WallBannerComponent(0x15A0), 0, 0, 0);
AddComponent(new WallBannerComponent(0x15A1), 1, 0, 0);
break;
}
case 19:
case 19:
{
AddComponent(new WallBannerComponent(0x1612), 0, 0, 0);
AddComponent(new WallBannerComponent(0x1611), 0, 1, 0);
break;
case 20:
}
case 20:
{
AddComponent(new WallBannerComponent(0x15A2), 0, 0, 0);
AddComponent(new WallBannerComponent(0x15A3), 1, 0, 0);
break;
}
case 21:
case 21:
{
AddComponent(new WallBannerComponent(0x1614), 0, 0, 0);
AddComponent(new WallBannerComponent(0x1613), 0, 1, 0);
break;
case 22:
}
case 22:
{
AddComponent(new WallBannerComponent(0x15A4), 0, 0, 0);
AddComponent(new WallBannerComponent(0x15A5), 1, 0, 0);
break;
}
case 23:
case 23:
{
AddComponent(new WallBannerComponent(0x1616), 0, 0, 0);
AddComponent(new WallBannerComponent(0x1615), 0, 1, 0);
break;
case 24:
}
case 24:
{
AddComponent(new WallBannerComponent(0x15A6), 0, 0, 0);
AddComponent(new WallBannerComponent(0x15A7), 1, 0, 0);
break;
}
case 25:
case 25:
{
AddComponent(new WallBannerComponent(0x1618), 0, 0, 0);
AddComponent(new WallBannerComponent(0x1617), 0, 1, 0);
break;
case 26:
}
case 26:
{
AddComponent(new WallBannerComponent(0x15A8), 0, 0, 0);
AddComponent(new WallBannerComponent(0x15A9), 1, 0, 0);
break;
}
case 27:
case 27:
{
AddComponent(new WallBannerComponent(0x161A), 0, 0, 0);
AddComponent(new WallBannerComponent(0x1619), 0, 1, 0);
break;
case 28:
}
case 28:
{
AddComponent(new WallBannerComponent(0x15AA), 0, 0, 0);
AddComponent(new WallBannerComponent(0x15AB), 1, 0, 0);
break;
}
case 29:
case 29:
{
AddComponent(new WallBannerComponent(0x161C), 0, 0, 0);
AddComponent(new WallBannerComponent(0x161B), 0, 1, 0);
break;
case 30:
}
case 30:
{
AddComponent(new WallBannerComponent(0x15AC), 0, 0, 0);
AddComponent(new WallBannerComponent(0x15AD), 1, 0, 0);
break;
}
}
public WallBanner(Serial serial) : base(serial)
{
}
public override BaseAddonDeed Deed
{
get
{
var deed = new WallBannerDeed();
deed.IsRewardItem = m_IsRewardItem;
return deed;
}
}
[CommandProperty(AccessLevel.GameMaster)]
public bool East
{
get => m_East;
set
{
m_IsRewardItem = value;
InvalidateProperties();
}
}
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
{
get => m_IsRewardItem;
set
{
m_IsRewardItem = value;
InvalidateProperties();
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
writer.Write(m_East);
writer.Write(m_IsRewardItem);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_East = reader.ReadBool();
m_IsRewardItem = reader.ReadBool();
}
}
}
public class WallBannerDeed : BaseAddonDeed, IRewardItem
public override BaseAddonDeed Deed =>
new WallBannerDeed
{
IsRewardItem = _isRewardItem
};
}
[SerializationGenerator(0)]
public partial class WallBannerDeed : BaseAddonDeed, IRewardItem
{
[InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _isRewardItem;
private int _bannerId;
[Constructible]
public WallBannerDeed() => LootType = LootType.Blessed;
public override int LabelNumber => 1080549; // Wall Banner Deed
public override BaseAddon Addon =>
new WallBanner(_bannerId)
{
IsRewardItem = _isRewardItem
};
public override void GetProperties(IPropertyList list)
{
private int m_BannerID;
private bool m_IsRewardItem;
base.GetProperties(list);
[Constructible]
public WallBannerDeed() => LootType = LootType.Blessed;
public WallBannerDeed(Serial serial) : base(serial)
if (_isRewardItem)
{
list.Add(1076225); // 9th Year Veteran Reward
}
}
public override void OnDoubleClick(Mobile from)
{
if (_isRewardItem && !RewardSystem.CheckIsUsableBy(from, this))
{
return;
}
public override int LabelNumber => 1080549; // Wall Banner Deed
public override BaseAddon Addon
if (IsChildOf(from.Backpack))
{
get
{
var addon = new WallBanner(m_BannerID);
addon.IsRewardItem = m_IsRewardItem;
from.CloseGump<InternalGump>();
from.SendGump(new InternalGump(this));
}
else
{
from.SendLocalizedMessage(1042038); // You must have the object in your backpack to use it.
}
}
return addon;
}
public void Use(Mobile m, int bannerID)
{
_bannerId = bannerID;
base.OnDoubleClick(m);
}
private class InternalGump : Gump
{
private readonly WallBannerDeed _wallBanner;
public InternalGump(WallBannerDeed wallBanner) : base(150, 50)
{
_wallBanner = wallBanner;
Closable = true;
Disposable = true;
Draggable = true;
Resizable = false;
AddBackground(25, 0, 500, 265, 0xA28);
AddLabel(70, 12, 0x3E3, "Choose a Wall Banner:");
AddPage(1);
AddItem(55, 110, 0x161D);
AddItem(75, 90, 0x161E);
AddItem(95, 70, 0x161F);
AddButton(70, 50, 0x845, 0x846, 1);
AddItem(105, 70, 0x1586);
AddItem(125, 90, 0x1587);
AddItem(145, 110, 0x1588);
AddButton(145, 50, 0x845, 0x846, 2);
AddItem(200, 110, 0x1620);
AddItem(220, 90, 0x1621);
AddItem(240, 70, 0x1622);
AddButton(220, 50, 0x845, 0x846, 3);
AddItem(250, 70, 0x1589);
AddItem(270, 90, 0x158A);
AddItem(290, 110, 0x158B);
AddButton(300, 50, 0x845, 0x846, 4);
AddItem(350, 110, 0x1623);
AddItem(370, 90, 0x1624);
AddItem(390, 70, 0x1625);
AddButton(365, 50, 0x845, 0x846, 5);
AddItem(400, 70, 0x158C);
AddItem(420, 90, 0x158D);
AddItem(440, 110, 0x158E);
AddButton(445, 50, 0x845, 0x846, 6);
AddButton(455, 205, 0x8B0, 0x8B0, 0, GumpButtonType.Page, 2);
AddPage(2);
AddItem(52, 110, 0x1626);
AddItem(72, 90, 0x1627);
AddItem(95, 70, 0x1628);
AddButton(70, 50, 0x845, 0x846, 7);
AddItem(105, 70, 0x1590);
AddItem(125, 90, 0x1591);
AddItem(145, 110, 0x158F);
AddButton(145, 50, 0x845, 0x846, 8);
AddItem(197, 110, 0x1626);
AddItem(217, 90, 0x1629);
AddItem(240, 70, 0x162A);
AddButton(220, 50, 0x845, 0x846, 9);
AddItem(250, 70, 0x1592);
AddItem(270, 90, 0x1593);
AddItem(290, 110, 0x158F);
AddButton(300, 50, 0x845, 0x846, 10);
AddItem(340, 110, 0x162B);
AddItem(363, 90, 0x162C);
AddItem(385, 70, 0x162D);
AddButton(365, 50, 0x845, 0x846, 11);
AddItem(395, 70, 0x1594);
AddItem(417, 90, 0x1595);
AddItem(439, 111, 0x1596);
AddButton(445, 50, 0x845, 0x846, 12);
AddButton(70, 205, 0x8AF, 0x8AF, 0, GumpButtonType.Page, 1);
AddButton(455, 205, 0x8B0, 0x8B0, 0, GumpButtonType.Page, 3);
AddPage(3);
AddItem(55, 110, 0x162E);
AddItem(75, 93, 0x1631);
AddItem(95, 70, 0x1632);
AddButton(70, 50, 0x845, 0x846, 13);
AddItem(118, 70, 0x1598);
AddItem(138, 94, 0x159B);
AddItem(159, 113, 0x159C);
AddButton(160, 50, 0x845, 0x846, 14);
AddItem(219, 111, 0x162F);
AddItem(238, 94, 0x1630);
AddItem(258, 70, 0x1633);
AddButton(240, 50, 0x845, 0x846, 15);
AddItem(279, 70, 0x1599);
AddItem(298, 93, 0x159A);
AddItem(319, 113, 0x159D);
AddButton(320, 50, 0x845, 0x846, 16);
AddItem(380, 90, 0x160F);
AddItem(400, 70, 0x1610);
AddButton(390, 50, 0x845, 0x846, 17);
AddItem(420, 70, 0x15A0);
AddItem(440, 90, 0x15A1);
AddButton(455, 50, 0x845, 0x846, 18);
AddButton(70, 205, 0x8AF, 0x8AF, 0, GumpButtonType.Page, 2);
AddButton(455, 205, 0x8B0, 0x8B0, 0, GumpButtonType.Page, 4);
AddPage(4);
AddItem(55, 90, 0x1611);
AddItem(75, 70, 0x1612);
AddButton(70, 50, 0x845, 0x846, 19);
AddItem(105, 70, 0x15A2);
AddItem(125, 90, 0x15A3);
AddButton(145, 50, 0x845, 0x846, 20);
AddItem(200, 84, 0x1613);
AddItem(220, 70, 0x1614);
AddButton(215, 50, 0x845, 0x846, 21);
AddItem(250, 70, 0x15A4);
AddItem(270, 84, 0x15A5);
AddButton(290, 50, 0x845, 0x846, 22);
AddItem(350, 90, 0x1615);
AddItem(370, 70, 0x1616);
AddButton(365, 50, 0x845, 0x846, 23);
AddItem(400, 70, 0x15A6);
AddItem(420, 90, 0x15A7);
AddButton(445, 50, 0x845, 0x846, 24);
AddButton(70, 205, 0x8AF, 0x8AF, 0, GumpButtonType.Page, 3);
AddButton(455, 205, 0x8B0, 0x8B0, 0, GumpButtonType.Page, 5);
AddPage(5);
AddItem(55, 90, 0x1617);
AddItem(77, 70, 0x1618);
AddButton(70, 50, 0x845, 0x846, 25);
AddItem(105, 70, 0x15A8);
AddItem(127, 90, 0x15A9);
AddButton(145, 50, 0x845, 0x846, 26);
AddItem(200, 90, 0x1619);
AddItem(222, 70, 0x161A);
AddButton(220, 50, 0x845, 0x846, 27);
AddItem(250, 70, 0x15AA);
AddItem(272, 90, 0x15AB);
AddButton(300, 50, 0x845, 0x846, 28);
AddItem(350, 90, 0x161B);
AddItem(372, 70, 0x161C);
AddButton(365, 50, 0x845, 0x846, 29);
AddItem(400, 70, 0x15AC);
AddItem(422, 90, 0x15AD);
AddButton(445, 50, 0x845, 0x846, 30);
AddButton(70, 205, 0x8AF, 0x8AF, 0, GumpButtonType.Page, 4);
}
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
public override void OnResponse(NetState sender, RelayInfo info)
{
get => m_IsRewardItem;
set
{
m_IsRewardItem = value;
InvalidateProperties();
}
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (m_IsRewardItem)
{
list.Add(1076225); // 9th Year Veteran Reward
}
}
public override void OnDoubleClick(Mobile from)
{
if (m_IsRewardItem && !RewardSystem.CheckIsUsableBy(from, this))
if (_wallBanner?.Deleted != false || info.ButtonID is <= 0 or >= 31)
{
return;
}
if (IsChildOf(from.Backpack))
{
from.CloseGump<InternalGump>();
from.SendGump(new InternalGump(this));
}
else
{
from.SendLocalizedMessage(1042038); // You must have the object in your backpack to use it.
}
}
public void Use(Mobile m, int bannerID)
{
m_BannerID = bannerID;
base.OnDoubleClick(m);
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
writer.Write(m_IsRewardItem);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_IsRewardItem = reader.ReadBool();
}
private class InternalGump : Gump
{
private readonly WallBannerDeed m_WallBanner;
public InternalGump(WallBannerDeed wallBanner) : base(150, 50)
{
m_WallBanner = wallBanner;
Closable = true;
Disposable = true;
Draggable = true;
Resizable = false;
AddBackground(25, 0, 500, 265, 0xA28);
AddLabel(70, 12, 0x3E3, "Choose a Wall Banner:");
AddPage(1);
AddItem(55, 110, 0x161D);
AddItem(75, 90, 0x161E);
AddItem(95, 70, 0x161F);
AddButton(70, 50, 0x845, 0x846, 1);
AddItem(105, 70, 0x1586);
AddItem(125, 90, 0x1587);
AddItem(145, 110, 0x1588);
AddButton(145, 50, 0x845, 0x846, 2);
AddItem(200, 110, 0x1620);
AddItem(220, 90, 0x1621);
AddItem(240, 70, 0x1622);
AddButton(220, 50, 0x845, 0x846, 3);
AddItem(250, 70, 0x1589);
AddItem(270, 90, 0x158A);
AddItem(290, 110, 0x158B);
AddButton(300, 50, 0x845, 0x846, 4);
AddItem(350, 110, 0x1623);
AddItem(370, 90, 0x1624);
AddItem(390, 70, 0x1625);
AddButton(365, 50, 0x845, 0x846, 5);
AddItem(400, 70, 0x158C);
AddItem(420, 90, 0x158D);
AddItem(440, 110, 0x158E);
AddButton(445, 50, 0x845, 0x846, 6);
AddButton(455, 205, 0x8B0, 0x8B0, 0, GumpButtonType.Page, 2);
AddPage(2);
AddItem(52, 110, 0x1626);
AddItem(72, 90, 0x1627);
AddItem(95, 70, 0x1628);
AddButton(70, 50, 0x845, 0x846, 7);
AddItem(105, 70, 0x1590);
AddItem(125, 90, 0x1591);
AddItem(145, 110, 0x158F);
AddButton(145, 50, 0x845, 0x846, 8);
AddItem(197, 110, 0x1626);
AddItem(217, 90, 0x1629);
AddItem(240, 70, 0x162A);
AddButton(220, 50, 0x845, 0x846, 9);
AddItem(250, 70, 0x1592);
AddItem(270, 90, 0x1593);
AddItem(290, 110, 0x158F);
AddButton(300, 50, 0x845, 0x846, 10);
AddItem(340, 110, 0x162B);
AddItem(363, 90, 0x162C);
AddItem(385, 70, 0x162D);
AddButton(365, 50, 0x845, 0x846, 11);
AddItem(395, 70, 0x1594);
AddItem(417, 90, 0x1595);
AddItem(439, 111, 0x1596);
AddButton(445, 50, 0x845, 0x846, 12);
AddButton(70, 205, 0x8AF, 0x8AF, 0, GumpButtonType.Page, 1);
AddButton(455, 205, 0x8B0, 0x8B0, 0, GumpButtonType.Page, 3);
AddPage(3);
AddItem(55, 110, 0x162E);
AddItem(75, 93, 0x1631);
AddItem(95, 70, 0x1632);
AddButton(70, 50, 0x845, 0x846, 13);
AddItem(118, 70, 0x1598);
AddItem(138, 94, 0x159B);
AddItem(159, 113, 0x159C);
AddButton(160, 50, 0x845, 0x846, 14);
AddItem(219, 111, 0x162F);
AddItem(238, 94, 0x1630);
AddItem(258, 70, 0x1633);
AddButton(240, 50, 0x845, 0x846, 15);
AddItem(279, 70, 0x1599);
AddItem(298, 93, 0x159A);
AddItem(319, 113, 0x159D);
AddButton(320, 50, 0x845, 0x846, 16);
AddItem(380, 90, 0x160F);
AddItem(400, 70, 0x1610);
AddButton(390, 50, 0x845, 0x846, 17);
AddItem(420, 70, 0x15A0);
AddItem(440, 90, 0x15A1);
AddButton(455, 50, 0x845, 0x846, 18);
AddButton(70, 205, 0x8AF, 0x8AF, 0, GumpButtonType.Page, 2);
AddButton(455, 205, 0x8B0, 0x8B0, 0, GumpButtonType.Page, 4);
AddPage(4);
AddItem(55, 90, 0x1611);
AddItem(75, 70, 0x1612);
AddButton(70, 50, 0x845, 0x846, 19);
AddItem(105, 70, 0x15A2);
AddItem(125, 90, 0x15A3);
AddButton(145, 50, 0x845, 0x846, 20);
AddItem(200, 84, 0x1613);
AddItem(220, 70, 0x1614);
AddButton(215, 50, 0x845, 0x846, 21);
AddItem(250, 70, 0x15A4);
AddItem(270, 84, 0x15A5);
AddButton(290, 50, 0x845, 0x846, 22);
AddItem(350, 90, 0x1615);
AddItem(370, 70, 0x1616);
AddButton(365, 50, 0x845, 0x846, 23);
AddItem(400, 70, 0x15A6);
AddItem(420, 90, 0x15A7);
AddButton(445, 50, 0x845, 0x846, 24);
AddButton(70, 205, 0x8AF, 0x8AF, 0, GumpButtonType.Page, 3);
AddButton(455, 205, 0x8B0, 0x8B0, 0, GumpButtonType.Page, 5);
AddPage(5);
AddItem(55, 90, 0x1617);
AddItem(77, 70, 0x1618);
AddButton(70, 50, 0x845, 0x846, 25);
AddItem(105, 70, 0x15A8);
AddItem(127, 90, 0x15A9);
AddButton(145, 50, 0x845, 0x846, 26);
AddItem(200, 90, 0x1619);
AddItem(222, 70, 0x161A);
AddButton(220, 50, 0x845, 0x846, 27);
AddItem(250, 70, 0x15AA);
AddItem(272, 90, 0x15AB);
AddButton(300, 50, 0x845, 0x846, 28);
AddItem(350, 90, 0x161B);
AddItem(372, 70, 0x161C);
AddButton(365, 50, 0x845, 0x846, 29);
AddItem(400, 70, 0x15AC);
AddItem(422, 90, 0x15AD);
AddButton(445, 50, 0x845, 0x846, 30);
AddButton(70, 205, 0x8AF, 0x8AF, 0, GumpButtonType.Page, 4);
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if (m_WallBanner?.Deleted != false || info.ButtonID is <= 0 or >= 31)
{
return;
}
m_WallBanner.Use(sender.Mobile, info.ButtonID);
}
_wallBanner.Use(sender.Mobile, info.ButtonID);
}
}
}

View file

@ -1,388 +1,318 @@
using ModernUO.Serialization;
using Server.Engines.VeteranRewards;
using Server.Gumps;
using Server.Mobiles;
using Server.Network;
using Server.Targeting;
namespace Server.Items
namespace Server.Items;
[SerializationGenerator(0, false)]
public partial class WeaponEngravingTool : Item, IUsesRemaining, IRewardItem
{
public class WeaponEngravingTool : Item, IUsesRemaining, IRewardItem
[InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private int _usesRemaining;
[InvalidateProperties]
[SerializableField(1)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _isRewardItem;
[Constructible]
public WeaponEngravingTool(int uses = 10) : base(0x32F8)
{
private bool m_IsRewardItem;
LootType = LootType.Blessed;
Weight = 1.0;
private int m_UsesRemaining;
_usesRemaining = uses;
}
[Constructible]
public WeaponEngravingTool(int uses = 10) : base(0x32F8)
public override int LabelNumber => 1076158; // Weapon Engraving Tool
public bool ShowUsesRemaining
{
get => true;
set { }
}
public override void OnDoubleClick(Mobile from)
{
if (_isRewardItem && !RewardSystem.CheckIsUsableBy(from, this))
{
LootType = LootType.Blessed;
Weight = 1.0;
m_UsesRemaining = uses;
return;
}
public WeaponEngravingTool(Serial serial) : base(serial)
if (_usesRemaining > 0)
{
from.SendLocalizedMessage(1072357); // Select an object to engrave.
from.Target = new TargetWeapon(this);
return;
}
public override int LabelNumber => 1076158; // Weapon Engraving Tool
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
if (from.Skills.Tinkering.Value == 0)
{
get => m_IsRewardItem;
set
// Since you have no tinkering skill, you will need to find an NPC tinkerer to repair this for you.
from.SendLocalizedMessage(1076179);
return;
}
if (from.Skills.Tinkering.Value < 75.0)
{
// Your tinkering skill is too low to fix this yourself. An NPC tinkerer can help you repair this for a fee.
from.SendLocalizedMessage(1076178);
return;
}
if (from.Backpack.FindItemByType<BlueDiamond>() == null)
{
// You do not have a blue diamond needed to recharge the engraving tool.
from.SendLocalizedMessage(1076166);
return;
}
from.SendLocalizedMessage(1076163); // There are no charges left on this engraving tool.
from.SendGump(new ConfirmGump(this, null));
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (_isRewardItem)
{
list.Add(1076224); // 8th Year Veteran Reward
}
if (ShowUsesRemaining)
{
list.Add(1060584, _usesRemaining); // uses remaining: ~1_val~
}
}
public virtual void Recharge(Mobile from, Mobile guildmaster)
{
if (from.Backpack == null)
{
return;
}
var diamond = from.Backpack.FindItemByType<BlueDiamond>();
if (guildmaster != null)
{
if (_usesRemaining > 0)
{
m_IsRewardItem = value;
InvalidateProperties();
// I can only help with this if you are carrying an engraving tool that needs repair.s
guildmaster.Say(1076164);
}
}
[CommandProperty(AccessLevel.GameMaster)]
public int UsesRemaining
{
get => m_UsesRemaining;
set
else if (diamond != null && Banker.Withdraw(from, 100000))
{
m_UsesRemaining = value;
InvalidateProperties();
diamond.Consume();
UsesRemaining = 10;
guildmaster.Say(1076165); // Your weapon engraver should be good as new!
}
else
{
// You need a 100,000 gold and a blue diamond to recharge the weapon engraver.
guildmaster.Say(1076167);
}
return;
}
public bool ShowUsesRemaining
if (from.Skills.Tinkering.Value == 0)
{
get => true;
set { }
// Since you have no tinkering skill, you will need to find an NPC tinkerer to repair this for you.
from.SendLocalizedMessage(1076179);
return;
}
public override void OnDoubleClick(Mobile from)
if (from.Skills.Tinkering.Value < 75.0)
{
if (m_IsRewardItem && !RewardSystem.CheckIsUsableBy(from, this))
// Your tinkering skill is too low to fix this yourself. An NPC tinkerer can help you repair this for a fee.
from.SendLocalizedMessage(1076178);
return;
}
if (diamond == null)
{
// You do not have a blue diamond needed to recharge the engraving tool.
from.SendLocalizedMessage(1076166);
return;
}
diamond.Consume();
if (Utility.RandomDouble() < from.Skills.Tinkering.Value / 100)
{
UsesRemaining = 10;
from.SendLocalizedMessage(1076165); // Your weapon engraver should be good as new! ?????
}
else
{
// You cracked the diamond attempting to fix the weapon engraver.
from.SendLocalizedMessage(1076175);
}
}
public static WeaponEngravingTool Find(Mobile from) => from.Backpack?.FindItemByType<WeaponEngravingTool>();
private class TargetWeapon : Target
{
private readonly WeaponEngravingTool _tool;
public TargetWeapon(WeaponEngravingTool tool) : base(-1, true, TargetFlags.None) => _tool = tool;
protected override void OnTarget(Mobile from, object targeted)
{
if (_tool?.Deleted != false)
{
return;
}
if (m_UsesRemaining > 0)
if (targeted is BaseWeapon item)
{
from.SendLocalizedMessage(1072357); // Select an object to engrave.
from.Target = new TargetWeapon(this);
from.CloseGump<InternalGump>();
from.SendGump(new InternalGump(_tool, item));
}
else
{
if (from.Skills.Tinkering.Value == 0)
{
from.SendLocalizedMessage(
1076179
); // Since you have no tinkering skill, you will need to find an NPC tinkerer to repair this for you.
}
else if (from.Skills.Tinkering.Value < 75.0)
{
from.SendLocalizedMessage(
1076178
); // Your tinkering skill is too low to fix this yourself. An NPC tinkerer can help you repair this for a fee.
}
else
{
if (from.Backpack.FindItemByType<BlueDiamond>() != null)
{
from.SendGump(new ConfirmGump(this, null));
}
else
{
from.SendLocalizedMessage(
1076166
); // You do not have a blue diamond needed to recharge the engraving tool.
}
}
from.SendLocalizedMessage(1076163); // There are no charges left on this engraving tool.
}
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (m_IsRewardItem)
{
list.Add(1076224); // 8th Year Veteran Reward
}
if (ShowUsesRemaining)
{
list.Add(1060584, m_UsesRemaining); // uses remaining: ~1_val~
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
writer.Write(m_UsesRemaining);
writer.Write(m_IsRewardItem);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
m_UsesRemaining = reader.ReadInt();
m_IsRewardItem = reader.ReadBool();
}
public virtual void Recharge(Mobile from, Mobile guildmaster)
{
if (from.Backpack == null)
{
return;
}
var diamond = from.Backpack.FindItemByType<BlueDiamond>();
if (guildmaster != null)
{
if (m_UsesRemaining <= 0)
{
if (diamond != null && Banker.Withdraw(from, 100000))
{
diamond.Consume();
UsesRemaining = 10;
guildmaster.Say(1076165); // Your weapon engraver should be good as new!
}
else
{
guildmaster.Say(
1076167
); // You need a 100,000 gold and a blue diamond to recharge the weapon engraver.
}
}
else
{
guildmaster.Say(
1076164
); // I can only help with this if you are carrying an engraving tool that needs repair.
}
}
else
{
if (from.Skills.Tinkering.Value == 0)
{
from.SendLocalizedMessage(
1076179
); // Since you have no tinkering skill, you will need to find an NPC tinkerer to repair this for you.
}
else if (from.Skills.Tinkering.Value < 75.0)
{
from.SendLocalizedMessage(
1076178
); // Your tinkering skill is too low to fix this yourself. An NPC tinkerer can help you repair this for a fee.
}
else if (diamond != null)
{
diamond.Consume();
if (Utility.RandomDouble() < from.Skills.Tinkering.Value / 100)
{
UsesRemaining = 10;
from.SendLocalizedMessage(1076165); // Your weapon engraver should be good as new! ?????
}
else
{
from.SendLocalizedMessage(
1076175
); // You cracked the diamond attempting to fix the weapon engraver.
}
}
else
{
from.SendLocalizedMessage(
1076166
); // You do not have a blue diamond needed to recharge the engraving tool.
}
}
}
public static WeaponEngravingTool Find(Mobile from) => from.Backpack?.FindItemByType<WeaponEngravingTool>();
private class TargetWeapon : Target
{
private readonly WeaponEngravingTool m_Tool;
public TargetWeapon(WeaponEngravingTool tool) : base(-1, true, TargetFlags.None) => m_Tool = tool;
protected override void OnTarget(Mobile from, object targeted)
{
if (m_Tool?.Deleted != false)
{
return;
}
if (targeted is BaseWeapon item)
{
from.CloseGump<InternalGump>();
from.SendGump(new InternalGump(m_Tool, item));
}
else
{
from.SendLocalizedMessage(1072309); // The selected item cannot be engraved by this engraving tool.
}
}
}
private class InternalGump : Gump
{
private readonly BaseWeapon m_Target;
private readonly WeaponEngravingTool m_Tool;
public InternalGump(WeaponEngravingTool tool, BaseWeapon target) : base(0, 0)
{
m_Tool = tool;
m_Target = target;
Closable = true;
Disposable = true;
Draggable = true;
Resizable = false;
AddBackground(50, 50, 400, 300, 0xA28);
AddPage(0);
AddHtmlLocalized(50, 70, 400, 20, 1072359, 0x0); // <CENTER>Engraving Tool</CENTER>
AddHtmlLocalized(
75,
95,
350,
145,
1076229,
0x0,
true,
true
); // Please enter the text to add to the selected object. Leave the text area blank to remove any existing text. Removing text does not use a charge.
AddButton(125, 300, 0x81A, 0x81B, (int)Buttons.Okay);
AddButton(320, 300, 0x819, 0x818, (int)Buttons.Cancel);
AddImageTiled(75, 245, 350, 40, 0xDB0);
AddImageTiled(76, 245, 350, 2, 0x23C5);
AddImageTiled(75, 245, 2, 40, 0x23C3);
AddImageTiled(75, 285, 350, 2, 0x23C5);
AddImageTiled(425, 245, 2, 42, 0x23C3);
AddTextEntry(75, 245, 350, 40, 0x0, (int)Buttons.Text, "");
}
public override void OnResponse(NetState state, RelayInfo info)
{
if (m_Tool?.Deleted != false || m_Target?.Deleted != false)
{
return;
}
if (info.ButtonID != (int)Buttons.Okay)
{
state.Mobile.SendLocalizedMessage(1072363); // The object was not engraved.
return;
}
var relay = info.GetTextEntry((int)Buttons.Text);
if (relay == null)
{
return;
}
if (string.IsNullOrEmpty(relay.Text))
{
m_Target.EngravedText = null;
state.Mobile.SendLocalizedMessage(1072362); // You remove the engraving from the object.
}
else
{
m_Target.EngravedText =
Utility.FixHtml(relay.Text.Length > 64 ? relay.Text[..64] : relay.Text);
state.Mobile.SendLocalizedMessage(1072361); // You engraved the object.
m_Target.InvalidateProperties();
m_Tool.UsesRemaining -= 1;
m_Tool.InvalidateProperties();
}
}
private enum Buttons
{
Cancel,
Okay,
Text
}
}
public class ConfirmGump : Gump
{
private readonly WeaponEngravingTool m_Engraver;
private readonly Mobile m_Guildmaster;
public ConfirmGump(WeaponEngravingTool engraver, Mobile guildmaster) : base(200, 200)
{
m_Engraver = engraver;
m_Guildmaster = guildmaster;
Closable = false;
Disposable = true;
Draggable = true;
Resizable = false;
AddPage(0);
AddBackground(0, 0, 291, 133, 0x13BE);
AddImageTiled(5, 5, 280, 100, 0xA40);
if (guildmaster != null)
{
AddHtmlLocalized(
9,
9,
272,
100,
1076169,
0x7FFF
); // It will cost you 100,000 gold and a blue diamond to recharge your weapon engraver with 10 charges.
AddHtmlLocalized(195, 109, 120, 20, 1076172, 0x7FFF); // Recharge it
}
else
{
AddHtmlLocalized(
9,
9,
272,
100,
1076176,
0x7FFF
); // You will need a blue diamond to repair the tip of the engraver. A successful repair will give the engraver 10 charges.
AddHtmlLocalized(195, 109, 120, 20, 1076177, 0x7FFF); // Replace the tip.
}
AddButton(160, 107, 0xFB7, 0xFB8, (int)Buttons.Confirm);
AddButton(5, 107, 0xFB1, 0xFB2, (int)Buttons.Cancel);
AddHtmlLocalized(40, 109, 100, 20, 1060051, 0x7FFF); // CANCEL
}
public override void OnResponse(NetState state, RelayInfo info)
{
if (m_Engraver?.Deleted != false || info.ButtonID != (int)Buttons.Confirm)
{
return;
}
m_Engraver.Recharge(state.Mobile, m_Guildmaster);
}
private enum Buttons
{
Cancel,
Confirm
from.SendLocalizedMessage(1072309); // The selected item cannot be engraved by this engraving tool.
}
}
}
private class InternalGump : Gump
{
private readonly BaseWeapon _target;
private readonly WeaponEngravingTool _tool;
public InternalGump(WeaponEngravingTool tool, BaseWeapon target) : base(0, 0)
{
_tool = tool;
_target = target;
Closable = true;
Disposable = true;
Draggable = true;
Resizable = false;
AddBackground(50, 50, 400, 300, 0xA28);
AddPage(0);
AddHtmlLocalized(50, 70, 400, 20, 1072359, 0x0); // <CENTER>Engraving Tool</CENTER>
// Please enter the text to add to the selected object. Leave the text area blank to remove any existing text. Removing text does not use a charge.
AddHtmlLocalized(75, 95, 350, 145, 1076229, 0x0, true, true);
AddButton(125, 300, 0x81A, 0x81B, (int)Buttons.Okay);
AddButton(320, 300, 0x819, 0x818, (int)Buttons.Cancel);
AddImageTiled(75, 245, 350, 40, 0xDB0);
AddImageTiled(76, 245, 350, 2, 0x23C5);
AddImageTiled(75, 245, 2, 40, 0x23C3);
AddImageTiled(75, 285, 350, 2, 0x23C5);
AddImageTiled(425, 245, 2, 42, 0x23C3);
AddTextEntry(75, 245, 350, 40, 0x0, (int)Buttons.Text, "");
}
public override void OnResponse(NetState state, RelayInfo info)
{
if (_tool?.Deleted != false || _target?.Deleted != false)
{
return;
}
if (info.ButtonID != (int)Buttons.Okay)
{
state.Mobile.SendLocalizedMessage(1072363); // The object was not engraved.
return;
}
var relay = info.GetTextEntry((int)Buttons.Text);
if (relay == null)
{
return;
}
if (string.IsNullOrEmpty(relay.Text))
{
_target.EngravedText = null;
state.Mobile.SendLocalizedMessage(1072362); // You remove the engraving from the object.
}
else
{
_target.EngravedText =
Utility.FixHtml(relay.Text.Length > 64 ? relay.Text[..64] : relay.Text);
state.Mobile.SendLocalizedMessage(1072361); // You engraved the object.
_target.InvalidateProperties();
_tool.UsesRemaining -= 1;
_tool.InvalidateProperties();
}
}
private enum Buttons
{
Cancel,
Okay,
Text
}
}
public class ConfirmGump : Gump
{
private readonly WeaponEngravingTool _engraver;
private readonly Mobile _guildmaster;
public ConfirmGump(WeaponEngravingTool engraver, Mobile guildmaster) : base(200, 200)
{
_engraver = engraver;
_guildmaster = guildmaster;
Closable = false;
Disposable = true;
Draggable = true;
Resizable = false;
AddPage(0);
AddBackground(0, 0, 291, 133, 0x13BE);
AddImageTiled(5, 5, 280, 100, 0xA40);
if (guildmaster != null)
{
// It will cost you 100,000 gold and a blue diamond to recharge your weapon engraver with 10 charges.
AddHtmlLocalized(9, 9, 272, 100, 1076169, 0x7FFF);
AddHtmlLocalized(195, 109, 120, 20, 1076172, 0x7FFF); // Recharge it
}
else
{
// You will need a blue diamond to repair the tip of the engraver. A successful repair will give the engraver 10 charges.
AddHtmlLocalized(9, 9, 272, 100, 1076176, 0x7FFF);
AddHtmlLocalized(195, 109, 120, 20, 1076177, 0x7FFF); // Replace the tip.
}
AddButton(160, 107, 0xFB7, 0xFB8, (int)Buttons.Confirm);
AddButton(5, 107, 0xFB1, 0xFB2, (int)Buttons.Cancel);
AddHtmlLocalized(40, 109, 100, 20, 1060051, 0x7FFF); // CANCEL
}
public override void OnResponse(NetState state, RelayInfo info)
{
if (_engraver?.Deleted != false || info.ButtonID != (int)Buttons.Confirm)
{
return;
}
_engraver.Recharge(state.Mobile, _guildmaster);
}
private enum Buttons
{
Cancel,
Confirm
}
}
}

View file

@ -0,0 +1,14 @@
{
"version": 0,
"type": "Server.Items.AnkhOfSacrificeAddon",
"properties": [
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

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

View file

@ -0,0 +1,14 @@
{
"version": 0,
"type": "Server.Items.AnkhOfSacrificeDeed",
"properties": [
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,14 @@
{
"version": 0,
"type": "Server.Items.Banner",
"properties": [
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,14 @@
{
"version": 0,
"type": "Server.Items.BloodyPentagramAddon",
"properties": [
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

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

View file

@ -0,0 +1,14 @@
{
"version": 0,
"type": "Server.Items.BloodyPentagramDeed",
"properties": [
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,27 @@
{
"version": 1,
"type": "Server.Items.CannonAddon",
"properties": [
{
"name": "CannonDirection",
"type": "Server.Engines.Quests.Haven.CannonDirection",
"rule": "EnumMigrationRule"
},
{
"name": "Charges",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

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

View file

@ -0,0 +1,22 @@
{
"version": 0,
"type": "Server.Items.CannonDeed",
"properties": [
{
"name": "Charges",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,14 @@
{
"version": 0,
"type": "Server.Items.CommodityDeedBox",
"properties": [
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,14 @@
{
"version": 0,
"type": "Server.Items.ContestMiniHouse",
"properties": [
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,14 @@
{
"version": 0,
"type": "Server.Items.ContestMiniHouseDeed",
"properties": [
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,14 @@
{
"version": 0,
"type": "Server.Items.DecorativeShield",
"properties": [
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,14 @@
{
"version": 0,
"type": "Server.Items.DecorativeShieldDeed",
"properties": [
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,14 @@
{
"version": 0,
"type": "Server.Items.FlamingHead",
"properties": [
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,14 @@
{
"version": 0,
"type": "Server.Items.FlamingHeadDeed",
"properties": [
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,14 @@
{
"version": 0,
"type": "Server.Items.HangingSkeleton",
"properties": [
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,14 @@
{
"version": 0,
"type": "Server.Items.HangingSkeletonDeed",
"properties": [
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,43 @@
{
"version": 3,
"type": "Server.Items.MiningCart",
"properties": [
{
"name": "CartType",
"type": "Server.Items.MiningCartType",
"rule": "EnumMigrationRule"
},
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "Gems",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "Ore",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "LastResourceTime",
"type": "System.DateTime",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,30 @@
{
"version": 0,
"type": "Server.Items.MiningCartDeed",
"properties": [
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "Gems",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "Ore",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,14 @@
{
"version": 0,
"type": "Server.Items.MinotaurStatue",
"properties": [
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,14 @@
{
"version": 0,
"type": "Server.Items.MinotaurStatueDeed",
"properties": [
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,14 @@
{
"version": 0,
"type": "Server.Items.PottedCactusDeed",
"properties": [
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

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

View file

@ -0,0 +1,19 @@
{
"version": 0,
"type": "Server.Items.RewardBrazier",
"properties": [
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "Fire",
"type": "Server.Item",
"rule": "SerializableInterfaceMigrationRule"
}
]
}

View file

@ -0,0 +1,14 @@
{
"version": 0,
"type": "Server.Items.RewardBrazierDeed",
"properties": [
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,14 @@
{
"version": 0,
"type": "Server.Items.RewardPottedCactus",
"properties": [
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

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

View file

@ -0,0 +1,14 @@
{
"version": 0,
"type": "Server.Items.StoneAnkh",
"properties": [
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

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

View file

@ -0,0 +1,14 @@
{
"version": 0,
"type": "Server.Items.StoneAnkhDeed",
"properties": [
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,30 @@
{
"version": 1,
"type": "Server.Items.TreeStump",
"properties": [
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "Logs",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "LastChecked",
"type": "System.DateTime",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,22 @@
{
"version": 0,
"type": "Server.Items.TreeStumpDeed",
"properties": [
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "Logs",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,30 @@
{
"version": 0,
"type": "Server.Items.ValentinesCard",
"properties": [
{
"name": "LabelNumber",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "From",
"type": "string",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "To",
"type": "string",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

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

View file

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

View file

@ -0,0 +1,22 @@
{
"version": 0,
"type": "Server.Items.WallBanner",
"properties": [
{
"name": "East",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

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

View file

@ -0,0 +1,14 @@
{
"version": 0,
"type": "Server.Items.WallBannerDeed",
"properties": [
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,22 @@
{
"version": 0,
"type": "Server.Items.WeaponEngravingTool",
"properties": [
{
"name": "UsesRemaining",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}