Convert Regions/Spawns to JSON (#138)
This commit is contained in:
parent
b8316e9202
commit
390f30e706
117 changed files with 97306 additions and 4848 deletions
739
Projects/Server/Regions/Region.cs
Normal file
739
Projects/Server/Regions/Region.cs
Normal file
|
|
@ -0,0 +1,739 @@
|
|||
/***************************************************************************
|
||||
* Region.cs
|
||||
* -------------------
|
||||
* begin : May 1, 2002
|
||||
* copyright : (C) The RunUO Software Team
|
||||
* email : info@runuo.com
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using Server.Json;
|
||||
using Server.Network;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public enum MusicName
|
||||
{
|
||||
Invalid = -1,
|
||||
OldUlt01 = 0,
|
||||
Create1,
|
||||
DragFlit,
|
||||
OldUlt02,
|
||||
OldUlt03,
|
||||
OldUlt04,
|
||||
OldUlt05,
|
||||
OldUlt06,
|
||||
Stones2,
|
||||
Britain1,
|
||||
Britain2,
|
||||
Bucsden,
|
||||
Jhelom,
|
||||
LBCastle,
|
||||
Linelle,
|
||||
Magincia,
|
||||
Minoc,
|
||||
Ocllo,
|
||||
Samlethe,
|
||||
Serpents,
|
||||
Skarabra,
|
||||
Trinsic,
|
||||
Vesper,
|
||||
Wind,
|
||||
Yew,
|
||||
Cave01,
|
||||
Dungeon9,
|
||||
Forest_a,
|
||||
InTown01,
|
||||
Jungle_a,
|
||||
Mountn_a,
|
||||
Plains_a,
|
||||
Sailing,
|
||||
Swamp_a,
|
||||
Tavern01,
|
||||
Tavern02,
|
||||
Tavern03,
|
||||
Tavern04,
|
||||
Combat1,
|
||||
Combat2,
|
||||
Combat3,
|
||||
Approach,
|
||||
Death,
|
||||
Victory,
|
||||
BTCastle,
|
||||
Nujelm,
|
||||
Dungeon2,
|
||||
Cove,
|
||||
Moonglow,
|
||||
Zento,
|
||||
TokunoDungeon,
|
||||
Taiko,
|
||||
DreadHornArea,
|
||||
ElfCity,
|
||||
GrizzleDungeon,
|
||||
MelisandesLair,
|
||||
ParoxysmusLair,
|
||||
GwennoConversation,
|
||||
GoodEndGame,
|
||||
GoodVsEvil,
|
||||
GreatEarthSerpents,
|
||||
Humanoids_U9,
|
||||
MinocNegative,
|
||||
Paws,
|
||||
SelimsBar,
|
||||
SerpentIsleCombat_U7,
|
||||
ValoriaShips
|
||||
}
|
||||
|
||||
public class Region : IComparable<Region>
|
||||
{
|
||||
public static readonly int DefaultPriority = 50;
|
||||
|
||||
public static readonly int MinZ = sbyte.MinValue;
|
||||
public static readonly int MaxZ = sbyte.MaxValue + 1;
|
||||
|
||||
private Point3D m_GoLocation;
|
||||
|
||||
private readonly string m_Name;
|
||||
private readonly int m_Priority;
|
||||
|
||||
public Region(string name, Map map, int priority, params Rectangle2D[] area) : this(name, map, priority,
|
||||
ConvertTo3D(area))
|
||||
{
|
||||
}
|
||||
|
||||
public Region(string name, Map map, int priority, params Rectangle3D[] area) : this(name, map, null, area) =>
|
||||
m_Priority = priority;
|
||||
|
||||
public Region(string name, Map map, Region parent, params Rectangle2D[] area) : this(name, map, parent,
|
||||
ConvertTo3D(area))
|
||||
{
|
||||
}
|
||||
|
||||
public Region(string name, Map map, Region parent, params Rectangle3D[] area)
|
||||
{
|
||||
m_Name = name;
|
||||
Map = map;
|
||||
Parent = parent;
|
||||
Area = area;
|
||||
Dynamic = true;
|
||||
Music = DefaultMusic;
|
||||
|
||||
if (Parent == null)
|
||||
{
|
||||
ChildLevel = 0;
|
||||
m_Priority = DefaultPriority;
|
||||
}
|
||||
else
|
||||
{
|
||||
ChildLevel = Parent.ChildLevel + 1;
|
||||
m_Priority = Parent.Priority;
|
||||
}
|
||||
}
|
||||
|
||||
public Region(DynamicJson json, JsonSerializerOptions options)
|
||||
{
|
||||
Map = json.GetProperty("map", options, out Map map) ? map : null;
|
||||
Parent = json.GetProperty("parent", options, out string parent) ? Find(parent, Map) : null;
|
||||
Dynamic = false;
|
||||
|
||||
if (Parent == null)
|
||||
{
|
||||
ChildLevel = 0;
|
||||
m_Priority = DefaultPriority;
|
||||
}
|
||||
else
|
||||
{
|
||||
ChildLevel = Parent.ChildLevel + 1;
|
||||
m_Priority = Parent.Priority;
|
||||
}
|
||||
|
||||
m_Name = json.GetProperty("name", options, out string name) ? name : null;
|
||||
|
||||
m_Priority = json.GetProperty("priority", options, out int priority) ? priority : 0;
|
||||
|
||||
Area = json.GetProperty("rects", options, out List<Rectangle3D> rects) ?
|
||||
rects.ToArray() : Array.Empty<Rectangle3D>();
|
||||
|
||||
if (Area.Length == 0)
|
||||
Console.WriteLine("Empty area for region '{0}'", this);
|
||||
|
||||
if (json.GetProperty("go", options, out Point3D go))
|
||||
{
|
||||
m_GoLocation = go;
|
||||
}
|
||||
else if (Area.Length > 0)
|
||||
{
|
||||
var start = Area[0].Start;
|
||||
var end = Area[0].End;
|
||||
|
||||
var x = start.X + (end.X - start.X) / 2;
|
||||
var y = start.Y + (end.Y - start.Y) / 2;
|
||||
|
||||
m_GoLocation = new Point3D(x, y, Map?.GetAverageZ(x, y) ?? start.Z + (end.Z - start.Z) / 2);
|
||||
}
|
||||
|
||||
Music = json.GetEnumProperty("music", options, out MusicName music) ? music : DefaultMusic;
|
||||
}
|
||||
|
||||
public static List<Region> Regions { get; } = new List<Region>();
|
||||
|
||||
public static Type DefaultRegionType { get; set; } = typeof(Region);
|
||||
|
||||
public static TimeSpan StaffLogoutDelay { get; set; } = TimeSpan.Zero;
|
||||
|
||||
public static TimeSpan DefaultLogoutDelay { get; set; } = TimeSpan.FromMinutes(5.0);
|
||||
|
||||
public string Name => m_Name;
|
||||
public Map Map { get; }
|
||||
|
||||
public Region Parent { get; }
|
||||
|
||||
public List<Region> Children { get; } = new List<Region>();
|
||||
|
||||
public Rectangle3D[] Area { get; }
|
||||
|
||||
public Sector[] Sectors { get; private set; }
|
||||
|
||||
public bool Dynamic { get; }
|
||||
|
||||
public int Priority => m_Priority;
|
||||
public int ChildLevel { get; }
|
||||
|
||||
public bool Registered { get; private set; }
|
||||
|
||||
public Point3D GoLocation
|
||||
{
|
||||
get => m_GoLocation;
|
||||
set => m_GoLocation = value;
|
||||
}
|
||||
|
||||
public MusicName Music { get; set; }
|
||||
|
||||
public bool IsDefault => Map.DefaultRegion == this;
|
||||
public virtual MusicName DefaultMusic => Parent?.Music ?? MusicName.Invalid;
|
||||
|
||||
public int CompareTo(Region reg)
|
||||
{
|
||||
if (reg == null)
|
||||
return 1;
|
||||
|
||||
// Dynamic regions go first
|
||||
if (Dynamic)
|
||||
{
|
||||
if (!reg.Dynamic)
|
||||
return -1;
|
||||
}
|
||||
else if (reg.Dynamic)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
var thisPriority = Priority;
|
||||
var regPriority = reg.Priority;
|
||||
|
||||
if (thisPriority != regPriority)
|
||||
return regPriority - thisPriority;
|
||||
|
||||
return reg.ChildLevel - ChildLevel;
|
||||
}
|
||||
|
||||
// This is not optimized. Use sparingly
|
||||
public static Region Find(string name, Map map, bool insensitive = false)
|
||||
{
|
||||
if (insensitive)
|
||||
name = name.ToLower();
|
||||
|
||||
for (int i = 0; i < Regions.Count; i++)
|
||||
{
|
||||
var region = Regions[i];
|
||||
if (region.Map != map)
|
||||
continue;
|
||||
|
||||
string rName = region.Name;
|
||||
if (insensitive)
|
||||
rName = rName.ToLower();
|
||||
|
||||
if (rName == name)
|
||||
return region;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Region Find(Point3D p, Map map)
|
||||
{
|
||||
if (map == null)
|
||||
return Map.Internal.DefaultRegion;
|
||||
|
||||
var sector = map.GetSector(p);
|
||||
var list = sector.RegionRects;
|
||||
|
||||
for (var i = 0; i < list.Count; ++i)
|
||||
{
|
||||
var regRect = list[i];
|
||||
|
||||
if (regRect.Contains(p))
|
||||
return regRect.Region;
|
||||
}
|
||||
|
||||
return map.DefaultRegion;
|
||||
}
|
||||
|
||||
public static Rectangle3D ConvertTo3D(Rectangle2D rect) =>
|
||||
new Rectangle3D(new Point3D(rect.Start, MinZ), new Point3D(rect.End, MaxZ));
|
||||
|
||||
public static Rectangle3D[] ConvertTo3D(Rectangle2D[] rects)
|
||||
{
|
||||
var ret = new Rectangle3D[rects.Length];
|
||||
|
||||
for (var i = 0; i < ret.Length; i++) ret[i] = ConvertTo3D(rects[i]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void Register()
|
||||
{
|
||||
if (Registered)
|
||||
return;
|
||||
|
||||
OnRegister();
|
||||
|
||||
Registered = true;
|
||||
|
||||
if (Parent != null)
|
||||
{
|
||||
Parent.Children.Add(this);
|
||||
Parent.OnChildAdded(this);
|
||||
}
|
||||
|
||||
Regions.Add(this);
|
||||
|
||||
Map.RegisterRegion(this);
|
||||
|
||||
var sectors = new List<Sector>();
|
||||
|
||||
for (var i = 0; i < Area.Length; i++)
|
||||
{
|
||||
var rect = Area[i];
|
||||
|
||||
var start = Map.Bound(new Point2D(rect.Start));
|
||||
var end = Map.Bound(new Point2D(rect.End));
|
||||
|
||||
var startSector = Map.GetSector(start);
|
||||
var endSector = Map.GetSector(end);
|
||||
|
||||
for (var x = startSector.X; x <= endSector.X; x++)
|
||||
for (var y = startSector.Y; y <= endSector.Y; y++)
|
||||
{
|
||||
var sector = Map.GetRealSector(x, y);
|
||||
|
||||
sector.OnEnter(this, rect);
|
||||
|
||||
if (!sectors.Contains(sector))
|
||||
sectors.Add(sector);
|
||||
}
|
||||
}
|
||||
|
||||
Sectors = sectors.ToArray();
|
||||
}
|
||||
|
||||
public void Unregister()
|
||||
{
|
||||
if (!Registered)
|
||||
return;
|
||||
|
||||
OnUnregister();
|
||||
|
||||
Registered = false;
|
||||
|
||||
if (Children.Count > 0)
|
||||
Console.WriteLine("Warning: Unregistering region '{0}' with children", this);
|
||||
|
||||
if (Parent != null)
|
||||
{
|
||||
Parent.Children.Remove(this);
|
||||
Parent.OnChildRemoved(this);
|
||||
}
|
||||
|
||||
Regions.Remove(this);
|
||||
|
||||
Map.UnregisterRegion(this);
|
||||
|
||||
if (Sectors != null)
|
||||
for (var i = 0; i < Sectors.Length; i++)
|
||||
Sectors[i].OnLeave(this);
|
||||
|
||||
Sectors = null;
|
||||
}
|
||||
|
||||
public bool Contains(Point3D p)
|
||||
{
|
||||
for (var i = 0; i < Area.Length; i++)
|
||||
{
|
||||
var rect = Area[i];
|
||||
|
||||
if (rect.Contains(p))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Memoize this
|
||||
public bool IsChildOf(Region region)
|
||||
{
|
||||
if (region == null)
|
||||
return false;
|
||||
|
||||
var p = Parent;
|
||||
|
||||
while (p != null)
|
||||
{
|
||||
if (p == region)
|
||||
return true;
|
||||
|
||||
p = p.Parent;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Memoize this
|
||||
public T GetRegion<T>() where T : Region
|
||||
{
|
||||
var r = this;
|
||||
|
||||
do
|
||||
{
|
||||
if (r is T tr)
|
||||
return tr;
|
||||
|
||||
r = r.Parent;
|
||||
} while (r != null);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Region GetRegion(Type regionType)
|
||||
{
|
||||
if (regionType == null)
|
||||
return null;
|
||||
|
||||
var r = this;
|
||||
|
||||
do
|
||||
{
|
||||
if (regionType.IsInstanceOfType(r))
|
||||
return r;
|
||||
|
||||
r = r.Parent;
|
||||
} while (r != null);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Region GetRegion(string regionName)
|
||||
{
|
||||
if (regionName == null)
|
||||
return null;
|
||||
|
||||
var r = this;
|
||||
|
||||
do
|
||||
{
|
||||
if (r.m_Name == regionName)
|
||||
return r;
|
||||
|
||||
r = r.Parent;
|
||||
} while (r != null);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool IsPartOf<T>() where T : Region => GetRegion<T>() != null;
|
||||
|
||||
public bool IsPartOf(Region region) => this == region || IsChildOf(region);
|
||||
|
||||
public bool IsPartOf(string regionName) => GetRegion(regionName) != null;
|
||||
|
||||
public virtual bool AcceptsSpawnsFrom(Region region) =>
|
||||
AllowSpawn() && (region == this || Parent?.AcceptsSpawnsFrom(region) == true);
|
||||
|
||||
public List<Mobile> GetPlayers()
|
||||
{
|
||||
var list = new List<Mobile>();
|
||||
|
||||
for (var i = 0; i < Sectors?.Length; i++)
|
||||
{
|
||||
var sector = Sectors[i];
|
||||
|
||||
foreach (var player in sector.Players)
|
||||
if (player.Region.IsPartOf(this))
|
||||
list.Add(player);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public int GetPlayerCount()
|
||||
{
|
||||
var count = 0;
|
||||
|
||||
for (var i = 0; i < Sectors?.Length; i++)
|
||||
{
|
||||
var sector = Sectors[i];
|
||||
|
||||
foreach (var player in sector.Players)
|
||||
if (player.Region.IsPartOf(this))
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public List<Mobile> GetMobiles()
|
||||
{
|
||||
var list = new List<Mobile>();
|
||||
|
||||
for (var i = 0; i < Sectors?.Length; i++)
|
||||
{
|
||||
var sector = Sectors[i];
|
||||
|
||||
foreach (var mobile in sector.Mobiles)
|
||||
if (mobile.Region.IsPartOf(this))
|
||||
list.Add(mobile);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public int GetMobileCount()
|
||||
{
|
||||
var count = 0;
|
||||
|
||||
for (var i = 0; i < Sectors?.Length; i++)
|
||||
{
|
||||
var sector = Sectors[i];
|
||||
|
||||
foreach (var mobile in sector.Mobiles)
|
||||
if (mobile.Region.IsPartOf(this))
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public override string ToString() => m_Name ?? GetType().Name;
|
||||
|
||||
public virtual void OnRegister()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void OnUnregister()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void OnChildAdded(Region child)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void OnChildRemoved(Region child)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual bool OnMoveInto(Mobile m, Direction d, Point3D newLocation, Point3D oldLocation) =>
|
||||
m.WalkRegion == null || AcceptsSpawnsFrom(m.WalkRegion);
|
||||
|
||||
public virtual void OnEnter(Mobile m)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void OnExit(Mobile m)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void MakeGuard(Mobile focus)
|
||||
{
|
||||
Parent?.MakeGuard(focus);
|
||||
}
|
||||
|
||||
public virtual Type GetResource(Type type) => Parent?.GetResource(type) ?? type;
|
||||
|
||||
public virtual bool CanUseStuckMenu(Mobile m) => Parent?.CanUseStuckMenu(m) != false;
|
||||
|
||||
public virtual void OnAggressed(Mobile aggressor, Mobile aggressed, bool criminal)
|
||||
{
|
||||
Parent?.OnAggressed(aggressor, aggressed, criminal);
|
||||
}
|
||||
|
||||
public virtual void OnDidHarmful(Mobile harmer, Mobile harmed)
|
||||
{
|
||||
Parent?.OnDidHarmful(harmer, harmed);
|
||||
}
|
||||
|
||||
public virtual void OnGotHarmful(Mobile harmer, Mobile harmed)
|
||||
{
|
||||
Parent?.OnGotHarmful(harmer, harmed);
|
||||
}
|
||||
|
||||
public virtual void OnLocationChanged(Mobile m, Point3D oldLocation)
|
||||
{
|
||||
Parent?.OnLocationChanged(m, oldLocation);
|
||||
}
|
||||
|
||||
public virtual bool OnTarget(Mobile m, Target t, object o) => Parent?.OnTarget(m, t, o) != false;
|
||||
|
||||
public virtual bool OnCombatantChange(Mobile m, Mobile old, Mobile @new) =>
|
||||
Parent?.OnCombatantChange(m, old, @new) != false;
|
||||
|
||||
public virtual bool AllowHousing(Mobile from, Point3D p) => Parent?.AllowHousing(from, p) != false;
|
||||
|
||||
public virtual bool SendInaccessibleMessage(Item item, Mobile from) =>
|
||||
Parent?.SendInaccessibleMessage(item, from) == true;
|
||||
|
||||
public virtual bool CheckAccessibility(Item item, Mobile from) => Parent?.CheckAccessibility(item, from) != false;
|
||||
|
||||
public virtual bool OnDecay(Item item) => Parent?.OnDecay(item) != false;
|
||||
|
||||
public virtual bool AllowHarmful(Mobile from, Mobile target) =>
|
||||
Parent?.AllowHarmful(from, target) ?? Mobile.AllowHarmfulHandler?.Invoke(from, target) ?? true;
|
||||
|
||||
public virtual void OnCriminalAction(Mobile m, bool message)
|
||||
{
|
||||
if (Parent != null)
|
||||
Parent.OnCriminalAction(m, message);
|
||||
else if (message)
|
||||
m.SendLocalizedMessage(1005040); // You've committed a criminal act!!
|
||||
}
|
||||
|
||||
public virtual bool AllowBeneficial(Mobile from, Mobile target) =>
|
||||
Parent?.AllowBeneficial(from, target) ??
|
||||
Mobile.AllowBeneficialHandler?.Invoke(from, target) ?? true;
|
||||
|
||||
public virtual void OnBeneficialAction(Mobile helper, Mobile target)
|
||||
{
|
||||
Parent?.OnBeneficialAction(helper, target);
|
||||
}
|
||||
|
||||
public virtual void OnGotBeneficialAction(Mobile helper, Mobile target)
|
||||
{
|
||||
Parent?.OnGotBeneficialAction(helper, target);
|
||||
}
|
||||
|
||||
public virtual void SpellDamageScalar(Mobile caster, Mobile target, ref double damage)
|
||||
{
|
||||
Parent?.SpellDamageScalar(caster, target, ref damage);
|
||||
}
|
||||
|
||||
public virtual void OnSpeech(SpeechEventArgs args)
|
||||
{
|
||||
Parent?.OnSpeech(args);
|
||||
}
|
||||
|
||||
public virtual bool OnSkillUse(Mobile m, int skill) => Parent?.OnSkillUse(m, skill) != false;
|
||||
|
||||
public virtual bool OnBeginSpellCast(Mobile m, ISpell s) => Parent?.OnBeginSpellCast(m, s) != false;
|
||||
|
||||
public virtual void OnSpellCast(Mobile m, ISpell s)
|
||||
{
|
||||
Parent?.OnSpellCast(m, s);
|
||||
}
|
||||
|
||||
public virtual bool OnResurrect(Mobile m) => Parent?.OnResurrect(m) != false;
|
||||
|
||||
public virtual bool OnBeforeDeath(Mobile m) => Parent?.OnBeforeDeath(m) != false;
|
||||
|
||||
public virtual void OnDeath(Mobile m)
|
||||
{
|
||||
Parent?.OnDeath(m);
|
||||
}
|
||||
|
||||
public virtual bool OnDamage(Mobile m, ref int damage) => Parent?.OnDamage(m, ref damage) != false;
|
||||
|
||||
public virtual bool OnHeal(Mobile m, ref int heal) => Parent?.OnHeal(m, ref heal) != false;
|
||||
|
||||
public virtual bool OnDoubleClick(Mobile m, object o) => Parent?.OnDoubleClick(m, o) != false;
|
||||
|
||||
public virtual bool OnSingleClick(Mobile m, object o) => Parent?.OnSingleClick(m, o) != false;
|
||||
|
||||
public virtual bool AllowSpawn() => Parent?.AllowSpawn() != false;
|
||||
|
||||
public virtual void AlterLightLevel(Mobile m, ref int global, ref int personal)
|
||||
{
|
||||
Parent?.AlterLightLevel(m, ref global, ref personal);
|
||||
}
|
||||
|
||||
public virtual TimeSpan GetLogoutDelay(Mobile m)
|
||||
{
|
||||
if (Parent != null)
|
||||
return Parent.GetLogoutDelay(m);
|
||||
|
||||
return m.AccessLevel > AccessLevel.Player ? StaffLogoutDelay : DefaultLogoutDelay;
|
||||
}
|
||||
|
||||
internal static bool CanMove(Mobile m, Direction d, Point3D newLocation, Point3D oldLocation, Map map)
|
||||
{
|
||||
var oldRegion = m.Region;
|
||||
var newRegion = Find(newLocation, map);
|
||||
|
||||
while (oldRegion != newRegion)
|
||||
{
|
||||
if (!newRegion.OnMoveInto(m, d, newLocation, oldLocation))
|
||||
return false;
|
||||
|
||||
if (newRegion.Parent == null)
|
||||
return true;
|
||||
|
||||
newRegion = newRegion.Parent;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static void OnRegionChange(Mobile m, Region oldRegion, Region newRegion)
|
||||
{
|
||||
if (newRegion != null && m.NetState != null)
|
||||
{
|
||||
m.CheckLightLevels(false);
|
||||
|
||||
if (oldRegion == null || oldRegion.Music != newRegion.Music) m.Send(PlayMusic.GetInstance(newRegion.Music));
|
||||
}
|
||||
|
||||
var oldR = oldRegion;
|
||||
var newR = newRegion;
|
||||
|
||||
while (oldR != newR)
|
||||
{
|
||||
var oldRChild = oldR?.ChildLevel ?? -1;
|
||||
var newRChild = newR?.ChildLevel ?? -1;
|
||||
|
||||
if (oldRChild >= newRChild)
|
||||
{
|
||||
oldR?.OnExit(m);
|
||||
oldR = oldR?.Parent;
|
||||
}
|
||||
|
||||
if (newRChild >= oldRChild)
|
||||
{
|
||||
newR?.OnEnter(m);
|
||||
newR = newR?.Parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
60
Projects/Server/Regions/RegionLoader.cs
Normal file
60
Projects/Server/Regions/RegionLoader.cs
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using Server.Json;
|
||||
using Server.Utilities;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public static class RegionLoader
|
||||
{
|
||||
public static void LoadRegions()
|
||||
{
|
||||
var path = Path.Join(Core.BaseDirectory, "Data/regions.json");
|
||||
|
||||
// Json Deserialization options for custom objects
|
||||
JsonSerializerOptions options = new JsonSerializerOptions();
|
||||
options.Converters.Add(new MapConverterFactory());
|
||||
options.Converters.Add(new Point3DConverterFactory());
|
||||
options.Converters.Add(new Rectangle3DConverterFactory());
|
||||
|
||||
List<string> failures = new List<string>();
|
||||
int count = 0;
|
||||
|
||||
Console.Write("Regions: Loading...");
|
||||
|
||||
var stopwatch = Stopwatch.StartNew();
|
||||
List<DynamicJson> regions = JsonConfig.Deserialize<List<DynamicJson>>(path);
|
||||
|
||||
foreach (var json in regions)
|
||||
{
|
||||
Type type = AssemblyHandler.FindFirstTypeForName(json.Type);
|
||||
|
||||
if (type == null || !typeof(Region).IsAssignableFrom(type))
|
||||
{
|
||||
failures.Add($"\tInvalid region type {json.Type}");
|
||||
continue;
|
||||
}
|
||||
|
||||
var region = ActivatorUtil.CreateInstance(type, json, options) as Region;
|
||||
region?.Register();
|
||||
count++;
|
||||
}
|
||||
|
||||
stopwatch.Stop();
|
||||
|
||||
Console.ForegroundColor = failures.Count > 0 ? ConsoleColor.Yellow : ConsoleColor.Green;
|
||||
Console.Write("done{0}. ", failures.Count > 0 ? " with failures" : "");
|
||||
Console.ResetColor();
|
||||
Console.WriteLine("({0} regions, {1} failures) ({2:F2} seconds)", count, failures.Count, stopwatch.Elapsed.TotalSeconds);
|
||||
if (failures.Count > 0)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine(string.Join("\n", failures));
|
||||
Console.ResetColor();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue