fix: Fixes regions having the wrong type (#1260)

## Possible Breaking Change
* Reverted regions.json back to RunUO until newer regions are implemented and proper expansion checks are added.

### Other Changes
- [X] Adds `Region.IsPartOf<T1, T2>()` to check for multiple types.
- [X] Fixes regions.json being wrong
- [X] Adds lots of missing regions. **They are not implemented properly yet**
- [X] Adds regions.xml -> regions.json (check ModernUO Discord)
- [X] Adds expansion specific regions.
This commit is contained in:
Kamron Batman 2022-11-21 16:47:40 -08:00 • committed by GitHub
parent f9c72a62df
commit 1f778cfacf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
38 changed files with 3424 additions and 2949 deletions

View file

@ -0,0 +1,50 @@
using System;
using System.Xml;
using Server;
using Server.Regions;
using Server.Mobiles;
namespace Server.Engines.Quests;
public class CancelQuestRegion : BaseRegion
{
public CancelQuestRegion(string name, Map map, Region parent, int priority, params Rectangle3D[] area) : base(name, map, parent, priority, area)
{
}
public CancelQuestRegion(string name, Map map, Region parent, params Rectangle3D[] area) : base(name, map, parent, area)
{
}
public Type Quest { get; set; }
public override bool OnMoveInto(Mobile m, Direction d, Point3D newLocation, Point3D oldLocation)
{
if (!base.OnMoveInto (m, d, newLocation, oldLocation))
{
return false;
}
if (m.AccessLevel > AccessLevel.Player)
{
return true;
}
if (Quest == null)
{
return true;
}
if (m is PlayerMobile player && player.Quest != null && player.Quest.GetType() == Quest)
{
if (!player.HasGump<QuestCancelGump>())
{
player.Quest.BeginCancelQuest();
}
return false;
}
return true;
}
}

View file

@ -0,0 +1,39 @@
using System;
using System.Xml;
using Server;
using Server.Regions;
using Server.Mobiles;
namespace Server.Engines.Quests;
public class QuestCompleteObjectiveRegion : BaseRegion
{
public QuestCompleteObjectiveRegion(string name, Map map, Region parent, int priority, params Rectangle3D[] area) : base(name, map, parent, priority, area)
{
}
public QuestCompleteObjectiveRegion(string name, Map map, Region parent, params Rectangle3D[] area) : base(name, map, parent, area)
{
}
public Type Quest { get; set; }
public Type Objective { get; set; }
public override void OnEnter(Mobile m)
{
base.OnEnter(m);
if (Quest != null && Objective != null)
{
if (m is PlayerMobile player && player?.Quest != null && player.Quest.GetType() == Quest)
{
QuestObjective obj = player.Quest.FindObjective(Objective);
if (obj is { Completed: false })
{
obj.Complete();
}
}
}
}
}

View file

@ -0,0 +1,63 @@
using System;
using System.Xml;
using Server;
using Server.Regions;
using Server.Mobiles;
namespace Server.Engines.Quests;
public class QuestNoEntryRegion : BaseRegion
{
public Type Quest { get; set; }
public Type MinObjective { get; set; }
public Type MaxObjective { get; set; }
public int Message { get; set; }
public QuestNoEntryRegion(string name, Map map, Region parent, int priority, params Rectangle3D[] area) : base(name, map, parent, priority, area)
{
}
public QuestNoEntryRegion(string name, Map map, Region parent, params Rectangle3D[] area) : base(name, map, parent, area)
{
}
public override bool OnMoveInto(Mobile m, Direction d, Point3D newLocation, Point3D oldLocation)
{
if (!base.OnMoveInto (m, d, newLocation, oldLocation))
{
return false;
}
if (m.AccessLevel > AccessLevel.Player)
{
return true;
}
if (m is BaseCreature { Controlled: false, Summoned: false })
{
return true;
}
if (Quest == null)
{
return true;
}
if (m is PlayerMobile player && player.Quest != null && player.Quest.GetType() == Quest
&& (MinObjective == null || player.Quest.FindObjective(MinObjective) != null)
&& (MaxObjective == null || player.Quest.FindObjective(MaxObjective) == null))
{
return true;
}
if (Message != 0)
{
m.SendLocalizedMessage(Message);
}
return false;
}
}

View file

@ -0,0 +1,47 @@
using System;
using System.Xml;
using Server;
using Server.Logging;
using Server.Regions;
using Server.Mobiles;
using Server.Utilities;
namespace Server.Engines.Quests;
public class QuestOfferRegion : BaseRegion
{
private static readonly ILogger logger = LogFactory.GetLogger(typeof(QuestOfferRegion));
public QuestOfferRegion(string name, Map map, Region parent, int priority, params Rectangle3D[] area) : base(name, map, parent, priority, area)
{
}
public QuestOfferRegion(string name, Map map, Region parent, params Rectangle3D[] area) : base(name, map, parent, area)
{
}
public Type Quest { get; set; }
public override void OnEnter(Mobile m)
{
base.OnEnter(m);
if (Quest == null)
{
return;
}
if (m is PlayerMobile player && player.Quest == null && QuestSystem.CanOfferQuest(m, Quest))
{
try
{
QuestSystem qs = Quest.CreateInstance<QuestSystem>(player);
qs.SendOffer();
}
catch (Exception ex)
{
logger.Error(ex, "Error creating quest {Quest}", Quest);
}
}
}
}

View file

@ -63,7 +63,7 @@ namespace Server.Multis
return HousePlacementResult.InvalidCastleKeep;
}
if (Region.Find(center, map).IsPartOf<NoHousingRegion>())
if (Region.Find(center, map).IsPartOf<NoHousingRegion, NoHousingGuardedRegion>())
{
return HousePlacementResult.BadRegion;
}

