fix: Moves ContextMenu out of core, streamlines code, fixes bugs (#1873)

## Summary
- Removes allocation of a `List<ContextMenuEntry>` every time a context menu is created.
- Moves packet/context menu creation logic out of the core
- Fixes tame entry

## BREAKING CHANGE
> [!Important]
> **Developer Note**
> ```cs
> public virtual void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
> ```
> and similar functions changed to
> ```cs
> public virtual void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
> ```
This commit is contained in:
Kamron Batman 2024-07-20 21:33:23 -07:00 • committed by GitHub
parent bb24b330e1
commit f58117a877
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
88 changed files with 1206 additions and 1483 deletions

View file

@ -162,7 +162,7 @@ namespace Server.Items
/*
public override void GetProperties(IPropertyList list) => _addon?.GetProperties(list);
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list) =>
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list) =>
_addon?.GetContextMenuEntries(from, list);
*/
public override void OnAfterDelete()

View file

@ -1,7 +1,7 @@
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Network;
@ -79,8 +79,8 @@ namespace Server.Items
public override void GetProperties(IPropertyList list) => _addon?.GetProperties(list);
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list) =>
_addon?.GetContextMenuEntries(from, list);
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list) =>
_addon?.GetContextMenuEntries(from, ref list);
public override void OnAfterDelete()
{

View file

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Multis;
using Server.Network;
@ -438,40 +439,40 @@ namespace Server.Items
}
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
base.GetContextMenuEntries(from, ref list);
if (from.Alive)
{
list.Add(new ExamineEntry(this));
list.Add(new ExamineEntry());
if (HasAccess(from))
{
if (_rewardAvailable)
{
list.Add(new CollectRewardEntry(this));
list.Add(new CollectRewardEntry());
}
if (_events.Count > 0)
{
list.Add(new ViewEventEntry(this));
list.Add(new ViewEventEntry());
}
if (_vacationLeft > 0)
{
list.Add(new CancelVacationMode(this));
list.Add(new CancelVacationMode());
}
}
}
if (from.AccessLevel >= AccessLevel.GameMaster)
{
list.Add(new GMAddFood(this));
list.Add(new GMAddWater(this));
list.Add(new GMForceEvaluate(this));
list.Add(new GMOpen(this));
list.Add(new GMFill(this));
list.Add(new GMAddFood());
list.Add(new GMAddWater());
list.Add(new GMForceEvaluate());
list.Add(new GMOpen());
list.Add(new GMFill());
}
}
@ -982,177 +983,171 @@ namespace Server.Items
private class ExamineEntry : ContextMenuEntry
{
private readonly Aquarium m_Aquarium;
public ExamineEntry(Aquarium aquarium) : base(6235, 2) // Examine Aquarium
=>
m_Aquarium = aquarium;
public override void OnClick()
public ExamineEntry() : base(6235, 2)
{
if (m_Aquarium.Deleted)
}
public override void OnClick(Mobile from, IEntity target)
{
if (!from.Alive || target is not Aquarium aquarium || aquarium.Deleted)
{
return;
}
m_Aquarium.ExamineAquarium(Owner.From);
aquarium.ExamineAquarium(from);
}
}
private class CollectRewardEntry : ContextMenuEntry
{
private readonly Aquarium m_Aquarium;
public CollectRewardEntry(Aquarium aquarium) : base(6237, 2) // Collect Reward
=>
m_Aquarium = aquarium;
public override void OnClick()
public CollectRewardEntry() : base(6237, 2)
{
if (m_Aquarium.Deleted || !m_Aquarium.HasAccess(Owner.From))
}
public override void OnClick(Mobile from, IEntity target)
{
if (!from.Alive || target is not Aquarium aquarium || aquarium.Deleted)
{
return;
}
m_Aquarium.GiveReward(Owner.From);
aquarium.GiveReward(from);
}
}
private class ViewEventEntry : ContextMenuEntry
{
private readonly Aquarium m_Aquarium;
public ViewEventEntry(Aquarium aquarium) : base(6239, 2) // View events
=>
m_Aquarium = aquarium;
public override void OnClick()
public ViewEventEntry() : base(6239, 2)
{
if (m_Aquarium.Deleted || !m_Aquarium.HasAccess(Owner.From) || m_Aquarium._events.Count == 0)
}
public override void OnClick(Mobile from, IEntity target)
{
if (!from.Alive || target is not Aquarium aquarium || aquarium.Deleted || aquarium.HasAccess(from) ||
aquarium._events.Count == 0)
{
return;
}
Owner.From.SendLocalizedMessage(m_Aquarium.Events[0]);
var firstEvent = aquarium.Events[0];
from.SendLocalizedMessage(firstEvent);
if (m_Aquarium.Events[0] == 1074366)
if (firstEvent == 1074366)
{
Owner.From.PlaySound(0x5A2);
from.PlaySound(0x5A2);
}
m_Aquarium.RemoveFromEventsAt(0);
m_Aquarium.InvalidateProperties();
aquarium.RemoveFromEventsAt(0);
aquarium.InvalidateProperties();
}
}
private class CancelVacationMode : ContextMenuEntry
{
private readonly Aquarium m_Aquarium;
public CancelVacationMode(Aquarium aquarium) : base(6240, 2) // Cancel vacation mode
=>
m_Aquarium = aquarium;
public override void OnClick()
public CancelVacationMode() : base(6240, 2)
{
if (m_Aquarium.Deleted || !m_Aquarium.HasAccess(Owner.From))
}
public override void OnClick(Mobile from, IEntity target)
{
if (!from.Alive || target is not Aquarium aquarium || aquarium.Deleted || aquarium.HasAccess(from))
{
return;
}
Owner.From.SendLocalizedMessage(1074429); // Vacation mode has been cancelled.
m_Aquarium.VacationLeft = 0;
m_Aquarium.InvalidateProperties();
from.SendLocalizedMessage(1074429); // Vacation mode has been cancelled.
aquarium.VacationLeft = 0;
aquarium.InvalidateProperties();
}
}
// GM context entries
private class GMAddFood : ContextMenuEntry
{
private readonly Aquarium m_Aquarium;
public GMAddFood(Aquarium aquarium) : base(6231) => m_Aquarium = aquarium;
public override void OnClick()
public GMAddFood() : base(6231)
{
if (m_Aquarium.Deleted)
}
public override void OnClick(Mobile from, IEntity target)
{
if (from.AccessLevel < AccessLevel.GameMaster || target is not Aquarium aquarium || aquarium.Deleted)
{
return;
}
m_Aquarium.Food.Added += 1;
m_Aquarium.InvalidateProperties();
aquarium.Food.Added += 1;
aquarium.InvalidateProperties();
}
}
private class GMAddWater : ContextMenuEntry
{
private readonly Aquarium m_Aquarium;
public GMAddWater(Aquarium aquarium) : base(6232) => m_Aquarium = aquarium;
public override void OnClick()
public GMAddWater() : base(6232)
{
if (m_Aquarium.Deleted)
}
public override void OnClick(Mobile from, IEntity target)
{
if (from.AccessLevel < AccessLevel.GameMaster || target is not Aquarium aquarium || aquarium.Deleted)
{
return;
}
m_Aquarium.Water.Added += 1;
m_Aquarium.InvalidateProperties();
aquarium.Water.Added += 1;
aquarium.InvalidateProperties();
}
}
private class GMForceEvaluate : ContextMenuEntry
{
private readonly Aquarium m_Aquarium;
public GMForceEvaluate(Aquarium aquarium) : base(6233) => m_Aquarium = aquarium;
public override void OnClick()
public GMForceEvaluate() : base(6233)
{
if (m_Aquarium.Deleted)
}
public override void OnClick(Mobile from, IEntity target)
{
if (from.AccessLevel < AccessLevel.GameMaster || target is not Aquarium aquarium || aquarium.Deleted)
{
return;
}
m_Aquarium.Evaluate();
aquarium.Evaluate();
}
}
private class GMOpen : ContextMenuEntry
{
private readonly Aquarium m_Aquarium;
public GMOpen(Aquarium aquarium) : base(6234) => m_Aquarium = aquarium;
public override void OnClick()
public GMOpen() : base(6234)
{
if (m_Aquarium.Deleted)
}
public override void OnClick(Mobile from, IEntity target)
{
if (from.AccessLevel < AccessLevel.GameMaster || target is not Aquarium aquarium || aquarium.Deleted)
{
return;
}
Owner.From.SendGump(new AquariumGump(m_Aquarium, true));
from.SendGump(new AquariumGump(aquarium, true));
}
}
private class GMFill : ContextMenuEntry
{
private readonly Aquarium m_Aquarium;
public GMFill(Aquarium aquarium) : base(6236) => m_Aquarium = aquarium;
public override void OnClick()
public GMFill() : base(6236)
{
if (m_Aquarium.Deleted)
}
public override void OnClick(Mobile from, IEntity target)
{
if (from.AccessLevel < AccessLevel.GameMaster || target is not Aquarium aquarium || aquarium.Deleted)
{
return;
}
m_Aquarium.Food.Added = m_Aquarium.Food.Maintain;
m_Aquarium.Water.Added = m_Aquarium.Water.Maintain;
m_Aquarium.InvalidateProperties();
aquarium.Food.Added = aquarium.Food.Maintain;
aquarium.Water.Added = aquarium.Water.Maintain;
aquarium.InvalidateProperties();
}
}
}

View file

@ -1,5 +1,5 @@
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Network;
@ -93,30 +93,30 @@ namespace Server.Items
}
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
base.GetContextMenuEntries(from, ref list);
if (!Empty && IsAccessibleTo(from))
{
list.Add(new RemoveCreature(this));
list.Add(new RemoveCreature());
}
}
private class RemoveCreature : ContextMenuEntry
{
private readonly FishBowl m_Bowl;
public RemoveCreature(FishBowl bowl) : base(6242, 3) => m_Bowl = bowl;
public override void OnClick()
public RemoveCreature() : base(6242, 3)
{
if (m_Bowl?.Deleted != false || !m_Bowl.IsAccessibleTo(Owner.From))
}
public override void OnClick(Mobile from, IEntity target)
{
if (target is not FishBowl { Deleted: false } bowl || !bowl.IsAccessibleTo(from))
{
return;
}
var fish = m_Bowl.Fish;
var fish = bowl.Fish;
if (fish == null)
{
@ -125,17 +125,17 @@ namespace Server.Items
if (fish.IsLockedDown) // for legacy fish bowls
{
Owner.From.SendLocalizedMessage(1010449); // You may not use this object while it is locked down.
from.SendLocalizedMessage(1010449); // You may not use this object while it is locked down.
}
else if (!Owner.From.PlaceInBackpack(fish))
else if (!from.PlaceInBackpack(fish))
{
Owner.From.SendLocalizedMessage(1074496); // There is no room in your pack for the creature.
from.SendLocalizedMessage(1074496); // There is no room in your pack for the creature.
}
else
{
Owner.From.SendLocalizedMessage(1074495); // The creature has been removed from the fish bowl.
from.SendLocalizedMessage(1074495); // The creature has been removed from the fish bowl.
fish.StartTimer();
m_Bowl.InvalidateProperties();
bowl.InvalidateProperties();
}
}
}

View file

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Gumps;
using Server.Multis;
@ -151,10 +152,10 @@ namespace Server.Items
}
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
SetSecureLevelEntry.AddTo(from, this, list);
base.GetContextMenuEntries(from, ref list);
SetSecureLevelEntry.AddTo(from, this, ref list);
}
private void Deserialize(IGenericReader reader, int version)

View file

