Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.TrashCollection
|
||||
{
|
||||
public interface ITrashTokenProperties
|
||||
{
|
||||
void GetProperties(ObjectPropertyList list);
|
||||
void InvalidateProperties();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
using Server;
|
||||
using Server.Items;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.TrashCollection
|
||||
{
|
||||
public abstract class BaseTrashContainer : BaseContainer, ITrashTokenProperties, IDyable
|
||||
{
|
||||
private int _ContainerItemID;
|
||||
|
||||
public virtual int DefaultContainerItemID => 0xE77;
|
||||
public override bool DisplayWeight => false;
|
||||
public override bool DisplaysContent => false;
|
||||
|
||||
[CommandProperty(AccessLevel.Counselor, AccessLevel.GameMaster)]
|
||||
public virtual int ContainerItemID
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_ContainerItemID <= 0)
|
||||
{
|
||||
_ContainerItemID = DefaultContainerItemID;
|
||||
}
|
||||
|
||||
return _ContainerItemID;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value <= 0)
|
||||
{
|
||||
value = DefaultContainerItemID;
|
||||
}
|
||||
|
||||
if (_ContainerItemID != value)
|
||||
{
|
||||
_ContainerItemID = value;
|
||||
Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public BaseTrashContainer(int itemID, int containerID)
|
||||
: base(itemID)
|
||||
{
|
||||
Weight = 1.0;
|
||||
|
||||
ItemID = ContainerItemID = containerID;
|
||||
}
|
||||
|
||||
public BaseTrashContainer(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public virtual bool Dye(Mobile mob, DyeTub sender)
|
||||
{
|
||||
if (mob == null || sender == null || !mob.CanSee(sender) || !sender.IsAccessibleTo(mob))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Hue = sender.DyedHue;
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void Update()
|
||||
{
|
||||
UpdateContainerData();
|
||||
}
|
||||
|
||||
public override void UpdateContainerData()
|
||||
{
|
||||
if (ContainerItemID > 0)
|
||||
{
|
||||
ContainerData = ContainerData.GetData(ContainerItemID);
|
||||
}
|
||||
else
|
||||
{
|
||||
base.UpdateContainerData();
|
||||
}
|
||||
|
||||
GumpID = -1;
|
||||
DropSound = -1;
|
||||
Delta(ItemDelta.Update);
|
||||
}
|
||||
|
||||
public bool Trash(Mobile mob, Item trashed, bool message = true)
|
||||
{
|
||||
var tokens = 0;
|
||||
return Trash(mob, trashed, ref tokens, message);
|
||||
}
|
||||
|
||||
public bool Trash(Mobile mob, Item trashed, ref int tokens, bool message = true)
|
||||
{
|
||||
tokens = Math.Max(0, tokens);
|
||||
|
||||
if (mob == null || trashed == null || trashed.Deleted)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mob.InRange(GetWorldLocation(), 5))
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
mob.SendMessage("You must be within 5 paces to use that trash container.");
|
||||
}
|
||||
|
||||
OnTrashRejected(mob, trashed, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CanTrash(mob, trashed, message))
|
||||
{
|
||||
OnTrashRejected(mob, trashed, message);
|
||||
return false;
|
||||
}
|
||||
|
||||
var tokenTmp = tokens;
|
||||
var success = TrashCollection.Handlers.Values.Where(h => h != null && h.Enabled)
|
||||
.Any(h => h.Trash(mob, trashed, ref tokenTmp, message));
|
||||
|
||||
tokens = tokenTmp;
|
||||
|
||||
if (success)
|
||||
{
|
||||
OnTrashed(mob, trashed, ref tokens, message);
|
||||
}
|
||||
else
|
||||
{
|
||||
OnTrashRejected(mob, trashed, message);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
protected virtual void OnTrashed(Mobile mob, Item trashed, ref int tokens, bool message = true)
|
||||
{
|
||||
tokens = Math.Max(0, tokens);
|
||||
}
|
||||
|
||||
protected virtual void OnTrashRejected(Mobile mob, Item trashed, bool message = true)
|
||||
{
|
||||
if (mob == null || trashed == null || trashed.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (message && !TrashCollection.CMOptions.ModuleEnabled)
|
||||
{
|
||||
mob.SendMessage(0x22, "Trash Collection is currently out of service.");
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool CanTrash(Mobile mob, Item trash, bool message = true)
|
||||
{
|
||||
if (trash == null || trash.Deleted || !trash.Movable || !trash.IsAccessibleTo(mob) ||
|
||||
!TrashCollection.CMOptions.ModuleEnabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return TrashCollection.Handlers.Values.Any(h => h != null && h.CanTrash(mob, trash, message));
|
||||
}
|
||||
|
||||
public override bool TryDropItem(Mobile mob, Item trashed, bool sendFullMessage)
|
||||
{
|
||||
return mob != null && trashed != null && !trashed.Deleted && IsAccessibleTo(mob) && Trash(mob, trashed) &&
|
||||
trashed.Deleted;
|
||||
}
|
||||
|
||||
public override bool OnDragDropInto(Mobile mob, Item trashed, Point3D p)
|
||||
{
|
||||
return mob != null && trashed != null && !trashed.Deleted && IsAccessibleTo(mob) && Trash(mob, trashed) &&
|
||||
trashed.Deleted;
|
||||
}
|
||||
|
||||
public override bool OnDragDrop(Mobile mob, Item trashed)
|
||||
{
|
||||
if (mob == null || trashed == null || trashed.Deleted || !IsAccessibleTo(mob))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(RootParent is Mobile))
|
||||
{
|
||||
return Trash(mob, trashed) && trashed.Deleted;
|
||||
}
|
||||
|
||||
mob.SendMessage(0x22, "Open the {0} to trash your items.", this.ResolveName(mob.GetLanguage()));
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(1);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
writer.Write(_ContainerItemID);
|
||||
goto case 0;
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
_ContainerItemID = reader.ReadInt();
|
||||
goto case 0;
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
|
||||
Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.TrashCollection
|
||||
{
|
||||
public class PersonalTrashBag : BaseTrashContainer
|
||||
{
|
||||
public bool ConfirmBind { get; protected set; }
|
||||
|
||||
public override bool DisplayWeight => false;
|
||||
|
||||
[Constructable]
|
||||
public PersonalTrashBag()
|
||||
: this(true)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public PersonalTrashBag(bool confirmBind)
|
||||
: base(0xE76, 0xE76)
|
||||
{
|
||||
ConfirmBind = confirmBind;
|
||||
Name = "Personal Trash Bag";
|
||||
GumpID = 0x2648;
|
||||
}
|
||||
|
||||
public PersonalTrashBag(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override bool OnDragDropInto(Mobile from, Item trashed, Point3D p)
|
||||
{
|
||||
if (from == null || trashed == null || trashed.Deleted || !IsAccessibleTo(from))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (BlessedFor != null && BlessedFor != from)
|
||||
{
|
||||
from.SendMessage(0x22, "That does not belong to you.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (BlessedFor == null)
|
||||
{
|
||||
BlessedFor = from;
|
||||
}
|
||||
|
||||
return base.OnDragDropInto(from, trashed, p);
|
||||
}
|
||||
|
||||
public override bool OnDragDrop(Mobile from, Item trashed)
|
||||
{
|
||||
if (from == null || trashed == null || trashed.Deleted || !IsAccessibleTo(from))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (BlessedFor != null && BlessedFor != from)
|
||||
{
|
||||
from.SendMessage(0x22, "That does not belong to you.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (BlessedFor == null)
|
||||
{
|
||||
BlessedFor = from;
|
||||
}
|
||||
|
||||
return base.OnDragDrop(from, trashed);
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (from == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!from.CanSee(this))
|
||||
{
|
||||
OnDoubleClickCantSee(from);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsAccessibleTo(from))
|
||||
{
|
||||
OnDoubleClickNotAccessible(from);
|
||||
return;
|
||||
}
|
||||
|
||||
if (BlessedFor != null && BlessedFor != from)
|
||||
{
|
||||
from.SendMessage(0x22, "That does not belong to you.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (BlessedFor == null)
|
||||
{
|
||||
BlessedFor = from;
|
||||
}
|
||||
|
||||
base.OnDoubleClick(from);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
writer.Write(ConfirmBind);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
ConfirmBind = reader.ReadBool();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,536 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
|
||||
using Server;
|
||||
|
||||
using VitaNex.FX;
|
||||
using VitaNex.Items;
|
||||
using VitaNex.Network;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.TrashCollection
|
||||
{
|
||||
public class SepticTank : BaseTrashContainer
|
||||
{
|
||||
public static List<SepticTank> Instances { get; private set; }
|
||||
|
||||
public static PollTimer UpdateTimer { get; protected set; }
|
||||
|
||||
static SepticTank()
|
||||
{
|
||||
Instances = new List<SepticTank>();
|
||||
|
||||
UpdateTimer = PollTimer.CreateInstance(TimeSpan.FromMinutes(1), CheckProduction, () => Instances.Count > 0);
|
||||
}
|
||||
|
||||
private static void CheckProduction()
|
||||
{
|
||||
Instances.ForEachReverse(
|
||||
o =>
|
||||
{
|
||||
if (o != null && o.Parent == null && o.ProducesWaste)
|
||||
{
|
||||
o.OnProductionTimerTick();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private TimeSpan _ProductionDelay;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool SwagMode { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool StinkMode { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool ProducesWaste { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TimeSpan ProductionDelay
|
||||
{
|
||||
get => _ProductionDelay;
|
||||
set
|
||||
{
|
||||
_ProductionDelay = value;
|
||||
Produce();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TimeSpan ProductionTimeBonus { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DateTime LastProduction { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.Counselor)]
|
||||
public TimeSpan NextProduction
|
||||
{
|
||||
get
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
var next = LastProduction + (ProductionDelay - ProductionTimeBonus);
|
||||
|
||||
if (now < next)
|
||||
{
|
||||
return next - now;
|
||||
}
|
||||
|
||||
return TimeSpan.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool ProductReady => NextProduction <= TimeSpan.Zero;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Products { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ProductsMax { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string Token { get; set; }
|
||||
|
||||
[Constructable]
|
||||
public SepticTank()
|
||||
: base(0xE77, 0xE77)
|
||||
{
|
||||
Name = "Septic Tank";
|
||||
Hue = 1270;
|
||||
|
||||
StinkMode = true;
|
||||
SwagMode = true;
|
||||
|
||||
ProducesWaste = true;
|
||||
ProductsMax = 100;
|
||||
ProductionDelay = TimeSpan.FromHours(12);
|
||||
LastProduction = DateTime.UtcNow;
|
||||
|
||||
Instances.Add(this);
|
||||
}
|
||||
|
||||
public SepticTank(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
Instances.Add(this);
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
base.OnDelete();
|
||||
|
||||
Instances.Remove(this);
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
base.OnAfterDelete();
|
||||
|
||||
Instances.Remove(this);
|
||||
}
|
||||
|
||||
public override void OnSingleClick(Mobile m)
|
||||
{
|
||||
base.OnSingleClick(m);
|
||||
|
||||
if (!ProducesWaste)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (UpdateTimer.Running && Parent == null && !ProductReady)
|
||||
{
|
||||
LabelTo(m, "Producing: {0}", NextProduction.ToSimpleString(@"!h\h m\m"));
|
||||
}
|
||||
|
||||
if (ProductsMax > 0)
|
||||
{
|
||||
LabelTo(m, "Units: {0:#,0} / {1:#,0}", Products, ProductsMax);
|
||||
}
|
||||
else if (Products > 0)
|
||||
{
|
||||
LabelTo(m, "Units: {0:#,0}", Products);
|
||||
}
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
if (!ProducesWaste)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var prop = new StringBuilder();
|
||||
|
||||
if (UpdateTimer.Running && Parent == null && !ProductReady)
|
||||
{
|
||||
prop.AppendFormat("Producing: {0}", NextProduction.ToSimpleString(@"!h\h m\m"));
|
||||
}
|
||||
|
||||
if (ProductsMax > 0)
|
||||
{
|
||||
prop.AppendFormat("{0}Units: {1:#,0} / {2:#,0}", prop.Length > 0 ? "\n" : String.Empty, Products, ProductsMax);
|
||||
}
|
||||
else if (Products > 0)
|
||||
{
|
||||
prop.AppendFormat("{0}Units: {1:#,0}", prop.Length > 0 ? "\n" : String.Empty, Products);
|
||||
}
|
||||
|
||||
var s = prop.ToString();
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(s))
|
||||
{
|
||||
list.Add(s.WrapUOHtmlColor(Color.Cyan));
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnDragDrop(Mobile m, Item trashed)
|
||||
{
|
||||
if (m == null || trashed == null || trashed.Deleted || !IsAccessibleTo(m))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (RootParent == null)
|
||||
{
|
||||
if (trashed is SepticWaste)
|
||||
{
|
||||
if (!ProducesWaste)
|
||||
{
|
||||
m.SendMessage("Dumping the waste in the {0}?! Dispose of it properly!", this.ResolveName(m));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Products >= ProductsMax)
|
||||
{
|
||||
m.SendMessage("The {0} is full.", this.ResolveName(m));
|
||||
return false;
|
||||
}
|
||||
|
||||
var waste = (SepticWaste)trashed;
|
||||
|
||||
if (Products + waste.Amount > ProductsMax)
|
||||
{
|
||||
var diff = (Products + waste.Amount) - ProductsMax;
|
||||
Products = ProductsMax;
|
||||
waste.Amount = diff;
|
||||
|
||||
m.SendMessage("You dump as much of the waste into the {0} as possible.", this.ResolveName(m));
|
||||
}
|
||||
else
|
||||
{
|
||||
Products += waste.Amount;
|
||||
waste.Delete();
|
||||
m.SendMessage("You dump the waste into the {0}.", this.ResolveName(m));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return Trash(m, trashed);
|
||||
}
|
||||
|
||||
m.SendMessage(0x22, "The {0} must be on the ground to dispose your items.", this.ResolveName(m));
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override void OnTrashed(Mobile m, Item trashed, ref int tokens, bool message = true)
|
||||
{
|
||||
base.OnTrashed(m, trashed, ref tokens, message);
|
||||
|
||||
if (tokens > 0 && ProductionTimeBonus < TimeSpan.FromSeconds(ProductionDelay.TotalSeconds / 2))
|
||||
{
|
||||
ProductionTimeBonus += TimeSpan.FromMinutes(tokens);
|
||||
}
|
||||
|
||||
var fx = GetProductionEffect();
|
||||
|
||||
if (fx != null)
|
||||
{
|
||||
fx.Send();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool CanProduce()
|
||||
{
|
||||
return !Deleted && ProducesWaste && Map != null && Map != Map.Internal && RootParent == null &&
|
||||
Products < ProductsMax && NextProduction <= TimeSpan.Zero;
|
||||
}
|
||||
|
||||
protected virtual void Produce()
|
||||
{
|
||||
BaseExplodeEffect fx;
|
||||
|
||||
if (!CanProduce())
|
||||
{
|
||||
if (SwagMode)
|
||||
{
|
||||
var next = NextProduction;
|
||||
|
||||
if (next.TotalSeconds <= 60 || next.TotalSeconds % 60 == 0 || Utility.RandomDouble() <= 0.10)
|
||||
{
|
||||
fx = GetProductionEffect();
|
||||
|
||||
if (fx != null)
|
||||
{
|
||||
fx.Send();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var amount = Utility.RandomMinMax(1, 3);
|
||||
|
||||
if (Products + amount > ProductsMax)
|
||||
{
|
||||
amount = ProductsMax - Products;
|
||||
}
|
||||
|
||||
if (amount > 0)
|
||||
{
|
||||
Products += amount;
|
||||
}
|
||||
|
||||
LastProduction = DateTime.UtcNow;
|
||||
ProductionTimeBonus = TimeSpan.Zero;
|
||||
|
||||
if (!SwagMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
fx = GetProductionEffect();
|
||||
|
||||
if (fx != null)
|
||||
{
|
||||
fx.Send();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual BaseExplodeEffect GetProductionEffect()
|
||||
{
|
||||
var fx = new FireExplodeEffect(this, Map, 0);
|
||||
|
||||
fx.Effects.ForEach(
|
||||
e =>
|
||||
{
|
||||
e.Hue = 65;
|
||||
|
||||
if (e.EffectID != 13401)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
e.Render = EffectRender.SemiTransparent;
|
||||
e.Duration = 40;
|
||||
});
|
||||
|
||||
return fx;
|
||||
}
|
||||
|
||||
public virtual BaseExplodeEffect GetClaimEffect(Mobile m)
|
||||
{
|
||||
var fx = new WaterRippleEffect(this, Map, 2);
|
||||
|
||||
fx.Effects.ForEach(
|
||||
e =>
|
||||
{
|
||||
e.Hue = 1270;
|
||||
e.Render = EffectRender.SemiTransparent;
|
||||
});
|
||||
|
||||
return fx;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile m)
|
||||
{
|
||||
if (!this.CheckDoubleClick(m, true, false, 3))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ProducesWaste && Products > 0)
|
||||
{
|
||||
double pFactor = Products / Math.Max(Products, ProductsMax);
|
||||
var pDuration = TimeSpan.FromSeconds(60.0 * pFactor);
|
||||
|
||||
var waste = new SepticWaste(Products);
|
||||
|
||||
if (m.PlaceInBackpack(waste))
|
||||
{
|
||||
m.SendMessage(0x55, "You gather the decomposed waste and place it in your backpack.");
|
||||
}
|
||||
else
|
||||
{
|
||||
waste.MoveToWorld(m.Location, m.Map);
|
||||
m.SendMessage(0x55, "The waste spills out at your feet.");
|
||||
}
|
||||
|
||||
if (SwagMode)
|
||||
{
|
||||
var fx = GetClaimEffect(m);
|
||||
|
||||
if (fx != null)
|
||||
{
|
||||
if (StinkMode)
|
||||
{
|
||||
fx.EffectHandler = e => e.Source.GetMobilesInRange(e.Map, 0).ForEach(mob => MakeStinky(mob, pDuration, pFactor));
|
||||
}
|
||||
|
||||
fx.Send();
|
||||
}
|
||||
}
|
||||
else if (StinkMode)
|
||||
{
|
||||
MakeStinky(m, pDuration, pFactor);
|
||||
}
|
||||
|
||||
Products = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m.SendMessage("You rummage around in the decomposing waste, but find nothing.");
|
||||
|
||||
MakeStinky(m, TimeSpan.FromSeconds(60.0 * Utility.RandomDouble()), 0.10);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void MakeStinky(Mobile m, TimeSpan duration, double chance)
|
||||
{
|
||||
if (StinkMode && !m.Hidden && m.Alive && Utility.RandomDouble() <= chance)
|
||||
{
|
||||
ThrowableStinkBomb.MakeStinky(m, duration);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnProductionTimerTick()
|
||||
{
|
||||
InvalidateProperties();
|
||||
Delta(ItemDelta.Properties);
|
||||
|
||||
VitaNexCore.TryCatch(Produce, TrashCollection.CMOptions.ToConsole);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(2);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 2:
|
||||
writer.Write(Token);
|
||||
goto case 1;
|
||||
case 1:
|
||||
{
|
||||
writer.Write(StinkMode);
|
||||
writer.Write(SwagMode);
|
||||
writer.Write(ProducesWaste);
|
||||
}
|
||||
goto case 0;
|
||||
case 0:
|
||||
{
|
||||
writer.Write(ProductionDelay);
|
||||
writer.Write(ProductionTimeBonus);
|
||||
writer.Write(LastProduction);
|
||||
writer.Write(Products);
|
||||
writer.Write(ProductsMax);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 2:
|
||||
Token = reader.ReadString();
|
||||
goto case 1;
|
||||
case 1:
|
||||
{
|
||||
StinkMode = reader.ReadBool();
|
||||
SwagMode = reader.ReadBool();
|
||||
ProducesWaste = reader.ReadBool();
|
||||
}
|
||||
goto case 0;
|
||||
case 0:
|
||||
{
|
||||
_ProductionDelay = reader.ReadTimeSpan();
|
||||
ProductionTimeBonus = reader.ReadTimeSpan();
|
||||
LastProduction = reader.ReadDateTime();
|
||||
Products = reader.ReadInt();
|
||||
ProductsMax = reader.ReadInt();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class SepticWaste : ThrowableStinkBomb
|
||||
{
|
||||
[Constructable]
|
||||
public SepticWaste()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public SepticWaste(int amount)
|
||||
: base(amount)
|
||||
{
|
||||
Name = "Septic Waste";
|
||||
Token = "Property of the Septic Tank Co.";
|
||||
|
||||
ItemID = 0x20E8;
|
||||
EffectID = ItemID;
|
||||
|
||||
StinkyDuration += TimeSpan.FromSeconds(Utility.RandomMinMax(5, 10));
|
||||
|
||||
ExplosionRange = 3;
|
||||
RequiredSkillValue = 0;
|
||||
ClearHands = false;
|
||||
}
|
||||
|
||||
public SepticWaste(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.TrashCollection
|
||||
{
|
||||
[Furniture]
|
||||
public class TrashCan : BaseTrashContainer
|
||||
{
|
||||
public static string[] SuccessEmotes =
|
||||
{
|
||||
"*Nom Nom Nom*", "*Burp*", "I Like Trash", "*Brofist*", "That's What SHE Said!", "I Have No Bottom, I Do Not Poop",
|
||||
"That Tickles!", "I Cast Thy trash Into The Abyss!", "Trash, Be Gone!", "*Boing*", "*Poof*", "Ha Ha, Made You Look",
|
||||
"It's Gone, Into The Void", "Have You Seen My Brothers?", "Your Trash Was Trashed, Heh", "*Weeeeeeeeeee... Thud*"
|
||||
};
|
||||
|
||||
public static string[] FailEmotes =
|
||||
{
|
||||
"Ewww", "Thanks, But No Thanks", "Are You Hitting On Me?", "Disgusting!", "Not My Kind Of Food",
|
||||
"I've Had That Before, It's Terrible", "Please! No!", "Pfft, You Eat It, If It's Sooo Good",
|
||||
"The Void Doesn't Want That", "That Gives Me Indigestion", "Risk Heartwood-Burn? No Thanks",
|
||||
"The Abyss Frowns At Your Offering"
|
||||
};
|
||||
|
||||
[Constructable]
|
||||
public TrashCan()
|
||||
: base(0xE77, 0xE77)
|
||||
{
|
||||
Name = "Trash Can";
|
||||
Weight = 5;
|
||||
}
|
||||
|
||||
public TrashCan(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override bool Dye(Mobile from, DyeTub sender)
|
||||
{
|
||||
if (from == null || sender == null || !from.CanSee(sender) || !sender.IsAccessibleTo(from))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(sender is FurnitureDyeTub))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.Dye(from, sender);
|
||||
}
|
||||
|
||||
protected override void OnTrashed(Mobile from, Item trashed, ref int tokens, bool message = true)
|
||||
{
|
||||
base.OnTrashed(from, trashed, ref tokens, message);
|
||||
|
||||
if (message && Utility.RandomDouble() < 0.20)
|
||||
{
|
||||
PublicOverheadMessage(MessageType.Emote, 0x55, true, SuccessEmotes[Utility.Random(SuccessEmotes.Length)]);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnTrashRejected(Mobile from, Item trashed, bool message = true)
|
||||
{
|
||||
base.OnTrashRejected(from, trashed, message);
|
||||
|
||||
if (message && Utility.RandomDouble() < 0.20)
|
||||
{
|
||||
PublicOverheadMessage(MessageType.Emote, 0x55, true, FailEmotes[Utility.Random(FailEmotes.Length)]);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{ }
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{ }
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
|
||||
using VitaNex.Items;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.TrashCollection
|
||||
{
|
||||
public sealed class TrashToken : Item, IVendorToken, ITrashTokenProperties
|
||||
{
|
||||
public override bool DisplayWeight => false;
|
||||
|
||||
[Constructable]
|
||||
public TrashToken()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public TrashToken(int amount)
|
||||
: base(0xEED)
|
||||
{
|
||||
Name = "Trash Token";
|
||||
Hue = 85;
|
||||
Weight = 0;
|
||||
|
||||
LootType = LootType.Blessed;
|
||||
|
||||
Stackable = true;
|
||||
Amount = Math.Max(1, Math.Min(60000, amount));
|
||||
}
|
||||
|
||||
public TrashToken(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(1);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
{ }
|
||||
break;
|
||||
case 0:
|
||||
{ }
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
{ }
|
||||
break;
|
||||
case 0:
|
||||
{
|
||||
ItemID = 0xEED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override DeathMoveResult OnInventoryDeath(Mobile parent)
|
||||
{
|
||||
if (parent is BaseCreature)
|
||||
{
|
||||
return DeathMoveResult.MoveToCorpse;
|
||||
}
|
||||
|
||||
return base.OnInventoryDeath(parent);
|
||||
}
|
||||
|
||||
public override int GetDropSound()
|
||||
{
|
||||
if (Amount <= 1)
|
||||
{
|
||||
return 0x2E4;
|
||||
}
|
||||
|
||||
if (Amount <= 5)
|
||||
{
|
||||
return 0x2E5;
|
||||
}
|
||||
|
||||
return 0x2E6;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
using Server;
|
||||
|
||||
using VitaNex.Items;
|
||||
using VitaNex.Mobiles;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.TrashCollection
|
||||
{
|
||||
public class TrashVendor : AdvancedVendor, ITrashTokenProperties
|
||||
{
|
||||
[Constructable]
|
||||
public TrashVendor()
|
||||
: base("the trash collector", typeof(TrashToken), "Trash Tokens", "TT")
|
||||
{ }
|
||||
|
||||
public TrashVendor(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
protected override void InitBuyInfo()
|
||||
{
|
||||
AddStock<TrashCan>(100);
|
||||
AddStock<PersonalTrashBag>(750);
|
||||
AddStock<SepticTank>(1000);
|
||||
|
||||
AddStock<ThrowableStinkBomb>(20);
|
||||
AddStock<ThrowableRat>(20);
|
||||
AddStock<ThrowableRock>(20);
|
||||
|
||||
AddStock<StrobeLantern>(10000);
|
||||
|
||||
AddStock<BroadcastScroll>(10);
|
||||
AddStock<BroadcastScroll_3Uses>(30);
|
||||
AddStock<BroadcastScroll_5Uses>(50);
|
||||
AddStock<BroadcastScroll_10Uses>(100);
|
||||
AddStock<BroadcastScroll_30Uses>(300);
|
||||
AddStock<BroadcastScroll_50Uses>(500);
|
||||
AddStock<BroadcastScroll_100Uses>(1000);
|
||||
}
|
||||
|
||||
public bool Trash(Mobile from, Item trashed, bool message = true)
|
||||
{
|
||||
var tokens = 0;
|
||||
return Trash(from, trashed, ref tokens, message);
|
||||
}
|
||||
|
||||
public bool Trash(Mobile from, Item trashed, ref int tokens, bool message = true)
|
||||
{
|
||||
tokens = Math.Max(0, tokens);
|
||||
|
||||
if (from == null || trashed == null || trashed.Deleted)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!from.InRange(Location, 5))
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
from.SendMessage("You must be within 5 paces to use that trash collector.");
|
||||
}
|
||||
|
||||
OnTrashRejected(from, trashed, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CanTrash(from, trashed, message))
|
||||
{
|
||||
OnTrashRejected(from, trashed, message);
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var h in TrashCollection.Handlers.Values)
|
||||
{
|
||||
if (h != null && h.Trash(from, trashed, ref tokens, message))
|
||||
{
|
||||
OnTrashed(from, trashed, ref tokens, message);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
OnTrashRejected(from, trashed, message);
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual void OnTrashed(Mobile from, Item trashed, ref int tokens, bool message = true)
|
||||
{
|
||||
tokens = Math.Max(0, tokens);
|
||||
|
||||
if (from == null || trashed == null || trashed.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (message && Utility.RandomDouble() < 0.20)
|
||||
{
|
||||
Say(TrashCan.SuccessEmotes.GetRandom());
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnTrashRejected(Mobile from, Item trashed, bool message = true)
|
||||
{
|
||||
if (from == null || trashed == null || trashed.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (message && !TrashCollection.CMOptions.ModuleEnabled)
|
||||
{
|
||||
Say("Sorry, I'm on my lunch break.");
|
||||
}
|
||||
else if (message && Utility.RandomDouble() < 0.20)
|
||||
{
|
||||
Say(TrashCan.FailEmotes.GetRandom());
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool CanTrash(Mobile from, Item trash, bool message = true)
|
||||
{
|
||||
if (trash == null || trash.Deleted || !trash.Movable || !trash.IsAccessibleTo(from) ||
|
||||
!TrashCollection.CMOptions.ModuleEnabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return TrashCollection.Handlers.Values.Any(h => h != null && h.CanTrash(from, trash, message));
|
||||
}
|
||||
|
||||
public override bool OnDragDrop(Mobile from, Item trashed)
|
||||
{
|
||||
if (from == null || trashed == null || trashed.Deleted)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Trash(from, trashed))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.OnDragDrop(from, trashed);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,337 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using Server;
|
||||
using Server.Items;
|
||||
|
||||
using VitaNex.Crypto;
|
||||
using VitaNex.Items;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.TrashCollection
|
||||
{
|
||||
public abstract class BaseTrashHandler
|
||||
{
|
||||
public static Type[] DefaultAcceptList = { typeof(Item) };
|
||||
|
||||
public static Type[] DefaultIgnoredList =
|
||||
{
|
||||
typeof(Gold), typeof(Bandage), typeof(Bottle), typeof(BaseReagent), typeof(IVendorToken), typeof(BaseTrashContainer)
|
||||
};
|
||||
|
||||
private int _BonusTokens;
|
||||
private int _BonusTokensChance;
|
||||
|
||||
private bool _Enabled = true;
|
||||
|
||||
private TrashPriority _Priority;
|
||||
|
||||
[CommandProperty(TrashCollection.Access)]
|
||||
public int BonusTokensChance
|
||||
{
|
||||
get => _BonusTokensChance;
|
||||
set => _BonusTokensChance = Math.Max(0, Math.Min(100, value));
|
||||
}
|
||||
|
||||
public string UID { get; private set; }
|
||||
|
||||
[CommandProperty(TrashCollection.Access)]
|
||||
public bool Enabled
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!TrashCollection.CMOptions.ModuleEnabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return _Enabled;
|
||||
}
|
||||
set => _Enabled = value;
|
||||
}
|
||||
|
||||
[CommandProperty(TrashCollection.Access)]
|
||||
public TrashPriority Priority
|
||||
{
|
||||
get => _Priority;
|
||||
set
|
||||
{
|
||||
if (_Priority == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_Priority = value;
|
||||
TrashCollection.InvalidateHandlers();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(TrashCollection.Access)]
|
||||
public int BonusTokens { get => _BonusTokens; set => _BonusTokens = Math.Max(0, value); }
|
||||
|
||||
public List<Type> Accepted { get; protected set; }
|
||||
public List<Type> Ignored { get; protected set; }
|
||||
|
||||
[CommandProperty(TrashCollection.Access)]
|
||||
public bool IgnoreBlessed { get; set; }
|
||||
|
||||
[CommandProperty(TrashCollection.Access)]
|
||||
public bool IgnoreInsured { get; set; }
|
||||
|
||||
public BaseTrashHandler()
|
||||
: this(true)
|
||||
{ }
|
||||
|
||||
public BaseTrashHandler(
|
||||
bool enabled,
|
||||
TrashPriority priority = TrashPriority.Normal,
|
||||
IEnumerable<Type> accepts = null,
|
||||
IEnumerable<Type> ignores = null)
|
||||
{
|
||||
UID = CryptoGenerator.GenString(CryptoHashType.MD5, GetType().FullName);
|
||||
|
||||
Accepted = new List<Type>(accepts ?? DefaultAcceptList);
|
||||
Ignored = new List<Type>(ignores ?? DefaultIgnoredList);
|
||||
|
||||
Enabled = enabled;
|
||||
Priority = priority;
|
||||
}
|
||||
|
||||
public BaseTrashHandler(GenericReader reader)
|
||||
{
|
||||
Deserialize(reader);
|
||||
}
|
||||
|
||||
public bool Trash(Mobile from, Item trashed, bool message = true)
|
||||
{
|
||||
var tokens = 0;
|
||||
|
||||
return Trash(from, trashed, ref tokens, message);
|
||||
}
|
||||
|
||||
public bool Trash(Mobile from, Item trashed, ref int tokens, bool message = true)
|
||||
{
|
||||
tokens = Math.Max(0, tokens);
|
||||
|
||||
if (!Enabled || from == null || trashed == null || trashed.Deleted)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var andThis = true;
|
||||
var multiple = false;
|
||||
|
||||
if (trashed is Container)
|
||||
{
|
||||
if (trashed.Items.Count > 0)
|
||||
{
|
||||
var i = trashed.Items.Count;
|
||||
|
||||
while (--i >= 0)
|
||||
{
|
||||
if (!trashed.Items.InBounds(i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Trash(from, trashed.Items[i], ref tokens, false))
|
||||
{
|
||||
multiple = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
andThis = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (trashed.Items.Count > 0)
|
||||
{
|
||||
andThis = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (multiple && message)
|
||||
{
|
||||
from.SendMessage(0x55, "You trashed multiple items, check your profile history for more information.");
|
||||
}
|
||||
|
||||
if (!CanTrash(from, trashed))
|
||||
{
|
||||
andThis = false;
|
||||
}
|
||||
|
||||
if (!andThis)
|
||||
{
|
||||
OnTrashRejected(from, trashed, message);
|
||||
return false;
|
||||
}
|
||||
|
||||
GetTrashTokens(from, trashed, ref tokens);
|
||||
OnTrashed(from, trashed, ref tokens, message);
|
||||
|
||||
var e = new ItemTrashedEventArgs(this, from, trashed, tokens, message);
|
||||
|
||||
VitaNexCore.TryCatch(e.Invoke, TrashCollection.CMOptions.ToConsole);
|
||||
|
||||
if (tokens != e.Tokens)
|
||||
{
|
||||
tokens = Math.Max(0, e.Tokens);
|
||||
}
|
||||
|
||||
message = e.Message;
|
||||
|
||||
if (!e.HandledTokens)
|
||||
{
|
||||
TrashCollection.EnsureProfile(from).TransferTokens(from, trashed, tokens, message);
|
||||
}
|
||||
|
||||
if (!multiple && from.Backpack != null && TrashCollection.CMOptions.UseTrashedProps)
|
||||
{
|
||||
from.Backpack.InvalidateProperties<ITrashTokenProperties>();
|
||||
}
|
||||
|
||||
trashed.Delete();
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual bool IsAccepted(Mobile from, Type trash)
|
||||
{
|
||||
return Accepted.Any(trash.IsEqualOrChildOf);
|
||||
}
|
||||
|
||||
public virtual bool IsIgnored(Mobile from, Type trash)
|
||||
{
|
||||
return Ignored.Any(trash.IsEqualOrChildOf);
|
||||
}
|
||||
|
||||
public virtual bool CanTrash(Mobile from, Item trash, bool message = true)
|
||||
{
|
||||
if (!Enabled || trash == null || trash.Deleted || !trash.Movable || !trash.IsAccessibleTo(from))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IgnoreInsured && trash.Insured)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IgnoreBlessed && (trash.LootType == LootType.Blessed || trash.BlessedFor != null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var iType = trash.GetType();
|
||||
|
||||
return IsAccepted(from, iType) && !IsIgnored(from, iType);
|
||||
}
|
||||
|
||||
protected virtual void OnTrashed(Mobile from, Item trashed, ref int tokens, bool message = true)
|
||||
{
|
||||
tokens = Math.Max(0, tokens);
|
||||
}
|
||||
|
||||
protected virtual void OnTrashRejected(Mobile from, Item trashed, bool message = true)
|
||||
{ }
|
||||
|
||||
protected virtual void GetTrashTokens(Mobile from, Item trashed, ref int tokens, bool message = true)
|
||||
{
|
||||
tokens = Math.Max(0, tokens);
|
||||
|
||||
if (!Enabled || from == null || trashed == null || trashed.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var amount = trashed.GetAttributeCount();
|
||||
|
||||
if (trashed.Stackable)
|
||||
{
|
||||
amount *= trashed.Amount;
|
||||
}
|
||||
|
||||
if (TrashCollection.CMOptions.GiveBonusTokens && BonusTokens > 0 &&
|
||||
Utility.RandomDouble() <= BonusTokensChance / 100.0)
|
||||
{
|
||||
amount += BonusTokens;
|
||||
}
|
||||
|
||||
if (amount > 0)
|
||||
{
|
||||
tokens += amount;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Serialize(GenericWriter writer)
|
||||
{
|
||||
var version = writer.SetVersion(1);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
writer.Write(IgnoreBlessed);
|
||||
writer.Write(IgnoreInsured);
|
||||
}
|
||||
goto case 0;
|
||||
case 0:
|
||||
{
|
||||
writer.Write(Enabled);
|
||||
writer.Write(UID);
|
||||
writer.WriteFlag(_Priority);
|
||||
writer.Write(_BonusTokens);
|
||||
writer.Write(_BonusTokensChance);
|
||||
writer.WriteList(Accepted, t => writer.WriteType(t));
|
||||
writer.WriteList(Ignored, t => writer.WriteType(t));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Deserialize(GenericReader reader)
|
||||
{
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
IgnoreBlessed = reader.ReadBool();
|
||||
IgnoreInsured = reader.ReadBool();
|
||||
}
|
||||
goto case 0;
|
||||
case 0:
|
||||
{
|
||||
Enabled = reader.ReadBool();
|
||||
UID = reader.ReadString();
|
||||
_Priority = reader.ReadFlag<TrashPriority>();
|
||||
_BonusTokens = reader.ReadInt();
|
||||
_BonusTokensChance = reader.ReadInt();
|
||||
Accepted = reader.ReadList(reader.ReadType);
|
||||
Ignored = reader.ReadList(reader.ReadType);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (version < 1)
|
||||
{
|
||||
IgnoreBlessed = true;
|
||||
IgnoreInsured = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.TrashCollection
|
||||
{
|
||||
public class GeneralTrashHandler : BaseTrashHandler
|
||||
{
|
||||
public GeneralTrashHandler()
|
||||
: this(true)
|
||||
{ }
|
||||
|
||||
public GeneralTrashHandler(
|
||||
bool enabled,
|
||||
TrashPriority priority = TrashPriority.Lowest,
|
||||
IEnumerable<Type> accepts = null,
|
||||
IEnumerable<Type> ignores = null)
|
||||
: base(enabled, priority, accepts, ignores)
|
||||
{
|
||||
IgnoreBlessed = true;
|
||||
IgnoreInsured = true;
|
||||
}
|
||||
|
||||
public GeneralTrashHandler(GenericReader reader)
|
||||
: base(reader)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(1);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
if (version > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IgnoreBlessed = true;
|
||||
IgnoreInsured = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.TrashCollection
|
||||
{
|
||||
public class ItemTrashedEventArgs : EventArgs
|
||||
{
|
||||
public ItemTrashedEventArgs(BaseTrashHandler handler, Mobile from, Item trashed, int tokens, bool message)
|
||||
{
|
||||
Handler = handler;
|
||||
Mobile = from;
|
||||
Trashed = trashed;
|
||||
Tokens = tokens;
|
||||
Message = message;
|
||||
}
|
||||
|
||||
public BaseTrashHandler Handler { get; private set; }
|
||||
public Mobile Mobile { get; private set; }
|
||||
public Item Trashed { get; private set; }
|
||||
public int Tokens { get; set; }
|
||||
public bool Message { get; set; }
|
||||
public bool HandledTokens { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.TrashCollection
|
||||
{
|
||||
public enum TrashPriority
|
||||
{
|
||||
Highest,
|
||||
High,
|
||||
Normal,
|
||||
Low,
|
||||
Lowest
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,478 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.TrashCollection
|
||||
{
|
||||
public sealed class TrashProfileEntry
|
||||
{
|
||||
public TrashProfileEntry(DateTime when, Mobile source, Item trashed, int tokens)
|
||||
{
|
||||
TrashedTime = when;
|
||||
|
||||
if (source != null)
|
||||
{
|
||||
SourceSerial = source.Serial;
|
||||
SourceName = source.RawName;
|
||||
}
|
||||
else
|
||||
{
|
||||
SourceSerial = Serial.Zero;
|
||||
SourceName = String.Empty;
|
||||
}
|
||||
|
||||
if (trashed != null)
|
||||
{
|
||||
TrashedSerial = trashed.Serial;
|
||||
TrashedType = trashed.GetType().Name;
|
||||
TrashedName = trashed.ResolveName();
|
||||
}
|
||||
else
|
||||
{
|
||||
TrashedSerial = Serial.Zero;
|
||||
TrashedType = String.Empty;
|
||||
TrashedName = String.Empty;
|
||||
}
|
||||
|
||||
TokenAmount = tokens;
|
||||
}
|
||||
|
||||
public TrashProfileEntry(GenericReader reader)
|
||||
{
|
||||
Deserialize(reader);
|
||||
}
|
||||
|
||||
public Serial SourceSerial { get; private set; }
|
||||
public string SourceName { get; private set; }
|
||||
|
||||
public Serial TrashedSerial { get; private set; }
|
||||
public string TrashedType { get; private set; }
|
||||
public string TrashedName { get; private set; }
|
||||
public DateTime TrashedTime { get; private set; }
|
||||
|
||||
public int TokenAmount { get; private set; }
|
||||
|
||||
public string ToHtmlString(bool technical = false)
|
||||
{
|
||||
var html = new StringBuilder();
|
||||
|
||||
if (technical)
|
||||
{
|
||||
html.AppendLine(
|
||||
String.Format(
|
||||
"[{0}]: '{1}' ({2}: {3}) trashed by '{4}' ({5}) for {6} tokens.",
|
||||
TrashedTime.ToSimpleString(TrashCollection.CMOptions.DateFormat),
|
||||
TrashedName,
|
||||
TrashedSerial,
|
||||
TrashedType,
|
||||
SourceName,
|
||||
SourceSerial,
|
||||
TokenAmount > 0 ? TokenAmount.ToString("#,#") : "0"));
|
||||
}
|
||||
else
|
||||
{
|
||||
html.AppendLine(
|
||||
String.Format(
|
||||
"[{0}]: '{1}' trashed by '{2}' for {3} tokens.",
|
||||
TrashedTime.ToSimpleString(TrashCollection.CMOptions.DateFormat),
|
||||
TrashedName,
|
||||
SourceName,
|
||||
TokenAmount > 0 ? TokenAmount.ToString("#,#") : "0"));
|
||||
}
|
||||
|
||||
return html.ToString();
|
||||
}
|
||||
|
||||
public void Serialize(GenericWriter writer)
|
||||
{
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
writer.Write(SourceSerial);
|
||||
writer.Write(SourceName);
|
||||
|
||||
writer.Write(TrashedSerial);
|
||||
writer.Write(TrashedType);
|
||||
writer.Write(TrashedName);
|
||||
writer.Write(TrashedTime);
|
||||
|
||||
writer.Write(TokenAmount);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void Deserialize(GenericReader reader)
|
||||
{
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
SourceSerial = reader.ReadSerial();
|
||||
SourceName = reader.ReadString();
|
||||
|
||||
TrashedSerial = reader.ReadSerial();
|
||||
TrashedType = reader.ReadString();
|
||||
TrashedName = reader.ReadString();
|
||||
TrashedTime = reader.ReadDateTime();
|
||||
|
||||
TokenAmount = reader.ReadInt();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class TrashProfile
|
||||
{
|
||||
public static event Action<TrashProfile, TrashToken> TokensReceived;
|
||||
|
||||
public bool Deleted { get; private set; }
|
||||
public Mobile Owner { get; private set; }
|
||||
|
||||
public Dictionary<TimeStamp, List<TrashProfileEntry>> History { get; private set; }
|
||||
|
||||
public TrashProfile(Mobile owner)
|
||||
{
|
||||
Owner = owner;
|
||||
History = new Dictionary<TimeStamp, List<TrashProfileEntry>>();
|
||||
}
|
||||
|
||||
public TrashProfile(GenericReader reader)
|
||||
{
|
||||
Deserialize(reader);
|
||||
}
|
||||
|
||||
private static TimeStamp GenerateKey(ref DateTime when)
|
||||
{
|
||||
return (when = new DateTime(when.Year, when.Month, when.Day)).ToTimeStamp();
|
||||
}
|
||||
|
||||
private static int InternalHistorySort(TrashProfileEntry a, TrashProfileEntry b)
|
||||
{
|
||||
if (a == null && b == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a == null)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (b == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (a.TrashedTime < b.TrashedTime)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (a.TrashedTime > b.TrashedTime)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public bool TransferTokens(Mobile source, Item trashed, int amount, bool message = true)
|
||||
{
|
||||
if (Deleted || Owner == null || Owner.Deleted)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (source == null)
|
||||
{
|
||||
source = Owner;
|
||||
}
|
||||
|
||||
var limitReached = false;
|
||||
var total = GetTokenTotal(DateTime.UtcNow);
|
||||
|
||||
if (TrashCollection.CMOptions.DailyLimit > 0)
|
||||
{
|
||||
if (total >= TrashCollection.CMOptions.DailyLimit)
|
||||
{
|
||||
limitReached = true;
|
||||
amount = 0;
|
||||
}
|
||||
else if (total + amount > TrashCollection.CMOptions.DailyLimit)
|
||||
{
|
||||
limitReached = true;
|
||||
amount = (total + amount) - TrashCollection.CMOptions.DailyLimit;
|
||||
}
|
||||
}
|
||||
|
||||
if (amount > 0)
|
||||
{
|
||||
var token = new TrashToken(amount);
|
||||
var name = token.ResolveName(Owner.GetLanguage());
|
||||
|
||||
if (Owner.Backpack.TryDropItem(Owner, token, true))
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
Owner.SendMessage(
|
||||
0x55,
|
||||
"{0}{1}{2} {3} been placed in your backpack.",
|
||||
!name.StartsWith("a") && amount == 1 ? "a " : String.Empty,
|
||||
name,
|
||||
!name.EndsWith("s") && amount > 1 ? "s" : String.Empty,
|
||||
amount > 1 ? "have" : "has");
|
||||
}
|
||||
}
|
||||
else if (Owner.BankBox.TryDropItem(Owner, token, true))
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
Owner.SendMessage(
|
||||
0x55,
|
||||
"{0}{1}{2} {3} been placed in your bank.",
|
||||
!name.StartsWith("a") && amount == 1 ? "a " : String.Empty,
|
||||
name,
|
||||
!name.EndsWith("s") && amount > 1 ? "s" : String.Empty,
|
||||
amount > 1 ? "have" : "has");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Owner.NetState == null && Owner is PlayerMobile)
|
||||
{
|
||||
token.MoveToWorld(Owner.LogoutLocation, Owner.LogoutMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
token.MoveToWorld(Owner.Location, Owner.Map);
|
||||
}
|
||||
|
||||
if (message)
|
||||
{
|
||||
Owner.SendMessage(
|
||||
0x55,
|
||||
"{0}{1}{2} {3} been placed at your feet.",
|
||||
!name.StartsWith("a") && amount == 1 ? "a " : String.Empty,
|
||||
name,
|
||||
!name.EndsWith("s") && amount > 1 ? "s" : String.Empty,
|
||||
amount > 1 ? "have" : "has");
|
||||
}
|
||||
}
|
||||
|
||||
if (TokensReceived != null)
|
||||
{
|
||||
TokensReceived.Invoke(this, token);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
Owner.SendMessage(0x22, "You didn't receive any tokens this time.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (limitReached && message)
|
||||
{
|
||||
Owner.SendMessage(
|
||||
0x22,
|
||||
"You have reached your daily trash token limit of {0:#,0}.",
|
||||
TrashCollection.CMOptions.DailyLimit);
|
||||
}
|
||||
|
||||
RegisterTokens(source, trashed, amount);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void RegisterTokens(Mobile source, Item trashed, int amount)
|
||||
{
|
||||
if (source == null || trashed == null || amount <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var when = DateTime.UtcNow;
|
||||
var key = GenerateKey(ref when);
|
||||
|
||||
if (!History.ContainsKey(key))
|
||||
{
|
||||
History.Add(key, new List<TrashProfileEntry>());
|
||||
}
|
||||
|
||||
History[key].Add(new TrashProfileEntry(when, source, trashed, amount));
|
||||
}
|
||||
|
||||
public void ClearHistory(DateTime when)
|
||||
{
|
||||
var key = GenerateKey(ref when);
|
||||
|
||||
if (!History.ContainsKey(key))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
History[key].Clear();
|
||||
History.Remove(key);
|
||||
}
|
||||
|
||||
public void ClearHistory()
|
||||
{
|
||||
History.Values.ForEach(l => l.Clear());
|
||||
History.Clear();
|
||||
}
|
||||
|
||||
public List<TrashProfileEntry> GetHistory(DateTime when, int limit = 0)
|
||||
{
|
||||
return GetHistory(GenerateKey(ref when), limit);
|
||||
}
|
||||
|
||||
public List<TrashProfileEntry> GetHistory(TimeStamp key, int limit = 0)
|
||||
{
|
||||
var list = History.ContainsKey(key) ? History[key].ToList() : new List<TrashProfileEntry>();
|
||||
|
||||
if (limit > 0 && list.Count > limit)
|
||||
{
|
||||
list.RemoveRange(limit, list.Count - limit);
|
||||
}
|
||||
|
||||
list.Sort(InternalHistorySort);
|
||||
return list;
|
||||
}
|
||||
|
||||
public List<TrashProfileEntry> GetHistory(int limit = 0)
|
||||
{
|
||||
var list = History.SelectMany(kv => kv.Value).ToList();
|
||||
|
||||
if (limit > 0 && list.Count > limit)
|
||||
{
|
||||
list.RemoveRange(limit, list.Count - limit);
|
||||
}
|
||||
|
||||
list.Sort(InternalHistorySort);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public int GetTokenTotal(DateTime when)
|
||||
{
|
||||
return GetHistory(when).Sum(e => e.TokenAmount);
|
||||
}
|
||||
|
||||
public int GetTokenTotal()
|
||||
{
|
||||
return GetHistory().Sum(e => e.TokenAmount);
|
||||
}
|
||||
|
||||
public void Delete()
|
||||
{
|
||||
if (Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Deleted = true;
|
||||
ClearHistory();
|
||||
|
||||
this.Remove();
|
||||
}
|
||||
|
||||
public string ToHtmlString(Mobile viewer = null)
|
||||
{
|
||||
var html = new StringBuilder();
|
||||
|
||||
html.AppendLine(String.Format("Trash Collection Profile for <big>{0}</big>", Owner.RawName));
|
||||
html.AppendLine();
|
||||
|
||||
var totalToday = GetTokenTotal(DateTime.UtcNow);
|
||||
var totalAllTime = GetTokenTotal();
|
||||
var limitToday = TrashCollection.CMOptions.DailyLimit;
|
||||
|
||||
html.AppendLine(
|
||||
limitToday > 0
|
||||
? String.Format("Tokens Collected Today: <big>{0:#,0}</big>/<big>{1:#,0}</big>", totalToday, limitToday)
|
||||
: String.Format("Tokens Collected Today: <big>{0:#,0}</big>", totalToday));
|
||||
|
||||
html.AppendLine(String.Format("Tokens Collected Total: <big>{0:#,0}</big>", totalAllTime));
|
||||
|
||||
return html.ToString();
|
||||
}
|
||||
|
||||
public void Serialize(GenericWriter writer)
|
||||
{
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
writer.Write(Owner);
|
||||
writer.Write(Deleted);
|
||||
|
||||
if (!Deleted)
|
||||
{
|
||||
writer.WriteBlockDictionary(
|
||||
History,
|
||||
(w1, k, v) =>
|
||||
{
|
||||
w1.Write(k.Stamp);
|
||||
w1.WriteBlockList(v, (w2, e) => e.Serialize(w2));
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void Deserialize(GenericReader reader)
|
||||
{
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
Owner = reader.ReadMobile<PlayerMobile>();
|
||||
Deleted = reader.ReadBool();
|
||||
|
||||
if (!Deleted)
|
||||
{
|
||||
History = reader.ReadBlockDictionary(
|
||||
r1 =>
|
||||
{
|
||||
TimeStamp k = r1.ReadDouble();
|
||||
var v = r1.ReadBlockList(r2 => new TrashProfileEntry(r2));
|
||||
return new KeyValuePair<TimeStamp, List<TrashProfileEntry>>(k, v);
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
using Server.Commands;
|
||||
using Server.Mobiles;
|
||||
|
||||
using VitaNex.SuperGumps;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.TrashCollection
|
||||
{
|
||||
public sealed class TrashCollectionOptions : CoreModuleOptions
|
||||
{
|
||||
private string _AdminCommand;
|
||||
|
||||
private string _ProfilesCommand;
|
||||
|
||||
public TrashCollectionOptions()
|
||||
: base(typeof(TrashCollection))
|
||||
{
|
||||
AdminCommand = "TrashAdmin";
|
||||
ProfilesCommand = "TrashProfiles";
|
||||
DateFormat = "m/d/y";
|
||||
DailyLimit = 500;
|
||||
UseTrashedProps = true;
|
||||
GiveBonusTokens = false;
|
||||
}
|
||||
|
||||
public TrashCollectionOptions(GenericReader reader)
|
||||
: base(reader)
|
||||
{ }
|
||||
|
||||
[CommandProperty(TrashCollection.Access)]
|
||||
public string AdminCommand
|
||||
{
|
||||
get => _AdminCommand;
|
||||
set => CommandUtility.Replace(_AdminCommand, TrashCollection.Access, HandleAdminCommand, (_AdminCommand = value));
|
||||
}
|
||||
|
||||
[CommandProperty(TrashCollection.Access)]
|
||||
public string ProfilesCommand
|
||||
{
|
||||
get => _ProfilesCommand;
|
||||
set => CommandUtility.Replace(_ProfilesCommand, AccessLevel.Player, HandleProfilesCommand, (_ProfilesCommand = value));
|
||||
}
|
||||
|
||||
[CommandProperty(TrashCollection.Access)]
|
||||
public string DateFormat { get; set; }
|
||||
|
||||
[CommandProperty(TrashCollection.Access)]
|
||||
public int DailyLimit { get; set; }
|
||||
|
||||
[CommandProperty(TrashCollection.Access)]
|
||||
public bool UseTrashedProps { get; set; }
|
||||
|
||||
[CommandProperty(TrashCollection.Access)]
|
||||
public bool GiveBonusTokens { get; set; }
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
base.Clear();
|
||||
|
||||
DailyLimit = 0;
|
||||
UseTrashedProps = false;
|
||||
GiveBonusTokens = false;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
|
||||
AdminCommand = "TrashAdmin";
|
||||
ProfilesCommand = "TrashProfiles";
|
||||
|
||||
DailyLimit = 500;
|
||||
UseTrashedProps = true;
|
||||
GiveBonusTokens = false;
|
||||
}
|
||||
|
||||
public void HandleAdminCommand(CommandEventArgs e)
|
||||
{
|
||||
var m = e.Mobile as PlayerMobile;
|
||||
|
||||
if (m == null || m.Deleted || m.NetState == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ModuleEnabled || m.AccessLevel >= TrashCollection.Access)
|
||||
{
|
||||
SuperGump.Send(new TrashCollectionAdminGump(m));
|
||||
}
|
||||
else
|
||||
{
|
||||
m.SendMessage(0x22, "Trash Collection is currently out of service.");
|
||||
}
|
||||
}
|
||||
|
||||
public void HandleProfilesCommand(CommandEventArgs e)
|
||||
{
|
||||
var m = e.Mobile as PlayerMobile;
|
||||
|
||||
if (m == null || m.Deleted || m.NetState == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ModuleEnabled || m.AccessLevel >= TrashCollection.Access)
|
||||
{
|
||||
SuperGump.Send(new TrashCollectionProfilesGump(m));
|
||||
}
|
||||
else
|
||||
{
|
||||
m.SendMessage(0x22, "Trash Collection is currently out of service.");
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "Trash Options";
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
writer.Write(AdminCommand);
|
||||
writer.Write(ProfilesCommand);
|
||||
writer.Write(DateFormat);
|
||||
writer.Write(DailyLimit);
|
||||
writer.Write(UseTrashedProps);
|
||||
writer.Write(GiveBonusTokens);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
AdminCommand = reader.ReadString();
|
||||
ProfilesCommand = reader.ReadString();
|
||||
DateFormat = reader.ReadString();
|
||||
DailyLimit = reader.ReadInt();
|
||||
UseTrashedProps = reader.ReadBool();
|
||||
GiveBonusTokens = reader.ReadBool();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,339 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
|
||||
using VitaNex.IO;
|
||||
using VitaNex.Network;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.TrashCollection
|
||||
{
|
||||
public static partial class TrashCollection
|
||||
{
|
||||
public const AccessLevel Access = AccessLevel.Administrator;
|
||||
|
||||
public static Type[] HandlerTypes { get; private set; }
|
||||
|
||||
public static TrashCollectionOptions CMOptions { get; private set; }
|
||||
|
||||
public static BinaryDataStore<string, BaseTrashHandler> Handlers { get; private set; }
|
||||
public static BinaryDataStore<Mobile, TrashProfile> Profiles { get; private set; }
|
||||
|
||||
public static event Action<ItemTrashedEventArgs> OnTrashed;
|
||||
|
||||
public static List<TrashProfile> GetSortedProfiles(bool today = false)
|
||||
{
|
||||
var list = new List<TrashProfile>(Profiles.Values);
|
||||
|
||||
if (today)
|
||||
{
|
||||
list.Sort(InternalProfileSortToday);
|
||||
}
|
||||
else
|
||||
{
|
||||
list.Sort(InternalProfileSort);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private static int InternalProfileSort(TrashProfile a, TrashProfile b)
|
||||
{
|
||||
if (a == b)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a == null)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (b == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (a.Deleted && b.Deleted)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a.Deleted)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (b.Deleted)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
var aTotal = a.GetTokenTotal();
|
||||
var bTotal = b.GetTokenTotal();
|
||||
|
||||
if (aTotal > bTotal)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (aTotal < bTotal)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static int InternalProfileSortToday(TrashProfile a, TrashProfile b)
|
||||
{
|
||||
if (a == b)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a == null)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (b == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (a.Deleted && b.Deleted)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a.Deleted)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (b.Deleted)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
var when = DateTime.UtcNow;
|
||||
|
||||
var aTotal = a.GetTokenTotal(when);
|
||||
var bTotal = b.GetTokenTotal(when);
|
||||
|
||||
if (aTotal > bTotal)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (aTotal < bTotal)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static void InternalHandlerSort()
|
||||
{
|
||||
if (Handlers.Count < 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var list = new List<BaseTrashHandler>(Handlers.Values);
|
||||
list.Sort(InternalHandlerSort);
|
||||
|
||||
Handlers.Clear();
|
||||
|
||||
list.ForEach(
|
||||
h =>
|
||||
{
|
||||
if (!Handlers.ContainsKey(h.UID))
|
||||
{
|
||||
Handlers.Add(h.UID, h);
|
||||
}
|
||||
else
|
||||
{
|
||||
Handlers[h.UID] = h;
|
||||
}
|
||||
});
|
||||
|
||||
list.Clear();
|
||||
}
|
||||
|
||||
private static int InternalHandlerSort(BaseTrashHandler a, BaseTrashHandler b)
|
||||
{
|
||||
if (a == b)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a == null)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (b == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!a.Enabled && !b.Enabled)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!a.Enabled)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!b.Enabled)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (a.Priority > b.Priority)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (a.Priority < b.Priority)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static void InvalidateHandlers()
|
||||
{
|
||||
InternalHandlerSort();
|
||||
}
|
||||
|
||||
public static void Invoke(this ItemTrashedEventArgs e)
|
||||
{
|
||||
if (OnTrashed != null && e != null)
|
||||
{
|
||||
OnTrashed(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static TrashProfile EnsureProfile(Mobile m, bool replace = false)
|
||||
{
|
||||
if (m == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!Profiles.ContainsKey(m))
|
||||
{
|
||||
Profiles.Add(m, new TrashProfile(m));
|
||||
}
|
||||
else if (replace || Profiles[m] == null || Profiles[m].Deleted)
|
||||
{
|
||||
Profiles[m] = new TrashProfile(m);
|
||||
}
|
||||
|
||||
return Profiles[m];
|
||||
}
|
||||
|
||||
public static void Remove(this TrashProfile profile)
|
||||
{
|
||||
if (profile == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Profiles.ContainsKey(profile.Owner))
|
||||
{
|
||||
Profiles.Remove(profile.Owner);
|
||||
}
|
||||
|
||||
profile.Delete();
|
||||
}
|
||||
|
||||
public static void AddTrashProperties(Item item, Mobile viewer, ExtendedOPL list)
|
||||
{
|
||||
if (!CMOptions.ModuleEnabled || !CMOptions.UseTrashedProps || item == null || item.Deleted || viewer == null ||
|
||||
viewer.Deleted || list == null || !(item is ITrashTokenProperties) || !(viewer is PlayerMobile))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
InternalAddTrashProperties(viewer, list);
|
||||
}
|
||||
|
||||
public static void AddTrashProperties(Mobile m, Mobile viewer, ExtendedOPL list)
|
||||
{
|
||||
if (!CMOptions.ModuleEnabled || !CMOptions.UseTrashedProps || m == null || m.Deleted || viewer == null ||
|
||||
viewer.Deleted || list == null || !(m is ITrashTokenProperties) || !(viewer is PlayerMobile))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
InternalAddTrashProperties(viewer, list);
|
||||
}
|
||||
|
||||
private static void InternalAddTrashProperties(Mobile viewer, ExtendedOPL list)
|
||||
{
|
||||
if (!CMOptions.ModuleEnabled || !CMOptions.UseTrashedProps || viewer == null || viewer.Deleted || list == null ||
|
||||
!(viewer is PlayerMobile))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var p = EnsureProfile(viewer);
|
||||
|
||||
var todayTotal = p.GetTokenTotal(DateTime.UtcNow);
|
||||
var total = p.GetTokenTotal();
|
||||
|
||||
list.Add(
|
||||
"<basefont color=#{0:X6}>Total Tokens Earned: {1}",
|
||||
Color.SkyBlue.ToRgb(),
|
||||
total <= 0 ? "0" : total.ToString("#,#"));
|
||||
|
||||
if (CMOptions.DailyLimit > 0)
|
||||
{
|
||||
const int blocks = 10;
|
||||
var cur = (Math.Max(0, Math.Min(CMOptions.DailyLimit, (double)todayTotal)) / CMOptions.DailyLimit) * 100.0;
|
||||
var left = (int)Math.Floor(cur / blocks);
|
||||
var right = blocks - left;
|
||||
|
||||
list.Add("<basefont color=#{0:X6}>Tokens Earned Today:", Color.SkyBlue.ToRgb());
|
||||
list.Add(
|
||||
"[<basefont color=#{0:X6}>{1}<basefont color=#{2:X6}>{3}<basefont color=#{4:X6}>] {5}/{6}",
|
||||
Color.LimeGreen.ToRgb(),
|
||||
new string('=', left),
|
||||
Color.OrangeRed.ToRgb(),
|
||||
new string('=', right),
|
||||
Color.SkyBlue.ToRgb(),
|
||||
todayTotal <= 0 ? "0" : todayTotal.ToString("#,#"),
|
||||
CMOptions.DailyLimit.ToString("#,#"));
|
||||
}
|
||||
else
|
||||
{
|
||||
list.Add("Tokens Earned Today: {0}", todayTotal <= 0 ? "0" : todayTotal.ToString("#,#"));
|
||||
}
|
||||
|
||||
list.Add("<basefont color=#ffffff>");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Server;
|
||||
|
||||
using VitaNex.IO;
|
||||
using VitaNex.Network;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.TrashCollection
|
||||
{
|
||||
[CoreModule("Trash Collection", "1.0.0.1")]
|
||||
public static partial class TrashCollection
|
||||
{
|
||||
static TrashCollection()
|
||||
{
|
||||
HandlerTypes = typeof(BaseTrashHandler).GetConstructableChildren();
|
||||
|
||||
CMOptions = new TrashCollectionOptions();
|
||||
|
||||
Handlers = new BinaryDataStore<string, BaseTrashHandler>(VitaNexCore.SavesDirectory + "/TrashCollection", "Handlers")
|
||||
{
|
||||
OnSerialize = SerializeHandlers,
|
||||
OnDeserialize = DeserializeHandlers
|
||||
};
|
||||
|
||||
Profiles = new BinaryDataStore<Mobile, TrashProfile>(VitaNexCore.SavesDirectory + "/TrashCollection", "Profiles")
|
||||
{
|
||||
Async = true,
|
||||
OnSerialize = SerializeProfiles,
|
||||
OnDeserialize = DeserializeProfiles
|
||||
};
|
||||
}
|
||||
|
||||
private static void CMConfig()
|
||||
{
|
||||
var handlers = new List<BaseTrashHandler>();
|
||||
|
||||
var count = 0;
|
||||
|
||||
HandlerTypes.ForEach(
|
||||
type =>
|
||||
{
|
||||
var handler = type.CreateInstance<BaseTrashHandler>();
|
||||
|
||||
if (handler == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
handlers.Update(handler);
|
||||
|
||||
if (CMOptions.ModuleDebug)
|
||||
{
|
||||
CMOptions.ToConsole(
|
||||
"Created trash handler '{0}' ({1})",
|
||||
handler.GetType().Name,
|
||||
handler.Enabled ? "Enabled" : "Disabled");
|
||||
}
|
||||
|
||||
++count;
|
||||
});
|
||||
|
||||
CMOptions.ToConsole("Created {0:#,0} trash handler{1}", count, count != 1 ? "s" : String.Empty);
|
||||
|
||||
handlers.ForEach(h => Handlers[h.UID] = h);
|
||||
handlers.Free(true);
|
||||
|
||||
ExtendedOPL.OnItemOPLRequest += AddTrashProperties;
|
||||
ExtendedOPL.OnMobileOPLRequest += AddTrashProperties;
|
||||
}
|
||||
|
||||
private static void CMEnabled()
|
||||
{
|
||||
ExtendedOPL.OnItemOPLRequest += AddTrashProperties;
|
||||
ExtendedOPL.OnMobileOPLRequest += AddTrashProperties;
|
||||
}
|
||||
|
||||
private static void CMDisabled()
|
||||
{
|
||||
ExtendedOPL.OnItemOPLRequest -= AddTrashProperties;
|
||||
ExtendedOPL.OnMobileOPLRequest -= AddTrashProperties;
|
||||
}
|
||||
|
||||
private static void CMInvoke()
|
||||
{
|
||||
InternalHandlerSort();
|
||||
}
|
||||
|
||||
private static void CMSave()
|
||||
{
|
||||
var result = Handlers.Export();
|
||||
CMOptions.ToConsole("{0:#,0} handlers saved, {1}", Handlers.Count, result);
|
||||
|
||||
result = Profiles.Export();
|
||||
CMOptions.ToConsole("{0:#,0} profiles saved, {1}", Profiles.Count, result);
|
||||
}
|
||||
|
||||
private static void CMLoad()
|
||||
{
|
||||
var result = Handlers.Import();
|
||||
CMOptions.ToConsole("{0:#,0} handlers loaded, {1}.", Handlers.Count, result);
|
||||
|
||||
result = Profiles.Import();
|
||||
CMOptions.ToConsole("{0:#,0} profiles loaded, {1}.", Profiles.Count, result);
|
||||
}
|
||||
|
||||
private static bool SerializeHandlers(GenericWriter writer)
|
||||
{
|
||||
writer.WriteBlockCollection(Handlers.Values, (w, obj) => w.WriteType(obj, t => obj.Serialize(w)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool DeserializeHandlers(GenericReader reader)
|
||||
{
|
||||
foreach (var h in reader.ReadBlockCollection(r => r.ReadTypeCreate<BaseTrashHandler>(r)))
|
||||
{
|
||||
if (h != null && h.UID != null)
|
||||
{
|
||||
Handlers[h.UID] = h;
|
||||
}
|
||||
}
|
||||
|
||||
InternalHandlerSort();
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool SerializeProfiles(GenericWriter writer)
|
||||
{
|
||||
writer.WriteBlockCollection(Profiles.Values, (w, obj) => obj.Serialize(w));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool DeserializeProfiles(GenericReader reader)
|
||||
{
|
||||
foreach (var p in reader.ReadBlockCollection(r => new TrashProfile(r)))
|
||||
{
|
||||
if (p != null && p.Owner != null)
|
||||
{
|
||||
Profiles[p.Owner] = p;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
|
||||
using Server;
|
||||
using Server.Gumps;
|
||||
|
||||
using VitaNex.SuperGumps.UI;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.TrashCollection
|
||||
{
|
||||
public sealed class TrashCollectionAdminGump : ListGump<BaseTrashHandler>
|
||||
{
|
||||
public TrashCollectionAdminGump(Mobile user, Gump parent = null)
|
||||
: base(user, parent, emptyText: "There are no trash handlers to display.", title: "Trash Collection Control Panel")
|
||||
{
|
||||
ForceRecompile = true;
|
||||
}
|
||||
|
||||
public override string GetSearchKeyFor(BaseTrashHandler key)
|
||||
{
|
||||
return key != null ? key.GetType().FullName : base.GetSearchKeyFor(null);
|
||||
}
|
||||
|
||||
protected override int GetLabelHue(int index, int pageIndex, BaseTrashHandler entry)
|
||||
{
|
||||
return entry != null ? (entry.Enabled ? HighlightHue : ErrorHue) : base.GetLabelHue(index, pageIndex, null);
|
||||
}
|
||||
|
||||
protected override string GetLabelText(int index, int pageIndex, BaseTrashHandler entry)
|
||||
{
|
||||
return entry != null ? entry.GetType().Name : base.GetLabelText(index, pageIndex, null);
|
||||
}
|
||||
|
||||
protected override void CompileList(List<BaseTrashHandler> list)
|
||||
{
|
||||
list.Clear();
|
||||
list.AddRange(TrashCollection.Handlers.Values);
|
||||
base.CompileList(list);
|
||||
}
|
||||
|
||||
protected override void CompileMenuOptions(MenuGumpOptions list)
|
||||
{
|
||||
if (User.AccessLevel >= TrashCollection.Access)
|
||||
{
|
||||
list.AppendEntry(new ListGumpEntry("System Options", OpenConfig, HighlightHue));
|
||||
}
|
||||
|
||||
list.AppendEntry(new ListGumpEntry("View Profiles", ShowProfiles));
|
||||
list.AppendEntry(new ListGumpEntry("Help", ShowHelp));
|
||||
base.CompileMenuOptions(list);
|
||||
}
|
||||
|
||||
protected override void SelectEntry(GumpButton button, BaseTrashHandler entry)
|
||||
{
|
||||
base.SelectEntry(button, entry);
|
||||
|
||||
var opts = new MenuGumpOptions();
|
||||
|
||||
if (User.AccessLevel >= TrashCollection.Access)
|
||||
{
|
||||
opts.AppendEntry(
|
||||
new ListGumpEntry(
|
||||
"Options",
|
||||
b =>
|
||||
{
|
||||
Refresh();
|
||||
|
||||
var pg = new PropertiesGump(User, Selected)
|
||||
{
|
||||
X = b.X,
|
||||
Y = b.Y
|
||||
};
|
||||
User.SendGump(pg);
|
||||
},
|
||||
HighlightHue));
|
||||
|
||||
opts.AppendEntry(
|
||||
new ListGumpEntry(
|
||||
"Accept List",
|
||||
b => Send(new TrashHandlerAcceptListGump(User, entry, Hide(true))),
|
||||
HighlightHue));
|
||||
|
||||
opts.AppendEntry(
|
||||
new ListGumpEntry(
|
||||
"Ignore List",
|
||||
b => Send(new TrashHandlerIgnoreListGump(User, entry, Hide(true))),
|
||||
HighlightHue));
|
||||
|
||||
opts.AppendEntry(
|
||||
new ListGumpEntry(
|
||||
entry.Enabled ? "Disable" : "Enable",
|
||||
b1 =>
|
||||
{
|
||||
entry.Enabled = !entry.Enabled;
|
||||
Refresh(true);
|
||||
},
|
||||
entry.Enabled ? ErrorHue : HighlightHue));
|
||||
|
||||
opts.AppendEntry(new ListGumpEntry("Cancel", b => { }));
|
||||
}
|
||||
|
||||
Send(new MenuGump(User, Refresh(), opts, button));
|
||||
}
|
||||
|
||||
private void OpenConfig(GumpButton btn)
|
||||
{
|
||||
Minimize();
|
||||
|
||||
var p = new PropertiesGump(User, TrashCollection.CMOptions)
|
||||
{
|
||||
X = X + btn.X,
|
||||
Y = Y + btn.Y
|
||||
};
|
||||
|
||||
User.SendGump(p);
|
||||
}
|
||||
|
||||
private void ShowProfiles(GumpButton button)
|
||||
{
|
||||
if (User != null && !User.Deleted)
|
||||
{
|
||||
Send(new TrashCollectionProfilesGump(User, Hide()));
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowHelp(GumpButton button)
|
||||
{
|
||||
if (User == null || User.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var sb = TrashCollectionGumpUtility.GetHelpText(User);
|
||||
Send(
|
||||
new HtmlPanelGump<StringBuilder>(User, Refresh())
|
||||
{
|
||||
Selected = sb,
|
||||
Html = sb.ToString(),
|
||||
Title = "Trash Collection Help",
|
||||
HtmlColor = Color.SkyBlue
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Server;
|
||||
using Server.Gumps;
|
||||
|
||||
using VitaNex.SuperGumps.UI;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.TrashCollection
|
||||
{
|
||||
public class TrashHandlerAcceptListGump : TypeListGump
|
||||
{
|
||||
public TrashHandlerAcceptListGump(Mobile user, BaseTrashHandler handler, Gump parent = null)
|
||||
: base(
|
||||
user,
|
||||
parent,
|
||||
list: handler.Accepted,
|
||||
title: handler.GetType().Name + " Accept List",
|
||||
emptyText: "There are no Types in the list.")
|
||||
{
|
||||
TrashHandler = handler;
|
||||
}
|
||||
|
||||
public BaseTrashHandler TrashHandler { get; set; }
|
||||
|
||||
public override List<Type> GetExternalList()
|
||||
{
|
||||
return TrashHandler.Accepted;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Server;
|
||||
using Server.Gumps;
|
||||
|
||||
using VitaNex.SuperGumps.UI;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.TrashCollection
|
||||
{
|
||||
public class TrashHandlerIgnoreListGump : TypeListGump
|
||||
{
|
||||
public TrashHandlerIgnoreListGump(Mobile user, BaseTrashHandler handler, Gump parent = null)
|
||||
: base(
|
||||
user,
|
||||
parent,
|
||||
list: handler.Ignored,
|
||||
title: handler.GetType().Name + " Ignore List",
|
||||
emptyText: "There are no Types in the list.")
|
||||
{
|
||||
TrashHandler = handler;
|
||||
}
|
||||
|
||||
public BaseTrashHandler TrashHandler { get; set; }
|
||||
|
||||
public override List<Type> GetExternalList()
|
||||
{
|
||||
return TrashHandler.Ignored;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,253 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Server;
|
||||
using Server.Gumps;
|
||||
|
||||
using VitaNex.SuperGumps.UI;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.TrashCollection
|
||||
{
|
||||
public sealed class TrashCollectionProfileHistoryGump : HtmlPanelGump<TrashProfile>
|
||||
{
|
||||
public DateTime? HistoryDate { get; set; }
|
||||
public bool UseConfirmDialog { get; set; }
|
||||
public bool TechnicalView { get; set; }
|
||||
|
||||
public TrashCollectionProfileHistoryGump(
|
||||
Mobile user,
|
||||
TrashProfile profile,
|
||||
Gump parent = null,
|
||||
bool useConfirm = true,
|
||||
DateTime? when = null)
|
||||
: base(user, parent, emptyText: "No profile selected.", title: "Trash Profile History", selected: profile)
|
||||
{
|
||||
HtmlColor = Color.SkyBlue;
|
||||
UseConfirmDialog = useConfirm;
|
||||
HistoryDate = when;
|
||||
}
|
||||
|
||||
protected override void Compile()
|
||||
{
|
||||
base.Compile();
|
||||
|
||||
if (Selected == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Html = String.Format("<basefont color=#{0:X6}>", HtmlColor.ToRgb());
|
||||
|
||||
if (HistoryDate != null && HistoryDate.Value <= DateTime.UtcNow)
|
||||
{
|
||||
Html += String.Format(
|
||||
"Viewing History for {0} on {1}\n\n",
|
||||
Selected.Owner.RawName,
|
||||
HistoryDate.Value.ToSimpleString(TrashCollection.CMOptions.DateFormat));
|
||||
|
||||
Html += "<big>Showing up to 500 entries...</big>\n\n";
|
||||
|
||||
Html += String.Join("\n", Selected.GetHistory(HistoryDate.Value, 500).Select(e => e.ToHtmlString(TechnicalView)));
|
||||
}
|
||||
else
|
||||
{
|
||||
Html += String.Format("Viewing Recent History for {0}\n\n", Selected.Owner.RawName);
|
||||
|
||||
Html += "<big>Showing up to 500 entries...</big>\n\n";
|
||||
|
||||
Html += String.Join("\n", Selected.GetHistory(500).Select(e => e.ToHtmlString(TechnicalView)));
|
||||
}
|
||||
}
|
||||
|
||||
protected override void CompileMenuOptions(MenuGumpOptions list)
|
||||
{
|
||||
if (Selected == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (User.AccessLevel >= TrashCollection.Access)
|
||||
{
|
||||
list.AppendEntry(new ListGumpEntry("Clear History", ClearHistory, HighlightHue));
|
||||
list.AppendEntry(new ListGumpEntry("Delete Profile", DeleteProfile, HighlightHue));
|
||||
|
||||
if (TechnicalView)
|
||||
{
|
||||
list.Replace(
|
||||
"Technical View",
|
||||
new ListGumpEntry(
|
||||
"Standard View",
|
||||
b =>
|
||||
{
|
||||
TechnicalView = false;
|
||||
Refresh(true);
|
||||
},
|
||||
HighlightHue));
|
||||
}
|
||||
else
|
||||
{
|
||||
list.Replace(
|
||||
"Standard View",
|
||||
new ListGumpEntry(
|
||||
"Technical View",
|
||||
b =>
|
||||
{
|
||||
TechnicalView = true;
|
||||
Refresh(true);
|
||||
},
|
||||
HighlightHue));
|
||||
}
|
||||
}
|
||||
|
||||
list.AppendEntry(
|
||||
new ListGumpEntry(
|
||||
"Show Recent",
|
||||
b =>
|
||||
{
|
||||
HistoryDate = null;
|
||||
Refresh(true);
|
||||
}));
|
||||
|
||||
list.AppendEntry(
|
||||
new ListGumpEntry(
|
||||
"Show Today",
|
||||
b =>
|
||||
{
|
||||
HistoryDate = DateTime.UtcNow;
|
||||
Refresh(true);
|
||||
}));
|
||||
|
||||
list.AppendEntry(
|
||||
new ListGumpEntry(
|
||||
"Select Date",
|
||||
b => Send(
|
||||
new InputDateDialogGump(User, Refresh())
|
||||
{
|
||||
Title = "Select Date",
|
||||
Html = "Type the date you wish to view history for.",
|
||||
InputDate = HistoryDate,
|
||||
MaxDate = DateTime.UtcNow,
|
||||
CallbackDate = (b1, d) =>
|
||||
{
|
||||
if (d.HasValue)
|
||||
{
|
||||
HistoryDate = d.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
User.SendMessage(0x22, "No valid date was given.");
|
||||
}
|
||||
|
||||
Refresh(true);
|
||||
}
|
||||
})));
|
||||
|
||||
list.AppendEntry(new ListGumpEntry("Help", ShowHelp));
|
||||
|
||||
base.CompileMenuOptions(list);
|
||||
}
|
||||
|
||||
private void ClearHistory(GumpButton button)
|
||||
{
|
||||
if (Selected == null || Selected.Deleted)
|
||||
{
|
||||
Selected = TrashCollection.EnsureProfile(User);
|
||||
}
|
||||
|
||||
if (UseConfirmDialog)
|
||||
{
|
||||
Send(
|
||||
new ConfirmDialogGump(User, Refresh())
|
||||
{
|
||||
Title = "Clear Profile History?",
|
||||
Html =
|
||||
"All data associated with the profile history will be lost.\nThis action can not be reversed!\nDo you want to continue?",
|
||||
AcceptHandler = ConfirmClearHistory
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Selected.ClearHistory();
|
||||
Refresh(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void DeleteProfile(GumpButton button)
|
||||
{
|
||||
if (Selected == null || Selected.Deleted)
|
||||
{
|
||||
Selected = TrashCollection.EnsureProfile(User);
|
||||
}
|
||||
|
||||
if (UseConfirmDialog)
|
||||
{
|
||||
Send(
|
||||
new ConfirmDialogGump(User, Refresh())
|
||||
{
|
||||
Title = "Delete Profile?",
|
||||
Html =
|
||||
"All data associated with this profile will be deleted.\nThis action can not be reversed!\nDo you want to continue?",
|
||||
AcceptHandler = ConfirmDeleteProfile
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Selected.Delete();
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
private void ConfirmClearHistory(GumpButton button)
|
||||
{
|
||||
if (Selected != null && !Selected.Deleted)
|
||||
{
|
||||
Selected.ClearHistory();
|
||||
}
|
||||
|
||||
Refresh(true);
|
||||
}
|
||||
|
||||
private void ConfirmDeleteProfile(GumpButton button)
|
||||
{
|
||||
if (Selected != null && !Selected.Deleted)
|
||||
{
|
||||
Selected.Delete();
|
||||
}
|
||||
|
||||
Close();
|
||||
}
|
||||
|
||||
private void ShowHelp(GumpButton button)
|
||||
{
|
||||
if (User == null || User.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var sb = TrashCollectionGumpUtility.GetHelpText(User);
|
||||
Send(
|
||||
new HtmlPanelGump<StringBuilder>(User, Refresh())
|
||||
{
|
||||
Selected = sb,
|
||||
Html = sb.ToString(),
|
||||
Title = "Trash Collection Help",
|
||||
HtmlColor = Color.SkyBlue
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
|
||||
using Server;
|
||||
using Server.Gumps;
|
||||
|
||||
using VitaNex.SuperGumps.UI;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.TrashCollection
|
||||
{
|
||||
public class TrashCollectionProfileGump : HtmlPanelGump<TrashProfile>
|
||||
{
|
||||
public bool UseConfirmDialog { get; set; }
|
||||
|
||||
public TrashCollectionProfileGump(Mobile user, TrashProfile profile, Gump parent = null, bool useConfirm = true)
|
||||
: base(user, parent, emptyText: "No profile selected.", title: "Trash Collection Profile", selected: profile)
|
||||
{
|
||||
UseConfirmDialog = useConfirm;
|
||||
HtmlColor = Color.SkyBlue;
|
||||
}
|
||||
|
||||
protected override void Compile()
|
||||
{
|
||||
base.Compile();
|
||||
|
||||
if (Selected == null || Selected.Deleted)
|
||||
{
|
||||
Selected = TrashCollection.EnsureProfile(User, true);
|
||||
}
|
||||
|
||||
Html = String.Format("<basefont color=#{0:X6}>", HtmlColor.ToRgb());
|
||||
Html += Selected.ToHtmlString(User);
|
||||
}
|
||||
|
||||
protected override void CompileMenuOptions(MenuGumpOptions list)
|
||||
{
|
||||
if (Selected == null || Selected.Deleted)
|
||||
{
|
||||
Selected = TrashCollection.EnsureProfile(User, true);
|
||||
}
|
||||
|
||||
if (User.AccessLevel >= TrashCollection.Access)
|
||||
{
|
||||
list.AppendEntry(new ListGumpEntry("Clear History", OnClearHistory, HighlightHue));
|
||||
list.AppendEntry(new ListGumpEntry("Delete Profile", OnDeleteProfile, HighlightHue));
|
||||
}
|
||||
|
||||
list.AppendEntry(new ListGumpEntry("View History", OnViewHistory, HighlightHue));
|
||||
|
||||
list.AppendEntry(new ListGumpEntry("Help", ShowHelp));
|
||||
|
||||
base.CompileMenuOptions(list);
|
||||
}
|
||||
|
||||
private void OnViewHistory(GumpButton button)
|
||||
{
|
||||
if (Selected == null || Selected.Deleted)
|
||||
{
|
||||
Selected = TrashCollection.EnsureProfile(User);
|
||||
}
|
||||
|
||||
Send(new TrashCollectionProfileHistoryGump(User, Selected, Hide(true), UseConfirmDialog, DateTime.UtcNow));
|
||||
}
|
||||
|
||||
protected virtual void OnClearHistory(GumpButton button)
|
||||
{
|
||||
if (Selected == null || Selected.Deleted)
|
||||
{
|
||||
Selected = TrashCollection.EnsureProfile(User);
|
||||
}
|
||||
|
||||
if (UseConfirmDialog)
|
||||
{
|
||||
Send(
|
||||
new ConfirmDialogGump(User, Refresh())
|
||||
{
|
||||
Title = "Clear Profile History?",
|
||||
Html = "All data associated with the profile history will be lost.\n" +
|
||||
"This action can not be reversed!\nDo you want to continue?",
|
||||
AcceptHandler = OnConfirmClearHistory
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Selected.ClearHistory();
|
||||
Refresh(true);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnDeleteProfile(GumpButton button)
|
||||
{
|
||||
if (Selected == null || Selected.Deleted)
|
||||
{
|
||||
Selected = TrashCollection.EnsureProfile(User);
|
||||
}
|
||||
|
||||
if (UseConfirmDialog)
|
||||
{
|
||||
Send(
|
||||
new ConfirmDialogGump(User, Refresh())
|
||||
{
|
||||
Title = "Delete Profile?",
|
||||
Html = "All data associated with this profile will be deleted.\n" +
|
||||
"This action can not be reversed!\nDo you want to continue?",
|
||||
AcceptHandler = ConfirmDeleteProfile
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Selected.Delete();
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnConfirmClearHistory(GumpButton button)
|
||||
{
|
||||
if (Selected != null && !Selected.Deleted)
|
||||
{
|
||||
Selected.ClearHistory();
|
||||
}
|
||||
|
||||
Refresh(true);
|
||||
}
|
||||
|
||||
protected virtual void ConfirmDeleteProfile(GumpButton button)
|
||||
{
|
||||
if (Selected != null && !Selected.Deleted)
|
||||
{
|
||||
Selected.Delete();
|
||||
}
|
||||
|
||||
Close();
|
||||
}
|
||||
|
||||
private void ShowHelp(GumpButton button)
|
||||
{
|
||||
if (User == null || User.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var sb = TrashCollectionGumpUtility.GetHelpText(User);
|
||||
Send(
|
||||
new HtmlPanelGump<StringBuilder>(User, Refresh())
|
||||
{
|
||||
Selected = sb,
|
||||
Html = sb.ToString(),
|
||||
Title = "Trash Collection Help",
|
||||
HtmlColor = Color.SkyBlue
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Server;
|
||||
using Server.Gumps;
|
||||
|
||||
using VitaNex.SuperGumps;
|
||||
using VitaNex.SuperGumps.UI;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.TrashCollection
|
||||
{
|
||||
public class TrashCollectionProfilesGump : ListGump<TrashProfile>
|
||||
{
|
||||
public bool SortByToday { get; set; }
|
||||
public bool UseConfirmDialog { get; set; }
|
||||
|
||||
public TrashCollectionProfilesGump(Mobile user, Gump parent = null, bool useConfirm = true, bool sortByToday = false)
|
||||
: base(user, parent, emptyText: "There are no profiles to display.", title: "Trash Collection Profiles")
|
||||
{
|
||||
UseConfirmDialog = useConfirm;
|
||||
SortByToday = sortByToday;
|
||||
|
||||
ForceRecompile = true;
|
||||
CanMove = false;
|
||||
CanResize = false;
|
||||
}
|
||||
|
||||
protected override void Compile()
|
||||
{
|
||||
base.Compile();
|
||||
|
||||
Title = String.Format("Trash Collection Profiles ({0})", (List.Count > 0) ? List.Count.ToString("#,#") : "0");
|
||||
}
|
||||
|
||||
protected override void CompileMenuOptions(MenuGumpOptions list)
|
||||
{
|
||||
list.Clear();
|
||||
|
||||
if (User.AccessLevel >= TrashCollection.Access)
|
||||
{
|
||||
list.AppendEntry(
|
||||
new ListGumpEntry(
|
||||
"Delete All",
|
||||
button => Send(
|
||||
new ConfirmDialogGump(User, this)
|
||||
{
|
||||
Title = "Delete All Profiles?",
|
||||
Html = "All profiles in the database will be deleted, erasing all data associated with them.\n" +
|
||||
"This action can not be reversed.\n\nDo you want to continue?",
|
||||
AcceptHandler = subButton =>
|
||||
{
|
||||
TrashCollection.Profiles.Values.ToArray().Where(p => p != null && !p.Deleted).ForEach(p => p.Delete());
|
||||
|
||||
Refresh(true);
|
||||
}
|
||||
}),
|
||||
ErrorHue));
|
||||
}
|
||||
|
||||
list.AppendEntry(new ListGumpEntry("My Profile", OnMyProfile, HighlightHue));
|
||||
|
||||
list.AppendEntry(
|
||||
new ListGumpEntry(
|
||||
SortByToday ? "Sort by Grand Total" : "Sort by Today's Total",
|
||||
b =>
|
||||
{
|
||||
SortByToday = !SortByToday;
|
||||
Refresh(true);
|
||||
}));
|
||||
|
||||
list.AppendEntry(new ListGumpEntry("Help", ShowHelp));
|
||||
|
||||
base.CompileMenuOptions(list);
|
||||
}
|
||||
|
||||
protected override void CompileList(List<TrashProfile> list)
|
||||
{
|
||||
list.Clear();
|
||||
list.AddRange(TrashCollection.GetSortedProfiles(SortByToday));
|
||||
base.CompileList(list);
|
||||
}
|
||||
|
||||
public override string GetSearchKeyFor(TrashProfile key)
|
||||
{
|
||||
return key != null && !key.Deleted ? key.Owner.RawName : base.GetSearchKeyFor(key);
|
||||
}
|
||||
|
||||
protected override void CompileLayout(SuperGumpLayout layout)
|
||||
{
|
||||
base.CompileLayout(layout);
|
||||
|
||||
layout.Replace(
|
||||
"label/header/title",
|
||||
() => AddLabelCropped(160, 15, 215, 20, GetTitleHue(), String.IsNullOrEmpty(Title) ? DefaultTitle : Title));
|
||||
}
|
||||
|
||||
protected override void CompileEntryLayout(
|
||||
SuperGumpLayout layout,
|
||||
int length,
|
||||
int index,
|
||||
int pIndex,
|
||||
int yOffset,
|
||||
TrashProfile entry)
|
||||
{
|
||||
base.CompileEntryLayout(layout, length, index, pIndex, yOffset, entry);
|
||||
|
||||
layout.Replace(
|
||||
"label/list/entry/" + index,
|
||||
() =>
|
||||
{
|
||||
AddLabelCropped(65, 2 + yOffset, 160, 20, GetLabelHue(index, pIndex, entry), GetLabelText(index, pIndex, entry));
|
||||
AddLabelCropped(
|
||||
225,
|
||||
2 + yOffset,
|
||||
150,
|
||||
20,
|
||||
GetSortLabelHue(index, pIndex, entry),
|
||||
GetSortLabelText(index, pIndex, entry));
|
||||
});
|
||||
}
|
||||
|
||||
protected override int GetLabelHue(int index, int pageIndex, TrashProfile entry)
|
||||
{
|
||||
return index < 3
|
||||
? HighlightHue
|
||||
: (entry != null
|
||||
? Notoriety.GetHue(Notoriety.Compute(User, entry.Owner))
|
||||
: base.GetLabelHue(index, pageIndex, null));
|
||||
}
|
||||
|
||||
protected override string GetLabelText(int index, int pageIndex, TrashProfile entry)
|
||||
{
|
||||
return entry != null && entry.Owner != null
|
||||
? String.Format("{0}: {1}", (index + 1).ToString("#,#"), entry.Owner.RawName)
|
||||
: base.GetLabelText(index, pageIndex, entry);
|
||||
}
|
||||
|
||||
protected virtual string GetSortLabelText(int index, int pageIndex, TrashProfile entry)
|
||||
{
|
||||
if (entry != null)
|
||||
{
|
||||
var val = SortByToday ? entry.GetTokenTotal(DateTime.UtcNow) : entry.GetTokenTotal();
|
||||
return String.Format("Tokens: {0}", (val > 0) ? val.ToString("#,#") : "0");
|
||||
}
|
||||
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
protected virtual int GetSortLabelHue(int index, int pageIndex, TrashProfile entry)
|
||||
{
|
||||
return entry != null ? ((index < 3) ? HighlightHue : TextHue) : ErrorHue;
|
||||
}
|
||||
|
||||
protected override void SelectEntry(GumpButton button, TrashProfile entry)
|
||||
{
|
||||
base.SelectEntry(button, entry);
|
||||
|
||||
if (button != null && entry != null && !entry.Deleted)
|
||||
{
|
||||
Send(new TrashCollectionProfileGump(User, entry, Hide(true), UseConfirmDialog));
|
||||
}
|
||||
}
|
||||
|
||||
private void OnMyProfile(GumpButton button)
|
||||
{
|
||||
Send(new TrashCollectionProfileGump(User, TrashCollection.EnsureProfile(User), Hide(true), UseConfirmDialog));
|
||||
}
|
||||
|
||||
private void ShowHelp(GumpButton button)
|
||||
{
|
||||
if (User == null || User.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var sb = TrashCollectionGumpUtility.GetHelpText(User);
|
||||
Send(
|
||||
new HtmlPanelGump<StringBuilder>(User, Refresh())
|
||||
{
|
||||
Selected = sb,
|
||||
Html = sb.ToString(),
|
||||
Title = "Trash Collection Help",
|
||||
HtmlColor = Color.SkyBlue
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
|
||||
using Server;
|
||||
using Server.Commands;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Modules.TrashCollection
|
||||
{
|
||||
public static class TrashCollectionGumpUtility
|
||||
{
|
||||
public static StringBuilder GetHelpText(Mobile m)
|
||||
{
|
||||
var help = new StringBuilder();
|
||||
|
||||
help.AppendFormat("<basefont color=#{0:X6}>", Color.SkyBlue.ToRgb());
|
||||
help.AppendLine("The Trash Collection service allows you to trash items in exchange for currency (usually tokens).");
|
||||
|
||||
if (TrashCollection.CMOptions.DailyLimit > 0)
|
||||
{
|
||||
help.AppendLine();
|
||||
help.AppendFormat("<basefont color=#{0:X6}>", Color.Orange.ToRgb());
|
||||
help.AppendLine(
|
||||
String.Format(
|
||||
"There is a daily limit of {0:#,0} tokens, when you reach this limit you can still trash items, but will not receive any tokens.",
|
||||
TrashCollection.CMOptions.DailyLimit));
|
||||
}
|
||||
|
||||
help.AppendLine();
|
||||
help.AppendFormat("<basefont color=#{0:X6}>", Color.Yellow.ToRgb());
|
||||
help.AppendLine("Everything you successfully trash will be logged to your personal trash profile.");
|
||||
help.AppendLine("These logs are separated by day and can be viewed at any time.");
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(TrashCollection.CMOptions.ProfilesCommand))
|
||||
{
|
||||
help.AppendLine();
|
||||
help.AppendFormat("<basefont color=#{0:X6}>", Color.YellowGreen.ToRgb());
|
||||
help.AppendLine(
|
||||
String.Format(
|
||||
"To view trash profiles, use the <big>{0}{1}</big> command.",
|
||||
CommandSystem.Prefix,
|
||||
TrashCollection.CMOptions.ProfilesCommand));
|
||||
|
||||
if (m.AccessLevel >= TrashCollection.Access)
|
||||
{
|
||||
help.AppendLine("You have access to administrate the trash system, you can also manage profiles.");
|
||||
}
|
||||
}
|
||||
|
||||
if (m.AccessLevel >= TrashCollection.Access)
|
||||
{
|
||||
if (!String.IsNullOrWhiteSpace(TrashCollection.CMOptions.AdminCommand))
|
||||
{
|
||||
help.AppendLine();
|
||||
help.AppendFormat("<basefont color=#{0:X6}>", Color.LimeGreen.ToRgb());
|
||||
help.AppendLine(
|
||||
String.Format(
|
||||
"To administrate the trash system, use the <big>{0}{1}</big> command.",
|
||||
CommandSystem.Prefix,
|
||||
TrashCollection.CMOptions.AdminCommand));
|
||||
}
|
||||
}
|
||||
|
||||
return help;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user