View file

@ -0,0 +1,14 @@
namespace Server.Regions;
// TODO: Implement damage boost regions
public class AcidRiverRegion : MondainRegion
{
public AcidRiverRegion(string name, Map map, Region parent, params Rectangle3D[] area): base(name, map, parent, area)
{
}
public AcidRiverRegion(string name, Map map, Region parent, int priority, params Rectangle3D[] area)
: base(name, map, parent, priority, area)
{
}
}

View file

@ -0,0 +1,13 @@
namespace Server.Regions;
// TODO: Implement
public class ApprenticeRegion : BaseRegion
{
public ApprenticeRegion(string name, Map map, Region parent, int priority, params Rectangle3D[] area) : base(name, map, parent, priority, area)
{
}
public ApprenticeRegion(string name, Map map, Region parent, params Rectangle3D[] area) : base(name, map, parent, area)
{
}
}

View file

@ -0,0 +1,12 @@
namespace Server.Regions;
public class BattleRegion : DungeonRegion
{
public BattleRegion(string name, Map map, Region parent, params Rectangle3D[] area) : base(name, map, parent, area)
{
}
public BattleRegion(string name, Map map, Region parent, int priority, params Rectangle3D[] area) : base(name, map, parent, priority, area)
{
}
}

View file

@ -0,0 +1,17 @@
namespace Server.Regions;
// TODO: Implement
public class BlackthornCastleRegion : GuardedRegion
{
public BlackthornCastleRegion(string name, Map map, int priority, params Rectangle3D[] area) : base(name, map, priority, area)
{
}
public BlackthornCastleRegion(string name, Map map, Region parent, params Rectangle3D[] area) : base(name, map, parent, area)
{
}
public BlackthornCastleRegion(string name, Map map, Region parent, int priority, params Rectangle3D[] area) : base(name, map, parent, priority, area)
{
}
}

View file

@ -0,0 +1,14 @@
namespace Server.Regions;
// TODO: Implement
public class BlackthornDungeonRegion : DungeonRegion
{
public BlackthornDungeonRegion(string name, Map map, Region parent, params Rectangle3D[] area) : base(name, map, parent, area)
{
}
public BlackthornDungeonRegion(string name, Map map, Region parent, int priority, params Rectangle3D[] area)
: base(name, map, parent, priority, area)
{
}
}

View file

@ -0,0 +1,22 @@
using System;
namespace Server.Regions;
public class CousteauPerronHouseRegion : GuardedRegion
{
public CousteauPerronHouseRegion(string name, Map map, int priority, params Rectangle3D[] area) : base(name, map, priority, area)
{
}
public CousteauPerronHouseRegion(string name, Map map, Region parent, params Rectangle3D[] area) : base(name, map, parent, area)
{
}
public CousteauPerronHouseRegion(string name, Map map, Region parent, int priority, params Rectangle3D[] area) : base(name, map, parent, priority, area)
{
}
public CousteauPerronHouseRegion(string name, Map map, Region parent, int priority, Type guardType, params Rectangle3D[] area) : base(name, map, parent, priority, guardType, area)
{
}
}

View file

@ -0,0 +1,14 @@
namespace Server.Regions;
// TODO: Implement damage boost regions
public class CrystalFieldRegion : MondainRegion
{
public CrystalFieldRegion(string name, Map map, Region parent, params Rectangle3D[] area): base(name, map, parent, area)
{
}
public CrystalFieldRegion(string name, Map map, Region parent, int priority, params Rectangle3D[] area)
: base(name, map, parent, priority, area)
{
}
}

View file

@ -0,0 +1,13 @@
namespace Server.Regions;
// TODO: Implement
public class DoomGuardianRegion : DungeonRegion
{
public DoomGuardianRegion(string name, Map map, Region parent, params Rectangle3D[] area) : base(name, map, parent, area)
{
}
public DoomGuardianRegion(string name, Map map, Region parent, int priority, params Rectangle3D[] area) : base(name, map, parent, priority, area)
{
}
}

View file

@ -0,0 +1,13 @@
namespace Server.Regions;
// TODO: Implement
public class ExodusDungeonRegion : DungeonRegion
{
public ExodusDungeonRegion(string name, Map map, Region parent, params Rectangle3D[] area) : base(name, map, parent, area)
{
}
public ExodusDungeonRegion(string name, Map map, Region parent, int priority, params Rectangle3D[] area) : base(name, map, parent, priority, area)
{
}
}

View file

@ -0,0 +1,13 @@
namespace Server.Regions;
// TODO: Implement
public class ExploringDeepCreaturesRegion : DungeonRegion
{
public ExploringDeepCreaturesRegion(string name, Map map, Region parent, params Rectangle3D[] area) : base(name, map, parent, area)
{
}
public ExploringDeepCreaturesRegion(string name, Map map, Region parent, int priority, params Rectangle3D[] area) : base(name, map, parent, priority, area)
{
}
}

View file

