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,159 @@
#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.Accounting;
#endregion
namespace Server
{
public static class AccountExtUtility
{
public static bool IsOnline(this IAccount acc)
{
return FindMobiles(acc, m => m.IsOnline()).Any();
}
public static Mobile GetOnlineMobile(this IAccount acc)
{
return FindMobiles(acc, m => m.IsOnline()).FirstOrDefault();
}
public static TMob GetOnlineMobile<TMob>(this IAccount acc)
where TMob : Mobile
{
return FindMobiles<TMob>(acc, m => m.IsOnline()).FirstOrDefault();
}
public static Mobile[] GetMobiles(this IAccount acc)
{
return GetMobiles(acc, null);
}
public static Mobile[] GetMobiles(this IAccount acc, Func<Mobile, bool> predicate)
{
return FindMobiles(acc, predicate).ToArray();
}
public static IEnumerable<Mobile> FindMobiles(this IAccount acc)
{
return FindMobiles(acc, null);
}
public static IEnumerable<Mobile> FindMobiles(this IAccount acc, Func<Mobile, bool> predicate)
{
if (acc == null)
{
yield break;
}
for (var i = 0; i < acc.Length; i++)
{
if (acc[i] != null && (predicate == null || predicate(acc[i])))
{
yield return acc[i];
}
}
}
public static TMob[] GetMobiles<TMob>(this IAccount acc)
where TMob : Mobile
{
return GetMobiles<TMob>(acc, null);
}
public static TMob[] GetMobiles<TMob>(this IAccount acc, Func<TMob, bool> predicate)
where TMob : Mobile
{
return FindMobiles(acc, predicate).ToArray();
}
public static IEnumerable<TMob> FindMobiles<TMob>(this IAccount acc)
where TMob : Mobile
{
return FindMobiles<TMob>(acc, null);
}
public static IEnumerable<TMob> FindMobiles<TMob>(this IAccount acc, Func<TMob, bool> predicate)
where TMob : Mobile
{
if (acc == null)
{
yield break;
}
for (var i = 0; i < acc.Length; i++)
{
if (acc[i] is TMob && (predicate == null || predicate((TMob)acc[i])))
{
yield return (TMob)acc[i];
}
}
}
public static Account[] GetSharedAccounts(this IAccount acc)
{
return GetSharedAccounts(acc as Account);
}
public static Account[] GetSharedAccounts(this Account acc)
{
return FindSharedAccounts(acc).ToArray();
}
public static IEnumerable<Account> FindSharedAccounts(this IAccount acc)
{
return FindSharedAccounts(acc as Account);
}
public static IEnumerable<Account> FindSharedAccounts(this Account acc)
{
if (acc == null)
{
yield break;
}
foreach (var a in Accounts.GetAccounts().AsParallel().OfType<Account>().Where(a => IsSharedWith(acc, a)))
{
yield return a;
}
}
public static bool IsSharedWith(this IAccount acc, IAccount a)
{
return IsSharedWith(acc as Account, a as Account);
}
public static bool IsSharedWith(this Account acc, Account a)
{
return acc != null && a != null && (acc == a || acc.LoginIPs.Any(a.LoginIPs.Contains));
}
public static bool CheckAccount(this Mobile a, Mobile b)
{
return a != null && b != null && (a == b || a.Account == b.Account);
}
public static bool CheckAccount(this Mobile a, IAccount b)
{
return a != null && b != null && a.Account == b;
}
public static bool CheckAccount(this IAccount a, Mobile b)
{
return a != null && b != null && a == b.Account;
}
}
}

View File

