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,436 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#if ServUO58
#define ServUOX
#endif
#region References
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Server;
using Server.Mobiles;
using Server.Network;
using VitaNex.Network;
#endregion
namespace VitaNex.Modules.EquipmentSets
{
public static partial class EquipmentSets
{
public const AccessLevel Access = AccessLevel.Administrator;
private static readonly object _OPLLock = new object(), _INVLock = new object();
public static readonly Type TypeOfEquipmentSet = typeof(EquipmentSet);
public static EquipmentSetsOptions CMOptions { get; private set; }
public static Type[] SetTypes { get; private set; }
public static Dictionary<Type, EquipmentSet> Sets { get; private set; }
public static OutgoingPacketOverrideHandler EquipItemParent { get; private set; }
public static PacketHandler EquipItemRequestParent { get; private set; }
public static PacketHandler DropItemRequestParent { get; private set; }
#if !ServUOX
public static PacketHandler EquipItemRequestParent6017 { get; private set; }
public static PacketHandler DropItemRequestParent6017 { get; private set; }
#endif
private static void OnLogin(LoginEventArgs e)
{
if (CMOptions.ModuleEnabled && e.Mobile != null)
{
Invalidate(e.Mobile);
}
}
private static void GetProperties(Item item, Mobile viewer, ExtendedOPL list)
{
if (!CMOptions.ModuleEnabled || item == null || item.Deleted || !item.Layer.IsEquip() || list == null || World.Loading)
{
return;
}
if (viewer == null && item.Parent is Mobile)
{
viewer = (Mobile)item.Parent;
}
if (viewer == null)
{
return;
}
if (!item.BeginAction(_OPLLock))
{
return;
}
var itemType = item.GetType();
var equipped = item.IsEquipped() || item.IsShopItem();
var parent = item.Parent as Mobile;
var npc = parent != null && ((parent is BaseCreature || !parent.Player) && !parent.IsControlled<PlayerMobile>());
foreach (var set in FindSetsFor(itemType).Where(s => s.Display && !s.Parts.Any(p => p.Display && p.IsTypeOf(itemType) && !p.DisplaySet)))
{
set.GetProperties(viewer, list, equipped);
if (npc)
{
continue;
}
if (set.DisplayParts)
{
foreach (var part in set.Parts.Where(p => p.Display))
{
part.GetProperties(viewer, list, equipped);
}
}
if (!set.DisplayMods)
{
continue;
}
foreach (var mod in set.Mods.Where(mod => mod.Display))
{
mod.GetProperties(viewer, list, equipped);
}
}
item.EndAction(_OPLLock);
}
private static void EquipItem(NetState state, PacketReader reader, ref byte[] buffer, ref int length)
{
var pos = reader.Seek(0, SeekOrigin.Current);
reader.Seek(1, SeekOrigin.Begin);
#if ServUOX
var item = World.FindItem(reader.ReadSerial());
#else
var item = World.FindItem(reader.ReadInt32());
#endif
reader.Seek(pos, SeekOrigin.Begin);
if (EquipItemParent != null)
{
EquipItemParent(state, reader, ref buffer, ref length);
}
if (!CMOptions.ModuleEnabled || item == null || item.Deleted || !item.Layer.IsEquip())
{
return;
}
if (CMOptions.ModuleDebug)
{
CMOptions.ToConsole("EquipItem: {0} equiped {1}", state.Mobile, item);
}
Timer.DelayCall(Invalidate, state.Mobile);
}
private static void EquipItemRequest(NetState state, PacketReader pvSrc)
{
EquipItemRequest(EquipItemRequestParent, state, pvSrc);
}
#if !ServUOX
private static void EquipItemRequest6017(NetState state, PacketReader pvSrc)
{
EquipItemRequest(EquipItemRequestParent6017, state, pvSrc);
}
#endif
private static void EquipItemRequest(PacketHandler parent, NetState state, PacketReader pvSrc)
{
var item = state.Mobile.Holding;
if (parent != null && parent.OnReceive != null)
{
parent.OnReceive(state, pvSrc);
}
if (!CMOptions.ModuleEnabled || item == null || item.Deleted || !item.Layer.IsEquip())
{
return;
}
if (CMOptions.ModuleDebug)
{
CMOptions.ToConsole("EquipItemRequest: {0} equiping {1}", state.Mobile, item);
}
Timer.DelayCall(Invalidate, state.Mobile);
}
private static void DropItemRequest(NetState state, PacketReader pvSrc)
{
DropItemRequest(DropItemRequestParent, state, pvSrc);
}
#if !ServUOX
private static void DropItemRequest6017(NetState state, PacketReader pvSrc)
{
DropItemRequest(DropItemRequestParent6017, state, pvSrc);
}
#endif
private static void DropItemRequest(PacketHandler parent, NetState state, PacketReader pvSrc)
{
var item = state.Mobile.Holding;
if (parent != null && parent.OnReceive != null)
{
parent.OnReceive(state, pvSrc);
}
if (!CMOptions.ModuleEnabled || item == null || item.Deleted || !item.Layer.IsEquip())
{
return;
}
if (CMOptions.ModuleDebug)
{
CMOptions.ToConsole("DropItemRequest: {0} dropping {1}", state.Mobile, item);
}
Timer.DelayCall(Invalidate, state.Mobile);
}
public static T ResolveSet<T>() where T : EquipmentSet
{
return Sets.GetValue(typeof(T)) as T;
}
public static List<EquipmentSet> GetSetsFor(Item item)
{
return FindSetsFor(item.GetType()).ToList();
}
public static List<EquipmentSet> GetSetsFor(Type type)
{
return FindSetsFor(type).ToList();
}
public static IEnumerable<EquipmentSet> FindSetsFor(Item item)
{
return FindSetsFor(item.GetType());
}
public static IEnumerable<EquipmentSet> FindSetsFor(Type type)
{
return Sets.Values.Where(set => set.HasPartTypeOf(type));
}
public static void Invalidate(Mobile owner)
{
if (CMOptions.ModuleEnabled && owner != null)
{
owner.Items.ForEachReverse(item => Invalidate(owner, item));
}
}
public static void Invalidate(Mobile owner, Item item)
{
if (!CMOptions.ModuleEnabled || owner == null)
{
return;
}
if (item == null || item.Deleted || !item.Layer.IsEquip())
{
return;
}
if (!item.BeginAction(_INVLock))
{
return;
}
if (!CMOptions.ModuleDebug)
{
foreach (var set in FindSetsFor(item))
{
set.Invalidate(owner, item);
}
}
else
{
var sets = GetSetsFor(item);
CMOptions.ToConsole("Found {0} sets for '{1}'", sets.Count, item);
if (sets.Count > 0)
{
CMOptions.ToConsole("'{0}'", String.Join("', '", sets.Select(s => s.Name)));
sets.ForEach(set => set.Invalidate(owner, item));
}
sets.Free(true);
}
item.EndAction(_INVLock);
}
public static IEnumerable<EquipmentSet> FindActiveSets(Mobile owner)
{
return Sets.Values.Where(s => s.ActiveOwners.Contains(owner));
}
public static IEnumerable<EquipmentSetMod> FindActiveMods(Mobile owner)
{
return FindActiveSets(owner).SelectMany(s => s.Mods.Where(m => m.ActiveOwners.Contains(owner)));
}
public static IEnumerable<EquipmentSetPart> FindEquippedParts(Mobile owner)
{
return FindActiveSets(owner).SelectMany(s => s.Parts.Where(p => p.EquipOwners.Contains(owner)));
}
public static IEnumerable<T> FindActiveSets<T>(Mobile owner) where T : EquipmentSet
{
return Sets.Values.OfType<T>().Where(s => s.ActiveOwners.Contains(owner));
}
public static IEnumerable<T> FindActiveMods<T>(Mobile owner) where T : EquipmentSetMod
{
return FindActiveSets(owner).SelectMany(s => s.Mods.OfType<T>().Where(m => m.IsActive(owner)));
}
public static IEnumerable<T> FindEquippedParts<T>(Mobile owner) where T : EquipmentSetPart
{
return FindActiveSets(owner).SelectMany(s => s.Parts.OfType<T>().Where(p => p.IsEquipped(owner)));
}
public static int AddSet<T>(Mobile owner) where T : EquipmentSet, new()
{
return AddSet<T>(owner, null);
}
public static int AddSet<T>(Mobile owner, Action<Item> action) where T : EquipmentSet, new()
{
var count = 0;
foreach (var o in GenerateEquip<T>(owner))
{
++count;
if (action != null)
{
action(o);
}
}
return count;
}
public static int AddSet(Type setType, Mobile owner)
{
return AddSet(setType, owner, null);
}
public static int AddSet(Type setType, Mobile owner, Action<Item> action)
{
var count = 0;
foreach (var o in GenerateEquip(setType, owner))
{
++count;
if (action != null)
{
action(o);
}
}
return count;
}
public static Item GenerateRandomPart<T>() where T : EquipmentSet, new()
{
return GenerateRandomPart(typeof(T));
}
public static Item GenerateRandomPart(Type setType)
{
var set = Sets.GetValue(setType);
return set == null ? null : set.GenerateRandomPart();
}
public static IEnumerable<Item> GenerateParts<T>() where T : EquipmentSet, new()
{
return GenerateParts(typeof(T));
}
public static IEnumerable<Item> GenerateParts(Type setType)
{
var set = Sets.GetValue(setType);
if (set == null)
{
yield break;
}
var parts = set.GenerateParts();
if (parts == null)
{
yield break;
}
foreach (var p in parts)
{
yield return p;
}
}
public static IEnumerable<Item> GenerateEquip<T>(Mobile owner) where T : EquipmentSet, new()
{
return GenerateEquip(typeof(T), owner);
}
public static IEnumerable<Item> GenerateEquip(Type setType, Mobile owner)
{
foreach (var p in GenerateParts(setType))
{
if (!owner.EquipItem(p) && (!owner.Player || !owner.PlaceInBackpack(p)))
{
p.Delete();
continue;
}
if (!owner.Player)
{
p.Movable = false;
}
yield return p;
}
}
}
}