@ -1,5 +1,5 @@
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Gumps;
using Server.Mobiles;
@ -12,18 +12,18 @@ namespace Server.Items
public const int TitheRange = 2;
public const int LockRange = 2;
public static void GetContextMenuEntries(Mobile from, Item item, List<ContextMenuEntry> list)
public static void GetContextMenuEntries(Mobile from, Item item, ref PooledRefList<ContextMenuEntry> list)
{
if (from is PlayerMobile mobile)
{
list.Add(new LockKarmaEntry(mobile));
list.Add(new LockKarmaEntry(mobile.KarmaLocked));
}
list.Add(new ResurrectEntry(from, item));
list.Add(new ResurrectEntry(from.Alive));
if (Core.AOS)
{
list.Add(new TitheEntry(from));
list.Add(new TitheEntry(from.Alive));
}
}
@ -51,62 +51,58 @@ namespace Server.Items
private class ResurrectEntry : ContextMenuEntry
{
private readonly Item _item;
private readonly Mobile _mobile;
public ResurrectEntry(bool enabled) : base(6195, ResurrectRange) => Enabled = enabled;
public ResurrectEntry(Mobile mobile, Item item) : base(6195, ResurrectRange)
public override void OnClick(Mobile from, IEntity target)
{
_mobile = mobile;
_item = item;
Enabled = !_mobile.Alive;
}
public override void OnClick()
{
Resurrect(_mobile, _item);
if (target is Item item)
{
Resurrect(from, item);
}
}
}
private class LockKarmaEntry : ContextMenuEntry
public class LockKarmaEntry : ContextMenuEntry
{
private readonly PlayerMobile _mobile;
public LockKarmaEntry(PlayerMobile mobile) : base(mobile.KarmaLocked ? 6197 : 6196, LockRange) =>
_mobile = mobile;
public override void OnClick()
public LockKarmaEntry(bool karmaLocked) : base(karmaLocked ? 6197 : 6196, LockRange)
{
_mobile.KarmaLocked = !_mobile.KarmaLocked;
}
if (_mobile.KarmaLocked)
public override void OnClick(Mobile from, IEntity target)
{
if (from is not PlayerMobile pm || target is not Item item)
{
return;
}
if (!from.InRange(item.GetWorldLocation(), 2))
{
from.SendLocalizedMessage(500446); // That is too far away.
}
pm.KarmaLocked = !pm.KarmaLocked;
if (pm.KarmaLocked)
{
// Your karma has been locked. Your karma can no longer be raised.
_mobile.SendLocalizedMessage(1060192);
pm.SendLocalizedMessage(1060192);
}
else
{
_mobile.SendLocalizedMessage(1060191); // Your karma has been unlocked. Your karma can be raised again.
pm.SendLocalizedMessage(1060191); // Your karma has been unlocked. Your karma can be raised again.
}
}
}
private class TitheEntry : ContextMenuEntry
{
private readonly Mobile _mobile;
public TitheEntry(bool enabled) : base(6198, TitheRange) => Enabled = enabled;
public TitheEntry(Mobile mobile) : base(6198, TitheRange)
public override void OnClick(Mobile from, IEntity target)
{
_mobile = mobile;
Enabled = _mobile.Alive;
}
public override void OnClick()
{
if (_mobile.CheckAlive())
if (from.CheckAlive())
{
_mobile.SendGump(new TithingGump(_mobile));
from.SendGump(new TithingGump(from));
}
}
}
@ -150,10 +146,10 @@ namespace Server.Items
}
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
Ankhs.GetContextMenuEntries(from, this, list);
base.GetContextMenuEntries(from, ref list);
Ankhs.GetContextMenuEntries(from, this, ref list);
}
public override void OnDoubleClickDead(Mobile m)
@ -244,10 +240,10 @@ namespace Server.Items
}
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
Ankhs.GetContextMenuEntries(from, this, list);
base.GetContextMenuEntries(from, ref list);
Ankhs.GetContextMenuEntries(from, this, ref list);
}
public override void OnDoubleClickDead(Mobile m)
@ -297,10 +293,10 @@ namespace Server.Items
}
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
Ankhs.GetContextMenuEntries(from, this, list);
base.GetContextMenuEntries(from, ref list);
Ankhs.GetContextMenuEntries(from, this, ref list);
}
public override void OnDoubleClickDead(Mobile m)
@ -393,10 +389,10 @@ namespace Server.Items
}
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
Ankhs.GetContextMenuEntries(from, this, list);
base.GetContextMenuEntries(from, ref list);
Ankhs.GetContextMenuEntries(from, this, ref list);
}
public override void OnDoubleClickDead(Mobile m)

View file

@ -1,5 +1,5 @@
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Gumps;
using Server.Multis;
@ -74,10 +74,10 @@ public abstract partial class BaseHouseDoor : BaseDoor, ISecurable
_level = SecureLevel.Anyone;
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
SetSecureLevelEntry.AddTo(from, this, list);
base.GetContextMenuEntries(from, ref list);
SetSecureLevelEntry.AddTo(from, this, ref list);
}
public BaseHouse FindHouse()

View file

@ -1,5 +1,5 @@
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Mobiles;
using Server.Multis;
@ -41,10 +41,10 @@ public abstract class BaseContainer : Container
return base.CheckItemUse(from, item);
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
SetSecureLevelEntry.AddTo(from, this, list);
base.GetContextMenuEntries(from, ref list);
SetSecureLevelEntry.AddTo(from, this, ref list);
}
public override bool TryDropItem(Mobile from, Item dropped, bool sendFullMessage)

View file

@ -1,9 +1,8 @@
using System;
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Engines.Craft;
using Server.Network;
namespace Server.Items;
@ -27,18 +26,18 @@ public partial class SalvageBag : Bag
public override int LabelNumber => 1079931; // Salvage Bag
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
base.GetContextMenuEntries(from, ref list);
if (from.Alive)
{
var inBackpack = IsChildOf(from.Backpack);
var resmeltables = inBackpack && Resmeltables();
var scissorables = inBackpack && Scissorables();
list.Add(new SalvageIngotsEntry(this, resmeltables));
list.Add(new SalvageClothEntry(this, scissorables));
list.Add(new SalvageAllEntry(this, resmeltables && scissorables));
list.Add(new SalvageIngotsEntry(resmeltables));
list.Add(new SalvageClothEntry(scissorables));
list.Add(new SalvageAllEntry(resmeltables && scissorables));
}
}
@ -287,90 +286,39 @@ public partial class SalvageBag : Bag
private class SalvageAllEntry : ContextMenuEntry
{
private readonly SalvageBag m_Bag;
public SalvageAllEntry(bool enabled) : base(6276) => Enabled = enabled;
public SalvageAllEntry(SalvageBag bag, bool enabled) : base(6276)
public override void OnClick(Mobile from, IEntity target)
{
m_Bag = bag;
if (!enabled)
if (from.CheckAlive() && target is SalvageBag { Deleted: false } bag)
{
Flags |= CMEFlags.Disabled;
}
}
public override void OnClick()
{
if (m_Bag.Deleted)
{
return;
}
var from = Owner.From;
if (from.CheckAlive())
{
m_Bag.SalvageAll(from);
bag.SalvageAll(from);
}
}
}
private class SalvageIngotsEntry : ContextMenuEntry
{
private readonly SalvageBag m_Bag;
public SalvageIngotsEntry(bool enabled) : base(6277) => Enabled = enabled;
public SalvageIngotsEntry(SalvageBag bag, bool enabled) : base(6277)
public override void OnClick(Mobile from, IEntity target)
{
m_Bag = bag;
if (!enabled)
if (from.CheckAlive() && target is SalvageBag { Deleted: false } bag)
{
Flags |= CMEFlags.Disabled;
}
}
public override void OnClick()
{
if (m_Bag.Deleted)
{
return;
}
var from = Owner.From;
if (from.CheckAlive())
{
m_Bag.SalvageIngots(from);
bag.SalvageIngots(from);
}
}
}
private class SalvageClothEntry : ContextMenuEntry
{
private readonly SalvageBag m_Bag;
public SalvageClothEntry(bool enabled) : base(6278) => Enabled = enabled;
public SalvageClothEntry(SalvageBag bag, bool enabled) : base(6278)
public override void OnClick(Mobile from, IEntity target)
{
m_Bag = bag;
if (!enabled)
if (from.CheckAlive() && target is SalvageBag { Deleted: false } bag)
{
Flags |= CMEFlags.Disabled;
}
}
public override void OnClick()
{
if (m_Bag.Deleted)
{
return;
}
var from = Owner.From;
if (from.CheckAlive())
{
m_Bag.SalvageCloth(from);
bag.SalvageCloth(from);
}
}
}

View file

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Engines.PartySystem;
using Server.Gumps;
@ -415,13 +416,13 @@ public partial class TreasureMapChest : LockableContainer
base.OnAfterDelete();
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
base.GetContextMenuEntries(from, ref list);
if (from.Alive)
{
list.Add(new RemoveEntry(from, this));
list.Add(new RemoveEntry(from == _owner));
}
}
@ -487,25 +488,16 @@ public partial class TreasureMapChest : LockableContainer
private class RemoveEntry : ContextMenuEntry
{
private readonly TreasureMapChest _chest;
private readonly Mobile _from;
public RemoveEntry(bool enabled) : base(6149, 3) => Enabled = enabled;
public RemoveEntry(Mobile from, TreasureMapChest chest) : base(6149, 3)
public override void OnClick(Mobile from, IEntity target)
{
_from = from;
_chest = chest;
Enabled = from == chest._owner;
}
public override void OnClick()
{
if (_chest.Deleted || _from != _chest._owner || !_from.CheckAlive())
if (!from.CheckAlive() || target is not TreasureMapChest chest || chest.Deleted || from != chest._owner)
{
return;
}
_chest.BeginRemove(_from);
chest.BeginRemove(from);
}
}
}

View file

@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Gumps;
using Server.Mobiles;
@ -205,13 +205,13 @@ public partial class VendorRentalContract : Item
}
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
base.GetContextMenuEntries(from, ref list);
if (IsUsableBy(from, true, true, true, false))
{
list.Add(new ContractOptionEntry(this));
list.Add(new ContractOptionEntry());
}
}
@ -224,18 +224,16 @@ public partial class VendorRentalContract : Item
private class ContractOptionEntry : ContextMenuEntry
{
private readonly VendorRentalContract m_Contract;
public ContractOptionEntry(VendorRentalContract contract) : base(6209) => m_Contract = contract;
public override void OnClick()
public ContractOptionEntry() : base(6209)
{
var from = Owner.From;
}
if (m_Contract.IsUsableBy(from, true, true, true, true))
public override void OnClick(Mobile from, IEntity target)
{
if (target is VendorRentalContract contract && contract.IsUsableBy(from, true, true, true, true))
{
from.CloseGump<VendorRentalContractGump>();
from.SendGump(new VendorRentalContractGump(m_Contract, from));
from.SendGump(new VendorRentalContractGump(contract, from));
}
}
}

View file

@ -1,5 +1,5 @@
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
namespace Server.Items;
@ -26,13 +26,13 @@ public abstract partial class Food : Item
FillFactor = 1;
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
base.GetContextMenuEntries(from, ref list);
if (from.Alive)
{
list.Add(new EatEntry(from, this));
list.Add(new EatEntry());
}
}

View file

@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Gumps;
using Server.Multis;
@ -86,16 +86,16 @@ public abstract partial class BaseBoard : Container, ISecurable
return false;
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
base.GetContextMenuEntries(from, ref list);
if (ValidateDefault(from, this))
{
list.Add(new DefaultEntry(from, this));
list.Add(new DefaultEntry(from.AccessLevel >= AccessLevel.GameMaster ? -1 : 1));
}
SetSecureLevelEntry.AddTo(from, this, list);
SetSecureLevelEntry.AddTo(from, this, ref list);
}
public static bool ValidateDefault(Mobile from, BaseBoard board) =>
@ -106,23 +106,15 @@ public abstract partial class BaseBoard : Container, ISecurable
public class DefaultEntry : ContextMenuEntry
{
private readonly BaseBoard m_Board;
private readonly Mobile m_From;
public DefaultEntry(Mobile from, BaseBoard board) : base(
6162,
from.AccessLevel >= AccessLevel.GameMaster ? -1 : 1
)
public DefaultEntry(int range) : base(6162, range)
{
m_From = from;
m_Board = board;
}
public override void OnClick()
public override void OnClick(Mobile from, IEntity target)
{
if (ValidateDefault(m_From, m_Board))
if (target is BaseBoard board && ValidateDefault(from, board))
{
m_Board.Reset();
board.Reset();
}
}
}

View file