@@ -0,0 +1,116 @@
#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.Items;
#endregion
namespace Server
{
public static class AddonExtUtility
{
static AddonExtUtility()
{
ComponentsCache = new Dictionary<int, MultiComponentList>();
}
public static Dictionary<int, MultiComponentList> ComponentsCache { get; private set; }
public static int ComputeHash(IAddon addon)
{
unchecked
{
var hash = -1;
hash = (hash * 397) ^ addon.GetTypeHashCode();
if (addon.GetPropertyValue("Components", out
IList comp))
{
hash = (hash * 397) ^ comp.Count;
hash = comp.Cast<Item>().Aggregate(hash, (h, c) => (h * 397) ^ c.GetTypeHashCode());
hash = comp.Cast<Item>().Aggregate(hash, (h, c) => (h * 397) ^ c.ItemID);
}
return hash;
}
}
public static MultiComponentList GetComponents(this IAddon addon)
{
if (addon == null)
{
return null;
}
var hash = ComputeHash(addon);
var mcl = ComponentsCache.GetValue(hash);
if (mcl != null)
{
return mcl;
}
mcl = new MultiComponentList(MultiComponentList.Empty);
int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
if (addon.GetPropertyValue("Components", out
IList comp))
{
foreach (var c in comp)
{
if (c.GetPropertyValue("Offset", out Point3D off))
{
x1 = Math.Min(off.X, x1);
y1 = Math.Min(off.Y, y1);
x2 = Math.Max(off.X, x2);
y2 = Math.Max(off.Y, y2);
}
}
}
mcl.Resize(1 + (x2 - x1), 1 + (y2 - y1));
if (comp != null)
{
foreach (var c in comp.OfType<Item>())
{
if (c.GetPropertyValue("Offset", out Point3D off))
{
off = off.Clone3D(Math.Abs(x1), Math.Abs(y1));
mcl.Add(c.ItemID, off.X, off.Y, off.Z);
}
}
}
if (addon is Item)
{
((Item)addon).Delete();
}
return ComponentsCache[hash] = mcl;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,193 @@
#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 VitaNex;
#endregion
namespace Server
{
public static class BodyExtUtility
{
public static Dictionary<int, string> Names { get; private set; }
static BodyExtUtility()
{
Names = new Dictionary<int, string>();
}
public static string GetName(this Body body)
{
if (body.IsEmpty)
{
return String.Empty;
}
if (Names.TryGetValue(body.BodyID, out var name) && !String.IsNullOrWhiteSpace(name))
{
return name;
}
var itemID = ShrinkTable.Lookup(body.BodyID) & TileData.MaxItemValue;
if (itemID == ShrinkTable.DefaultItemID)
{
name = String.Empty;
}
if (String.IsNullOrWhiteSpace(name))
{
name = ClilocLNG.NULL.GetRawString(itemID + (itemID < 0x4000 ? 1020000 : 1078872));
}
if (String.IsNullOrWhiteSpace(name))
{
name = TileData.ItemTable[itemID].Name;
}
if (String.IsNullOrWhiteSpace(name))
{
name = body.Type.ToString();
}
if (!String.IsNullOrWhiteSpace(name))
{
name = name.SpaceWords().ToUpperWords();
name = String.Concat(" ", name, " ");
if (body.IsHuman || body.IsGhost)
{
if (body >= 400 && body <= 403)
{
name = "Human";
}
else if (body >= 605 && body <= 608)
{
name = "Elf";
}
else if ((body >= 666 && body <= 667) || (body >= 694 && body <= 695))
{
name = "Gargoyle";
}
if (body.IsMale && !Insensitive.Contains(name, "Male"))
{
name += " Male";
}
else if (body.IsFemale && !Insensitive.Contains(name, "Female"))
{
name += " Female";
}
if (body.IsGhost && !Insensitive.Contains(name, "Ghost"))
{
name += " Ghost";
}
}
else
{
switch (itemID)
{
case 9611:
name = "Evil Mage";
break;
case 9776:
name = "Wanderer Of The Void";
break;
case 11676:
name = "Charger";
break;
case 38990:
name = "Baby Dragon Turtle";
break;
case 40369:
name = "Aztec Golem";
break;
case 40374:
name = "Myrmadex Queen";
break;
case 40420:
name = "Spector";
break;
case 40429:
name = "T-Rex";
break;
case 40501:
name = "Rainbow Unicorn";
break;
case 40661:
name = "Windrunner";
break;
case 40704:
name = "Sabertooth Tiger";
break;
case 40705:
name = "Small Platinum Dragon";
break;
case 40706:
name = "Platinum Dragon";
break;
case 40710:
name = "Small Crimson Dragon";
break;
case 40711:
name = "Crimson Dragon";
break;
case 40713:
name = "Small Fox";
break;
case 40714:
name = "Small Stygian Dragon";
break;
case 40718:
name = "Stygian Dragon";
break;
case 40976:
name = "Eastern Dragon";
break;
}
}
name = name.Replace(" Fr ", " Frame ");
name = name.Replace("Frame", String.Empty);
name = name.Replace("Statuette", String.Empty);
name = name.Replace("Statue", String.Empty);
name = name.StripExcessWhiteSpace().Trim();
}
if (String.IsNullOrWhiteSpace(name))
{
name = body.Type.ToString();
}
Names[body.BodyID] = name;
return name;
}
public static int GetPaperdoll(this Body body)
{
return ArtworkSupport.LookupGump(body);
}
public static bool HasPaperdoll(this Body body)
{
return GetPaperdoll(body) >= 0;
}
}
}

View File

@@ -0,0 +1,155 @@
#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.Items;
#endregion
namespace Server
{
public static class ContainerExtUtility
{
public static bool HasItem<TItem>(
this Container container,
int amount = 1,
bool children = true,
Func<TItem, bool> predicate = null)
where TItem : Item
{
return predicate == null
? HasItem(container, typeof(TItem), amount, children)
: HasItem(container, typeof(TItem), amount, children, i => predicate(i as TItem));
}
public static bool HasItem(
this Container container,
Type type,
int amount = 1,
bool children = true,
Func<Item, bool> predicate = null)
{
if (container == null || type == null || amount < 1)
{
return false;
}
long total = 0;
total = container.FindItemsByType(type, true)
.Where(i => i != null && !i.Deleted && i.TypeEquals(type, children) && (predicate == null || predicate(i)))
.Aggregate(total, (c, i) => c + i.Amount);
return total >= amount;
}
public static bool HasItems(
this Container container,
Type[] types,
int[] amounts = null,
bool children = true,
Func<Item, bool> predicate = null)
{
if (container == null || types == null || types.Length == 0)
{
return false;
}
if (amounts == null)
{
amounts = new int[0];
}
var count = 0;
for (var i = 0; i < types.Length; i++)
{
var t = types[i];
var amount = amounts.InBounds(i) ? amounts[i] : 1;
if (HasItem(container, t, amount, children, predicate))
{
++count;
}
}
return count >= types.Length;
}
public static bool DropItemStack(this Container c, Item item)
{
if (c == null || c.Deleted || item == null || item.Deleted)
{
return false;
}
return DropItemStack(c, c.RootParent as Mobile, item);
}
public static bool DropItemStack(this Container c, Mobile m, Item item)
{
if (c == null || c.Deleted || item == null || item.Deleted)
{
return false;
}
c.DropItem(item);
if (item.Stackable)
{
MergeStacks(c, item.GetType(), m);
}
return true;
}
public static void MergeStacks<T>(this Container c, Mobile m)
where T : Item
{
MergeStacks(c, typeof(T), m);
}
public static void MergeStacks(this Container c, Mobile m)
{
MergeStacks(c, null, m);
}
public static void MergeStacks(this Container c, Type t, Mobile m)
{
if (c == null || c.Deleted || (t != null && t.TypeEquals<Container>(true)))
{
return;
}
var i = c.Items.Count;
while (--i >= 1)
{
var o = c.Items[i];
if (!o.Stackable || (t != null && !o.TypeEquals(t, false)))
{
continue;
}
foreach (var s in c.Items.Take(i).NotType<Item, Container>().Where(s => t == null || s.TypeEquals(t, false)))
{
if (s.StackWith(m, o))
{
break;
}
}
}
}
}
}

View File

@@ -0,0 +1,26 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using Server.Mobiles;
#endregion
namespace Server
{
public static class CreatureExtUtility
{
public static TMobile GetMaster<TMobile>(this BaseCreature creature)
where TMobile : Mobile
{
return creature != null ? creature.GetMaster() as TMobile : null;
}
}
}

View File

@@ -0,0 +1,268 @@
#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 VitaNex;
using VitaNex.Network;
#endregion
namespace Server
{
public static class EntityExtUtility
{
public static ObjectPropertyList GetOPL(this IEntity e)
{
return ExtendedOPL.ResolveOPL(e);
}
public static ObjectPropertyList GetOPL(this IEntity e, Mobile viewer)
{
return ExtendedOPL.ResolveOPL(e, viewer);
}
public static ObjectPropertyList GetOPL(this IEntity e, bool headerOnly)
{
return ExtendedOPL.ResolveOPL(e, headerOnly);
}
public static ObjectPropertyList GetOPL(this IEntity e, Mobile viewer, bool headerOnly)
{
return ExtendedOPL.ResolveOPL(e, viewer, headerOnly);
}
public static string GetOPLHeader(this IEntity e)
{
ObjectPropertyList opl = null;
try
{
opl = GetOPL(e, true);
if (opl != null)
{
return opl.DecodePropertyListHeader();
}
return String.Empty;
}
catch
{
return String.Empty;
}
finally
{
if (opl != null)
{
opl.Release();
}
}
}
public static string GetOPLHeader(this IEntity e, ClilocLNG lng)
{
ObjectPropertyList opl = null;
try
{
opl = GetOPL(e, true);
if (opl != null)
{
return opl.DecodePropertyListHeader(lng);
}
return String.Empty;
}
catch
{
return String.Empty;
}
finally
{
if (opl != null)
{
opl.Release();
}
}
}
public static string GetOPLHeader(this IEntity e, Mobile viewer)
{
ObjectPropertyList opl = null;
try
{
opl = GetOPL(e, viewer, true);
if (opl != null)
{
return opl.DecodePropertyListHeader(viewer);
}
return String.Empty;
}
catch
{
return String.Empty;
}
finally
{
if (opl != null)
{
opl.Release();
}
}
}
public static IEnumerable<string> GetOPLStrings(this IEntity e)
{
ObjectPropertyList opl = null;
try
{
opl = GetOPL(e);
if (opl != null)
{
return opl.DecodePropertyList();
}
return Enumerable.Empty<string>();
}
catch
{
return Enumerable.Empty<string>();
}
finally
{
if (opl != null)
{
opl.Release();
}
}
}
public static IEnumerable<string> GetOPLStrings(this IEntity e, ClilocLNG lng)
{
ObjectPropertyList opl = null;
try
{
opl = GetOPL(e);
if (opl != null)
{
return opl.DecodePropertyList(lng);
}
return Enumerable.Empty<string>();
}
catch
{
return Enumerable.Empty<string>();
}
finally
{
if (opl != null)
{
opl.Release();
}
}
}
public static IEnumerable<string> GetOPLStrings(this IEntity e, Mobile viewer)
{
ObjectPropertyList opl = null;
try
{
opl = GetOPL(e, viewer);
if (opl != null)
{
return opl.DecodePropertyList(viewer);
}
return Enumerable.Empty<string>();
}
catch
{
return Enumerable.Empty<string>();
}
finally
{
if (opl != null)
{
opl.Release();
}
}
}
public static string GetOPLString(this IEntity e)
{
return String.Join("\n", GetOPLStrings(e));
}
public static string GetOPLString(this IEntity e, ClilocLNG lng)
{
return String.Join("\n", GetOPLStrings(e, lng));
}
public static string GetOPLString(this IEntity e, Mobile viewer)
{
return String.Join("\n", GetOPLStrings(e, viewer));
}
public static string ResolveName(this IEntity e, Mobile viewer = null)
{
if (e is Item)
{
return ((Item)e).ResolveName(viewer);
}
if (e is Mobile)
{
return ((Mobile)e).GetFullName(viewer);
}
if (String.IsNullOrEmpty(e.Name))
{
return e.GetTypeName(false);
}
return e.Name;
}
public static bool IsInside(this IEntity e)
{
if (e != null && e.Map != null && e.Map != Map.Internal)
{
return e.IsInside(e.Map);
}
return false;
}
public static bool IsOutside(this IEntity e)
{
return !IsInside(e);
}
public static bool Intersects(this IEntity e, IPoint3D o)
{
return Block3D.Intersects(e, o);
}
}
}

View File

@@ -0,0 +1,765 @@
#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.Items;
using Server.Mobiles;
#endregion
namespace Server
{
public static class GeoExtUtility
{
public static Point3D ToPoint3D(this IPoint3D p)
{
return new Point3D(p.X, p.Y, p.Z);
}
public static Point3D ToPoint3D(this IPoint2D p, int z = 0)
{
return new Point3D(p.X, p.Y, z);
}
public static Point2D ToPoint2D(this IPoint3D p)
{
return new Point2D(p.X, p.Y);
}
public static Point2D ToPoint2D(this StaticTile t)
{
return new Point2D(t.X, t.Y);
}
public static Point3D ToPoint3D(this StaticTile t)
{
return new Point3D(t.X, t.Y, t.Z);
}
public static string ToCoordsString(this IPoint2D p, Map map)
{
return ToCoords(p, map).ToString();
}
public static Coords ToCoords(this IPoint2D p, Map m)
{
return new Coords(m, p);
}
public static Coords ToCoords(this IEntity e)
{
return e == null ? Coords.Zero : new Coords(e.Map, e.Location);
}
public static Coords ToCoords(this PlayerMobile m)
{
if (m == null)
{
return Coords.Zero;
}
var online = m.IsOnline();
return new Coords(online ? m.Map : m.LogoutMap, online ? m.Location : m.LogoutLocation);
}
public static Coords ToCoords(this StaticTile t, Map m)
{
return new Coords(m, ToPoint3D(t));
}
public static MapPoint ToMapPoint(this IPoint2D p, Map m, int z = 0)
{
return new MapPoint(m, p, z);
}
public static MapPoint ToMapPoint(this IPoint3D p, Map m)
{
return new MapPoint(m, p);
}
public static MapPoint ToMapPoint(this IEntity e)
{
return e == null ? MapPoint.Empty : new MapPoint(e.Map, e.Location);
}
public static MapPoint ToMapPoint(this PlayerMobile m)
{
if (m == null)
{
return MapPoint.Empty;
}
var online = m.IsOnline();
return new MapPoint(online ? m.Map : m.LogoutMap, online ? m.Location : m.LogoutLocation);
}
public static MapPoint ToMapPoint(this StaticTile t, Map m)
{
return new MapPoint(m, ToPoint3D(t));
}
public static IEnumerable<Block3D> Flatten(this IEnumerable<Block3D> blocks)
{
foreach (var o in blocks.GroupBy(o => o.ToPoint2D()))
{
var v = new Block3D(o.Key.X, o.Key.Y, o.Min(b => b.Z), 0);
v.H = o.Max(b => b.Z + b.H) - v.Z;
yield return v;
}
}
public static Direction GetDirection(this IPoint2D from, IPoint2D to)
{
int dx = to.X - from.X, dy = to.Y - from.Y, adx = Math.Abs(dx), ady = Math.Abs(dy);
if (adx >= ady * 3)
{
if (dx > 0)
{
return Direction.East;
}
return Direction.West;
}
if (ady >= adx * 3)
{
if (dy > 0)
{
return Direction.South;
}
return Direction.North;
}
if (dx > 0)
{
if (dy > 0)
{
return Direction.Down;
}
return Direction.Right;
}
if (dy > 0)
{
return Direction.Left;
}
return Direction.Up;
}
public static Direction4 GetDirection4(this Direction dir, bool clockwise = true)
{
dir = dir & Direction.Mask;
switch (dir)
{
case Direction.Up:
return clockwise ? Direction4.North : Direction4.West;
case Direction.Right:
return clockwise ? Direction4.East : Direction4.North;
case Direction.Down:
return clockwise ? Direction4.South : Direction4.East;
case Direction.Left:
return clockwise ? Direction4.West : Direction4.South;
}
return (Direction4)dir;
}
public static Point2D[] GetLine2D(this IPoint2D start, IPoint2D end)
{
return PlotLine2D(start, end).ToArray();
}
public static Point3D[] GetLine3D(this IPoint3D start, IPoint3D end, bool avgZ = true)
{
Map map = null;
if (avgZ && start is IEntity)
{
map = ((IEntity)start).Map;
}
return GetLine3D(start, end, map, avgZ);
}
public static Point3D[] GetLine3D(this IPoint3D start, IPoint3D end, Map map, bool avgZ = true)
{
return PlotLine3D(start, end, map, avgZ).ToArray();
}
public static IEnumerable<Point2D> PlotLine2D(this IPoint2D start, IPoint2D end)
{
return Line2D.Plot(start, end);
}
public static IEnumerable<Point3D> PlotLine3D(this IPoint3D start, IPoint3D end, bool avgZ = true)
{
Map map = null;
if (avgZ && start is IEntity)
{
map = ((IEntity)start).Map;
}
return PlotLine3D(start, end, map, avgZ);
}
public static IEnumerable<Point3D> PlotLine3D(this IPoint3D start, IPoint3D end, Map map, bool avgZ = true)
{
var dist = GetDistance(start, end);
var dZ = end.Z - start.Z;
return Line2D.Plot(start, end)
.Select(
(p, i) =>
{
var z = start.Z;
if (avgZ && map != null)
{
z = map.GetAverageZ(p.X, p.Y);
}
else
{
z += (int)(dZ * (i / dist));
}
return new Point3D(p, z);
});
}
public static Point2D Rotate2D(this IPoint2D from, IPoint2D to, int count)
{
var rx = from.X - to.X;
var ry = from.Y - to.Y;
for (var i = 0; i < count; ++i)
{
var temp = rx;
rx = -ry;
ry = temp;
}
return new Point2D(to.X + rx, to.Y + ry);
}
public static Point3D Rotate3D(this IPoint3D from, IPoint3D to, int count)
{
return new Point3D(Rotate2D(from, to, count), from.Z);
}
public static Point2D Clone2D(this IPoint2D p, IPoint2D t)
{
return new Point2D(p.X + t.X, p.Y + t.Y);
}
public static Point2D Clone2D(this IPoint2D p, int xOffset = 0, int yOffset = 0)
{
return new Point2D(p.X + xOffset, p.Y + yOffset);
}
public static Point3D Clone3D(this IPoint3D p, IPoint3D t)
{
return new Point3D(p.X + t.X, p.Y + t.Y, p.Z + t.Z);
}
public static Point3D Clone3D(this IPoint3D p, int xOffset = 0, int yOffset = 0, int zOffset = 0)
{
return new Point3D(p.X + xOffset, p.Y + yOffset, p.Z + zOffset);
}
public static Point2D Lerp2D(this IPoint2D start, IPoint2D end, double percent)
{
return Lerp2D(start, end.X, end.Y, percent);
}
public static Point2D Lerp2D(this IPoint2D start, int x, int y, double percent)
{
return Clone2D(start, (int)((x - start.X) * percent), (int)((y - start.Y) * percent));
}
public static Point3D Lerp3D(this IPoint3D start, IPoint3D end, double percent)
{
return Lerp3D(start, end.X, end.Y, end.Z, percent);
}
public static Point3D Lerp3D(this IPoint3D start, int x, int y, int z, double percent)
{
return Clone3D(
start,
(int)((x - start.X) * percent),
(int)((y - start.Y) * percent),
(int)((z - start.Z) * percent));
}
public static Point2D Delta2D(this IPoint2D start, IPoint2D end)
{
return new Point2D(start.X - end.X, start.Y - end.Y);
}
public static Point2D Delta2D(this IPoint2D start, int endX, int endY)
{
return new Point2D(start.X - endX, start.Y - endY);
}
public static Point3D Delta3D(this IPoint3D start, IPoint3D end)
{
return new Point3D(start.X - end.X, start.Y - end.Y, start.Z - end.Z);
}
public static Point3D Delta3D(this IPoint3D start, int endX, int endY, int endZ)
{
return new Point3D(start.X - endX, start.Y - endY, start.Z - endZ);
}
public static double GetDistance(this IPoint2D start, IPoint2D end)
{
return Math.Abs(Math.Sqrt(Math.Pow(end.X - start.X, 2) + Math.Pow(end.Y - start.Y, 2)));
}
public static double GetDistance(this IPoint3D start, IPoint3D end)
{
return Math.Abs(
Math.Sqrt(Math.Pow(end.X - start.X, 2) + Math.Pow(end.Y - start.Y, 2) + (Math.Pow(end.Z - start.Z, 2) / 44.0)));
}
public static TimeSpan GetTravelTime(this IPoint2D start, IPoint2D end, double speed)
{
var span = GetDistance(start, end) / (speed * 1.25);
span = Math.Max(0, Math.Min(TimeSpan.MaxValue.TotalSeconds, span));
return TimeSpan.FromSeconds(span);
}
public static TimeSpan GetTravelTime(this IPoint3D start, IPoint3D end, double speed)
{
var span = GetDistance(start, end) / (speed * 1.25);
var z1 = (double)start.Z;
var z2 = (double)end.Z;
var zDiff = Math.Abs(z2 - z1);
if (zDiff >= 5)
{
span -= (zDiff / 5.0) * 0.1;
}
span = Math.Max(0, Math.Min(TimeSpan.MaxValue.TotalSeconds, span));
return TimeSpan.FromSeconds(span);
}
public static object GetTopSurface(this Map map, Point3D p, bool multis)
{
if (map == Map.Internal)
{
return null;
}
object surface = null;
var surfaceZ = Int32.MinValue;
var lt = map.Tiles.GetLandTile(p.X, p.Y);
if (!lt.Ignored)
{
var avgZ = map.GetAverageZ(p.X, p.Y);
if (avgZ <= p.Z)
{
surface = lt;
surfaceZ = avgZ;
if (surfaceZ == p.Z)
{
return surface;
}
}
}
var staticTiles = map.Tiles.GetStaticTiles(p.X, p.Y, multis);
ItemData id;
int tileZ;
foreach (var tile in staticTiles)
{
id = TileData.ItemTable[tile.ID & TileData.MaxItemValue];
if (!id.Surface && (id.Flags & TileFlag.Wet) == 0)
{
continue;
}
tileZ = tile.Z + id.CalcHeight;
if (tileZ <= surfaceZ || tileZ > p.Z)
{
continue;
}
surface = tile;
surfaceZ = tileZ;
if (surfaceZ == p.Z)
{
return surface;
}
}
var sector = map.GetSector(p.X, p.Y);
int itemZ;
var items = sector.Items.Where(
o => o.ItemID <= TileData.MaxItemValue && !o.Movable && !(o is BaseMulti) && o.AtWorldPoint(p.X, p.Y));
foreach (var item in items)
{
id = item.ItemData;
if (!id.Surface && (id.Flags & TileFlag.Wet) == 0)
{
continue;
}
itemZ = item.Z + id.CalcHeight;
if (itemZ <= surfaceZ || itemZ > p.Z)
{
continue;
}
surface = item;
surfaceZ = itemZ;
if (surfaceZ == p.Z)
{
return surface;
}
}
return surface;
}
public static Point3D GetSurfaceTop(this IPoint2D p, Map map, bool items = true, bool multis = true)
{
if (map == null || map == Map.Internal)
{
return ToPoint3D(p);
}
return GetSurfaceTop(ToPoint3D(p, Region.MaxZ), map, items, multis);
}
public static Point3D GetSurfaceTop(this IPoint3D p, Map map, bool items = true, bool multis = true)
{
if (map == null || map == Map.Internal)
{
return ToPoint3D(p);
}
var o = GetTopSurface(map, ToPoint3D(p, Region.MaxZ), multis);
if (o != null)
{
if (o is LandTile)
{
var t = (LandTile)o;
return ToPoint3D(p, t.Z + t.Height);
}
if (o is StaticTile)
{
var t = (StaticTile)o;
return ToPoint3D(p, t.Z + TileData.ItemTable[t.ID].CalcHeight);
}
if (o is Item && items)
{
var t = (Item)o;
return ToPoint3D(p, t.Z + t.ItemData.CalcHeight);
}
}
return ToPoint3D(p);
}
public static Point3D GetWorldTop(this IPoint2D p, Map map)
{
return GetSurfaceTop(p, map, false);
}
public static Point3D GetWorldTop(this IPoint3D p, Map map)
{
return GetSurfaceTop(p, map, false);
}
public static int GetTopZ(this Rectangle2D b, Map map)
{
return GetTopZ(map, b.EnumeratePoints());
}
public static int GetTopZ(this Rectangle3D b, Map map)
{
return GetTopZ(map, b.EnumeratePoints2D());
}
public static int GetTopZ(this IPoint2D p, Map map, int range)
{
return GetTopZ(new Rectangle2D(p.X - range, p.Y - range, (range * 2) + 1, (range * 2) + 1), map);
}
public static int GetTopZ(this Map map, Rectangle2D b)
{
return GetTopZ(map, b.EnumeratePoints());
}
public static int GetTopZ(this Map map, Rectangle3D b)
{
return GetTopZ(map, b.EnumeratePoints2D());
}
public static int GetTopZ(this Map map, params Point2D[] points)
{
return GetTopZ(map, points.Ensure());
}
public static int GetTopZ(this Map map, IEnumerable<Point2D> points)
{
try
{
return points.Max(p => GetTopZ(p, map));
}
catch (InvalidCastException)
{
return 0;
}
}
public static int GetTopZ(this IPoint2D p, Map map)
{
GetAverageZ(p, map, out var c, out var a, out var t);
return t;
}
public static int GetAverageZ(this IPoint2D p, Map map, int range)
{
return GetAverageZ(new Rectangle2D(p.X - range, p.Y - range, (range * 2) + 1, (range * 2) + 1), map);
}
public static int GetAverageZ(this Rectangle2D b, Map map)
{
return GetAverageZ(map, b.EnumeratePoints());
}
public static int GetAverageZ(this Rectangle3D b, Map map)
{
return GetAverageZ(map, b.EnumeratePoints2D());
}
public static int GetAverageZ(this Map map, Rectangle2D b)
{
return GetAverageZ(map, b.EnumeratePoints());
}
public static int GetAverageZ(this Map map, Rectangle3D b)
{
return GetAverageZ(map, b.EnumeratePoints2D());
}
public static int GetAverageZ(this Map map, params Point2D[] points)
{
return GetAverageZ(map, points.Ensure());
}
public static int GetAverageZ(this Map map, IEnumerable<Point2D> points)
{
try
{
return (int)points.Average(p => GetAverageZ(p, map));
}
catch (InvalidCastException)
{
return 0;
}
}
/// <summary>
/// (( ,A,_,A,
/// )) ,{=^;^=}
/// (( {,,}#{,,}
/// `{,,}{,,}
/// </summary>
public static int GetAverageZ(this IPoint2D p, Map map)
{
GetAverageZ(p, map, out var c, out var a, out var t);
return a;
}
public static void GetAverageZ(this IPoint2D p, Map map, out int cur, out int avg, out int top)
{
var land = new
{
T = map.Tiles.GetLandTile(p.X, p.Y),
L = map.Tiles.GetLandTile(p.X, p.Y + 1),
R = map.Tiles.GetLandTile(p.X + 1, p.Y),
B = map.Tiles.GetLandTile(p.X + 1, p.Y + 1)
};
var surf = new
{
T = GetSurfaceTop(p, map, false, false),
L = GetSurfaceTop(Clone2D(p, 0, 1), map, false, false),
R = GetSurfaceTop(Clone2D(p, 1), map, false, false),
B = GetSurfaceTop(Clone2D(p, 1, 1), map, false, false)
};
var zT = (land.T.Ignored || surf.T.Z > Region.MinZ) ? surf.T.Z : land.T.Z;
var zL = (land.L.Ignored || surf.L.Z > Region.MinZ) ? surf.L.Z : land.L.Z;
var zR = (land.R.Ignored || surf.R.Z > Region.MinZ) ? surf.R.Z : land.R.Z;
var zB = (land.B.Ignored || surf.B.Z > Region.MinZ) ? surf.B.Z : land.B.Z;
cur = zT;
if (zL > Region.MinZ && zL < cur)
{
cur = zL;
}
if (zR > Region.MinZ && zR < cur)
{
cur = zR;
}
if (zB > Region.MinZ && zB < cur)
{
cur = zB;
}
top = zT;
if (zL > Region.MinZ && zL > top)
{
top = zL;
}
if (zR > Region.MinZ && zR > top)
{
top = zR;
}
if (zB > Region.MinZ && zB > top)
{
top = zB;
}
if (cur <= Region.MinZ)
{
cur = 0;
}
if (top <= Region.MinZ)
{
top = 0;
}
if (zT <= Region.MinZ)
{
zT = 0;
}
if (zL <= Region.MinZ)
{
zL = 0;
}
if (zR <= Region.MinZ)
{
zR = 0;
}
if (zB <= Region.MinZ)
{
zB = 0;
}
var vL = zL + zR;
if (vL < 0)
{
--vL;
}
var vR = zT + zB;
if (vR < 0)
{
--vR;
}
avg = Math.Abs(zT - zB) > Math.Abs(zL - zR) ? vL / 2 : vR / 2;
}
public static bool IsInside(this IPoint3D p, Map map)
{
if (p != null && map != null && map != Map.Internal)
{
return IsInside(p, p.Z, map);
}
return false;
}
public static bool IsOutside(this IPoint3D p, Map map)
{
return !IsInside(p, map);
}
public static bool IsInside(this IPoint2D p, int z, Map map)
{
if (p == null || map == null || map == Map.Internal)
{
return false;
}
if (p is Item)
{
z += Math.Max(0, ((Item)p).ItemData.Height) + 1;
}
z = Math.Max(Region.MinZ, Math.Min(Region.MaxZ, z));
return !map.CanFit(p.X, p.Y, z, Region.MaxZ - z, true, false, false);
}
public static bool IsOutside(this IPoint2D p, int z, Map map)
{
return !IsInside(p, z, map);
}
}
}

View File

@@ -0,0 +1,301 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using System;
using VitaNex.SuperGumps;
#endregion
namespace Server.Gumps
{
public static class GumpExtUtility
{
public static bool TryGetX(this GumpEntry e, out int x)
{
if (e is IGumpEntryPoint)
{
x = ((IGumpEntryPoint)e).X;
return true;
}
return e.GetPropertyValue("X", out x);
}
public static bool TrySetX(this GumpEntry e, int x)
{
if (e is IGumpEntryPoint)
{
((IGumpEntryPoint)e).X = x;
return true;
}
return e.SetPropertyValue("X", x);
}
public static bool TryOffsetX(this GumpEntry e, int x)
{
if (TryGetX(e, out var ox))
{
return TrySetX(e, ox + x);
}
return false;
}
public static bool TryGetY(this GumpEntry e, out int y)
{
if (e is IGumpEntryPoint)
{
y = ((IGumpEntryPoint)e).Y;
return true;
}
return e.GetPropertyValue("Y", out y);
}
public static bool TrySetY(this GumpEntry e, int y)
{
if (e is IGumpEntryPoint)
{
((IGumpEntryPoint)e).Y = y;
return true;
}
return e.SetPropertyValue("Y", y);
}
public static bool TryOffsetY(this GumpEntry e, int y)
{
if (TryGetY(e, out var oy))
{
return TrySetY(e, oy + y);
}
return false;
}
public static bool TryGetWidth(this GumpEntry e, out int width)
{
if (e is IGumpEntrySize)
{
width = ((IGumpEntrySize)e).Width;
return true;
}
return e.GetPropertyValue("Width", out width);
}
public static bool TrySetWidth(this GumpEntry e, int width)
{
if (e is IGumpEntrySize)
{
((IGumpEntrySize)e).Width = width;
return true;
}
return e.SetPropertyValue("Width", width);
}
public static bool TryOffsetWidth(this GumpEntry e, int width)
{
if (TryGetWidth(e, out var ow))
{
return TrySetWidth(e, ow + width);
}
return false;
}
public static bool TryGetHeight(this GumpEntry e, out int height)
{
if (e is IGumpEntrySize)
{
height = ((IGumpEntrySize)e).Height;
return true;
}
return e.GetPropertyValue("Height", out height);
}
public static bool TrySetHeight(this GumpEntry e, int height)
{
if (e is IGumpEntrySize)
{
((IGumpEntrySize)e).Height = height;
return true;
}
return e.SetPropertyValue("Height", height);
}
public static bool TryOffsetHeight(this GumpEntry e, int height)
{
if (TryGetHeight(e, out var oh))
{
return TrySetHeight(e, oh + height);
}
return false;
}
public static bool TryGetPosition(this GumpEntry e, out int x, out int y)
{
if (e is IGumpEntryPoint)
{
x = ((IGumpEntryPoint)e).X;
y = ((IGumpEntryPoint)e).Y;
return true;
}
return e.GetPropertyValue("X", out x) & e.GetPropertyValue("Y", out y);
}
public static bool TrySetPosition(this GumpEntry e, int x, int y)
{
if (e is IGumpEntryPoint)
{
((IGumpEntryPoint)e).X = x;
((IGumpEntryPoint)e).Y = y;
return true;
}
return e.SetPropertyValue("X", x) & e.SetPropertyValue("Y", y);
}
public static bool TryOffsetPosition(this GumpEntry e, int x, int y)
{
if (TryGetPosition(e, out var ox, out var oy))
{
return TrySetPosition(e, ox + x, oy + y);
}
return false;
}
public static bool TryGetSize(this GumpEntry e, out int width, out int height)
{
if (e is IGumpEntrySize)
{
width = ((IGumpEntrySize)e).Width;
height = ((IGumpEntrySize)e).Height;
return true;
}
return e.GetPropertyValue("Width", out width) & e.GetPropertyValue("Height", out height);
}
public static bool TrySetSize(this GumpEntry e, int width, int height)
{
if (e is IGumpEntrySize)
{
((IGumpEntrySize)e).Width = width;
((IGumpEntrySize)e).Height = height;
return true;
}
return e.SetPropertyValue("Width", width) & e.SetPropertyValue("Height", height);
}
public static bool TryOffsetSize(this GumpEntry e, int width, int height)
{
if (TryGetSize(e, out var ow, out var oh))
{
return TrySetSize(e, ow + width, oh + height);
}
return false;
}
public static bool TryGetBounds(this GumpEntry e, out int x, out int y, out int width, out int height)
{
if (e is IGumpEntryVector)
{
x = ((IGumpEntryVector)e).X;
y = ((IGumpEntryVector)e).Y;
width = ((IGumpEntryVector)e).Width;
height = ((IGumpEntryVector)e).Height;
return true;
}
return e.GetPropertyValue("X", out x) & e.GetPropertyValue("Y", out y) & //
e.GetPropertyValue("Width", out width) & e.GetPropertyValue("Height", out height);
}
public static bool TrySetBounds(this GumpEntry e, int x, int y, int width, int height)
{
if (e is IGumpEntryVector)
{
((IGumpEntryVector)e).X = x;
((IGumpEntryVector)e).Y = y;
((IGumpEntryVector)e).Width = width;
((IGumpEntryVector)e).Height = height;
return true;
}
return e.SetPropertyValue("X", x) & e.SetPropertyValue("Y", y) & //
e.SetPropertyValue("Width", width) & e.SetPropertyValue("Height", height);
}
public static bool TryOffsetBounds(this GumpEntry e, int x, int y, int width, int height)
{
if (TryGetBounds(e, out var ox, out var oy, out var ow, out var oh))
{
return TrySetBounds(e, ox + x, oy + y, ow + width, oh + height);
}
return false;
}
public static Rectangle2D GetBounds(this Gump g)
{
int x = g.X, y = g.Y, w = 0, h = 0;
if (g is SuperGump)
{
var sg = (SuperGump)g;
x += sg.XOffset;
y += sg.YOffset;
if (sg.Modal)
{
x += sg.ModalXOffset;
y += sg.ModalYOffset;
}
w = sg.OuterWidth;
h = sg.OuterHeight;
}
else
{
foreach (var e in g.Entries)
{
e.TryGetPosition(out var ex, out var ey);
e.TryGetSize(out var ew, out var eh);
w = Math.Max(ex + ew, w);
h = Math.Max(ey + eh, h);
}
}
return new Rectangle2D(x, y, w, h);
}
}
}

View File

@@ -0,0 +1,926 @@
#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.Globalization;
using System.IO;
using Server.Items;
using Server.Multis;
using Server.Network;
using VitaNex;
using VitaNex.Collections;
#endregion
namespace Server
{
[Flags]
public enum GiveFlags
{
None = 0x0,
Pack = 0x1,
Bank = 0x2,
Corpse = 0x4,
Feet = 0x8,
Delete = 0x40000000,
PackBank = Pack | Bank,
PackCorpse = Pack | Corpse,
PackFeet = Pack | Feet,
PackDelete = Pack | Delete,
PackBankCorpse = PackBank | Corpse,
PackBankFeet = PackBank | Feet,
PackBankDelete = PackBank | Delete,
PackBankCorpseFeet = PackBankCorpse | Feet,
PackBankCorpseDelete = PackBankCorpse | Delete,
PackBankFeetDelete = PackBankFeet | Delete,
PackBankCorpseFeetDelete = PackBankCorpseFeet | Delete,
PackCorpseFeet = PackCorpse | Feet,
PackCorpseDelete = PackCorpse | Delete,
PackCorpseFeetDelete = PackCorpseFeet | Delete,
PackFeetDelete = PackFeet | Delete,
BankCorpse = Bank | Corpse,
BankFeet = Bank | Feet,
BankDelete = Bank | Delete,
BankCorpseFeet = BankCorpse | Feet,
BankCorpseDelete = BankCorpse | Delete,
BankFeetDelete = BankFeet | Delete,
BankCorpseFeetDelete = BankCorpseFeet | Delete,
CorpseFeet = Corpse | Feet,
CorpseDelete = Corpse | Delete,
CorpseFeetDelete = CorpseFeet | Delete,
FeetDelete = Feet | Delete,
All = ~None
}
public static class ItemExtUtility
{
public static T BinaryClone<T>(this T item)
where T : Item
{
var t = item.GetType();
var o = t.CreateInstanceSafe<T>(Serial.NewItem);
if (o != null)
{
try
{
using (var ms = new MemoryStream())
{
var w = ms.GetBinaryWriter();
item.Serialize(w);
ms.Position = 0;
var r = ms.GetBinaryReader();
o.Deserialize(r);
w.Close();
r.Close();
}
var m = o.Parent as Mobile;
o.Amount = 1;
if (o.Items != null)
{
o.Items.Clear();
}
o.Internalize();
o.Parent = null;
if (m != null)
{
o.OnRemoved(m);
m.OnItemRemoved(o);
}
}
catch
{
o.Delete();
o = null;
}
}
return o;
}
public static void InvalidateProperties<T>(this Item item)
{
if (item is T)
{
item.InvalidateProperties();
}
var i = item.Items.Count;
while (--i >= 0)
{
InvalidateProperties<T>(item.Items[i]);
}
}
public static void InvalidateProperties(this Item item, Type type)
{
if (item.TypeEquals(type))
{
item.InvalidateProperties();
}
var i = item.Items.Count;
while (--i >= 0)
{
InvalidateProperties(item.Items[i], type);
}
}
public static int GetAnimID(this Item item)
{
return item != null && item.Layer.IsValid() ? ArtworkSupport.LookupAnimation(item.ItemID) : 0;
}
public static int GetGumpID(this Item item, bool female)
{
return item != null && item.Layer.IsValid() ? ArtworkSupport.LookupGump(item.ItemID, female) : 0;
}
public static PaperdollBounds GetGumpBounds(this Item item)
{
if (item == null)
{
return PaperdollBounds.Empty;
}
if (item.Layer == Layer.TwoHanded)
{
if (item is BaseRanged)
{
return PaperdollBounds.MainHand;
}
if (item is BaseEquipableLight || item is BaseShield)
{
return PaperdollBounds.OffHand;
}
}
return PaperdollBounds.Find(item.Layer);
}
public static Mobile FindOwner(this Item item)
{
return FindOwner<Mobile>(item);
}
public static TMobile FindOwner<TMobile>(this Item item)
where TMobile : Mobile
{
if (item == null || item.Deleted)
{
return null;
}
var owner = item.RootParent as TMobile;
if (owner == null)
{
var h = BaseHouse.FindHouseAt(item);
if (h != null)
{
owner = h.Owner as TMobile;
}
}
return owner;
}
public static GiveFlags GiveTo(this Item item, Mobile m, GiveFlags flags = GiveFlags.All, bool message = true)
{
if (item == null || item.Deleted || m == null || m.Deleted || flags == GiveFlags.None)
{
return GiveFlags.None;
}
var pack = flags.HasFlag(GiveFlags.Pack);
var bank = flags.HasFlag(GiveFlags.Bank);
var feet = flags.HasFlag(GiveFlags.Feet);
var corpse = flags.HasFlag(GiveFlags.Corpse);
var delete = flags.HasFlag(GiveFlags.Delete);
if (pack && (m.Backpack == null || m.Backpack.Deleted || !m.Backpack.CheckHold(m, item, false)))
{
pack = false;
flags &= ~GiveFlags.Pack;
}
if (bank && (!m.Player || !m.BankBox.CheckHold(m, item, false)))
{
bank = false;
flags &= ~GiveFlags.Bank;
}
if (corpse && (m.Alive || m.Corpse == null || m.Corpse.Deleted))
{
corpse = false;
flags &= ~GiveFlags.Corpse;
}
if (feet && (m.Map == null || m.Map == Map.Internal) && (m.LogoutMap == null || m.LogoutMap == Map.Internal))
{
feet = false;
flags &= ~GiveFlags.Feet;
}
var result = VitaNexCore.TryCatchGet(
f =>
{
if (pack && m.Backpack.DropItemStack(m, item))
{
return GiveFlags.Pack;
}
if (bank && m.BankBox.DropItemStack(m, item))
{
return GiveFlags.Bank;
}
if (corpse && m.Corpse.DropItemStack(m, item))
{
return GiveFlags.Corpse;
}
if (feet)
{
if (m.Map != null && m.Map != Map.Internal)
{
item.MoveToWorld(m.Location, m.Map);
if (m.Player)
{
item.SendInfoTo(m.NetState);
}
return GiveFlags.Feet;
}
if (m.LogoutMap != null && m.LogoutMap != Map.Internal)
{
item.MoveToWorld(m.LogoutLocation, m.LogoutMap);
return GiveFlags.Feet;
}
}
if (delete)
{
item.Delete();
return GiveFlags.Delete;
}
return GiveFlags.None;
},
flags);
if (!message || result == GiveFlags.None || result == GiveFlags.Delete)
{
return result;
}
var amount = String.Empty;
var name = ResolveName(item, m);
var p = item.Stackable && item.Amount > 1;
if (p)
{
amount = item.Amount.ToString("#,0") + " ";
if (!Insensitive.EndsWith(name, "s") && !Insensitive.EndsWith(name, "z"))
{
name += "s";
}
}
switch (result)
{
case GiveFlags.Pack:
m.SendMessage("{0}{1} {2} been placed in your pack.", amount, name, p ? "have" : "has");
break;
case GiveFlags.Bank:
m.SendMessage("{0}{1} {2} been placed in your bank.", amount, name, p ? "have" : "has");
break;
case GiveFlags.Corpse:
m.SendMessage("{0}{1} {2} been placed in your corpse.", amount, name, p ? "have" : "has");
break;
case GiveFlags.Feet:
m.SendMessage("{0}{1} {2} been placed at your feet.", amount, name, p ? "have" : "has");
break;
}
return result;
}
public static bool WasReceived(this GiveFlags flags)
{
return flags != GiveFlags.None && flags != GiveFlags.Delete;
}
private static readonly Dictionary<Item, List<object>> _Actions = new Dictionary<Item, List<object>>();
public static bool BeginAction(this Item item, object toLock)
{
if (!_Actions.TryGetValue(item, out var actions) || actions == null)
{
ObjectPool.Acquire(out actions);
_Actions[item] = actions;
}
if (!actions.Contains(toLock))
{
actions.Add(toLock);
return true;
}
return false;
}
public static bool CanBeginAction(this Item item, object toLock)
{
var actions = _Actions.GetValue(item);
return actions == null || !actions.Contains(toLock);
}
public static void EndAction(this Item item, object toLock)
{
var actions = _Actions.GetValue(item);
if (actions == null)
{
return;
}
actions.Remove(toLock);
if (actions.Count == 0)
{
_Actions.Remove(item);
ObjectPool.Free(ref actions);
}
}
public static bool BeginAction<T>(this Item item, T locker, TimeSpan duration)
{
var o = BeginAction(item, locker);
if (o)
{
Timer.DelayCall(duration, EndAction, Tuple.Create(item, locker));
}
return o;
}
private static void EndAction<T>(Tuple<Item, T> t)
{
if (!CanBeginAction(t.Item1, t.Item2))
{
EndAction(t.Item1, t.Item2);
}
}
public static bool BeginAction<T>(this Item item, T locker, TimeSpan duration, Action<Item> callback)
{
var o = BeginAction(item, locker);
if (o)
{
Timer.DelayCall(duration, EndAction, Tuple.Create(item, locker, callback));
}
return o;
}
private static void EndAction<T>(Tuple<Item, T, Action<Item>> t)
{
if (!CanBeginAction(t.Item1, t.Item2))
{
EndAction(t.Item1, t.Item2);
if (t.Item3 != null)
{
t.Item3(t.Item1);
}
}
}
public static bool BeginAction<T>(this Item item, T locker, TimeSpan duration, Action<Item, T> callback)
{
var o = BeginAction(item, locker);
if (o)
{
Timer.DelayCall(duration, EndAction, Tuple.Create(item, locker, callback));
}
return o;
}
private static void EndAction<T>(Tuple<Item, T, Action<Item, T>> t)
{
if (!CanBeginAction(t.Item1, t.Item2))
{
EndAction(t.Item1, t.Item2);
if (t.Item3 != null)
{
t.Item3(t.Item1, t.Item2);
}
}
}
public static string ResolveName(this Item item)
{
return ResolveName(item, Clilocs.DefaultLanguage);
}
public static string ResolveName(this Item item, Mobile viewer)
{
return ResolveName(item, viewer.GetLanguage());
}
public static string ResolveName(this Item item, ClilocLNG lng)
{
if (item == null)
{
return String.Empty;
}
var label = item.GetOPLHeader(lng);
if (!String.IsNullOrEmpty(label))
{
label = label.Replace("\t", " ").Replace("\u0009", " ").Replace("<br>", "\n").Replace("<BR>", "\n").Trim();
}
if (!String.IsNullOrEmpty(label))
{
label = label.StripHtml(false);
label = label.Trim();
int idx;
if ((idx = label.IndexOf('\n')) >= 0)
{
if (idx > 0)
{
label = label.Substring(0, idx);
}
else
{
label = label.TrimStart('\n');
}
}
label = label.Trim();
if ((idx = label.IndexOf(' ')) >= 0)
{
if (idx > 0)
{
if (Int32.TryParse(label.Substring(0, idx), NumberStyles.Number, CultureInfo.InvariantCulture, out var amount))
{
label = label.Substring(idx + 1);
}
}
else
{
label = label.TrimStart(' ');
}
}
label = label.Trim();
}
if (String.IsNullOrWhiteSpace(label) && item.Name != null)
{
label = item.Name;
}
if (String.IsNullOrWhiteSpace(label) && item.DefaultName != null)
{
label = item.DefaultName;
}
if (String.IsNullOrWhiteSpace(label) && item.LabelNumber > 0)
{
label = lng.GetString(item.LabelNumber);
}
if (String.IsNullOrWhiteSpace(label) && TileData.ItemTable.InBounds(item.ItemID))
{
label = TileData.ItemTable[item.ItemID].Name;
}
if (String.IsNullOrWhiteSpace(label))
{
label = item.GetType().Name.SpaceWords();
}
if (!String.IsNullOrEmpty(label))
{
label = label.StripExcessWhiteSpace().Trim();
}
return label;
}
public static bool HasUsesRemaining(this Item item)
{
return CheckUsesRemaining(item, false, out var uses);
}
public static bool HasUsesRemaining(this Item item, out int uses)
{
return CheckUsesRemaining(item, false, out uses);
}
public static bool CheckUsesRemaining(this Item item, bool deplete, out int uses)
{
return CheckUsesRemaining(item, deplete ? 1 : 0, out uses);
}
public static bool CheckUsesRemaining(this Item item, int deplete, out int uses)
{
uses = -1;
if (item == null || item.Deleted)
{
return false;
}
if (!(item is IUsesRemaining))
{
return true;
}
var u = (IUsesRemaining)item;
if (u.UsesRemaining <= 0)
{
uses = 0;
return false;
}
if (deplete > 0)
{
if (u.UsesRemaining < deplete)
{
uses = u.UsesRemaining;
return false;
}
u.UsesRemaining = Math.Max(0, u.UsesRemaining - deplete);
}
uses = u.UsesRemaining;
return true;
}
public static bool CheckUse(
this Item item,
Mobile from,
bool handle = true,
bool allowDead = false,
int range = -1,
bool packOnly = false,
bool inTrade = false,
bool inDisplay = true,
AccessLevel access = AccessLevel.Player)
{
return CheckDoubleClick(item, from, handle, allowDead, range, packOnly, inTrade, inDisplay, access);
}
public static bool CheckDoubleClick(
this Item item,
Mobile from,
bool handle = true,
bool allowDead = false,
int range = -1,
bool packOnly = false,
bool inTrade = false,
bool inDisplay = true,
AccessLevel access = AccessLevel.Player)
{
if (item == null || item.Deleted || from == null || from.Deleted)
{
return false;
}
if (from.AccessLevel < access)
{
if (handle)
{
from.SendMessage("You do not have sufficient access to use this item.");
}
return false;
}
if (!from.CanSee(item) && !(item is IAddon))
{
if (handle)
{
from.SendMessage("This item can't be seen.");
item.OnDoubleClickCantSee(from);
}
return false;
}
if (!item.IsAccessibleTo(from))
{
if (handle)
{
item.OnDoubleClickNotAccessible(from);
}
return false;
}
if (item.InSecureTrade && !inTrade)
{
if (handle)
{
item.OnDoubleClickSecureTrade(from);
}
return false;
}
if (((item.Parent == null && !item.Movable && !item.IsLockedDown && !item.IsSecure && !item.InSecureTrade) ||
IsShopItem(item)) && !inDisplay)
{
if (handle)
{
from.SendMessage("This item can not be accessed because it is part of a display.");
}
return false;
}
if (!from.Alive && !allowDead)
{
if (handle)
{
item.OnDoubleClickDead(from);
}
return false;
}
if (range >= 0 && !packOnly && !from.InRange(item, range))
{
if (handle)
{
if (range > 0)
{
from.SendMessage("You must be within {0:#,0} paces to use this item.", range);
}
else
{
from.SendMessage("You must be standing on this item to use it.");
}
item.OnDoubleClickOutOfRange(from);
}
return false;
}
if (packOnly && item.RootParent != from)
{
if (handle)
{
// This item must be in your backpack.
from.SendLocalizedMessage(1054107);
}
return false;
}
return true;
}
public static bool IsShopItem(this Item item)
{
return HasParent(item, "Server.Mobiles.GenericBuyInfo+DisplayCache");
}
public static bool IsParentOf(this Item item, Item child)
{
if (item == null || child == null || item == child)
{
return false;
}
var p = child.Parent as Item;
while (p != null && p != item)
{
p = p.Parent as Item;
}
return item == p;
}
public static bool HasParent<TEntity>(this Item item)
where TEntity : IEntity
{
return HasParent(item, typeof(TEntity));
}
public static bool HasParent(this Item item, string typeName)
{
if (item == null || String.IsNullOrWhiteSpace(typeName))
{
return false;
}
var t = Type.GetType(typeName, false, false) ?? ScriptCompiler.FindTypeByFullName(typeName, false) ??
ScriptCompiler.FindTypeByName(typeName, false);
return HasParent(item, t);
}
public static bool HasParent(this Item item, Type t)
{
if (item == null || t == null)
{
return false;
}
var p = item.Parent;
while (p is Item)
{
if (p.GetType().IsEqualOrChildOf(t))
{
return true;
}
var i = (Item)p;
if (i.Parent == null)
{
break;
}
p = i.Parent;
}
return p is Mobile && p.GetType().IsEqualOrChildOf(t);
}
public static bool IsEquipped(this Item item)
{
return item != null && item.Parent is Mobile && ((Mobile)item.Parent).FindItemOnLayer(item.Layer) == item;
}
public static bool IsEquippedBy(this Item item, Mobile m)
{
return item != null && item.Parent == m && m.FindItemOnLayer(item.Layer) == item;
}
#region *OverheadMessage
public static void PrivateOverheadMessage(this Item item, MessageType type, int hue, bool ascii, string text, NetState state)
{
if (state == null)
{
return;
}
if (ascii)
{
state.Send(new AsciiMessage(item.Serial, item.ItemID, type, hue, 3, item.Name, text));
}
else
{
state.Send(new UnicodeMessage(item.Serial, item.ItemID, type, hue, 3, "ENU", item.Name, text));
}
}
public static void PrivateOverheadMessage(this Item item, MessageType type, int hue, int number, NetState state)
{
PrivateOverheadMessage(item, type, hue, number, "", state);
}
public static void PrivateOverheadMessage(this Item item, MessageType type, int hue, int number, string args, NetState state)
{
if (state != null)
{
state.Send(new MessageLocalized(item.Serial, item.ItemID, type, hue, 3, number, item.Name, args));
}
}
public static void NonlocalOverheadMessage(this Item item, MessageType type, int hue, int number)
{
NonlocalOverheadMessage(item, type, hue, number, "");
}
public static void NonlocalOverheadMessage(this Item item, MessageType type, int hue, int number, string args)
{
if (item == null || item.Map == null)
{
return;
}
var p = Packet.Acquire(new MessageLocalized(item.Serial, item.ItemID, type, hue, 3, number, item.Name, args));
var eable = item.GetClientsInRange(Core.GlobalMaxUpdateRange);
foreach (var state in eable)
{
if (state.Mobile.InUpdateRange(item) && state.Mobile.CanSee(item))
state.Send(p);
}
eable.Free();
Packet.Release(p);
}
public static void NonlocalOverheadMessage(this Item item, MessageType type, int hue, bool ascii, string text)
{
if (item == null || item.Map == null)
{
return;
}
Packet p;
if (ascii)
{
p = new AsciiMessage(item.Serial, item.ItemID, type, hue, 3, item.Name, text);
}
else
{
p = new UnicodeMessage(item.Serial, item.ItemID, type, hue, 3, "ENU", item.Name, text);
}
p.Acquire();
var eable = item.GetClientsInRange(Core.GlobalMaxUpdateRange);
foreach (var state in eable)
{
if (state.Mobile.InUpdateRange(item) && state.Mobile.CanSee(item))
state.Send(p);
}
eable.Free();
Packet.Release(p);
}
#endregion
}
}

View File

@@ -0,0 +1,221 @@
#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 VitaNex;
#endregion
namespace Server
{
public static class LayerExtUtility
{
private const Layer _Face = (Layer)15;
private const Layer _ShopMax = (Layer)30;
private const Layer _PlateArms = (Layer)255;
private const Layer _ChainTunic = (Layer)254;
private const Layer _LeatherShorts = (Layer)253;
public static Layer[] LayerOrder =
{
Layer.Cloak, Layer.Bracelet, Layer.Ring, Layer.Shirt, Layer.Pants, Layer.InnerLegs, Layer.Shoes, _LeatherShorts,
Layer.Arms, Layer.InnerTorso, _LeatherShorts, _PlateArms, Layer.MiddleTorso, Layer.OuterLegs, Layer.Neck,
Layer.Gloves, Layer.OuterTorso, Layer.Waist, Layer.OneHanded, Layer.TwoHanded, _Face, Layer.FacialHair, Layer.Hair,
Layer.Helm, Layer.Talisman
};
public static Layer[] EquipLayers =
{
Layer.Arms, Layer.Bracelet, Layer.Cloak, Layer.Earrings, Layer.Gloves, Layer.Helm, Layer.InnerLegs, Layer.InnerTorso,
Layer.MiddleTorso, Layer.Neck, Layer.OneHanded, Layer.OuterLegs, Layer.OuterTorso, Layer.Pants, Layer.Ring,
Layer.Shirt, Layer.Shoes, Layer.Talisman, Layer.TwoHanded, Layer.Waist, Layer.Mount
};
public static int[] LayerTable { get; private set; }
static LayerExtUtility()
{
LayerTable = new int[256];
for (var i = 0; i < LayerOrder.Length; ++i)
{
LayerTable[(int)LayerOrder[i]] = LayerOrder.Length - i;
}
}
public static int GetOrderIndex(this Layer layer)
{
return LayerOrder.IndexOf(layer);
}
public static bool IsEquip(this Layer layer)
{
return EquipLayers.Contains(layer);
}
public static bool IsMount(this Layer layer)
{
return layer == Layer.Mount;
}
public static bool IsPack(this Layer layer)
{
return layer == Layer.Backpack;
}
public static bool IsBank(this Layer layer)
{
return layer == Layer.Bank;
}
public static bool IsPackOrBank(this Layer layer)
{
return IsPack(layer) || IsBank(layer);
}
public static bool IsFace(this Layer layer)
{
return layer == _Face;
}
public static bool IsHair(this Layer layer)
{
return layer == Layer.Hair;
}
public static bool IsFacialHair(this Layer layer)
{
return layer == Layer.FacialHair;
}
public static bool IsHairOrFacialHair(this Layer layer)
{
return IsHair(layer) || IsFacialHair(layer);
}
public static bool IsFaceOrHair(this Layer layer)
{
return IsFace(layer) || IsHair(layer);
}
public static bool IsFaceOrHairOrFacialHair(this Layer layer)
{
return IsFace(layer) || IsHair(layer) || IsFacialHair(layer);
}
public static bool IsShop(this Layer layer)
{
return layer == Layer.ShopBuy || layer == Layer.ShopResale || layer == Layer.ShopSell || layer == _ShopMax;
}
public static bool IsInvalid(this Layer layer)
{
return layer == Layer.Invalid;
}
public static bool IsValid(this Layer layer)
{
return IsEquip(layer) || IsPackOrBank(layer) || IsFaceOrHair(layer);
}
public static IOrderedEnumerable<Item> OrderByLayer(this IEnumerable<Item> items)
{
return items.OrderBy(item => item == null ? 0 : LayerTable[(int)Fix(item.Layer, item.ItemID)]);
}
public static IOrderedEnumerable<Item> OrderByLayerDescending(this IEnumerable<Item> items)
{
return items.OrderByDescending(item => item == null ? 0 : LayerTable[(int)Fix(item.Layer, item.ItemID)]);
}
public static IOrderedEnumerable<Layer> OrderByLayer(this IEnumerable<Layer> layers)
{
return layers.OrderBy(layer => LayerTable[(int)layer]);
}
public static IOrderedEnumerable<Layer> OrderByLayerDescending(this IEnumerable<Layer> layers)
{
return layers.OrderByDescending(layer => LayerTable[(int)layer]);
}
public static void SortLayers(this List<Item> items)
{
if (items != null && items.Count > 1)
{
items.Sort(CompareLayer);
}
}
public static void SortLayers(this List<Layer> layers)
{
if (layers != null && layers.Count > 1)
{
layers.Sort(CompareLayer);
}
}
public static int CompareLayer(this Item item, Item other)
{
var res = 0;
if (item.CompareNull(other, ref res))
{
return res;
}
return CompareLayer(Fix(item.Layer, item.ItemID), Fix(other.Layer, other.ItemID));
}
public static int CompareLayer(this Layer layer, Layer other)
{
return LayerTable[(int)other] - LayerTable[(int)layer];
}
public static bool IsOrdered(this Layer layer)
{
return LayerTable[(int)layer] > 0;
}
public static Layer Fix(this Layer layer, int itemID)
{
if (itemID == 0x1410 || itemID == 0x1417) // platemail arms
{
return _PlateArms;
}
if (itemID == 0x13BF || itemID == 0x13C4) // chainmail tunic
{
return _ChainTunic;
}
if (itemID == 0x1C08 || itemID == 0x1C09) // leather skirt
{
return _LeatherShorts;
}
if (itemID == 0x1C00 || itemID == 0x1C01) // leather shorts
{
return _LeatherShorts;
}
return layer;
}
public static PaperdollBounds GetPaperdollBounds(this Layer layer)
{
return PaperdollBounds.Find(layer);
}
}
}

View File

@@ -0,0 +1,322 @@
#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.Targeting;
#endregion
namespace Server
{
public static class MapExtUtility
{
#region StaticWaterTiles
public static List<int> StaticWaterTiles = new List<int>
{
5465,
6038,
6039,
6040,
6041,
6042,
6043,
6044,
13422,
13423,
13424,
13425,
13426,
13427,
13428,
13429,
13430,
13431,
13432,
13433,
13434,
13435,
13436,
13437,
13438,
13439,
13440,
13441,
13442,
13443,
13445,
13456,
13457,
13458,
13459,
13460,
13461,
13462,
13463,
13464,
13465,
13466,
13467,
13468,
13469,
13470,
13471,
13472,
13473,
13474,
13475,
13476,
13477,
13478,
13479,
13480,
13481,
13482,
13483,
13494,
13495,
13496,
13497,
13498,
13499,
13500,
13501,
13502,
13503,
13504,
13505,
13506,
13507,
13508,
13509,
13510,
13511,
13512,
13513,
13514,
13515,
13516,
13517,
13518,
13519,
13520,
13521,
13522,
13523,
13524,
13525,
13597,
13598,
13599,
13600,
13601,
13602,
13603,
13604,
13605,
13606,
13607,
13608,
13609,
13610,
13611,
13612,
13613,
13614,
13615,
13616
};
#endregion
#region LandWaterTiles
public static List<int> LandWaterTiles = new List<int>
{
168,
169,
170,
171,
310,
311,
#region Coastlines
76,
77,
78,
79,
80,
81,
82,
83,
84,
85,
86,
87,
88,
89,
90,
91,
92,
93,
94,
95,
96,
97,
98,
99,
100,
101,
102,
103,
104,
105,
106,
107,
108,
109,
110,
111
#endregion
};
#endregion
#region LandCoastlineTiles
public static List<int> LandCoastlineTiles = new List<int>
{
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50
};
#endregion
public static bool IsWater(this Item item)
{
return StaticWaterTiles.Contains(item.ItemID) || item.ItemData.Flags.HasFlag(TileFlag.Wet) ||
Insensitive.Contains(item.Name, "water");
}
public static bool IsWater(this LandTarget targ)
{
return LandWaterTiles.Contains(targ.TileID) || TileData.LandTable[targ.TileID].Flags.HasFlag(TileFlag.Wet) ||
Insensitive.Contains(TileData.LandTable[targ.TileID].Name, "water");
}
public static bool IsWater(this StaticTarget targ)
{
return StaticWaterTiles.Contains(targ.ItemID) || TileData.ItemTable[targ.ItemID].Flags.HasFlag(TileFlag.Wet) ||
Insensitive.Contains(TileData.ItemTable[targ.ItemID].Name, "water");
}
public static bool IsWater(this LandTile tile)
{
return LandWaterTiles.Contains(tile.ID) || TileData.LandTable[tile.ID].Flags.HasFlag(TileFlag.Wet) ||
Insensitive.Contains(TileData.LandTable[tile.ID].Name, "water");
}
public static bool IsWater(this StaticTile tile)
{
return StaticWaterTiles.Contains(tile.ID) || TileData.ItemTable[tile.ID].Flags.HasFlag(TileFlag.Wet) ||
Insensitive.Contains(TileData.ItemTable[tile.ID].Name, "water");
}
public static bool IsCoastline(this LandTile tile)
{
return LandCoastlineTiles.Contains(tile.ID) || (TileData.LandTable[tile.ID].Flags == TileFlag.Impassable &&
Insensitive.Contains(TileData.LandTable[tile.ID].Name, "sand"));
}
public static bool HasWater(this Map map, IPoint2D p)
{
return IsWater(GetLandTile(map, p)) || GetStaticTiles(map, p).Any(IsWater);
}
public static bool HasLand(this Map map, IPoint2D p)
{
return !GetLandTile(map, p).Ignored;
}
public static LandTile GetLandTile(this Map map, IPoint2D p)
{
return map.Tiles.GetLandTile(p.X, p.Y);
}
public static StaticTile[] GetStaticTiles(this Map map, IPoint2D p)
{
return map.Tiles.GetStaticTiles(p.X, p.Y);
}
public static StaticTile[] GetStaticTiles(this Map map, IPoint2D p, bool multis)
{
return map.Tiles.GetStaticTiles(p.X, p.Y, multis);
}
public static Rectangle2D GetInnerBounds2D(this Map map)
{
switch (map.MapID)
{
case 0:
case 1:
return new Rectangle2D(0, 0, Math.Min(5120, map.Width), map.Height);
case 3:
return new Rectangle2D(512, 0, map.Width - 512, map.Height);
}
return new Rectangle2D(0, 0, map.Width, map.Height);
}
public static Rectangle3D GetInnerBounds3D(this Map map)
{
switch (map.MapID)
{
case 0:
case 1:
return new Rectangle3D(0, 0, Region.MinZ, Math.Min(5120, map.Width), map.Height, Region.MaxZ - Region.MinZ);
case 3:
return new Rectangle3D(512, 0, Region.MinZ, map.Width - 512, map.Height, Region.MaxZ - Region.MinZ);
}
return new Rectangle3D(0, 0, Region.MinZ, map.Width, map.Height, Region.MaxZ - Region.MinZ);
}
public static Rectangle2D GetBounds2D(this Map map)
{
return new Rectangle2D(0, 0, map.Width, map.Height);
}
public static Rectangle3D GetBounds3D(this Map map)
{
return new Rectangle3D(0, 0, Region.MinZ, map.Width, map.Height, Region.MaxZ - Region.MinZ);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,331 @@
#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.Items;
#endregion
namespace Server
{
public static class MultiExtUtility
{
static MultiExtUtility()
{
ComponentsCache = new Dictionary<int, MultiComponentList>();
WireframeCache = new Dictionary<int, Wireframe>();
BoundsCache = new Dictionary<int, Rectangle3D>();
}
#region Components
public static Dictionary<int, MultiComponentList> ComponentsCache { get; private set; }
public static MultiComponentList GetComponents(this BaseMulti multi)
{
return GetComponents(multi, multi.ItemID);
}
public static MultiComponentList GetComponents(this BaseMulti multi, int multiID)
{
multiID &= 0x3FFF;
if (multiID <= 0)
{
multiID = multi.ItemID;
}
return GetComponents(multiID);
}
public static MultiComponentList GetComponents(int multiID)
{
multiID &= 0x3FFF;
if (ComponentsCache.TryGetValue(multiID, out var mcl) && mcl != null)
{
return mcl;
}
ComponentsCache[multiID] = mcl = MultiData.GetComponents(multiID);
// Minax Fortress
if (multiID == 0x1388)
{
// That tree...
mcl.Remove(3405, 17, -13, 15);
mcl.Remove(3406, 18, -14, 15);
mcl.Remove(3393, 18, -14, 17);
}
if (mcl.List.Length == 0)
{
mcl.Resize(1, 1);
mcl.Add(0, 0, 0, 0);
}
return mcl;
}
public static void TileAdd(this MultiComponentList mcl, int itemID, int x, int y, int w, int h, int z = 0, int d = 1)
{
TileAdd(mcl, itemID, new Rectangle2D(x, y, w, h), z, d);
}
public static void TileAdd(this MultiComponentList mcl, int itemID, Rectangle2D bounds, int z = 0, int d = 1)
{
TileAdd(mcl, itemID, bounds.ToRectangle3D(z, d));
}
public static void TileAdd(this MultiComponentList mcl, int itemID, Rectangle3D bounds)
{
for (var z = bounds.Start.Z; z < bounds.End.Z; z++)
{
for (var x = bounds.Start.X; x < bounds.End.X; x++)
{
for (var y = bounds.Start.Y; y < bounds.End.Y; y++)
{
mcl.Add(itemID, x, y, z);
}
}
}
}
#endregion
#region Wireframes
public static Dictionary<int, Wireframe> WireframeCache { get; private set; }
public static Wireframe GetWireframe(this BaseMulti multi, IPoint3D offset)
{
return GetWireframe(multi, multi.ItemID, offset);
}
public static Wireframe GetWireframe(this BaseMulti multi, IPoint3D offset, int hOffset)
{
return GetWireframe(multi, multi.ItemID, offset, hOffset);
}
public static Wireframe GetWireframe(this BaseMulti multi, IBlock3D offset)
{
return GetWireframe(multi, multi.ItemID, offset);
}
public static Wireframe GetWireframe(this BaseMulti multi, int multiID, IPoint3D offset)
{
return GetWireframe(multi, multiID, offset, 0);
}
public static Wireframe GetWireframe(this BaseMulti multi, int multiID, IBlock3D offset)
{
return GetWireframe(multi, multiID, offset, offset.H);
}
public static Wireframe GetWireframe(this BaseMulti multi, int multiID, IPoint3D offset, int hOffset)
{
var o = GetWireframe(multi, multiID);
return new Wireframe(o.Select(b => b.Offset(offset.X, offset.Y, offset.Z, hOffset)));
}
public static Wireframe GetWireframe(this BaseMulti multi)
{
return GetWireframe(multi, multi.ItemID);
}
public static Wireframe GetWireframe(this BaseMulti multi, int multiID)
{
multiID &= 0x3FFF;
if (multiID < 0)
{
multiID = multi.ItemID;
}
return GetWireframe(multiID);
}
public static Wireframe GetWireframe(int multiID)
{
multiID &= 0x3FFF;
if (WireframeCache.TryGetValue(multiID, out var frame))
{
return frame;
}
frame = GetWireframe(GetComponents(multiID));
WireframeCache[multiID] = frame;
return frame;
}
public static Wireframe GetWireframe(this MultiComponentList mcl, IPoint3D offset)
{
return new Wireframe(GetWireframe(mcl).Select(b => b.Offset(offset.X, offset.Y, offset.Z)));
}
public static Wireframe GetWireframe(this MultiComponentList mcl, IBlock3D offset)
{
return new Wireframe(GetWireframe(mcl).Offset(offset.X, offset.Y, offset.Z, offset.H));
}
public static Wireframe GetWireframe(this MultiComponentList mcl)
{
if (mcl == null)
{
return Wireframe.Empty;
}
var frame = new Block3D[mcl.List.Length];
frame.SetAll(
i =>
{
var o = mcl.List[i];
var h = Math.Max(5, TileData.ItemTable[o.m_ItemID].Height);
return new Block3D(o.m_OffsetX, o.m_OffsetY, o.m_OffsetZ, h);
});
return new Wireframe(frame);
}
#endregion
#region Bounds
public static Dictionary<int, Rectangle3D> BoundsCache { get; private set; }
public static Rectangle3D GetBoundsOffset(this BaseMulti multi)
{
return GetBoundsOffset(multi, multi.Location);
}
public static Rectangle3D GetBoundsOffset(this BaseMulti multi, Point3D offset)
{
return GetBounds(multi).Resize(offset.X, offset.Y, offset.Z);
}
public static Rectangle3D GetBounds(this BaseMulti multi)
{
return GetBounds(multi, multi.ItemID);
}
public static Rectangle3D GetBounds(this BaseMulti multi, int multiID)
{
multiID &= 0x3FFF;
if (multiID <= 0)
{
multiID = multi.ItemID;
}
return GetBounds(multiID);
}
public static Rectangle3D GetBounds(int multiID)
{
multiID &= 0x3FFF;
if (BoundsCache.TryGetValue(multiID, out var bounds))
{
return bounds;
}
var mcl = GetComponents(multiID);
int minZ = mcl.List.Min(t => t.m_OffsetZ);
var maxZ = mcl.List.Max(t => t.m_OffsetZ + Math.Max(1, TileData.ItemTable[t.m_ItemID].Height));
if (multiID >= 24 && multiID <= 71)
{
if (multiID >= 24 && multiID <= 35)
{
maxZ = Math.Max(80, maxZ);
}
else if (multiID >= 36 && multiID <= 47)
{
maxZ = Math.Max(100, maxZ);
}
else if (multiID >= 48 && multiID <= 59)
{
maxZ = Math.Max(90, maxZ);
}
else if (multiID >= 60 && multiID <= 63)
{
maxZ = Math.Max(20, maxZ);
}
else if (multiID >= 64 && multiID <= 71)
{
maxZ = Math.Max(110, maxZ);
}
}
bounds = new Rectangle3D(mcl.Min.X, mcl.Min.Y, minZ, mcl.Width + 1, mcl.Height + 1, maxZ - minZ);
BoundsCache[multiID] = bounds;
return bounds;
}
#endregion
/*
public static bool Contains(Point2D p)
{
return Contains(p.m_X, p.m_Y);
}
public static bool Contains(Point3D p)
{
return Contains(p.m_X, p.m_Y);
}
public static bool Contains(IPoint3D p)
{
return Contains(p.X, p.Y);
}
public static bool Contains(int x, int y)
{
MultiComponentList mcl = Components;
x -= X + mcl.Min.m_X;
y -= Y + mcl.Min.m_Y;
return x >= 0 && x < mcl.Width && y >= 0 && y < mcl.Height && mcl.Tiles[x][y].Length > 0;
}
*/
public static bool IsEmpty(this MultiComponentList mcl, int x, int y)
{
return x < 0 || x >= mcl.Width || y < 0 || y >= mcl.Height || mcl.Tiles[x][y].Length == 0;
}
public static bool HasEntry(this MultiComponentList mcl, int x, int y, int z)
{
return !IsEmpty(mcl, x, y) && mcl.Tiles[x][y].Any(t => t.Z == z);
}
public static bool HasEntry(this MultiComponentList mcl, int itemID, int x, int y, int z)
{
return !IsEmpty(mcl, x, y) && mcl.Tiles[x][y].Any(t => t.ID == itemID && t.Z == z);
}
public static Rectangle2D GetAbsoluteBounds(this MultiComponentList mcl)
{
return new Rectangle2D(mcl.Min.X, mcl.Min.Y, mcl.Width, mcl.Height);
}
}
}

View File

@@ -0,0 +1,60 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#if ServUO58
#define ServUOX
#endif
#region References
#if !ServUOX
using System;
#endif
#endregion
namespace Server.Network
{
public static class NetStateExtUtility
{
private static readonly ClientVersion _70500 = new ClientVersion(7, 0, 50, 0);
private static readonly ClientVersion _70610 = new ClientVersion(7, 0, 61, 0);
public static bool IsEnhanced(this NetState state)
{
#if ServUOX
return state?.IsEnhancedClient == true;
#else
var v = state.Version;
if (v == null || (v.Major == 0 && v.Minor == 0 && v.Revision == 0 && v.Patch == 0))
{
return false;
}
if (!state.GetPropertyValue("IsEnhancedClient", out bool ec))
{
ec = v.Major >= 67 || v.Type == ClientType.UOTD;
}
return ec;
#endif
}
public static bool SupportsUltimaStore(this NetState state)
{
return state != null && state.Version >= _70500;
}
public static bool SupportsEndlessJourney(this NetState state)
{
return state != null && state.Version >= _70610;
}
}
}

View File

@@ -0,0 +1,59 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using System.Drawing;
#endregion
namespace Server
{
public enum NotorietyType
{
None = 0,
Innocent = Notoriety.Innocent,
Ally = Notoriety.Ally,
CanBeAttacked = Notoriety.CanBeAttacked,
Criminal = Notoriety.Criminal,
Enemy = Notoriety.Enemy,
Murderer = Notoriety.Murderer,
Invulnerable = Notoriety.Invulnerable
}
public static class NotorietyExtUtility
{
public static int GetHue(this NotorietyType noto)
{
return Notoriety.GetHue((int)noto);
}
public static Color GetColor(this NotorietyType noto)
{
switch ((int)noto)
{
case Notoriety.Innocent:
return Color.SkyBlue;
case Notoriety.Ally:
return Color.LawnGreen;
case Notoriety.CanBeAttacked:
case Notoriety.Criminal:
return Color.Silver;
case Notoriety.Enemy:
return Color.Orange;
case Notoriety.Murderer:
return Color.IndianRed;
case Notoriety.Invulnerable:
return Color.Yellow;
}
return Color.White;
}
}
}

View File

@@ -0,0 +1,217 @@
#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 Server.Network;
#endregion
namespace VitaNex.Network
{
public static class PacketExtUtility
{
#if ServUOX
public static bool RewriteItemID(this WorldItem p, int itemID, bool reset = true)
{
if (p == null)
{
return false;
}
int offset;
if (p.PacketID == 0x1A)
{
offset = 7;
}
else
{
offset = 8;
}
return Rewrite(p, offset, (ushort)itemID, reset);
}
public static bool RewriteBody(this MobileIncoming p, int itemID, bool reset = true)
{
return Rewrite(p, 7, (short)itemID, reset);
}
public static bool RewriteHue(this MobileIncoming p, int hue, bool reset = true)
{
return Rewrite(p, 15, (short)hue, reset);
}
#else
public static bool RewriteItemID(this WorldItem p, int itemID, bool reset = true)
{
return Rewrite(p, 7, (short)itemID, reset);
}
public static bool RewriteItemID(this WorldItemSA p, int itemID, bool reset = true)
{
return Rewrite(p, 8, (short)itemID, reset);
}
public static bool RewriteItemID(this WorldItemHS p, int itemID, bool reset = true)
{
return Rewrite(p, 8, (short)itemID, reset);
}
public static bool RewriteBody(this MobileIncomingOld p, int itemID, bool reset = true)
{
return Rewrite(p, 7, (short)itemID, reset);
}
public static bool RewriteHue(this MobileIncomingOld p, int hue, bool reset = true)
{
return Rewrite(p, 15, (short)hue, reset);
}
public static bool RewriteBody(this MobileIncoming p, int itemID, bool reset = true)
{
return Rewrite(p, 7, (short)itemID, reset);
}
public static bool RewriteHue(this MobileIncoming p, int hue, bool reset = true)
{
return Rewrite(p, 15, (short)hue, reset);
}
public static bool RewriteBody(this MobileIncomingSA p, int itemID, bool reset = true)
{
return Rewrite(p, 7, (short)itemID, reset);
}
public static bool RewriteHue(this MobileIncomingSA p, int hue, bool reset = true)
{
return Rewrite(p, 15, (short)hue, reset);
}
#endif
public static bool Rewrite(this Packet packet, int offset, bool value, bool reset = true)
{
var writer = GetWriter(packet);
return writer != null && Rewrite(writer, offset, reset, writer.Write, value);
}
public static bool Rewrite(this Packet packet, int offset, sbyte value, bool reset = true)
{
var writer = GetWriter(packet);
return writer != null && Rewrite(writer, offset, reset, writer.Write, value);
}
public static bool Rewrite(this Packet packet, int offset, byte value, bool reset = true)
{
var writer = GetWriter(packet);
return writer != null && Rewrite(writer, offset, reset, writer.Write, value);
}
public static bool Rewrite(this Packet packet, int offset, short value, bool reset = true)
{
var writer = GetWriter(packet);
return writer != null && Rewrite(writer, offset, reset, writer.Write, value);
}
public static bool Rewrite(this Packet packet, int offset, ushort value, bool reset = true)
{
var writer = GetWriter(packet);
return writer != null && Rewrite(writer, offset, reset, writer.Write, value);
}
public static bool Rewrite(this Packet packet, int offset, int value, bool reset = true)
{
var writer = GetWriter(packet);
return writer != null && Rewrite(writer, offset, reset, writer.Write, value);
}
public static bool Rewrite(this Packet packet, int offset, uint value, bool reset = true)
{
var writer = GetWriter(packet);
return writer != null && Rewrite(writer, offset, reset, writer.Write, value);
}
private static bool Rewrite<T>(PacketWriter writer, int offset, bool reset, Action<T> write, T value)
{
var pos = -1L;
try
{
pos = writer.Position;
writer.Position = offset;
write(value);
return true;
}
catch
{
}
finally
{
if (reset && pos >= 0)
{
writer.Position = pos;
}
}
return false;
}
public static byte[] GetBuffer(this Packet packet)
{
var writer = GetWriter(packet);
if (writer != null)
{
return writer.ToArray();
}
if (GetCompiledBuffer(packet, out var buffer))
{
return buffer;
}
return Array.Empty<byte>();
}
public static bool GetCompiledBuffer(this Packet packet, out byte[] buffer)
{
return packet.GetFieldValue("m_CompiledBuffer", out buffer);
}
public static bool SetCompiledBuffer(this Packet packet, byte[] buffer)
{
return packet.SetFieldValue("m_CompiledBuffer", buffer);
}
public static PacketWriter GetWriter(this Packet packet)
{
#if ServUOX
return packet?.Stream;
#else
return packet?.UnderlyingStream;
#endif
}
}
}

View File

@@ -0,0 +1,67 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
namespace Server.Mobiles
{
public static class PlayerMobileExtUtility
{
public static ClientVersion GetClientVersion(this PlayerMobile player)
{
return player.IsOnline() ? player.NetState.Version : new ClientVersion(null);
}
public static ClientType GetClientType(this PlayerMobile player)
{
return player.IsOnline() ? player.NetState.Version.Type : ClientType.Regular;
}
public static bool HasClient(this PlayerMobile player, ClientType type)
{
return player.IsOnline() && player.NetState.Version.Type == type;
}
public static void FixMap(this PlayerMobile m, MapPoint mp)
{
FixMap(m, mp.Map, mp.Location);
}
public static void FixMap(this PlayerMobile m, Map def, Point3D loc)
{
if (m == null || m.Deleted || def == null || def == Map.Internal || loc == Point3D.Zero)
{
return;
}
if (m.LogoutMap == null || m.LogoutMap == Map.Internal)
{
m.LogoutLocation = loc.ToPoint3D();
m.LogoutMap = def;
}
if (m.Map != null)
{
return;
}
if (m.IsOnline())
{
BaseCreature.TeleportPets(m, loc, def);
m.MoveToWorld(loc, def);
}
else
{
m.Location = loc;
m.Internalize();
m.AutoStablePets();
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,247 @@
#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;
#endregion
namespace Server
{
public static class Rectangle2DExtUtility
{
public static Point2D GetRandomPoint(this Rectangle2D bounds)
{
return new Point2D(
Utility.RandomMinMax(bounds.Start.X, bounds.End.X),
Utility.RandomMinMax(bounds.Start.Y, bounds.End.Y));
}
public static Rectangle2D Combine(this IEnumerable<Rectangle2D> bounds)
{
int count = 0, minX = Int32.MaxValue, minY = Int32.MaxValue, maxX = Int32.MinValue, maxY = Int32.MinValue;
foreach (var r in bounds)
{
minX = Math.Min(minX, Math.Min(r.Start.X, r.End.X));
minY = Math.Min(minY, Math.Min(r.Start.Y, r.End.Y));
maxX = Math.Max(maxX, Math.Max(r.Start.X, r.End.X));
maxY = Math.Max(maxY, Math.Max(r.Start.Y, r.End.Y));
++count;
}
if (count > 0)
{
return new Rectangle2D(new Point2D(minX, minY), new Point2D(maxX, maxY));
}
return new Rectangle2D(0, 0, 0, 0);
}
public static Rectangle3D ToRectangle3D(this Rectangle2D r, int floor = 0, int roof = 0)
{
return new Rectangle3D(r.X, r.Y, floor, r.Width, r.Height, roof);
}
public static int GetBoundsHashCode(this Rectangle2D r)
{
unchecked
{
var hash = r.Width * r.Height;
hash = (hash * 397) ^ r.Start.GetHashCode();
hash = (hash * 397) ^ r.End.GetHashCode();
return hash;
}
}
public static int GetBoundsHashCode(this IEnumerable<Rectangle2D> list)
{
unchecked
{
return list.Aggregate(0, (hash, r) => (hash * 397) ^ GetBoundsHashCode(r));
}
}
public static Point2D GetCenter(this Rectangle2D r)
{
return r.Start.Clone2D(r.Width / 2, r.Height / 2);
}
public static int GetArea(this Rectangle2D r)
{
return r.Width * r.Height;
}
public static Rectangle2D Resize(this Rectangle2D r, int xOff = 0, int yOff = 0, int wOff = 0, int hOff = 0)
{
return new Rectangle2D(r.X + xOff, r.Y + yOff, r.Width + wOff, r.Height + hOff);
}
public static IEnumerable<Rectangle2D> Slice(this Rectangle2D rect, int w, int h)
{
if (rect.Width <= w && rect.Height <= h)
{
yield return rect;
yield break;
}
int x, y;
int ow, oh;
x = rect.Start.X;
while (x < rect.End.X)
{
ow = Math.Min(w, rect.End.X - x);
y = rect.Start.Y;
while (y < rect.End.Y)
{
oh = Math.Min(h, rect.End.Y - y);
yield return new Rectangle2D(x, y, ow, oh);
y += oh;
}
x += ow;
}
}
public static IEnumerable<T> FindObjects<T>(this Rectangle2D r, Map m)
{
if (m == null || m == Map.Internal)
{
yield break;
}
var o = m.GetObjectsInBounds(r);
foreach (var e in o.OfType<T>())
{
yield return e;
}
o.Free();
}
public static IEnumerable<TEntity> FindEntities<TEntity>(this Rectangle2D r, Map m)
where TEntity : IEntity
{
if (m == null || m == Map.Internal)
{
yield break;
}
var o = m.GetObjectsInBounds(r);
foreach (var e in o.OfType<TEntity>().Where(e => e.Map == m && r.Contains(e)))
{
yield return e;
}
o.Free();
}
public static IEnumerable<IEntity> FindEntities(this Rectangle2D r, Map m)
{
return FindEntities<IEntity>(r, m);
}
public static List<TEntity> GetEntities<TEntity>(this Rectangle2D r, Map m)
where TEntity : IEntity
{
return FindEntities<TEntity>(r, m).ToList();
}
public static List<IEntity> GetEntities(this Rectangle2D r, Map m)
{
return FindEntities<IEntity>(r, m).ToList();
}
public static List<Item> GetItems(this Rectangle2D r, Map m)
{
return FindEntities<Item>(r, m).ToList();
}
public static List<Mobile> GetMobiles(this Rectangle2D r, Map m)
{
return FindEntities<Mobile>(r, m).ToList();
}
public static IEnumerable<Point2D> EnumeratePoints(this Rectangle2D r)
{
for (var x = r.Start.X; x <= r.End.X; x++)
{
for (var y = r.Start.Y; y <= r.End.Y; y++)
{
yield return new Point2D(x, y);
}
}
}
public static void ForEach(this Rectangle2D r, Action<Point2D> action)
{
if (action == null)
{
return;
}
foreach (var p in EnumeratePoints(r))
{
action(p);
}
}
public static IEnumerable<Point2D> GetBorder(this Rectangle2D r, int size)
{
size = Math.Max(1, size);
int x, y;
int x1 = r.Start.X + size, y1 = r.Start.Y + size;
int x2 = r.End.X - size, y2 = r.End.Y - size;
for (x = r.Start.X; x <= r.End.X; x++)
{
if (x >= x1 || x <= x2)
{
continue;
}
for (y = r.Start.Y; y <= r.End.Y; y++)
{
if (y >= y1 || y <= y2)
{
continue;
}
yield return new Point2D(x, y);
}
}
}
public static IEnumerable<Point2D> GetBorder(this Rectangle2D r)
{
return GetBorder(r, 1);
}
public static bool Intersects(this Rectangle2D r, Rectangle2D or)
{
return GetBorder(r).Union(GetBorder(or)).GroupBy(p => p).Any(g => g.Count() > 1);
}
}
}

View File

@@ -0,0 +1,544 @@
#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;
#endregion
namespace Server
{
public static class Rectangle3DExtUtility
{
public static Point3D GetRandomPoint(this Rectangle3D bounds)
{
return new Point3D(
Utility.RandomMinMax(bounds.Start.X, bounds.End.X),
Utility.RandomMinMax(bounds.Start.Y, bounds.End.Y),
Utility.RandomMinMax(bounds.Start.Z, bounds.End.Z));
}
public static Point2D GetRandomPoint2D(this Rectangle3D bounds)
{
return new Point2D(
Utility.RandomMinMax(bounds.Start.X, bounds.End.X),
Utility.RandomMinMax(bounds.Start.Y, bounds.End.Y));
}
public static Rectangle2D Combine2D(this IEnumerable<Rectangle3D> bounds)
{
int count = 0, minX = Int32.MaxValue, minY = Int32.MaxValue, maxX = Int32.MinValue, maxY = Int32.MinValue;
foreach (var r in bounds)
{
minX = Math.Min(minX, Math.Min(r.Start.X, r.End.X));
minY = Math.Min(minY, Math.Min(r.Start.Y, r.End.Y));
maxX = Math.Max(maxX, Math.Max(r.Start.X, r.End.X));
maxY = Math.Max(maxY, Math.Max(r.Start.Y, r.End.Y));
++count;
}
if (count > 0)
{
return new Rectangle2D(new Point2D(minX, minY), new Point2D(maxX, maxY));
}
return new Rectangle2D(0, 0, 0, 0);
}
public static Rectangle3D Combine(this IEnumerable<Rectangle3D> bounds)
{
int count = 0,
minX = Int32.MaxValue,
minY = Int32.MaxValue,
maxX = Int32.MinValue,
maxY = Int32.MinValue,
minZ = Region.MaxZ,
maxZ = Region.MinZ;
foreach (var r in bounds)
{
minX = Math.Min(minX, Math.Min(r.Start.X, r.End.X));
minY = Math.Min(minY, Math.Min(r.Start.Y, r.End.Y));
minZ = Math.Min(minZ, Math.Min(r.Start.Z, r.End.Z));
maxX = Math.Max(maxX, Math.Max(r.Start.X, r.End.X));
maxY = Math.Max(maxY, Math.Max(r.Start.Y, r.End.Y));
maxZ = Math.Max(maxZ, Math.Max(r.Start.Z, r.End.Z));
++count;
}
if (count > 0)
{
return new Rectangle3D(new Point3D(minX, minY, minZ), new Point3D(maxX, maxY, maxZ));
}
return new Rectangle3D(0, 0, 0, 0, 0, 0);
}
public static IEnumerable<Rectangle3D> ZFix(this IEnumerable<Rectangle3D> rects)
{
return ZFix(rects, Region.MinZ, Region.MaxZ);
}
public static IEnumerable<Rectangle3D> ZFix(this IEnumerable<Rectangle3D> rects, int zMin, int zMax)
{
if (rects == null)
{
yield break;
}
foreach (var r in rects.Select(r => r.ZFix(zMin, zMax)))
{
yield return r;
}
}
public static Rectangle3D ZFix(this Rectangle3D rect)
{
return ZFix(rect, Region.MinZ, Region.MaxZ);
}
public static Rectangle3D ZFix(this Rectangle3D rect, int zMin, int zMax)
{
return new Rectangle3D(rect.Start.ToPoint3D(Math.Min(zMin, zMax)), rect.End.ToPoint3D(Math.Max(zMin, zMax)));
}
public static Rectangle2D ToRectangle2D(this Rectangle3D r)
{
return new Rectangle2D(r.Start, r.End);
}
public static int GetBoundsHashCode(this Rectangle3D r)
{
unchecked
{
var hash = r.Width * r.Height * r.Depth;
hash = (hash * 397) ^ r.Start.GetHashCode();
hash = (hash * 397) ^ r.End.GetHashCode();
return hash;
}
}
public static int GetBoundsHashCode(this IEnumerable<Rectangle3D> list)
{
unchecked
{
return list.Aggregate(0, (hash, r) => (hash * 397) ^ GetBoundsHashCode(r));
}
}
#if !ServUOX
public static bool Contains(this RegionRect[] rects, IPoint3D p)
{
return rects.Any(rect => Contains(rect.Rect, p.X, p.Y, p.Z));
}
public static bool Contains(this RegionRect[] rects, Point3D p)
{
return rects.Any(rect => Contains(rect.Rect, p.X, p.Y, p.Z));
}
#endif
public static bool Contains(this Rectangle3D[] rects, IPoint3D p)
{
return rects.Any(rect => Contains(rect, p.X, p.Y, p.Z));
}
public static bool Contains(this Rectangle3D[] rects, Point3D p)
{
return rects.Any(rect => Contains(rect, p.X, p.Y, p.Z));
}
public static bool Contains(this Rectangle3D[] rects, IPoint2D p)
{
return rects.Any(rect => Contains(rect, p.X, p.Y));
}
public static bool Contains(this Rectangle3D[] rects, Point2D p)
{
return rects.Any(rect => Contains(rect, p.X, p.Y));
}
#if !ServUOX
public static bool Contains(this List<RegionRect> rects, IPoint3D p)
{
return rects.Any(rect => Contains(rect.Rect, p.X, p.Y, p.Z));
}
public static bool Contains(this List<RegionRect> rects, Point3D p)
{
return rects.Any(rect => Contains(rect.Rect, p.X, p.Y, p.Z));
}
#endif
public static bool Contains(this List<Rectangle3D> rects, IPoint3D p)
{
return rects.Any(rect => Contains(rect, p.X, p.Y, p.Z));
}
public static bool Contains(this List<Rectangle3D> rects, Point3D p)
{
return rects.Any(rect => Contains(rect, p.X, p.Y, p.Z));
}
public static bool Contains(this List<Rectangle3D> rects, IPoint2D p)
{
return rects.Any(rect => Contains(rect, p.X, p.Y));
}
public static bool Contains(this List<Rectangle3D> rects, Point2D p)
{
return rects.Any(rect => Contains(rect, p.X, p.Y));
}
public static bool Contains(this Rectangle3D rect, IPoint2D p)
{
return Contains(rect, p.X, p.Y);
}
public static bool Contains(this Rectangle3D rect, IPoint3D p)
{
return Contains(rect, p.X, p.Y, p.Z);
}
public static bool Contains(this Rectangle3D rect, int x, int y)
{
return x >= rect.Start.X && y >= rect.Start.Y && x < rect.End.X && y < rect.End.Y;
}
public static bool Contains(this Rectangle3D rect, int x, int y, int z)
{
return Contains(rect, x, y) && z >= rect.Start.Z && z < rect.End.Z;
}
public static Point2D GetCenter2D(this Rectangle3D r)
{
return r.Start.Clone2D(r.Width / 2, r.Height / 2);
}
public static Point3D GetCenter(this Rectangle3D r)
{
return r.Start.Clone3D(r.Width / 2, r.Height / 2);
}
public static int GetArea(this Rectangle3D r)
{
return r.Width * r.Height;
}
public static int GetVolume(this Rectangle3D r)
{
return r.Width * r.Height * r.Depth;
}
public static Rectangle2D Resize2D(
this Rectangle3D r,
int xOff = 0,
int yOff = 0,
int zOff = 0,
int wOff = 0,
int hOff = 0,
int dOff = 0)
{
return ToRectangle2D(r).Resize(xOff, yOff, wOff, hOff);
}
public static Rectangle3D Resize(
this Rectangle3D r,
int xOff = 0,
int yOff = 0,
int zOff = 0,
int wOff = 0,
int hOff = 0,
int dOff = 0)
{
var s = r.Start;
return new Rectangle3D(s.X + xOff, s.Y + yOff, s.Z + zOff, r.Width + wOff, r.Height + hOff, r.Depth + dOff);
}
public static IEnumerable<Rectangle2D> Slice2D(this Rectangle3D rect, int w, int h)
{
return ToRectangle2D(rect).Slice(w, h);
}
public static IEnumerable<Rectangle3D> Slice(this Rectangle3D rect, int w, int h)
{
if (rect.Width <= w && rect.Height <= h)
{
yield return rect;
yield break;
}
int x, y, z = Math.Min(rect.Start.Z, rect.End.Z);
int ow, oh, od = rect.Depth;
x = rect.Start.X;
while (x < rect.End.X)
{
ow = Math.Min(w, rect.End.X - x);
y = rect.Start.Y;
while (y < rect.End.Y)
{
oh = Math.Min(h, rect.End.Y - y);
yield return new Rectangle3D(x, y, z, ow, oh, od);
y += oh;
}
x += ow;
}
}
public static IEnumerable<T> FindObjects<T>(this Rectangle3D r, Map m)
{
if (m == null || m == Map.Internal)
{
yield break;
}
var o = m.GetObjectsInBounds(r.ToRectangle2D());
foreach (var e in o.OfType<T>())
{
yield return e;
}
o.Free();
}
public static IEnumerable<TEntity> FindEntities<TEntity>(this Rectangle3D r, Map m)
where TEntity : IEntity
{
if (m == null || m == Map.Internal)
{
yield break;
}
var o = m.GetObjectsInBounds(r.ToRectangle2D());
foreach (var e in o.OfType<TEntity>().Where(e => e.Map == m && r.Contains(e)))
{
yield return e;
}
o.Free();
}
public static IEnumerable<IEntity> FindEntities(this Rectangle3D r, Map m)
{
return FindEntities<IEntity>(r, m);
}
public static List<TEntity> GetEntities<TEntity>(this Rectangle3D r, Map m)
where TEntity : IEntity
{
return FindEntities<TEntity>(r, m).ToList();
}
public static List<IEntity> GetEntities(this Rectangle3D r, Map m)
{
return FindEntities<IEntity>(r, m).ToList();
}
public static List<Item> GetItems(this Rectangle3D r, Map m)
{
return FindEntities<Item>(r, m).ToList();
}
public static List<Mobile> GetMobiles(this Rectangle3D r, Map m)
{
return FindEntities<Mobile>(r, m).ToList();
}
public static IEnumerable<Point2D> EnumeratePoints2D(this Rectangle3D r)
{
for (var x = r.Start.X; x <= r.End.X; x++)
{
for (var y = r.Start.Y; y <= r.End.Y; y++)
{
yield return new Point2D(x, y);
}
}
}
public static IEnumerable<Point3D> EnumeratePoints(this Rectangle3D r)
{
if (r.Depth > 10)
{
Utility.PushColor(ConsoleColor.Yellow);
"> Warning!".ToConsole();
"> Rectangle3DExtUtility.EnumeratePoints() called on Rectangle3D with depth exceeding 10;".ToConsole();
"> This may cause serious performance issues.".ToConsole();
Utility.PopColor();
}
for (var z = r.Start.Z; z <= r.End.Z; z++)
{
for (var x = r.Start.X; x <= r.End.X; x++)
{
for (var y = r.Start.Y; y <= r.End.Y; y++)
{
yield return new Point3D(x, y, z);
}
}
}
}
public static void ForEach2D(this Rectangle3D r, Action<Point2D> action)
{
if (action == null)
{
return;
}
foreach (var p in EnumeratePoints2D(r))
{
action(p);
}
}
public static void ForEach(this Rectangle3D r, Action<Point3D> action)
{
if (action == null)
{
return;
}
foreach (var p in EnumeratePoints(r))
{
action(p);
}
}
public static IEnumerable<Point2D> GetBorder2D(this Rectangle3D r, int size)
{
size = Math.Max(1, size);
int x, y;
int x1 = r.Start.X + size, y1 = r.Start.Y + size;
int x2 = r.End.X - size, y2 = r.End.Y - size;
for (x = r.Start.X; x <= r.End.X; x++)
{
if (x >= x1 || x <= x2)
{
continue;
}
for (y = r.Start.Y; y <= r.End.Y; y++)
{
if (y >= y1 || y <= y2)
{
continue;
}
yield return new Point2D(x, y);
}
}
}
public static IEnumerable<Point2D> GetBorder2D(this Rectangle3D r)
{
return GetBorder2D(r, 1);
}
public static IEnumerable<Point3D> GetBorder(this Rectangle3D r, int size)
{
if (r.Depth > 10)
{
Utility.PushColor(ConsoleColor.Yellow);
"> Warning!".ToConsole();
"> Rectangle3DExtUtility.EnumeratePoints() called on Rectangle3D with depth exceeding 10;".ToConsole();
"> This may cause serious performance issues.".ToConsole();
Utility.PopColor();
}
size = Math.Max(1, size);
int x, y;
int x1 = r.Start.X + size, y1 = r.Start.Y + size, z1 = r.Start.Z + size;
int x2 = r.End.X - size, y2 = r.End.Y - size, z2 = r.End.Z - size;
for (var z = r.Start.Z; z <= r.End.Z; z++)
{
if (z >= z1 || z <= z2)
{
continue;
}
for (x = r.Start.X; x <= r.End.X; x++)
{
if (x >= x1 || x <= x2)
{
continue;
}
for (y = r.Start.Y; y <= r.End.Y; y++)
{
if (y >= y1 || y <= y2)
{
continue;
}
yield return new Point3D(x, y, z);
}
}
}
}
public static IEnumerable<Point3D> GetBorder(this Rectangle3D r)
{
return GetBorder(r, 1);
}
public static bool Intersects2D(this Rectangle3D r, Rectangle3D or)
{
return GetBorder2D(r).Any(GetBorder2D(or).Contains);
}
public static bool Intersects(this Rectangle3D r, Rectangle3D or)
{
var minZL = Math.Min(r.Start.Z, r.End.Z);
var maxZL = Math.Max(r.Start.Z, r.End.Z);
var minZR = Math.Min(or.Start.Z, or.End.Z);
var maxZR = Math.Max(or.Start.Z, or.End.Z);
if (minZL > maxZR)
{
return false;
}
if (maxZL < minZR)
{
return false;
}
return GetBorder2D(r).Union(GetBorder2D(or)).GroupBy(p => p).Any(g => g.Count() > 1);
}
}
}

View File

@@ -0,0 +1,618 @@
#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 System.Reflection;
using System.Threading.Tasks;
using VitaNex;
using VitaNex.Crypto;
using VitaNex.FX;
using VitaNex.Network;
#endregion
namespace Server
{
public static class RegionExtUtility
{
public class RegionSerial : CryptoHashCode
{
public override string Value => base.Value.Replace("-", String.Empty);
public RegionSerial(Region r)
: base(
CryptoHashType.MD5,
r.GetType().FullName + r.Map.Name + r.Name + r.Area.GetBoundsHashCode() + TimeStamp.UtcNow.Stamp +
Utility.RandomDouble())
{ }
public RegionSerial(GenericReader reader)
: base(reader)
{ }
}
public class PreviewRegion : Region, IEquatable<Region>
{
private static ulong _UID;
public RegionSerial Serial { get; private set; }
public PollTimer Timer { get; private set; }
public EffectInfo[] Effects { get; private set; }
public DateTime Expire { get; set; }
public int EffectID { get; set; }
public int EffectHue { get; set; }
public EffectRender EffectRender { get; set; }
public PreviewRegion(Region r)
: this(r.Name, r.Map, r.Area)
{
Serial = GetSerial(r);
}
public PreviewRegion(string name, Map map, params Rectangle2D[] area)
: base(name + " " + _UID++, map, null, area)
{
Serial = new RegionSerial(this);
EnsureDefaults();
}
public PreviewRegion(string name, Map map, params Rectangle3D[] area)
: base(name + " " + _UID++, map, null, area)
{
Serial = new RegionSerial(this);
EnsureDefaults();
}
public void EnsureDefaults()
{
Expire = DateTime.UtcNow.AddSeconds(300.0);
EffectID = 1801;
EffectHue = 85;
EffectRender = EffectRender.ShadowOutline;
}
public void Refresh()
{
Expire = DateTime.UtcNow.AddSeconds(300.0);
Register();
}
public override void OnRegister()
{
base.OnRegister();
Expire = DateTime.UtcNow.AddSeconds(300.0);
if (Effects == null)
{
var effects = new EffectInfo[Area.Length][,];
effects.SetAll(i => new EffectInfo[Area[i].Width, Area[i].Height]);
for (var index = 0; index < Area.Length; index++)
{
var b = Area[index];
var xSpacing = Math.Max(1, Math.Min(16, b.Width / 8));
var ySpacing = Math.Max(1, Math.Min(16, b.Height / 8));
var minX = Math.Min(b.Start.X, b.End.X);
var maxX = Math.Max(b.Start.X, b.End.X);
var minY = Math.Min(b.Start.Y, b.End.Y);
var maxY = Math.Max(b.Start.Y, b.End.Y);
Parallel.For(
minX,
maxX,
x => Parallel.For(
minY,
maxY,
y =>
{
if (x != b.Start.X && x != b.End.X - 1 && x % xSpacing != 0 //
&& y != b.Start.Y && y != b.End.Y - 1 && y % ySpacing != 0)
{
return;
}
var idxX = x - minX;
var idxY = y - minY;
effects[index][idxX, idxY] = new EffectInfo(
new Point3D(x, y, 0),
Map,
EffectID,
EffectHue,
1,
25,
EffectRender);
}));
}
Effects = effects.SelectMany(list => list.OfType<EffectInfo>()).ToArray();
foreach (var e in Effects)
{
e.SetSource(e.Source.ToPoint3D(e.Source.GetAverageZ(e.Map)));
}
}
if (Timer == null)
{
Timer = PollTimer.FromSeconds(
1.0,
() =>
{
if (DateTime.UtcNow > Expire)
{
Unregister();
return;
}
foreach (var e in Effects)
{
e.Send();
}
},
() => Registered);
}
else
{
Timer.Running = true;
}
_Previews.Update(Serial, this);
}
public override void OnUnregister()
{
base.OnUnregister();
if (Timer != null)
{
Timer.Running = false;
Timer = null;
}
if (Effects != null)
{
foreach (var e in Effects)
{
e.Dispose();
}
Effects.SetAll(i => null);
Effects = null;
}
Expire = DateTime.UtcNow;
_Previews.Remove(Serial);
}
public bool Equals(Region other)
{
return !ReferenceEquals(other, null) && Serial.Equals(GetSerial(other));
}
}
private static readonly Dictionary<RegionSerial, Region> _Regions;
private static readonly Dictionary<RegionSerial, PreviewRegion> _Previews;
static RegionExtUtility()
{
_Regions = new Dictionary<RegionSerial, Region>();
_Previews = new Dictionary<RegionSerial, PreviewRegion>();
}
public static RegionSerial GetSerial(this Region r)
{
if (r == null)
{
return null;
}
if (r is PreviewRegion)
{
return ((PreviewRegion)r).Serial;
}
lock (_Regions)
{
if (_Regions.ContainsValue(r))
{
return _Regions.GetKey(r);
}
var s = new RegionSerial(r);
_Regions.Update(s, r);
//Console.WriteLine("Region Serial: ('{0}', '{1}', '{2}') = {3}", r.GetType().Name, r.Map, r.Name, s.ValueHash);
return s;
}
}
public static PreviewRegion DisplayPreview(
string name,
Map map,
int hue = 85,
int effect = 1801,
EffectRender render = EffectRender.SemiTransparent,
params Rectangle2D[] bounds)
{
return DisplayPreview(new PreviewRegion(name, map, bounds), hue, effect, render);
}
public static PreviewRegion DisplayPreview(
string name,
Map map,
int hue = 85,
int effect = 1801,
EffectRender render = EffectRender.SemiTransparent,
params Rectangle3D[] bounds)
{
return DisplayPreview(new PreviewRegion(name, map, bounds), hue, effect, render);
}
public static PreviewRegion DisplayPreview(
this Region r,
int hue = 85,
int effect = 1801,
EffectRender render = EffectRender.SemiTransparent)
{
if (r == null || r.Area == null || r.Area.Length == 0)
{
return null;
}
if (hue < 0)
{
hue = 0;
}
if (effect <= 0)
{
effect = 1801;
}
PreviewRegion pr;
if (r is PreviewRegion)
{
pr = (PreviewRegion)r;
pr.EffectID = effect;
pr.EffectHue = hue;
pr.EffectRender = render;
pr.Register();
return pr;
}
var s = GetSerial(r);
if (s == null)
{
return null;
}
if (_Previews.TryGetValue(s, out pr) && pr != null && pr.Area.GetBoundsHashCode() != r.Area.GetBoundsHashCode())
{
pr.Unregister();
pr = null;
}
if (pr == null)
{
pr = new PreviewRegion(r)
{
EffectHue = hue,
EffectID = effect,
EffectRender = render
};
}
pr.Register();
return pr;
}
public static void ClearPreview(this Region r)
{
if (r == null)
{
return;
}
PreviewRegion pr;
if (r is PreviewRegion)
{
pr = (PreviewRegion)r;
pr.Unregister();
return;
}
var s = GetSerial(r);
if (s == null)
{
return;
}
if (_Previews.TryGetValue(s, out pr) && pr != null)
{
pr.Unregister();
}
}
public static bool Contains(this Sector s, Point3D p, Map m)
{
return s.Owner == m && s.Contains(p);
}
public static bool Contains(this Region r, Point3D p, Map m)
{
return r.Map == m && r.Contains(p);
}
#if ServUOX
public static bool Contains(this Sector s, Point3D p)
{
foreach (var r in s.RegionRects.Values.SelectMany(o => o))
{
if (r.Contains(p))
{
return true;
}
}
return false;
}
#else
public static bool Contains(this RegionRect r, Point3D p, Map m)
{
return r.Region.Map == m && r.Contains(p);
}
public static bool Contains(this Sector s, Point3D p)
{
foreach (var r in s.RegionRects)
{
if (r.Contains(p))
{
return true;
}
}
return false;
}
public static bool Contains(this RegionRect r, Point3D p)
{
return r.Rect.Contains(p);
}
#endif
public static TRegion Create<TRegion>(params object[] args)
where TRegion : Region
{
return Create(typeof(TRegion), args) as TRegion;
}
public static Region Create(Type type, params object[] args)
{
return type.CreateInstanceSafe<Region>(args);
}
public static TRegion Clone<TRegion>(this TRegion region, params object[] args)
where TRegion : Region
{
if (region == null)
{
return null;
}
var fields = region.GetFields(BindingFlags.Instance | BindingFlags.NonPublic);
var remove = new[]
{
"Serial",
"Name",
"Map",
"Parent",
"Area",
"Sectors",
"ChildLevel",
"Registered"
};
foreach (var entry in remove)
{
if (!fields.Remove("m_" + entry))
{
fields.Remove("_" + entry);
}
}
region.Unregister();
var reg = Create(region.GetType(), args) as TRegion;
if (reg != null)
{
fields.Serialize(reg);
reg.Register();
}
return reg;
}
#if ServUOX
public static bool IsPartOf<TRegion>(Region region)
where TRegion : Region
{
return region != null && region.IsPartOf<TRegion>();
}
public static TRegion GetRegion<TRegion>(Region region)
where TRegion : Region
{
return region != null ? region.GetRegion<TRegion>() : null;
}
#else
public static bool IsPartOf<TRegion>(this Region region)
where TRegion : Region
{
return region != null && region.IsPartOf(typeof(TRegion));
}
public static TRegion GetRegion<TRegion>(this Region region)
where TRegion : Region
{
return region != null ? region.GetRegion(typeof(TRegion)) as TRegion : null;
}
#endif
public static TRegion GetRegion<TRegion>(this Mobile m)
where TRegion : Region
{
return m != null ? GetRegion<TRegion>(m.Region) : null;
}
public static Region GetRegion(this Mobile m, Type type)
{
return m != null && m.Region != null ? m.Region.GetRegion(type) : null;
}
public static Region GetRegion(this Mobile m, string name)
{
return m != null && m.Region != null ? m.Region.GetRegion(name) : null;
}
public static bool InRegion<TRegion>(this Mobile m)
where TRegion : Region
{
return m != null && GetRegion<TRegion>(m.Region) != null;
}
public static bool InRegion(this Mobile m, Type type)
{
return m != null && GetRegion(m, type) != null;
}
public static bool InRegion(this Mobile m, string name)
{
return m != null && GetRegion(m, name) != null;
}
public static bool InRegion(this Mobile m, Region r)
{
return m != null && m.Region != null && m.Region.IsPartOf(r);
}
public static Region GetRegion(this Item i)
{
if (i == null)
{
return null;
}
return Region.Find(i.GetWorldLocation(), i.Map);
}
public static TRegion GetRegion<TRegion>(this Item i)
where TRegion : Region
{
if (i == null)
{
return null;
}
var reg = Region.Find(i.GetWorldLocation(), i.Map);
return reg != null ? GetRegion<TRegion>(reg) : null;
}
public static Region GetRegion(this Item i, string name)
{
if (i == null)
{
return null;
}
var reg = Region.Find(i.GetWorldLocation(), i.Map);
return reg != null ? reg.GetRegion(name) : null;
}
public static Region GetRegion(this Item i, Type type)
{
if (i == null)
{
return null;
}
var reg = Region.Find(i.GetWorldLocation(), i.Map);
return reg != null ? reg.GetRegion(type) : null;
}
public static bool InRegion<TRegion>(this Item i)
where TRegion : Region
{
if (i == null)
{
return false;
}
var reg = Region.Find(i.GetWorldLocation(), i.Map);
return reg != null && GetRegion<TRegion>(reg) != null;
}
public static bool InRegion(this Item i, Type type)
{
return i != null && GetRegion(i, type) != null;
}
public static bool InRegion(this Item i, string name)
{
return i != null && GetRegion(i, name) != null;
}
public static bool InRegion(this Item i, Region r)
{
if (i == null)
{
return false;
}
var reg = Region.Find(i.GetWorldLocation(), i.Map);
return reg != null && reg.IsPartOf(r);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,431 @@
#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;
#endregion
namespace Server
{
public enum SkillCategory
{
None = 0,
Combat,
Healing,
Magic,
Bardic,
Rogue,
Knowledge,
Craft,
Harvest
}
public enum SkillIcon
{
None = 1033,
Combat = 1008,
Healing = 1037,
Magic = 1006,
Bardic = 1031,
Rogue = 1002,
Knowledge = 1034,
Craft = 1030,
Harvest = 1036
}
public static class SkillExtUtility
{
public static readonly SkillName[] EmptySkills = new SkillName[0];
public static readonly SkillName[] AllSkills = default(SkillName).GetValues<SkillName>();
public static readonly SkillName[] CombatSkills =
{
SkillName.Archery, SkillName.Fencing, SkillName.Focus, SkillName.Macing, SkillName.Parry, SkillName.Swords,
SkillName.Tactics, SkillName.Wrestling, SkillName.Bushido
};
public static readonly SkillName[] HealingSkills =
{
SkillName.Healing, SkillName.Veterinary
};
public static readonly SkillName[] MagicSkills =
{
SkillName.EvalInt, SkillName.Inscribe, SkillName.Magery, SkillName.Meditation, SkillName.Chivalry,
SkillName.Necromancy, SkillName.MagicResist, SkillName.Spellweaving, SkillName.SpiritSpeak
};
public static readonly SkillName[] BardicSkills =
{SkillName.Discordance, SkillName.Musicianship, SkillName.Peacemaking, SkillName.Provocation};
public static readonly SkillName[] RogueSkills =
{
SkillName.Begging, SkillName.DetectHidden, SkillName.Hiding, SkillName.Lockpicking, SkillName.Poisoning,
SkillName.RemoveTrap, SkillName.Snooping, SkillName.Stealing, SkillName.Stealth, SkillName.Ninjitsu
};
public static readonly SkillName[] KnowledgeSkills =
{
SkillName.Anatomy, SkillName.AnimalLore, SkillName.AnimalTaming, SkillName.ArmsLore, SkillName.Camping,
SkillName.Forensics, SkillName.Herding, SkillName.ItemID, SkillName.TasteID, SkillName.Tracking
};
public static readonly SkillName[] CraftSkills =
{
SkillName.Alchemy, SkillName.Blacksmith, SkillName.Fletching, SkillName.Carpentry, SkillName.Cooking,
SkillName.Cartography, SkillName.Tailoring, SkillName.Tinkering, SkillName.Imbuing
};
public static readonly SkillName[] HarvestSkills =
{
SkillName.Fishing, SkillName.Mining, SkillName.Lumberjacking
};
public static readonly SkillCategory[] Categories =
{
SkillCategory.Combat, SkillCategory.Healing, SkillCategory.Magic, SkillCategory.Bardic, SkillCategory.Rogue,
SkillCategory.Knowledge, SkillCategory.Craft, SkillCategory.Harvest
};
public static readonly SkillIcon[] Icons =
{
SkillIcon.None, SkillIcon.Combat, SkillIcon.Healing, SkillIcon.Magic, SkillIcon.Bardic, SkillIcon.Rogue,
SkillIcon.Knowledge, SkillIcon.Craft, SkillIcon.Harvest
};
public static IEnumerable<Skill> OfExpansion(this Skills skills)
{
return OfExpansion(skills.Select(sk => sk.SkillName)).Select(sk => skills[sk]);
}
public static IEnumerable<Skill> OfExpansion(this Skills skills, Expansion ex)
{
return OfExpansion(skills.Select(sk => sk.SkillName), ex).Select(sk => skills[sk]);
}
public static IEnumerable<SkillName> OfExpansion(this IEnumerable<SkillName> skills)
{
return OfExpansion(skills, Core.Expansion);
}
public static IEnumerable<SkillName> OfExpansion(this IEnumerable<SkillName> skills, Expansion ex)
{
foreach (var sk in skills)
{
switch (sk)
{
case SkillName.Chivalry:
case SkillName.Focus:
case SkillName.Necromancy:
case SkillName.SpiritSpeak:
{
if (ex >= Expansion.AOS)
{
yield return sk;
}
}
break;
case SkillName.Bushido:
case SkillName.Ninjitsu:
{
if (ex >= Expansion.SE)
{
yield return sk;
}
}
break;
case SkillName.Spellweaving:
{
if (ex >= Expansion.ML)
{
yield return sk;
}
}
break;
case SkillName.Imbuing:
case SkillName.Throwing:
case SkillName.Mysticism:
{
if (ex >= Expansion.SA)
{
yield return sk;
}
}
break;
default:
yield return sk;
break;
}
}
}
public static SkillName[] GetSkills(this SkillCategory cat)
{
switch (cat)
{
case SkillCategory.Combat:
return CombatSkills;
case SkillCategory.Healing:
return HealingSkills;
case SkillCategory.Magic:
return MagicSkills;
case SkillCategory.Bardic:
return BardicSkills;
case SkillCategory.Rogue:
return RogueSkills;
case SkillCategory.Knowledge:
return KnowledgeSkills;
case SkillCategory.Craft:
return CraftSkills;
case SkillCategory.Harvest:
return HarvestSkills;
}
return EmptySkills;
}
public static SkillIcon GetIcon(this SkillCategory cat)
{
return Icons[(int)cat];
}
public static SkillIcon GetIcon(this SkillInfo info)
{
return GetIcon((SkillName)info.SkillID);
}
public static SkillIcon GetIcon(this SkillName skill)
{
return GetIcon(GetCategory(skill));
}
public static int GetIconID(this SkillInfo info)
{
return (int)GetIcon(info);
}
public static int GetIconID(this SkillCategory cat)
{
return (int)GetIcon(cat);
}
public static int GetIconID(this SkillName skill)
{
return (int)GetIcon(skill);
}
public static bool IsLocked(this Skill skill, SkillLock locked)
{
return skill.Lock == locked;
}
public static bool IsCapped(this Skill skill)
{
return skill.Base >= skill.Cap;
}
public static bool IsZero(this Skill skill)
{
return skill.Base <= 0;
}
public static bool IsZeroOrCapped(this Skill skill)
{
return IsZero(skill) || IsCapped(skill);
}
public static bool WillCap(this Skill skill, double value, bool isEqual = true)
{
return isEqual ? (skill.Base + value >= skill.Cap) : (skill.Base + value > skill.Cap);
}
public static bool WillZero(this Skill skill, double value, bool isEqual = true)
{
return isEqual ? (skill.Base - value <= 0) : (skill.Base - value < 0);
}
public static bool DecreaseBase(this Skill skill, double value, bool ignoreZero = false, bool trim = true)
{
if (trim)
{
value = Math.Min(skill.Base, value);
}
if (ignoreZero || (!IsZero(skill) && !WillZero(skill, value, false)))
{
skill.Base -= value;
return true;
}
return false;
}
public static bool IncreaseBase(this Skill skill, double value, bool ignoreCap = false, bool trim = true)
{
if (trim)
{
value = Math.Min(skill.Cap - skill.Base, value);
}
if (ignoreCap || (!IsCapped(skill) && !WillCap(skill, value, false)))
{
skill.Base += value;
return true;
}
return false;
}
public static bool SetBase(this Skill skill, double value, bool ignoreLimits = false, bool trim = true)
{
if (trim)
{
value = Math.Max(0, Math.Min(skill.Cap, value));
}
if (ignoreLimits || (value < skill.Base && !IsZero(skill) && !WillZero(skill, skill.Base - value, false)) ||
(value > skill.Base && !IsCapped(skill) && !WillCap(skill, value - skill.Base, false)))
{
skill.Base = value;
return true;
}
return false;
}
public static void DecreaseCap(this Skill skill, double value)
{
SetCap(skill, skill.Cap - value);
}
public static void IncreaseCap(this Skill skill, double value)
{
SetCap(skill, skill.Cap + value);
}
public static void SetCap(this Skill skill, double value)
{
skill.Cap = Math.Max(0, value);
Normalize(skill);
}
public static void Normalize(this Skill skill)
{
if (IsCapped(skill))
{
skill.BaseFixedPoint = skill.CapFixedPoint;
}
if (IsZero(skill))
{
skill.BaseFixedPoint = 0;
}
}
public static string GetName(this SkillName skill)
{
return SkillInfo.Table[(int)skill].Name;
}
public static bool CheckCategory(this SkillName skill, SkillCategory category)
{
return GetCategory(skill) == category;
}
public static SkillCategory GetCategory(this SkillName skill)
{
if (IsCombat(skill))
{
return SkillCategory.Combat;
}
if (IsHealing(skill))
{
return SkillCategory.Healing;
}
if (IsMagic(skill))
{
return SkillCategory.Magic;
}
if (IsBardic(skill))
{
return SkillCategory.Bardic;
}
if (IsRogue(skill))
{
return SkillCategory.Rogue;
}
if (IsKnowledge(skill))
{
return SkillCategory.Knowledge;
}
if (IsCraft(skill))
{
return SkillCategory.Craft;
}
if (IsHarvest(skill))
{
return SkillCategory.Harvest;
}
return SkillCategory.None;
}
public static bool IsCombat(this SkillName skill)
{
return CombatSkills.Contains(skill);
}
public static bool IsHealing(this SkillName skill)
{
return HealingSkills.Contains(skill);
}
public static bool IsMagic(this SkillName skill)
{
return MagicSkills.Contains(skill);
}
public static bool IsBardic(this SkillName skill)
{
return BardicSkills.Contains(skill);
}
public static bool IsRogue(this SkillName skill)
{
return RogueSkills.Contains(skill);
}
public static bool IsKnowledge(this SkillName skill)
{
return KnowledgeSkills.Contains(skill);
}
public static bool IsCraft(this SkillName skill)
{
return CraftSkills.Contains(skill);
}
public static bool IsHarvest(this SkillName skill)
{
return HarvestSkills.Contains(skill);
}
}
}

View File

@@ -0,0 +1,27 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using Server.Spells;
using VitaNex;
#endregion
namespace Server
{
public static class SpellExtUtility
{
public static SpellInfo GetSpellInfo(this ISpell s)
{
return SpellUtility.GetSpellInfo(s);
}
}
}