View File

@@ -0,0 +1,117 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#if ServUO58
#define ServUOX
#endif
#region References
using System;
using System.Collections.Generic;
using System.Linq;
using Server;
using Server.Network;
using VitaNex.Network;
#endregion
namespace VitaNex.Modules.EquipmentSets
{
[CoreModule("Equipment Sets", "3.0.0.1")]
public static partial class EquipmentSets
{
static EquipmentSets()
{
CMOptions = new EquipmentSetsOptions();
SetTypes = TypeOfEquipmentSet.GetConstructableChildren();
Sets = new Dictionary<Type, EquipmentSet>(SetTypes.Length);
foreach (var t in SetTypes)
{
Sets[t] = t.CreateInstanceSafe<EquipmentSet>();
}
}
private static void CMConfig()
{
EquipItemParent = OutgoingPacketOverrides.GetHandler(0x2E);
OutgoingPacketOverrides.Register(0x2E, EquipItem);
EquipItemRequestParent = PacketHandlers.GetHandler(0x13);
DropItemRequestParent = PacketHandlers.GetHandler(0x08);
PacketHandlers.Register(EquipItemRequestParent.PacketID, EquipItemRequestParent.Length, EquipItemRequestParent.Ingame, EquipItemRequest);
PacketHandlers.Register(DropItemRequestParent.PacketID, DropItemRequestParent.Length, DropItemRequestParent.Ingame, DropItemRequest);
#if !ServUOX
EquipItemRequestParent6017 = PacketHandlers.Get6017Handler(0x13);
DropItemRequestParent6017 = PacketHandlers.Get6017Handler(0x08);
PacketHandlers.Register6017(EquipItemRequestParent6017.PacketID, EquipItemRequestParent6017.Length, EquipItemRequestParent6017.Ingame, EquipItemRequest6017);
PacketHandlers.Register6017(DropItemRequestParent6017.PacketID, DropItemRequestParent6017.Length, DropItemRequestParent6017.Ingame, DropItemRequest6017);
#endif
}
private static void CMInvoke()
{
EventSink.Login += OnLogin;
ExtendedOPL.OnItemOPLRequest += GetProperties;
}
private static void CMEnabled()
{
if (World.Loaded)
{
World.Mobiles.Values.AsParallel().Where(m => m.Items != null && m.Items.Any(i => i.Layer.IsEquip())).ForEach(Invalidate);
}
}
private static void CMDisabled()
{
if (World.Loaded)
{
foreach (var set in Sets.Values)
{
set.ActiveOwners.ForEachReverse(Invalidate);
}
}
}
private static void CMDispose()
{
if (EquipItemRequestParent != null && EquipItemRequestParent.OnReceive != null)
{
PacketHandlers.Register(EquipItemRequestParent.PacketID, EquipItemRequestParent.Length, EquipItemRequestParent.Ingame, EquipItemRequestParent.OnReceive);
}
if (DropItemRequestParent != null && DropItemRequestParent.OnReceive != null)
{
PacketHandlers.Register(DropItemRequestParent.PacketID, DropItemRequestParent.Length, DropItemRequestParent.Ingame, DropItemRequestParent.OnReceive);
}
#if !ServUOX
if (EquipItemRequestParent6017 != null && EquipItemRequestParent6017.OnReceive != null)
{
PacketHandlers.Register(EquipItemRequestParent6017.PacketID, EquipItemRequestParent6017.Length, EquipItemRequestParent6017.Ingame, EquipItemRequestParent6017.OnReceive);
}
if (DropItemRequestParent6017 != null && DropItemRequestParent6017.OnReceive != null)
{
PacketHandlers.Register(DropItemRequestParent6017.PacketID, DropItemRequestParent6017.Length, DropItemRequestParent6017.Ingame, DropItemRequestParent6017.OnReceive);
}
#endif
}
}
}

View File

@@ -0,0 +1,42 @@
#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.EquipmentSets
{
public class HueOverrideSetMod : EquipmentSetMod
{
public int Hue { get; private set; }
public HueOverrideSetMod(int partsReq, bool display, int hue)
: base("Taste The Rainbow", String.Empty, partsReq, display)
{
Hue = hue;
}
protected override bool OnActivate(Mobile m, Tuple<EquipmentSetPart, Item>[] equipped)
{
m.SolidHueOverride = Hue;
return true;
}
protected override bool OnDeactivate(Mobile m, Tuple<EquipmentSetPart, Item>[] equipped)
{
m.SolidHueOverride = -1;
return true;
}
}
}

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 Server;
#endregion
namespace VitaNex.Modules.EquipmentSets
{
public class ResistOffsetSetMod : EquipmentSetMod
{
public string UID { get; private set; }
public ResistanceType Resist { get; private set; }
public int Offset { get; private set; }
public ResistOffsetSetMod(string uid, string name, int partsReq, bool display, ResistanceType resist, int offset)
: base(name, null, partsReq, display, ExpansionFlags.PostAOS)
{
UID = uid ?? Name + TimeStamp.UtcNow;
Resist = resist;
Offset = offset;
InvalidateDesc();
}
public virtual void InvalidateDesc()
{
var name = Resist.ToString().SpaceWords().ToUpperWords();
Desc = String.Format("{0} {1} Resistance By {2}%", Offset >= 0 ? "Increase" : "Decrease", name, Offset);
}
protected override bool OnActivate(Mobile m, Tuple<EquipmentSetPart, Item>[] equipped)
{
if (m == null || m.Deleted || equipped == null)
{
return false;
}
if (EquipmentSets.CMOptions.ModuleDebug)
{
EquipmentSets.CMOptions.ToConsole("OnActivate: '{0}', '{1}', '{2}', '{3}'", m, UID, Resist, Offset);
}
UniqueResistMod.ApplyTo(m, Resist, UID, Offset);
return true;
}
protected override bool OnDeactivate(Mobile m, Tuple<EquipmentSetPart, Item>[] equipped)
{
if (m == null || m.Deleted || equipped == null)
{
return false;
}
if (EquipmentSets.CMOptions.ModuleDebug)
{
EquipmentSets.CMOptions.ToConsole("OnDeactivate: '{0}', '{1}', '{2}', '{3}'", m, UID, Resist, Offset);
}
UniqueResistMod.RemoveFrom(m, Resist, UID);
return true;
}
}
}

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 Server;
#endregion
namespace VitaNex.Modules.EquipmentSets
{
public class SkillOffsetSetMod : EquipmentSetMod
{
public string UID { get; private set; }
public SkillName Skill { get; private set; }
public double Offset { get; private set; }
public SkillOffsetSetMod(string uid, string name, int partsReq, bool display, SkillName skill, double offset)
: base(name, null, partsReq, display)
{
UID = uid ?? Name + TimeStamp.UtcNow;
Skill = skill;
Offset = offset;
InvalidateDesc();
}
public virtual void InvalidateDesc()
{
var name = Skill.GetName();
Desc = String.Format("{0} {1} By {2:F1}", Offset >= 0 ? "Increase" : "Decrease", name, Offset);
}
protected override bool OnActivate(Mobile m, Tuple<EquipmentSetPart, Item>[] equipped)
{
if (m == null || m.Deleted || equipped == null)
{
return false;
}
if (EquipmentSets.CMOptions.ModuleDebug)
{
EquipmentSets.CMOptions.ToConsole("OnActivate: '{0}', '{1}', '{2}', '{3}'", m, UID, Skill, Offset);
}
UniqueSkillMod.ApplyTo(m, Skill, UID, true, Offset);
return true;
}
protected override bool OnDeactivate(Mobile m, Tuple<EquipmentSetPart, Item>[] equipped)
{
if (m == null || m.Deleted || equipped == null)
{
return false;
}
if (EquipmentSets.CMOptions.ModuleDebug)
{
EquipmentSets.CMOptions.ToConsole("OnDeactivate: '{0}', '{1}', '{2}', '{3}'", m, UID, Skill, Offset);
}
UniqueSkillMod.RemoveFrom(m, Skill, UID);
return true;
}
}
}

View File

@@ -0,0 +1,96 @@
#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.EquipmentSets
{
public class StatOffsetSetMod : EquipmentSetMod
{
public string UID { get; private set; }
public StatType Stat { get; private set; }
public int Offset { get; private set; }
public StatOffsetSetMod(string uid, string name, int partsReq, bool display, StatType stat, int offset)
: base(name, null, partsReq, display)
{
UID = uid ?? Name + TimeStamp.UtcNow;
Stat = stat;
Offset = offset;
InvalidateDesc();
}
public virtual void InvalidateDesc()
{
var statName = String.Empty;
switch (Stat)
{
case StatType.All:
statName = "All Stats";
break;
case StatType.Dex:
statName = "Dexterity";
break;
case StatType.Int:
statName = "Intelligence";
break;
case StatType.Str:
statName = "Strength";
break;
}
Desc = String.Format("{0} {1} By {2}", Offset >= 0 ? "Increase" : "Decrease", statName, Offset);
}
protected override bool OnActivate(Mobile m, Tuple<EquipmentSetPart, Item>[] equipped)
{
if (m == null || m.Deleted || equipped == null)
{
return false;
}
if (EquipmentSets.CMOptions.ModuleDebug)
{
EquipmentSets.CMOptions.ToConsole("OnActivate: '{0}', '{1}', '{2}', '{3}'", m, UID, Stat, Offset);
}
UniqueStatMod.ApplyTo(m, Stat, UID, Offset, TimeSpan.Zero);
return true;
}
protected override bool OnDeactivate(Mobile m, Tuple<EquipmentSetPart, Item>[] equipped)
{
if (m == null || m.Deleted || equipped == null)
{
return false;
}
if (EquipmentSets.CMOptions.ModuleDebug)
{
EquipmentSets.CMOptions.ToConsole("OnDeactivate: '{0}', '{1}', '{2}', '{3}'", m, UID, Stat, Offset);
}
UniqueStatMod.RemoveFrom(m, Stat, UID);
return true;
}
}
}

View File