@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Gumps;
using Server.Multis;
@ -187,18 +187,18 @@ public partial class MahjongGame : Item, ISecurable
}
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
base.GetContextMenuEntries(from, ref list);
_players.CheckPlayers();
if (from.Alive && IsAccessibleTo(from) && _players.GetInGameMobiles(true, false).Count == 0)
{
list.Add(new ResetGameEntry(this));
list.Add(new ResetGameEntry());
}
SetSecureLevelEntry.AddTo(from, this, list);
SetSecureLevelEntry.AddTo(from, this, ref list);
}
public override void OnDoubleClick(Mobile from)
@ -299,18 +299,16 @@ public partial class MahjongGame : Item, ISecurable
private class ResetGameEntry : ContextMenuEntry
{
private readonly MahjongGame _game;
public ResetGameEntry(MahjongGame game) : base(6162) => _game = game;
public override void OnClick()
public ResetGameEntry() : base(6162)
{
var from = Owner.From;
}
if (from.CheckAlive() && !_game.Deleted && _game.IsAccessibleTo(from) &&
_game.Players.GetInGameMobiles(true, false).Count == 0)
public override void OnClick(Mobile from, IEntity target)
{
if (from.CheckAlive() && target is MahjongGame { Deleted: false } game && game.IsAccessibleTo(from) &&
game.Players.GetInGameMobiles(true, false).Count == 0)
{
_game.ResetGame(from);
game.ResetGame(from);
}
}
}

View file

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Engines.Harvest;
using Server.Mobiles;
@ -454,22 +455,20 @@ public partial class TreasureMap : MapItem
base.DisplayTo(from);
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
base.GetContextMenuEntries(from, ref list);
if (!_completed)
{
if (_decoder == null)
{
list.Add(new DecodeMapEntry(this));
list.Add(new DecodeMapEntry());
}
else
{
var digTool = HasDiggingTool(from);
list.Add(new OpenMapEntry(this));
list.Add(new DigEntry(this, digTool));
list.Add(new OpenMapEntry());
list.Add(new DigEntry(HasDiggingTool(from)));
}
}
}
@ -842,65 +841,52 @@ public partial class TreasureMap : MapItem
private class DecodeMapEntry : ContextMenuEntry
{
private readonly TreasureMap m_Map;
public DecodeMapEntry(TreasureMap map) : base(6147, 2) => m_Map = map;
public override void OnClick()
public DecodeMapEntry() : base(6147, 2)
{
if (!m_Map.Deleted)
}
public override void OnClick(Mobile from, IEntity target)
{
if (target is TreasureMap { Deleted: false } map)
{
m_Map.Decode(Owner.From);
map.Decode(from);
}
}
}
private class OpenMapEntry : ContextMenuEntry
{
private readonly TreasureMap m_Map;
public OpenMapEntry(TreasureMap map) : base(6150, 2) => m_Map = map;
public override void OnClick()
public OpenMapEntry() : base(6150, 2)
{
if (!m_Map.Deleted)
}
public override void OnClick(Mobile from, IEntity target)
{
if (target is TreasureMap { Deleted: false } map)
{
m_Map.DisplayTo(Owner.From);
map.DisplayTo(from);
}
}
}
private class DigEntry : ContextMenuEntry
{
private readonly TreasureMap m_Map;
public DigEntry(bool enabled) : base(6148, 2) => Enabled = enabled;
public DigEntry(TreasureMap map, bool enabled) : base(6148, 2)
public override void OnClick(Mobile from, IEntity target)
{
m_Map = map;
if (!enabled)
{
Flags |= CMEFlags.Disabled;
}
}
public override void OnClick()
{
if (m_Map.Deleted)
if (target is not TreasureMap { Deleted: false } map)
{
return;
}
var from = Owner.From;
if (HasDiggingTool(from))
{
m_Map.OnBeginDig(from);
}
else
if (!HasDiggingTool(from))
{
from.SendLocalizedMessage(1114416); // You must have a digging tool to dig for treasure.
return;
}
map.OnBeginDig(from);
}
}
}

View file

@ -696,9 +696,9 @@ public partial class Corpse : Container, ICarvable
_instancedItems?.Remove(item);
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
base.GetContextMenuEntries(from, ref list);
if (Core.AOS && _owner == from && from.Alive)
{
@ -1050,11 +1050,11 @@ public partial class Corpse : Container, ICarvable
{
}
public override void OnClick()
public override void OnClick(Mobile from, IEntity target)
{
if (Owner.Target is Corpse corpse && Owner.From.CheckAlive())
if (from.CheckAlive() && target is Corpse corpse)
{
corpse.Open(Owner.From, false);
corpse.Open(from, false);
}
}
}

View file

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Gumps;
using Server.Mobiles;
@ -75,10 +76,10 @@ public abstract partial class BasePlayerBB : Item, ISecurable
}
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
SetSecureLevelEntry.AddTo(from, this, list);
base.GetContextMenuEntries(from, ref list);
SetSecureLevelEntry.AddTo(from, this, ref list);
}
public static bool CheckAccess(BaseHouse house, Mobile from)

View file

@ -1,5 +1,5 @@
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Engines.Harvest;
@ -29,11 +29,11 @@ public partial class FishingPole : Item
}
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
base.GetContextMenuEntries(from, ref list);
BaseHarvestTool.AddContextMenuEntries(from, this, list, Fishing.System);
BaseHarvestTool.AddContextMenuEntries(from, this, ref list, Fishing.System);
}
public override bool CheckConflictingLayer(Mobile m, Item item, Layer layer)

View file

