Overwrite

Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
Unstable Kitsune
2023-11-28 23:20:26 -05:00
parent 3cd54811de
commit b918192e4e
11608 changed files with 2644205 additions and 47 deletions

View File

@@ -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();
}
}

View File

@@ -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();
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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; }
}
}

View File

@@ -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
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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>");
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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
});
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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
});
}
}
}

View File

@@ -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
});
}
}
}

View File

@@ -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
});
}
}
}

View File

@@ -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;
}
}
}