@@ -0,0 +1,141 @@
#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.Network;
#endregion
namespace VitaNex.Modules.EquipmentSets
{
public abstract class EquipmentSetMod : IExpansionCheck
{
public List<Mobile> ActiveOwners { get; private set; }
public string Name { get; set; }
public string Desc { get; set; }
public int PartsRequired { get; set; }
public bool Display { get; set; }
public ExpansionFlags Expansions { get; set; }
public EquipmentSetMod(
string name = "Set Mod",
string desc = null,
int partsReq = 1,
bool display = true,
ExpansionFlags ex = ExpansionFlags.None)
{
Name = name;
Desc = desc ?? String.Empty;
Display = display;
PartsRequired = partsReq;
Expansions = ex;
ActiveOwners = new List<Mobile>();
}
public bool IsActive(Mobile m)
{
return m != null && ActiveOwners.Contains(m);
}
public bool Activate(Mobile m, Tuple<EquipmentSetPart, Item>[] equipped)
{
if (m == null || m.Deleted || equipped == null || !this.CheckExpansion())
{
return false;
}
if (OnActivate(m, equipped))
{
ActiveOwners.Update(m);
return true;
}
return false;
}
public bool Deactivate(Mobile m, Tuple<EquipmentSetPart, Item>[] equipped)
{
if (m == null || m.Deleted || equipped == null)
{
return false;
}
if (OnDeactivate(m, equipped))
{
ActiveOwners.Remove(m);
return true;
}
return false;
}
protected abstract bool OnActivate(Mobile m, Tuple<EquipmentSetPart, Item>[] equipped);
protected abstract bool OnDeactivate(Mobile m, Tuple<EquipmentSetPart, Item>[] equipped);
public virtual void GetProperties(Mobile viewer, ExtendedOPL list, bool equipped)
{
if (!this.CheckExpansion())
{
return;
}
string value;
if (String.IsNullOrEmpty(Desc))
{
if (String.IsNullOrWhiteSpace(Name))
{
return;
}
value = String.Format("[{0:#,0}] {1}", PartsRequired, Name.ToUpperWords());
}
else if (String.IsNullOrWhiteSpace(Name))
{
value = String.Format("[{0:#,0}]: {1}", PartsRequired, Desc);
}
else
{
value = String.Format("[{0:#,0}] {1}: {2}", PartsRequired, Name.ToUpperWords(), Desc);
}
if (String.IsNullOrWhiteSpace(value))
{
return;
}
var color = equipped && IsActive(viewer)
? EquipmentSets.CMOptions.ModNameColorRaw
: EquipmentSets.CMOptions.InactiveColorRaw;
value = value.WrapUOHtmlColor(color);
list.Add(value);
}
public override string ToString()
{
return String.Format("{0}", Name);
}
}
}

View File

@@ -0,0 +1,150 @@
#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 VitaNex.Network;
#endregion
namespace VitaNex.Modules.EquipmentSets
{
public class EquipmentSetPart
{
private static readonly Item[] _EmptyItems = new Item[0];
private readonly List<Mobile> _EquipOwners = new List<Mobile>();
public List<Mobile> EquipOwners => _EquipOwners;
public string Name { get; set; }
public Type[] Types { get; set; }
public bool IncludeChildTypes { get; set; }
public bool Display { get; set; }
public bool DisplaySet { get; set; }
public EquipmentSetPart(string name, Type type)
: this(name, new[] { type })
{ }
public EquipmentSetPart(string name, Type type, bool childTypes)
: this(name, new[] { type }, childTypes)
{ }
public EquipmentSetPart(string name, Type type, bool childTypes, bool display, bool displaySet)
: this(name, new[] { type }, childTypes, display, displaySet)
{ }
public EquipmentSetPart(string name, params Type[] types)
: this(name, types, false)
{ }
public EquipmentSetPart(string name, Type[] types, bool childTypes)
: this(name, types, childTypes, true, true)
{ }
public EquipmentSetPart(string name, Type[] types, bool childTypes, bool display, bool displaySet)
{
Name = name;
Types = types;
IncludeChildTypes = childTypes;
Display = display;
DisplaySet = displaySet;
}
public bool IsTypeOf(Type type)
{
return type != null && Types != null && Types.Any(t => type.TypeEquals(t, IncludeChildTypes));
}
public bool IsEquipped(Mobile m)
{
return IsEquipped(m, out var item);
}
public bool IsEquipped(Mobile m, out Item item)
{
item = null;
if (m == null)
{
return false;
}
item = m.Items.Find(i => IsTypeOf(i.GetType()));
if (item != null)
{
EquipOwners.Update(m);
return true;
}
EquipOwners.Remove(m);
return false;
}
public Item[] CreateParts(params object[] args)
{
if (Types == null || Types.Length == 0)
{
return _EmptyItems;
}
var items = new Item[Types.Length];
items.SetAll(i => Types[i].CreateInstanceSafe<Item>(args));
return items;
}
public Item CreatePart(int index, params object[] args)
{
if (Types == null || !Types.InBounds(index))
{
return null;
}
return Types[index].CreateInstance<Item>(args);
}
public Item CreateRandomPart(params object[] args)
{
if (Types == null || Types.Length == 0)
{
return null;
}
return CreatePart(Utility.Random(Types.Length), args);
}
public virtual void GetProperties(Mobile viewer, ExtendedOPL list, bool equipped)
{
list.Add(
equipped && IsEquipped(viewer, out var item)
? item.ResolveName(viewer).ToUpperWords().WrapUOHtmlColor(EquipmentSets.CMOptions.PartNameColorRaw)
: Name.ToUpperWords().WrapUOHtmlColor(EquipmentSets.CMOptions.InactiveColorRaw));
}
public override string ToString()
{
return String.Format("{0}", Name);
}
}
}

View File

@@ -0,0 +1,335 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Server;
using VitaNex.Network;
#endregion
namespace VitaNex.Modules.EquipmentSets
{
public abstract class EquipmentSet : IEnumerable<EquipmentSetPart>
{
public static Item[] GenerateParts<TSet>()
where TSet : EquipmentSet
{
return GenerateParts(typeof(TSet));
}
public static Item[] GenerateParts(Type set)
{
var s = EquipmentSets.Sets.Values.FirstOrDefault(t => t.TypeEquals(set));
if (s != null)
{
return s.GenerateParts();
}
return new Item[0];
}
public List<Mobile> ActiveOwners { get; private set; }
public List<EquipmentSetPart> Parts { get; protected set; }
public List<EquipmentSetMod> Mods { get; protected set; }
public EquipmentSetPart this[int index] { get => Parts[index]; set => Parts[index] = value; }
public int Count => Parts.Count;
public string Name { get; set; }
public bool Display { get; set; }
public bool DisplayParts { get; set; }
public bool DisplayMods { get; set; }
public EquipmentSet(
string name,
bool display = true,
bool displayParts = true,
bool displayMods = true,
IEnumerable<EquipmentSetPart> parts = null,
IEnumerable<EquipmentSetMod> mods = null)
{
ActiveOwners = new List<Mobile>();
Name = name;
Display = display;
DisplayParts = displayParts;
DisplayMods = displayMods;
Parts = parts.Ensure().ToList();
Mods = mods.Ensure().ToList();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public IEnumerator<EquipmentSetPart> GetEnumerator()
{
return Parts.GetEnumerator();
}
public bool Contains(EquipmentSetPart part)
{
return Parts.Contains(part);
}
public void Add(EquipmentSetPart part)
{
Parts.Add(part);
}
public void AddRange(IEnumerable<EquipmentSetPart> parts)
{
Parts.AddRange(parts);
}
public bool Remove(EquipmentSetPart part)
{
return Parts.Remove(part);
}
public bool Contains(EquipmentSetMod mod)
{
return Mods.Contains(mod);
}
public void Add(EquipmentSetMod mod)
{
Mods.Add(mod);
}
public void AddRange(IEnumerable<EquipmentSetMod> mods)
{
Mods.AddRange(mods);
}
public bool Remove(EquipmentSetMod mod)
{
return Mods.Remove(mod);
}
public bool HasPartTypeOf(Type type)
{
return Parts.Exists(part => part.IsTypeOf(type));
}
public int CountEquippedParts(Mobile m)
{
var count = 0;
foreach (var part in Parts)
{
if (part.IsEquipped(m, out var item))
{
++count;
}
}
return count;
}
public IEnumerable<Tuple<EquipmentSetPart, Item>> FindEquippedParts(Mobile m)
{
foreach (var part in Parts)
{
if (part.IsEquipped(m, out var item))
{
yield return Tuple.Create(part, item);
}
}
}
public Tuple<EquipmentSetPart, Item>[] GetEquippedParts(Mobile m)
{
return FindEquippedParts(m).ToArray();
}
public IEnumerable<EquipmentSetMod> FindAvailableMods(Mobile m, EquipmentSetPart[] equipped)
{
return Mods.Where(mod => equipped.Length >= mod.PartsRequired);
}
public EquipmentSetMod[] GetAvailableMods(Mobile m, EquipmentSetPart[] equipped)
{
return FindAvailableMods(m, equipped).ToArray();
}
public Item GenerateRandomPart()
{
var p = Parts.GetRandom();
return p != null ? p.CreateRandomPart() : null;
}
public Item[] GenerateParts()
{
return Parts.SelectMany(part => part.CreateParts()).Not(item => item == null || item.Deleted).ToArray();
}
public void Invalidate(Mobile m, Item item)
{
var totalActive = 0;
var type = item.GetType();
var changedPart = Tuple.Create(Parts.FirstOrDefault(p => p.IsTypeOf(type)), item);
var equippedParts = GetEquippedParts(m);
foreach (var mod in Mods)
{
if (mod.IsActive(m))
{
++totalActive;
if (equippedParts.Length < mod.PartsRequired && Deactivate(m, equippedParts, changedPart, mod))
{
--totalActive;
}
}
else if (mod.CheckExpansion())
{
if (equippedParts.Length >= mod.PartsRequired && Activate(m, equippedParts, changedPart, mod))
{
++totalActive;
}
}
}
if (EquipmentSets.CMOptions.ModuleDebug)
{
EquipmentSets.CMOptions.ToConsole("Mods: {0}, Parts: {1}", totalActive, equippedParts.Length);
}
SetActiveOwner(m, totalActive > 0);
InvalidateAllProperties(m, equippedParts.Select(t => t.Item2), changedPart.Item2);
m.UpdateResistances();
m.UpdateSkillMods();
}
public void InvalidateAllProperties(Mobile m, IEnumerable<Item> equipped, Item changed)
{
if (World.Loading || World.Saving || m == null || m.Deleted || m.Map == null || m.Map == Map.Internal)
{
return;
}
m.InvalidateProperties();
if (equipped != null)
{
foreach (var item in equipped.Where(item => item != changed))
{
InvalidateItemProperties(item);
}
}
if (changed != null)
{
InvalidateItemProperties(changed);
}
}
public void InvalidateItemProperties(Item item)
{
if (World.Loading || World.Saving || item == null || item.Deleted)
{
return;
}
item.ClearProperties();
item.InvalidateProperties();
}
private void SetActiveOwner(Mobile m, bool state)
{
if (state)
{
ActiveOwners.Update(m);
}
else
{
ActiveOwners.Remove(m);
}
}
public bool Activate(
Mobile m,
Tuple<EquipmentSetPart, Item>[] equipped,
Tuple<EquipmentSetPart, Item> added,
EquipmentSetMod mod)
{
return OnActivate(m, equipped, added, mod) && mod.Activate(m, equipped);
}
public bool Deactivate(
Mobile m,
Tuple<EquipmentSetPart, Item>[] equipped,
Tuple<EquipmentSetPart, Item> added,
EquipmentSetMod mod)
{
return OnDeactivate(m, equipped, added, mod) && mod.Deactivate(m, equipped);
}
protected virtual bool OnActivate(
Mobile m,
Tuple<EquipmentSetPart, Item>[] equipped,
Tuple<EquipmentSetPart, Item> added,
EquipmentSetMod mod)
{
return m != null && !m.Deleted && equipped != null && mod != null && !mod.IsActive(m);
}
protected virtual bool OnDeactivate(
Mobile m,
Tuple<EquipmentSetPart, Item>[] equipped,
Tuple<EquipmentSetPart, Item> removed,
EquipmentSetMod mod)
{
return m != null && !m.Deleted && equipped != null && mod != null && mod.IsActive(m);
}
public virtual void GetProperties(Mobile viewer, ExtendedOPL list, bool equipped)
{
list.Add(String.Empty);
var name = Name.ToUpperWords();
var count = Parts.Count;
if (!equipped)
{
list.Add("{0} [{1:#,0}]".WrapUOHtmlColor(EquipmentSets.CMOptions.SetNameColorRaw), name, count);
}
else
{
var cur = CountEquippedParts(viewer);
list.Add("{0} [{1:#,0} / {2:#,0}]".WrapUOHtmlColor(EquipmentSets.CMOptions.SetNameColorRaw), name, cur, count);
}
}
public override string ToString()
{
return Name;
}
}
}

View File

@@ -0,0 +1,138 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using System;
using System.Drawing;
using Server;
using Server.Commands;
using Server.Mobiles;
using VitaNex.SuperGumps;
#endregion
namespace VitaNex.Modules.EquipmentSets
{
public sealed class EquipmentSetsOptions : CoreModuleOptions
{
private string _AdminCommand = String.Empty;
[CommandProperty(EquipmentSets.Access)]
public string AdminCommand
{
get => _AdminCommand;
set => CommandUtility.Replace(_AdminCommand ?? value, EquipmentSets.Access, HandleAdminCommand, (_AdminCommand = value));
}
[CommandProperty(EquipmentSets.Access)]
public KnownColor SetNameColor { get; set; }
[CommandProperty(EquipmentSets.Access)]
public KnownColor PartNameColor { get; set; }
[CommandProperty(EquipmentSets.Access)]
public KnownColor ModNameColor { get; set; }
[CommandProperty(EquipmentSets.Access)]
public KnownColor InactiveColor { get; set; }
public Color SetNameColorRaw => Color.FromKnownColor(SetNameColor);
public Color PartNameColorRaw => Color.FromKnownColor(PartNameColor);
public Color ModNameColorRaw => Color.FromKnownColor(ModNameColor);
public Color InactiveColorRaw => Color.FromKnownColor(InactiveColor);
public EquipmentSetsOptions()
: base(typeof(EquipmentSets))
{
SetNameColor = KnownColor.Gold;
PartNameColor = KnownColor.LawnGreen;
ModNameColor = KnownColor.SkyBlue;
InactiveColor = KnownColor.Transparent;
AdminCommand = "EquipSets";
}
public EquipmentSetsOptions(GenericReader reader)
: base(reader)
{ }
public void HandleAdminCommand(CommandEventArgs e)
{
if (e.Mobile != null && !e.Mobile.Deleted && e.Mobile is PlayerMobile)
{
SuperGump.Send(new EquipmentSetsAdminUI((PlayerMobile)e.Mobile));
}
}
public override void Clear()
{
SetNameColor = KnownColor.White;
PartNameColor = KnownColor.White;
ModNameColor = KnownColor.White;
InactiveColor = KnownColor.Transparent;
AdminCommand = "EquipSets";
}
public override void Reset()
{
SetNameColor = KnownColor.LightGoldenrodYellow;
PartNameColor = KnownColor.LawnGreen;
ModNameColor = KnownColor.SkyBlue;
InactiveColor = KnownColor.Transparent;
AdminCommand = "EquipSets";
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
var version = writer.SetVersion(0);
switch (version)
{
case 0:
{
writer.WriteFlag(SetNameColor);
writer.WriteFlag(PartNameColor);
writer.WriteFlag(ModNameColor);
writer.WriteFlag(InactiveColor);
writer.Write(AdminCommand);
}
break;
}
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
var version = reader.GetVersion();
switch (version)
{
case 0:
{
SetNameColor = reader.ReadFlag<KnownColor>();
PartNameColor = reader.ReadFlag<KnownColor>();
ModNameColor = reader.ReadFlag<KnownColor>();
InactiveColor = reader.ReadFlag<KnownColor>();
AdminCommand = reader.ReadString();
}
break;
}
}
}
}

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 Server;
using Server.Items;
#endregion
namespace VitaNex.Modules.EquipmentSets
{
public sealed class PlateArmorSet : EquipmentSet
{
public PlateArmorSet()
: base("Plate Avenger")
{
/*Add Parts to this Set*/
Add(new EquipmentSetPart("Avenger's Chestguard", typeof(PlateChest)));
Add(new EquipmentSetPart("Avenger's Pauldrons", typeof(PlateArms)));
Add(new EquipmentSetPart("Avenger's Gauntlets", typeof(PlateGloves)));
Add(new EquipmentSetPart("Avenger's Neckguard", typeof(PlateGorget)));
Add(new EquipmentSetPart("Avenger's Legguards", typeof(PlateLegs)));
Add(new EquipmentSetPart("Avenger's Helmet", typeof(PlateHelm)));
/*Add Mods to this Set*/
Add(new StatOffsetSetMod("PlateAvenger1", "Avenger I", 2, true, StatType.All, 1));
Add(new StatOffsetSetMod("PlateAvenger2", "Avenger II", 4, true, StatType.All, 1));
Add(new StatOffsetSetMod("PlateAvenger3", "Avenger III", 6, true, StatType.All, 1));
}
}
}

View File

@@ -0,0 +1,119 @@
#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 Server.Items;
using VitaNex.SuperGumps.UI;
#endregion
namespace VitaNex.Modules.EquipmentSets
{
public sealed class EquipmentSetsAdminUI : ListGump<EquipmentSet>
{
public static string HelpText =
"Sets: List specific Item Types and Mods as an Equipment Set.\nWhenever the equipped parts total meets a Mods' requirement, the Mod will activate.\nWhenever the equipped parts total falls below a Mods' requirement, the Mod will deactivate."
;
public EquipmentSetsAdminUI(Mobile user, Gump parent = null)
: base(user, parent, emptyText: "There are no equipment sets to display.", title: "Equipment Sets Control Panel")
{
ForceRecompile = true;
}
protected override void CompileList(List<EquipmentSet> list)
{
list.Clear();
list.AddRange(EquipmentSets.Sets.Values);
base.CompileList(list);
}
public override string GetSearchKeyFor(EquipmentSet key)
{
return key != null ? key.Name : base.GetSearchKeyFor(null);
}
protected override void CompileMenuOptions(MenuGumpOptions list)
{
if (User.AccessLevel >= EquipmentSets.Access)
{
list.AppendEntry(new ListGumpEntry("Module Settings", OpenConfig, HighlightHue));
}
list.AppendEntry(new ListGumpEntry("Help", ShowHelp));
base.CompileMenuOptions(list);
}
protected override void SelectEntry(GumpButton button, EquipmentSet entry)
{
base.SelectEntry(button, entry);
var opts = new MenuGumpOptions();
if (User.AccessLevel >= EquipmentSets.Access)
{
opts.AppendEntry(
new ListGumpEntry(
"Create Bag Of Parts",
b =>
{
if (entry.Count == 0)
{
User.SendMessage("This equipment set contains no parts.");
Refresh();
return;
}
var bag = new Bag
{
Name = String.Format("a bag of {0} parts", entry.Name)
};
entry.GenerateParts().ForEach(bag.DropItem);
if (!User.PlaceInBackpack(bag))
{
bag.Delete();
}
},
HighlightHue));
}
Send(new MenuGump(User, Refresh(), opts, button));
}
private void OpenConfig(GumpButton btn)
{
Minimize();
var p = new PropertiesGump(User, EquipmentSets.CMOptions)
{
X = X + btn.X,
Y = Y + btn.Y
};
User.SendGump(p);
}
private void ShowHelp(GumpButton button)
{
if (User != null && !User.Deleted)
{
Send(new NoticeDialogGump(User, Refresh(), title: "Help", html: HelpText));
}
}
}
}