@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Engines.Craft;
using Server.Engines.Harvest;
@ -125,14 +125,14 @@ public abstract partial class BaseHarvestTool : Item, IUsesRemaining, ICraftable
}
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
base.GetContextMenuEntries(from, ref list);
AddContextMenuEntries(from, this, list, HarvestSystem);
AddContextMenuEntries(from, this, ref list, HarvestSystem);
}
public static void AddContextMenuEntries(Mobile from, Item item, List<ContextMenuEntry> list, HarvestSystem system)
public static void AddContextMenuEntries(Mobile from, Item item, ref PooledRefList<ContextMenuEntry> list, HarvestSystem system)
{
if (system != Mining.System)
{
@ -149,12 +149,14 @@ public abstract partial class BaseHarvestTool : Item, IUsesRemaining, ICraftable
return;
}
var miningEntry = new ContextMenuEntry(pm.ToggleMiningStone ? 6179 : 6178);
miningEntry.Color = 0x421F;
list.Add(miningEntry);
list.Add(new ContextMenuEntry(pm.ToggleMiningStone ? 6179 : 6178)
{
Color = 0x421F
});
list.Add(new ToggleMiningStoneEntry(pm, false, 6176));
list.Add(new ToggleMiningStoneEntry(pm, true, 6177));
var stoneMining = pm.StoneMining && pm.Skills.Mining.Base >= 100.0;
list.Add(new ToggleMiningStoneEntry(false, pm.ToggleMiningStone, 6176));
list.Add(new ToggleMiningStoneEntry(true, !pm.ToggleMiningStone && stoneMining, 6177));
}
private void Deserialize(IGenericReader reader, int version)
@ -178,51 +180,48 @@ public abstract partial class BaseHarvestTool : Item, IUsesRemaining, ICraftable
private class ToggleMiningStoneEntry : ContextMenuEntry
{
private PlayerMobile _mobile;
private bool _value;
private readonly bool _value;
public ToggleMiningStoneEntry(PlayerMobile mobile, bool value, int number) : base(number)
public ToggleMiningStoneEntry(bool value, bool enabled, int number) : base(number)
{
_mobile = mobile;
_value = value;
var stoneMining = mobile.StoneMining && mobile.Skills.Mining.Base >= 100.0;
if (mobile.ToggleMiningStone == value || value && !stoneMining)
{
Flags |= CMEFlags.Disabled;
}
Enabled = enabled;
}
public override void OnClick()
public override void OnClick(Mobile from, IEntity target)
{
var oldValue = _mobile.ToggleMiningStone;
if (from is not PlayerMobile pm)
{
return;
}
var oldValue = pm.ToggleMiningStone;
if (_value)
{
if (oldValue)
{
_mobile.SendLocalizedMessage(1054023); // You are already set to mine both ore and stone!
pm.SendLocalizedMessage(1054023); // You are already set to mine both ore and stone!
}
else if (!_mobile.StoneMining || _mobile.Skills.Mining.Base < 100.0)
else if (!pm.StoneMining || pm.Skills.Mining.Base < 100.0)
{
// You have not learned how to mine stone or you do not have enough skill!
_mobile.SendLocalizedMessage(1054024);
pm.SendLocalizedMessage(1054024);
}
else
{
_mobile.ToggleMiningStone = true;
_mobile.SendLocalizedMessage(1054022); // You are now set to mine both ore and stone.
pm.ToggleMiningStone = true;
pm.SendLocalizedMessage(1054022); // You are now set to mine both ore and stone.
}
}
else if (oldValue)
{
_mobile.ToggleMiningStone = false;
_mobile.SendLocalizedMessage(1054020); // You are now set to mine only ore.
pm.ToggleMiningStone = false;
pm.SendLocalizedMessage(1054020); // You are now set to mine only ore.
}
else
{
_mobile.SendLocalizedMessage(1054021); // You are already set to mine only ore!
pm.SendLocalizedMessage(1054021); // You are already set to mine only ore!
}
}
}

View file

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Engines.Craft;
using Server.Gumps;
@ -113,10 +114,10 @@ public partial class Runebook : Item, ISecurable, ICraftable
public override bool AllowEquippedCast(Mobile from) => true;
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
SetSecureLevelEntry.AddTo(from, this, list);
base.GetContextMenuEntries(from, ref list);
SetSecureLevelEntry.AddTo(from, this, ref list);
}
private void Deserialize(IGenericReader reader, int version)

View file

@ -1,5 +1,5 @@
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Multis;
using Server.Spells;
@ -25,9 +25,9 @@ public partial class SpellScroll : Item, ICommodity
int ICommodity.DescriptionNumber => LabelNumber;
bool ICommodity.IsDeedable => Core.ML;
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
base.GetContextMenuEntries(from, ref list);
if (from.Alive && Movable)
{

View file

@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Mobiles;
@ -79,14 +79,14 @@ public partial class Fukiya : Item, INinjaWeapon
NinjaWeapon.AttemptShoot((PlayerMobile)from, this);
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
base.GetContextMenuEntries(from, ref list);
if (IsChildOf(from))
{
list.Add(new NinjaWeapon.LoadEntry(this, 6224));
list.Add(new NinjaWeapon.UnloadEntry(this, 6225));
list.Add(new NinjaWeapon.LoadEntry(6224));
list.Add(new NinjaWeapon.UnloadEntry(6225, UsesRemaining > 0));
}
}
}

View file

@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Mobiles;
@ -92,14 +92,14 @@ public partial class LeatherNinjaBelt : BaseWaist, INinjaWeapon
NinjaWeapon.AttemptShoot((PlayerMobile)from, this);
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
base.GetContextMenuEntries(from, ref list);
if (IsChildOf(from))
{
list.Add(new NinjaWeapon.LoadEntry(this, 6222));
list.Add(new NinjaWeapon.UnloadEntry(this, 6223));
list.Add(new NinjaWeapon.LoadEntry(6222));
list.Add(new NinjaWeapon.UnloadEntry(6223, UsesRemaining > 0));
}
}
}

View file

@ -329,39 +329,29 @@ public static class NinjaWeapon
public class LoadEntry : ContextMenuEntry
{
private readonly INinjaWeapon weapon;
public LoadEntry(INinjaWeapon wep, int entry)
: base(entry, 0) =>
weapon = wep;
public override void OnClick()
public LoadEntry(int entry) : base(entry, 0)
{
if (WeaponIsValid(weapon, Owner.From))
}
public override void OnClick(Mobile from, IEntity target)
{
if (target is INinjaWeapon weapon && WeaponIsValid(weapon, from))
{
Owner.From.BeginTarget(10, false, TargetFlags.Harmful, OnTarget, weapon);
from.BeginTarget(10, false, TargetFlags.Harmful, OnTarget, weapon);
}
}
}
public class UnloadEntry : ContextMenuEntry
{
private readonly INinjaWeapon weapon;
public UnloadEntry(int entry, bool enabled) : base(entry, 0) => Enabled = enabled;
public UnloadEntry(INinjaWeapon wep, int entry)
: base(entry, 0)
public override void OnClick(Mobile from, IEntity target)
{
weapon = wep;
Enabled = weapon.UsesRemaining > 0;
}
public override void OnClick()
{
if (WeaponIsValid(weapon, Owner.From))
if (target is INinjaWeapon weapon && WeaponIsValid(weapon, from))
{
Unload(Owner.From, weapon);
Unload(from, weapon);
}
}
}
}
}

View file

@ -1,5 +1,5 @@
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Gumps;
using Server.Multis;
@ -86,10 +86,10 @@ namespace Server.Items
}
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
SetSecureLevelEntry.AddTo(from, this, list);
base.GetContextMenuEntries(from, ref list);
SetSecureLevelEntry.AddTo(from, this, ref list);
}
public override void OnDoubleClick(Mobile from)

View file

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Gumps;
using Server.Multis;
@ -191,11 +192,11 @@ public partial class DawnsMusicBox : Item, ISecurable
}
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
base.GetContextMenuEntries(from, ref list);
SetSecureLevelEntry.AddTo(from, this, list); // Set secure level
SetSecureLevelEntry.AddTo(from, this, ref list); // Set secure level
}
public override void OnDoubleClick(Mobile from)

View file

@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Gumps;
using Server.Multis;
@ -77,11 +77,11 @@ public partial class RoseOfTrinsic : Item, ISecurable
list.Add(1062925, Petals); // Petals: ~1_COUNT~
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
base.GetContextMenuEntries(from, ref list);
SetSecureLevelEntry.AddTo(from, this, list);
SetSecureLevelEntry.AddTo(from, this, ref list);
}
private void StartSpawnTimer(TimeSpan delay)

View file

@ -1,5 +1,5 @@
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Gumps;
using Server.Multis;
@ -24,11 +24,11 @@ public partial class TapestryOfSosaria : Item, ISecurable
public override int LabelNumber => 1062917; // The Tapestry of Sosaria
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
base.GetContextMenuEntries(from, ref list);
SetSecureLevelEntry.AddTo(from, this, list);
SetSecureLevelEntry.AddTo(from, this, ref list);
}
public override void OnDoubleClick(Mobile from)

View file

@ -4,10 +4,10 @@ using System.Net;
using System.Runtime.CompilerServices;
using ModernUO.Serialization;
using Server.Accounting;
using Server.Collections;
using Server.ContextMenus;
using Server.Gumps;
using Server.Mobiles;
using Server.Network;
using Server.Regions;
using Server.Text;
@ -394,21 +394,21 @@ public partial class HouseRaffleStone : Item
}
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
base.GetContextMenuEntries(from, ref list);
if (from.AccessLevel >= AccessLevel.Seer)
{
list.Add(new EditEntry(from, this));
list.Add(new EditEntry());
if (_currentState == HouseRaffleState.Inactive)
{
list.Add(new ActivateEntry(from, this));
list.Add(new ActivateEntry(ValidLocation(_plotBounds, _plotFacet)));
}
else
{
list.Add(new ManagementEntry(from, this));
list.Add(new ManagementEntry());
}
}
}
@ -597,70 +597,49 @@ public partial class HouseRaffleStone : Item
}
}
private class RaffleContextMenuEntry : ContextMenuEntry
private class EditEntry : ContextMenuEntry
{
protected readonly Mobile _from;
protected readonly HouseRaffleStone _stone;
public RaffleContextMenuEntry(Mobile from, HouseRaffleStone stone, int label) : base(label)
{
_from = from;
_stone = stone;
}
}
private class EditEntry : RaffleContextMenuEntry
{
public EditEntry(Mobile from, HouseRaffleStone stone) : base(from, stone, 5101) // Edit
public EditEntry() : base(5101)
{
}
public override void OnClick()
public override void OnClick(Mobile from, IEntity target)
{
if (_stone.Deleted || _from.AccessLevel < AccessLevel.Seer)
if (from.AccessLevel < AccessLevel.Seer || target is not HouseRaffleStone stone || stone.Deleted)
{
return;
}
_from.SendGump(new PropertiesGump(_from, _stone));
from.SendGump(new PropertiesGump(from, stone));
}
}
private class ActivateEntry : RaffleContextMenuEntry
private class ActivateEntry : ContextMenuEntry
{
public ActivateEntry(Mobile from, HouseRaffleStone stone) : base(from, stone, 5113) // Start
{
if (!ValidLocation(stone._plotBounds, stone._plotFacet))
{
Flags |= CMEFlags.Disabled;
}
}
public ActivateEntry(bool enabled) : base(5113) => Enabled = enabled;
public override void OnClick()
public override void OnClick(Mobile from, IEntity target)
{
if (_stone.Deleted || _from.AccessLevel < AccessLevel.Seer || !ValidLocation(_stone._plotBounds, _stone._plotFacet))
if (from.AccessLevel >= AccessLevel.Seer && target is HouseRaffleStone { Deleted: false } stone &&
ValidLocation(stone._plotBounds, stone._plotFacet))
{
return;
stone.CurrentState = HouseRaffleState.Active;
}
_stone.CurrentState = HouseRaffleState.Active;
}
}
private class ManagementEntry : RaffleContextMenuEntry
private class ManagementEntry : ContextMenuEntry
{
public ManagementEntry(Mobile from, HouseRaffleStone stone) : base(from, stone, 5032) // Game Monitor
public ManagementEntry() : base(5032)
{
}
public override void OnClick()
public override void OnClick(Mobile from, IEntity target)
{
if (_stone.Deleted || _from.AccessLevel < AccessLevel.Seer)
if (from.AccessLevel >= AccessLevel.Seer && target is HouseRaffleStone { Deleted: false } stone)
{
return;
from.SendGump(new HouseRaffleManagementGump(stone));
}
_from.SendGump(new HouseRaffleManagementGump(_stone));
}
}

View file

@ -1,9 +1,8 @@
using System;
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Engines.Quests;
using Server.Network;
using Server.Regions;
using Server.Spells;
using Server.Targeting;
@ -116,13 +115,13 @@ public partial class BagOfSending : Item, TranslocationItem
LabelTo(from, 1060741, _charges.ToString()); // charges: ~1_val~
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
base.GetContextMenuEntries(from, ref list);
if (from.Alive)
{
list.Add(new UseBagEntry(this, Charges > 0 && IsChildOf(from.Backpack)));
list.Add(new UseBagEntry(Charges > 0 && IsChildOf(from.Backpack)));
}
}
@ -156,30 +155,13 @@ public partial class BagOfSending : Item, TranslocationItem
private class UseBagEntry : ContextMenuEntry
{
private readonly BagOfSending _bag;
public UseBagEntry(bool enabled) : base(6189) => Enabled = enabled;
public UseBagEntry(BagOfSending bag, bool enabled) : base(6189)
public override void OnClick(Mobile from, IEntity target)
{
_bag = bag;
if (!enabled)
if (from.CheckAlive() && target is BagOfSending bag && !bag.Deleted)
{
Flags |= CMEFlags.Disabled;
}
}
public override void OnClick()
{
if (_bag.Deleted)
{
return;
}
var from = Owner.From;
if (from.CheckAlive())
{
_bag.OnDoubleClick(from);
bag.OnDoubleClick(from);
}
}
}