@ -9,8 +9,6 @@ namespace Server.Regions;
public class GuardedRegion : BaseRegion
{
private static readonly ILogger logger = LogFactory.GetLogger(typeof(GuardedRegion));
private static readonly object[] m_GuardParams = new object[1];
private readonly Dictionary<Mobile, GuardTimer> m_GuardCandidates = new();

View file

@ -0,0 +1,14 @@
namespace Server.Regions;
// TODO: Implement damage boost regions
public class IcyRiverRegion : MondainRegion
{
public IcyRiverRegion(string name, Map map, Region parent, params Rectangle3D[] area): base(name, map, parent, area)
{
}
public IcyRiverRegion(string name, Map map, Region parent, int priority, params Rectangle3D[] area)
: base(name, map, parent, priority, area)
{
}
}

View file

@ -4,18 +4,60 @@ public static class RegionJsonDtoExt
{
public static void Configure()
{
RegionJsonSerializer.RegisterRegionForSerialization<BaseRegionJsonDto<BaseRegion>, BaseRegion>();
RegionJsonSerializer.Register<BaseRegionJsonDto<BaseRegion>, BaseRegion>();
RegionJsonSerializer.RegisterRegionForSerialization<DungeonRegionJsonDto<DungeonRegion>, DungeonRegion>();
RegionJsonSerializer.RegisterRegionForSerialization<GuardedRegionJsonDto<GuardedRegion>, GuardedRegion>();
RegionJsonSerializer.Register<DungeonRegionJsonDto<DungeonRegion>, DungeonRegion>();
RegionJsonSerializer.Register<GuardedRegionJsonDto<GuardedRegion>, GuardedRegion>();
RegionJsonSerializer.RegisterRegionForSerialization<BaseRegionJsonDto<GreenAcresRegion>, GreenAcresRegion>();
RegionJsonSerializer.RegisterRegionForSerialization<BaseRegionJsonDto<JailRegion>, JailRegion>();
RegionJsonSerializer.RegisterRegionForSerialization<BaseRegionJsonDto<MondainRegion>, MondainRegion>();
RegionJsonSerializer.RegisterRegionForSerialization<BaseRegionJsonDto<NewMaginciaRegion>, NewMaginciaRegion>();
RegionJsonSerializer.RegisterRegionForSerialization<BaseRegionJsonDto<NoHousingRegion>, NoHousingRegion>();
RegionJsonSerializer.RegisterRegionForSerialization<BaseRegionJsonDto<NoTravelSpellsAllowedRegion>, NoTravelSpellsAllowedRegion>();
RegionJsonSerializer.RegisterRegionForSerialization<BaseRegionJsonDto<TownRegion>, TownRegion>();
RegionJsonSerializer.RegisterRegionForSerialization<BaseRegionJsonDto<TwistedWealdDesertRegion>, TwistedWealdDesertRegion>();
RegionJsonSerializer.Register<BaseRegionJsonDto<GreenAcresRegion>, GreenAcresRegion>();
RegionJsonSerializer.Register<BaseRegionJsonDto<JailRegion>, JailRegion>();
RegionJsonSerializer.Register<BaseRegionJsonDto<MondainRegion>, MondainRegion>();
RegionJsonSerializer.Register<TownRegionJsonDto<NewMaginciaRegion>, NewMaginciaRegion>();
RegionJsonSerializer.Register<BaseRegionJsonDto<NoHousingRegion>, NoHousingRegion>();
RegionJsonSerializer.Register<BaseRegionJsonDto<NoHousingGuardedRegion>, NoHousingGuardedRegion>();
RegionJsonSerializer.Register<BaseRegionJsonDto<NoTravelSpellsAllowedRegion>, NoTravelSpellsAllowedRegion>();
RegionJsonSerializer.Register<TownRegionJsonDto<TownRegion>, TownRegion>();
RegionJsonSerializer.Register<BaseRegionJsonDto<TwistedWealdDesertRegion>, TwistedWealdDesertRegion>();
// Damage boost regions
RegionJsonSerializer.Register<DungeonRegionJsonDto<CrystalFieldRegion>, CrystalFieldRegion>();
RegionJsonSerializer.Register<DungeonRegionJsonDto<IcyRiverRegion>, IcyRiverRegion>();
RegionJsonSerializer.Register<DungeonRegionJsonDto<AcidRiverRegion>, AcidRiverRegion>();
RegionJsonSerializer.Register<DungeonRegionJsonDto<PoisonedTreeRegion>, PoisonedTreeRegion>();
RegionJsonSerializer.Register<DungeonRegionJsonDto<LostCityEntranceRegion>, LostCityEntranceRegion>();
RegionJsonSerializer.Register<DungeonRegionJsonDto<PoisonedCemeteryRegion>, PoisonedCemeteryRegion>();
// Wrong Jail
RegionJsonSerializer.Register<DungeonRegionJsonDto<WrongLevel3Region>, WrongLevel3Region>();
RegionJsonSerializer.Register<DungeonRegionJsonDto<WrongJailRegion>, WrongJailRegion>();
// Blackthorn Dungeon
RegionJsonSerializer.Register<DungeonRegionJsonDto<BlackthornDungeonRegion>, BlackthornDungeonRegion>();
RegionJsonSerializer.Register<GuardedRegionJsonDto<CousteauPerronHouseRegion>, CousteauPerronHouseRegion>();
RegionJsonSerializer.Register<BaseRegionJsonDto<ApprenticeRegion>, ApprenticeRegion>();
RegionJsonSerializer.Register<BaseRegionJsonDto<SeaMarketRegion>, SeaMarketRegion>();
// Exploring the Deep
RegionJsonSerializer.Register<DungeonRegionJsonDto<ExploringDeepCreaturesRegion>, ExploringDeepCreaturesRegion>();
RegionJsonSerializer.Register<BaseRegionJsonDto<UnderwaterRegion>, UnderwaterRegion>();
// Exodus Dungeon
RegionJsonSerializer.Register<DungeonRegionJsonDto<ExodusDungeonRegion>, ExodusDungeonRegion>();
// Doom
RegionJsonSerializer.Register<DungeonRegionJsonDto<DoomGuardianRegion>, DoomGuardianRegion>();
// Tokuno
RegionJsonSerializer.Register<GuardedRegionJsonDto<TokunoDocksRegion>, TokunoDocksRegion>();
// Tomb of Kings
RegionJsonSerializer.Register<BaseRegionJsonDto<TombOfKingsRegion>, TombOfKingsRegion>();
RegionJsonSerializer.Register<BaseRegionJsonDto<ToKBridgeRegion>, ToKBridgeRegion>();
// Myrmidex
RegionJsonSerializer.Register<DungeonRegionJsonDto<BattleRegion>, BattleRegion>();
}
}

View file

@ -0,0 +1,26 @@
namespace Server.Regions;
public class TownRegionJsonDto<TRegion> : BaseRegionJsonDto<TRegion> where TRegion : TownRegion
{
public Point3D Entrance { get; set; }
public override void FromRegion(Region region)
{
base.FromRegion(region);
if (region is TownRegion townRegion)
{
Entrance = townRegion.Entrance;
}
}
protected override void HydrateRegion(Region region)
{
base.HydrateRegion(region);
if (region is TownRegion townRegion)
{
townRegion.Entrance = Entrance;
}
}
}

View file

@ -0,0 +1,14 @@
namespace Server.Regions;
// TODO: Implement damage boost regions
public class LostCityEntranceRegion : MondainRegion
{
public LostCityEntranceRegion(string name, Map map, Region parent, params Rectangle3D[] area): base(name, map, parent, area)
{
}
public LostCityEntranceRegion(string name, Map map, Region parent, int priority, params Rectangle3D[] area)
: base(name, map, parent, priority, area)
{
}
}

View file

@ -0,0 +1,26 @@
using System;
namespace Server.Regions;
public class NoHousingGuardedRegion : GuardedRegion
{
public NoHousingGuardedRegion(string name, Map map, int priority, params Rectangle3D[] area) : base(name, map, priority, area)
{
}
public NoHousingGuardedRegion(string name, Map map, int priority, params Rectangle2D[] area) : base(name, map, priority, area)
{
}
public NoHousingGuardedRegion(string name, Map map, Region parent, params Rectangle3D[] area) : base(name, map, parent, area)
{
}
public NoHousingGuardedRegion(string name, Map map, Region parent, int priority, params Rectangle3D[] area) : base(name, map, parent, priority, area)
{
}
public NoHousingGuardedRegion(string name, Map map, Region parent, int priority, Type guardType, params Rectangle3D[] area) : base(name, map, parent, priority, guardType, area)
{
}
}

View file

@ -2,6 +2,8 @@ namespace Server.Regions;
public class NoHousingRegion : BaseRegion
{
// We don't set AllowHousing to false because it is manually checked so that a part of a house cannot overlap
public NoHousingRegion(string name, Map map, Region parent, params Rectangle3D[] area)
: base(name, map, parent, area)
{

View file

@ -0,0 +1,14 @@
namespace Server.Regions;
// TODO: Implement damage boost regions
public class PoisonedTreeRegion : MondainRegion
{
public PoisonedTreeRegion(string name, Map map, Region parent, params Rectangle3D[] area): base(name, map, parent, area)
{
}
public PoisonedTreeRegion(string name, Map map, Region parent, int priority, params Rectangle3D[] area)
: base(name, map, parent, priority, area)
{
}
}

View file

@ -0,0 +1,14 @@
namespace Server.Regions;
// TODO: Implement damage boost regions
public class PoisonedCemeteryRegion : MondainRegion
{
public PoisonedCemeteryRegion(string name, Map map, Region parent, params Rectangle3D[] area): base(name, map, parent, area)
{
}
public PoisonedCemeteryRegion(string name, Map map, Region parent, int priority, params Rectangle3D[] area)
: base(name, map, parent, priority, area)
{
}
}

View file

@ -0,0 +1,13 @@
namespace Server.Regions;
// TODO: Implement
public class SeaMarketRegion : BaseRegion
{
public SeaMarketRegion(string name, Map map, Region parent, int priority, params Rectangle3D[] area) : base(name, map, parent, priority, area)
{
}
public SeaMarketRegion(string name, Map map, Region parent, params Rectangle3D[] area) : base(name, map, parent, area)
{
}
}

View file

@ -0,0 +1,13 @@
namespace Server.Regions;
// TODO: Implement
public class ToKBridgeRegion : BaseRegion
{
public ToKBridgeRegion(string name, Map map, Region parent, int priority, params Rectangle3D[] area) : base(name, map, parent, priority, area)
{
}
public ToKBridgeRegion(string name, Map map, Region parent, params Rectangle3D[] area) : base(name, map, parent, area)
{
}
}

View file

@ -0,0 +1,26 @@
using System;
namespace Server.Regions;
public class TokunoDocksRegion : NoHousingGuardedRegion
{
public TokunoDocksRegion(string name, Map map, int priority, params Rectangle3D[] area) : base(name, map, priority, area)
{
}
public TokunoDocksRegion(string name, Map map, int priority, params Rectangle2D[] area) : base(name, map, priority, area)
{
}
public TokunoDocksRegion(string name, Map map, Region parent, params Rectangle3D[] area) : base(name, map, parent, area)
{
}
public TokunoDocksRegion(string name, Map map, Region parent, int priority, params Rectangle3D[] area) : base(name, map, parent, priority, area)
{
}
public TokunoDocksRegion(string name, Map map, Region parent, int priority, Type guardType, params Rectangle3D[] area) : base(name, map, parent, priority, guardType, area)
{
}
}

View file

@ -0,0 +1,17 @@
namespace Server.Regions;
public class TombOfKingsRegion : BaseRegion
{
public TombOfKingsRegion(string name, Map map, Region parent, int priority, params Rectangle3D[] area) : base(name, map, parent, priority, area)
{
}
public TombOfKingsRegion(string name, Map map, Region parent, params Rectangle3D[] area) : base(name, map, parent, area)
{
}
public override void AlterLightLevel(Mobile m, ref int global, ref int personal)
{
global = 0;
}
}

View file

@ -2,6 +2,8 @@ namespace Server.Regions;
public class TownRegion : GuardedRegion
{
public Point3D Entrance { get; set; }
public TownRegion(string name, Map map, Region parent, params Rectangle3D[] area)
: base(name, map, parent, area)
{

View file

@ -0,0 +1,13 @@
namespace Server.Regions;
// TODO: Implement
public class UnderwaterRegion : BaseRegion
{
public UnderwaterRegion(string name, Map map, Region parent, int priority, params Rectangle3D[] area) : base(name, map, parent, priority, area)
{
}
public UnderwaterRegion(string name, Map map, Region parent, params Rectangle3D[] area) : base(name, map, parent, area)
{
}
}

View file

@ -0,0 +1,14 @@
namespace Server.Regions;
// TODO: Implement jail safe zone
public class WrongJailRegion : DungeonRegion
{
public WrongJailRegion(string name, Map map, Region parent, params Rectangle3D[] area) : base(name, map, parent, area)
{
}
public WrongJailRegion(string name, Map map, Region parent, int priority, params Rectangle3D[] area)
: base(name, map, parent, priority, area)
{
}
}

View file

@ -0,0 +1,14 @@
namespace Server.Regions;
// TODO: Implement jail
public class WrongLevel3Region : DungeonRegion
{
public WrongLevel3Region(string name, Map map, Region parent, params Rectangle3D[] area) : base(name, map, parent, area)
{
}
public WrongLevel3Region(string name, Map map, Region parent, int priority, params Rectangle3D[] area)
: base(name, map, parent, priority, area)
{
}
}