View file

@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Engines.ConPVP;
using Server.Mobiles;
@ -97,9 +97,9 @@ public partial class BallOfSummoning : Item, TranslocationItem
LabelTo(from, 1054131, $"{_charges}\t{_petName.DefaultIfNullOrEmpty(" ")}");
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
base.GetContextMenuEntries(from, ref list);
if (!from.Alive || RootParent != from)
{
@ -299,10 +299,8 @@ public partial class BallOfSummoning : Item, TranslocationItem
public BallEntry(BallCallback callback, int number) : base(number, 2) => _callback = callback;
public override void OnClick()
public override void OnClick(Mobile from, IEntity target)
{
var from = Owner.From;
if (from.CheckAlive())
{
_callback(from);

View file

@ -1,11 +1,10 @@
using System;
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Factions;
using Server.Misc;
using Server.Mobiles;
using Server.Network;
using Server.Prompts;
using Server.Regions;
using Server.Spells;
@ -93,9 +92,9 @@ public partial class BraceletOfBinding : BaseBracelet, TranslocationItem
LabelTo(from, 1054000, $"{_charges}\t{_inscription.DefaultIfNullOrEmpty(" ")}");
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
base.GetContextMenuEntries(from, ref list);
if (from.Alive && IsChildOf(from))
{
@ -326,17 +325,11 @@ public partial class BraceletOfBinding : BaseBracelet, TranslocationItem
public BraceletEntry(BraceletCallback callback, int number, bool enabled) : base(number)
{
_callback = callback;
if (!enabled)
{
Flags |= CMEFlags.Disabled;
}
Enabled = enabled;
}
public override void OnClick()
public override void OnClick(Mobile from, IEntity target)
{
var from = Owner.From;
if (from.CheckAlive())
{
_callback(from);

View file

@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Engines.VeteranRewards;
using Server.Gumps;
@ -19,16 +19,16 @@ public partial class AnkhOfSacrificeComponent : AddonComponent
public override bool ForceShowProperties => ObjectPropertyList.Enabled;
public override int LabelNumber => 1027772; // Ankh of Sacrifice
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
base.GetContextMenuEntries(from, ref list);
if (from is PlayerMobile mobile)
{
list.Add(new LockKarmaEntry(mobile, Addon as AnkhOfSacrificeAddon));
list.Add(new Ankhs.LockKarmaEntry(mobile.KarmaLocked));
}
list.Add(new ResurrectEntry(from, Addon as AnkhOfSacrificeAddon));
list.Add(new ResurrectEntry());
}
public static void Resurrect(PlayerMobile m, AnkhOfSacrificeAddon ankh)
@ -68,57 +68,15 @@ public partial class AnkhOfSacrificeComponent : AddonComponent
private class ResurrectEntry : ContextMenuEntry
{
private readonly AnkhOfSacrificeAddon _ankh;
private readonly Mobile _mobile;
public ResurrectEntry(Mobile mobile, AnkhOfSacrificeAddon ankh) : base(6195, 2)
public ResurrectEntry() : base(6195, 2)
{
_mobile = mobile;
_ankh = ankh;
}
public override void OnClick()
public override void OnClick(Mobile from, IEntity target)
{
if (_ankh?.Deleted != false)
if (target is AnkhOfSacrificeAddon { Deleted: false } ankh)
{
return;
}
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))
{
_mobile.SendLocalizedMessage(500446); // That is too far away.
}
else
{
_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);
}
Resurrect(from as PlayerMobile, ankh);
}
}
}

View file

@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Items;
@ -19,33 +19,33 @@ public partial class BaseTalismanSummon : BaseCreature
public override bool Commandable => false;
public override bool InitialInnocent => true;
public override void AddCustomContextEntries(Mobile from, List<ContextMenuEntry> list)
public override void AddCustomContextEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
if (from.Alive && ControlMaster == from)
{
list.Add(new TalismanReleaseEntry(this));
list.Add(new TalismanReleaseEntry());
}
}
private class TalismanReleaseEntry : ContextMenuEntry
{
private readonly Mobile m_Mobile;
public TalismanReleaseEntry() : base(6118, 3)
{
}
public TalismanReleaseEntry(Mobile m) : base(6118, 3) => m_Mobile = m;
public override void OnClick()
public override void OnClick(Mobile from, IEntity target)
{
Effects.SendLocationParticles(
EffectItem.Create(m_Mobile.Location, m_Mobile.Map, EffectItem.DefaultDuration),
EffectItem.Create(from.Location, from.Map, EffectItem.DefaultDuration),
0x3728,
8,
20,
5042
);
Effects.PlaySound(m_Mobile,0x201);
Effects.PlaySound(from,0x201);
m_Mobile.Delete();
from.Delete();
}
}
}

View file

@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Engines.ConPVP;
using Server.Engines.Harvest;
@ -95,13 +95,13 @@ namespace Server.Items
HarvestSystem.BeginHarvesting(from, this);
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
base.GetContextMenuEntries(from, ref list);
if (HarvestSystem != null)
{
BaseHarvestTool.AddContextMenuEntries(from, this, list, HarvestSystem);
BaseHarvestTool.AddContextMenuEntries(from, this, ref list, HarvestSystem);
}
}

View file

@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Engines.ConPVP;
using Server.Engines.Harvest;
@ -48,13 +48,13 @@ namespace Server.Items
}
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
base.GetContextMenuEntries(from, ref list);
if (HarvestSystem != null)
{
BaseHarvestTool.AddContextMenuEntries(from, this, list, HarvestSystem);
BaseHarvestTool.AddContextMenuEntries(from, this, ref list, HarvestSystem);
}
}