Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
1048
Scripts/Services/PVP Arena System/ArenaDuel.cs
Normal file
1048
Scripts/Services/PVP Arena System/ArenaDuel.cs
Normal file
File diff suppressed because it is too large
Load Diff
86
Scripts/Services/PVP Arena System/ArenaExitBanner.cs
Normal file
86
Scripts/Services/PVP Arena System/ArenaExitBanner.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
using Server;
|
||||
using System;
|
||||
using Server.Items;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.ArenaSystem
|
||||
{
|
||||
public class ArenaExitBanner : Item
|
||||
{
|
||||
public override bool ForceShowProperties { get { return true; } }
|
||||
public override int LabelNumber { get { return 1116111; } } // Arena Exit Banner
|
||||
public override bool HandlesOnMovement { get { return true; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public PVPArena Arena { get; set; }
|
||||
|
||||
[Constructable]
|
||||
public ArenaExitBanner(int itemid, PVPArena arena)
|
||||
: base(itemid)
|
||||
{
|
||||
Arena = arena;
|
||||
Movable = false;
|
||||
Weight = 0;
|
||||
}
|
||||
|
||||
public override void OnMovement(Mobile m, Point3D oldLocation)
|
||||
{
|
||||
if (m is PlayerMobile && Arena != null && !m.Alive && m.InRange(Location, 2) && !m.HasGump(typeof(ResurrectGump)))
|
||||
{
|
||||
m.SendGump(new ResurrectGump(m, null, ResurrectMessage.Generic, false, 0.0, mob =>
|
||||
{
|
||||
Arena.RemovePlayer((PlayerMobile)mob);
|
||||
|
||||
if (mob.Corpse != null)
|
||||
mob.Corpse.MoveToWorld(mob.Location, mob.Map);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!from.InRange(Location, 3) || !from.InLOS(this) || !from.CanSee(this))
|
||||
{
|
||||
from.LocalOverheadMessage(Network.MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
|
||||
}
|
||||
else if (Arena != null)
|
||||
{
|
||||
var duel = Arena.CurrentDuel;
|
||||
|
||||
if (duel != null && duel.InPreFight)
|
||||
{
|
||||
from.SendLocalizedMessage(1115968); // You cannot exit until this duel has started.
|
||||
return;
|
||||
}
|
||||
|
||||
from.SendGump(new ConfirmCallbackGump((PlayerMobile)from, 1115969, 1115970, null, null, (m, state) =>
|
||||
{
|
||||
Arena.RemovePlayer((PlayerMobile)m);
|
||||
|
||||
if (duel != null && !duel.Complete)
|
||||
{
|
||||
duel.OnPlayerLeave((PlayerMobile)m);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
public ArenaExitBanner(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
111
Scripts/Services/PVP Arena System/ArenaGate.cs
Normal file
111
Scripts/Services/PVP Arena System/ArenaGate.cs
Normal file
@@ -0,0 +1,111 @@
|
||||
using Server;
|
||||
using System;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.ArenaSystem
|
||||
{
|
||||
public class ArenaGate : Item
|
||||
{
|
||||
public override bool ForceShowProperties { get { return true; } }
|
||||
public override int LabelNumber { get { return 1115879; } } // Arena Gate
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public ArenaDuel Duel { get; set; }
|
||||
|
||||
[Constructable]
|
||||
public ArenaGate(ArenaDuel duel)
|
||||
: base(0xF6C)
|
||||
{
|
||||
Duel = duel;
|
||||
Movable = false;
|
||||
|
||||
Hue = 1194;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (from.InRange(Location, 1))
|
||||
TryUse(from);
|
||||
}
|
||||
|
||||
public override bool OnMoveOver(Mobile m)
|
||||
{
|
||||
TryUse(m);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void TryUse(Mobile m)
|
||||
{
|
||||
if (m is PlayerMobile && CheckValidation((PlayerMobile)m))
|
||||
{
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(.5), () =>
|
||||
{
|
||||
Effects.SendLocationEffect(m.Location, m.Map, 0x3728, 10, 10);
|
||||
Duel.MoveToArena((PlayerMobile)m);
|
||||
Effects.SendLocationEffect(m.Location, m.Map, 0x3728, 10, 10);
|
||||
|
||||
m.PlaySound(0x1FE);
|
||||
m.ProcessDelta();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private bool CheckValidation(PlayerMobile pm)
|
||||
{
|
||||
if (!Duel.IsParticipant(pm))
|
||||
return false;
|
||||
|
||||
if (pm.Young)
|
||||
{
|
||||
PVPArenaSystem.SendMessage(pm, 1149696); // As a young player, you may not enter this area.
|
||||
return false;
|
||||
}
|
||||
else if (pm.Followers > Duel.PetSlots)
|
||||
{
|
||||
PVPArenaSystem.SendMessage(pm, 1115974); // You currently exceed the maximum number of pet slots for this duel. Please stable your pet(s) with the arena manager before proceeding.
|
||||
return false;
|
||||
}
|
||||
else if (Duel.EntryFee > EntryFee.Zero)
|
||||
{
|
||||
int fee = (int)Duel.EntryFee;
|
||||
|
||||
if (pm.Backpack != null && pm.Backpack.ConsumeTotal(typeof(Gold), fee))
|
||||
{
|
||||
pm.SendLocalizedMessage(1149610); // You have paid the entry fee from your backpack.
|
||||
}
|
||||
else if (Banker.Withdraw(pm, fee, true))
|
||||
{
|
||||
pm.SendLocalizedMessage(1149609); // You have paid the entry fee from your bank account.
|
||||
}
|
||||
else
|
||||
{
|
||||
pm.SendLocalizedMessage(1149611); // You don't have enough money to pay the entry fee.
|
||||
return false;
|
||||
}
|
||||
|
||||
Duel.Pot += fee;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public ArenaGate(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
104
Scripts/Services/PVP Arena System/ArenaManager.cs
Normal file
104
Scripts/Services/PVP Arena System/ArenaManager.cs
Normal file
@@ -0,0 +1,104 @@
|
||||
using Server;
|
||||
using System;
|
||||
using Server.Mobiles;
|
||||
using Server.Items;
|
||||
using Server.Gumps;
|
||||
|
||||
namespace Server.Engines.ArenaSystem
|
||||
{
|
||||
public class ArenaManager : AnimalTrainer
|
||||
{
|
||||
public override bool IsActiveVendor { get { return false; } }
|
||||
public override bool IsActiveBuyer { get { return false; } }
|
||||
public override bool IsActiveSeller { get { return false; } }
|
||||
public override bool CanTeach { get { return false; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public PVPArena Arena { get; set; }
|
||||
|
||||
[Constructable]
|
||||
public ArenaManager(PVPArena arena)
|
||||
{
|
||||
Title = "The Arena Manager";
|
||||
|
||||
Arena = arena;
|
||||
CantWalk = true;
|
||||
}
|
||||
|
||||
public override void InitBody()
|
||||
{
|
||||
Female = true;
|
||||
Body = 0x191;
|
||||
Name = NameList.RandomName("female");
|
||||
|
||||
HairItemID = Race.RandomHair(true);
|
||||
HairHue = Race.RandomHairHue();
|
||||
Hue = Race.RandomSkinHue();
|
||||
|
||||
SetStr(100);
|
||||
SetInt(100);
|
||||
SetDex(100);
|
||||
}
|
||||
|
||||
public override void InitOutfit()
|
||||
{
|
||||
SetWearable(new PlateHaidate(), 1173);
|
||||
SetWearable(new FemalePlateChest(), 1173);
|
||||
SetWearable(new PlateGloves(), 1173);
|
||||
SetWearable(new Bonnet(), 1173);
|
||||
SetWearable(new Sandals(), 1173);
|
||||
SetWearable(new Spellbook(), 1168);
|
||||
}
|
||||
|
||||
public virtual void OfferResurrection(Mobile m)
|
||||
{
|
||||
Direction = GetDirectionTo(m);
|
||||
|
||||
m.PlaySound(0x1F2);
|
||||
m.FixedEffect(0x376A, 10, 16);
|
||||
|
||||
m.CloseGump(typeof(ResurrectGump));
|
||||
m.SendGump(new ResurrectGump(m, ResurrectMessage.Healer));
|
||||
}
|
||||
|
||||
public override void OnMovement(Mobile m, Point3D oldLocation)
|
||||
{
|
||||
if (!m.Alive && !m.Frozen && InRange(m, 4) && !InRange(oldLocation, 4) && InLOS(m))
|
||||
{
|
||||
if (m.Map == null || !m.Map.CanFit(m.Location, 16, false, false))
|
||||
{
|
||||
m.SendLocalizedMessage(502391); // Thou can not be resurrected there!
|
||||
}
|
||||
else
|
||||
{
|
||||
OfferResurrection(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (CanPaperdollBeOpenedBy(from))
|
||||
{
|
||||
DisplayPaperdollTo(from);
|
||||
}
|
||||
}
|
||||
|
||||
public ArenaManager(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
0
Scripts/Services/PVP Arena System/ArenaStats.cs
Normal file
0
Scripts/Services/PVP Arena System/ArenaStats.cs
Normal file
156
Scripts/Services/PVP Arena System/ArenaStone.cs
Normal file
156
Scripts/Services/PVP Arena System/ArenaStone.cs
Normal file
@@ -0,0 +1,156 @@
|
||||
using Server;
|
||||
using System;
|
||||
using Server.Items;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Engines.ArenaSystem
|
||||
{
|
||||
[DeleteConfirm("Are you sure you want to delete this? Deleting this stone will remove this arena from the system.")]
|
||||
public class ArenaStone : Item
|
||||
{
|
||||
public override bool ForceShowProperties { get { return true; } }
|
||||
public override int LabelNumber { get { return 1115878; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public PVPArena Arena { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool ShowArenaEffects
|
||||
{
|
||||
get { return false; }
|
||||
set { if (value) DoArenaEffects(); if (!value) HideArenaEffects(); }
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public ArenaStone(PVPArena arena)
|
||||
: base(0xEDD)
|
||||
{
|
||||
Arena = arena;
|
||||
|
||||
Movable = false;
|
||||
Hue = 1194;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (from is PlayerMobile && from.InRange(Location, 10))
|
||||
{
|
||||
PlayerMobile pm = from as PlayerMobile;
|
||||
|
||||
if (pm.Young)
|
||||
{
|
||||
from.SendLocalizedMessage(1116002); // Young players and Trial Account users may not participate in duels.
|
||||
}
|
||||
else if (Arena != null && PVPArenaSystem.Enabled)
|
||||
{
|
||||
if (Arena.CurrentDuel != null && Arena.CurrentDuel.IsParticipant(pm))
|
||||
{
|
||||
if (Arena.CurrentDuel.InPreFight)
|
||||
{
|
||||
BaseGump.SendGump(new OfferDuelGump(pm, Arena.CurrentDuel, Arena, false, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1116387); // Please wait until the session which you participated is finished completely.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var duel = Arena.GetPendingDuel(from);
|
||||
|
||||
if (duel == null)
|
||||
{
|
||||
var booked = PVPArenaSystem.Instance.GetBookedDuel(pm);
|
||||
|
||||
if (booked != null)
|
||||
{
|
||||
BaseGump.SendGump(new OfferDuelGump(pm, booked, booked.Arena, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseGump.SendGump(new ArenaStoneGump(pm, Arena));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseGump.SendGump(new PendingDuelGump(pm, duel, Arena));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(502138); // That is too far away for you to use.
|
||||
}
|
||||
}
|
||||
|
||||
private List<Item> _Items;
|
||||
|
||||
public void DoArenaEffects()
|
||||
{
|
||||
if (Arena == null)
|
||||
return;
|
||||
|
||||
_Items = new List<Item>();
|
||||
|
||||
foreach (var rec in Arena.Definition.EffectAreas)
|
||||
{
|
||||
for (int x = rec.X; x < rec.X + rec.Width; x++)
|
||||
{
|
||||
for (int y = rec.Y; y < rec.Y + rec.Height; y++)
|
||||
{
|
||||
var st = new Static(0x3709);
|
||||
st.MoveToWorld(new Point3D(x, y, Arena.Definition.Map.GetAverageZ(x, y)), Map);
|
||||
_Items.Add(st);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void HideArenaEffects()
|
||||
{
|
||||
if (_Items == null)
|
||||
return;
|
||||
|
||||
_Items.ForEach(s =>
|
||||
{
|
||||
s.Delete();
|
||||
});
|
||||
|
||||
ColUtility.Free(_Items);
|
||||
_Items = null;
|
||||
}
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
base.Delete();
|
||||
|
||||
Timer.DelayCall(() =>
|
||||
{
|
||||
if (Arena != null && PVPArenaSystem.Instance != null)
|
||||
{
|
||||
PVPArenaSystem.Instance.AddBlockedArena(Arena);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public ArenaStone(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
99
Scripts/Services/PVP Arena System/ArenaTeam.cs
Normal file
99
Scripts/Services/PVP Arena System/ArenaTeam.cs
Normal file
@@ -0,0 +1,99 @@
|
||||
using Server;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using System.Linq;
|
||||
|
||||
namespace Server.Engines.ArenaSystem
|
||||
{
|
||||
[PropertyObject]
|
||||
public class ArenaTeam
|
||||
{
|
||||
public Dictionary<PlayerMobile, PlayerStatsEntry> Players { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Count { get { return Players == null ? 0 : Players.Count; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool Unoccupied { get { return Count == 0; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public PlayerMobile PlayerZero { get; set; }
|
||||
|
||||
public ArenaTeam()
|
||||
{
|
||||
Players = new Dictionary<PlayerMobile, PlayerStatsEntry>();
|
||||
}
|
||||
|
||||
public ArenaTeam(PlayerMobile pm)
|
||||
{
|
||||
Players = new Dictionary<PlayerMobile, PlayerStatsEntry>();
|
||||
AddParticipant(pm);
|
||||
}
|
||||
|
||||
public void AddParticipant(PlayerMobile pm)
|
||||
{
|
||||
if (Players.Count == 0)
|
||||
PlayerZero = pm;
|
||||
|
||||
Players[pm] = PVPArenaSystem.Instance.GetPlayerEntry<PlayerStatsEntry>(pm);
|
||||
}
|
||||
|
||||
public bool RemoveParticipant(PlayerMobile pm)
|
||||
{
|
||||
if (Players == null)
|
||||
return false;
|
||||
|
||||
if (Players.ContainsKey(pm))
|
||||
{
|
||||
Players.Remove(pm);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Contains(PlayerMobile pm)
|
||||
{
|
||||
return Players.ContainsKey(pm);
|
||||
}
|
||||
|
||||
public ArenaTeam(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Players = new Dictionary<PlayerMobile, PlayerStatsEntry>();
|
||||
List<PlayerMobile> list = new List<PlayerMobile>();
|
||||
|
||||
int count = reader.ReadInt();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
PlayerMobile pm = reader.ReadMobile() as PlayerMobile;
|
||||
|
||||
if (pm != null)
|
||||
list.Add(pm);
|
||||
}
|
||||
|
||||
// have to wait for everything else to deserialize :(
|
||||
Timer.DelayCall(() =>
|
||||
{
|
||||
foreach (var pm in list)
|
||||
{
|
||||
AddParticipant(pm);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void Serialize(GenericWriter writer)
|
||||
{
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(Players.Count);
|
||||
foreach(var kvp in Players)
|
||||
{
|
||||
writer.Write(kvp.Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
268
Scripts/Services/PVP Arena System/Definitions.cs
Normal file
268
Scripts/Services/PVP Arena System/Definitions.cs
Normal file
@@ -0,0 +1,268 @@
|
||||
using Server;
|
||||
using System;
|
||||
|
||||
namespace Server.Engines.ArenaSystem
|
||||
{
|
||||
[PropertyObject]
|
||||
public class ArenaDefinition
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string Name { get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Point3D StoneLocation { get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Point3D ManagerLocation { get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Point3D BannerLocation1 { get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Point3D BannerLocation2 { get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Point3D GateLocation { get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int BannerID1 { get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int BannerID2 { get; private set; }
|
||||
|
||||
public Rectangle2D[] EffectAreas { get; private set; }
|
||||
public Rectangle2D[] RegionBounds { get; private set; }
|
||||
public Rectangle2D[] GuardBounds { get; private set; }
|
||||
public Rectangle2D[] StartLocations { get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Rectangle2D StartLocation1 { get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Rectangle2D StartLocation2 { get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Rectangle2D EjectLocation { get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Rectangle2D DeadEjectLocation { get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int MapIndex { get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Map Map { get { return Map.Maps[MapIndex]; } }
|
||||
|
||||
public ArenaDefinition(
|
||||
string name,
|
||||
int mapIndex,
|
||||
Point3D stoneLoc,
|
||||
Point3D manLoc,
|
||||
Point3D banloc1,
|
||||
Point3D banloc2,
|
||||
int id1,
|
||||
int id2,
|
||||
Rectangle2D[] effectAreas,
|
||||
Rectangle2D[] startLocs,
|
||||
Point3D gateLoc,
|
||||
Rectangle2D[] bounds,
|
||||
Rectangle2D[] guardbounds,
|
||||
Rectangle2D eject,
|
||||
Rectangle2D deadEject)
|
||||
{
|
||||
Name = name;
|
||||
MapIndex = mapIndex;
|
||||
StoneLocation = stoneLoc;
|
||||
ManagerLocation = manLoc;
|
||||
BannerLocation1 = banloc1;
|
||||
BannerLocation2 = banloc2;
|
||||
BannerID1 = id1;
|
||||
BannerID2 = id2;
|
||||
EffectAreas = effectAreas;
|
||||
StartLocations = startLocs;
|
||||
StartLocation1 = startLocs[0];
|
||||
StartLocation2 = startLocs[1];
|
||||
GateLocation = gateLoc;
|
||||
RegionBounds = bounds;
|
||||
GuardBounds = guardbounds;
|
||||
EjectLocation = eject;
|
||||
DeadEjectLocation = deadEject;
|
||||
}
|
||||
|
||||
public static ArenaDefinition LostLandsTrammel { get; set; }
|
||||
public static ArenaDefinition LostLandsFelucca { get; set; }
|
||||
public static ArenaDefinition HavenTrammel { get; set; }
|
||||
public static ArenaDefinition HavenFelucca { get; set; }
|
||||
|
||||
public static ArenaDefinition[] Definitions { get { return _Definitions; } }
|
||||
private static ArenaDefinition[] _Definitions = new ArenaDefinition[4];
|
||||
|
||||
static ArenaDefinition()
|
||||
{
|
||||
LostLandsTrammel = new ArenaDefinition("Lostland (T)", 1,
|
||||
new Point3D(6102, 3721, 25),
|
||||
new Point3D(6097, 3730, 20),
|
||||
new Point3D(6081, 3713, 26),
|
||||
new Point3D(6087, 3713, 26),
|
||||
17101,
|
||||
17099,
|
||||
new Rectangle2D[]
|
||||
{
|
||||
new Rectangle2D(6072, 3718, 24, 1),
|
||||
new Rectangle2D(6072, 3723, 24, 1),
|
||||
new Rectangle2D(6075, 3714, 1, 14),
|
||||
new Rectangle2D(6083, 3713, 1, 16),
|
||||
new Rectangle2D(6091, 3714, 1, 14),
|
||||
},
|
||||
new Rectangle2D[]
|
||||
{
|
||||
new Rectangle2D(6071, 3719, 4, 3),
|
||||
new Rectangle2D(6092, 3719, 4, 3),
|
||||
new Rectangle2D(6077, 3713, 5, 4),
|
||||
new Rectangle2D(6084, 3713, 5, 4),
|
||||
new Rectangle2D(6076, 3724, 5, 4),
|
||||
new Rectangle2D(6084, 3724, 5, 4),
|
||||
new Rectangle2D(6073, 3716, 1, 1),
|
||||
new Rectangle2D(6073, 3724, 1, 1),
|
||||
new Rectangle2D(6091, 3714, 2, 2),
|
||||
new Rectangle2D(6091, 3724, 2, 2),
|
||||
},
|
||||
new Point3D(6100, 3721, 25),
|
||||
new Rectangle2D[]
|
||||
{
|
||||
new Rectangle2D(6070, 3713, 27, 16)
|
||||
},
|
||||
new Rectangle2D[]
|
||||
{
|
||||
new Rectangle2D(6059, 3697, 53, 56)
|
||||
},
|
||||
new Rectangle2D(6099, 3718, 5, 7),
|
||||
new Rectangle2D(6097, 3729, 2, 2));
|
||||
|
||||
LostLandsFelucca = new ArenaDefinition("Lostland (F)", 0,
|
||||
new Point3D(6102, 3721, 25),
|
||||
new Point3D(6097, 3730, 20),
|
||||
new Point3D(6081, 3713, 26),
|
||||
new Point3D(6087, 3713, 26),
|
||||
17101,
|
||||
17099,
|
||||
new Rectangle2D[]
|
||||
{
|
||||
new Rectangle2D(6072, 3718, 24, 1),
|
||||
new Rectangle2D(6072, 3723, 24, 1),
|
||||
new Rectangle2D(6075, 3714, 1, 14),
|
||||
new Rectangle2D(6083, 3713, 1, 16),
|
||||
new Rectangle2D(6090, 3713, 1, 16),
|
||||
},
|
||||
new Rectangle2D[]
|
||||
{
|
||||
new Rectangle2D(6071, 3719, 4, 3),
|
||||
new Rectangle2D(6092, 3719, 4, 3),
|
||||
new Rectangle2D(6077, 3713, 5, 4),
|
||||
new Rectangle2D(6084, 3713, 5, 4),
|
||||
new Rectangle2D(6076, 3724, 5, 4),
|
||||
new Rectangle2D(6084, 3724, 5, 4),
|
||||
new Rectangle2D(6073, 3716, 1, 1),
|
||||
new Rectangle2D(6073, 3724, 1, 1),
|
||||
new Rectangle2D(6091, 3714, 2, 2),
|
||||
new Rectangle2D(6091, 3724, 2, 2),
|
||||
},
|
||||
new Point3D(6100, 3721, 25),
|
||||
new Rectangle2D[]
|
||||
{
|
||||
new Rectangle2D(6070, 3713, 27, 16)
|
||||
},
|
||||
new Rectangle2D[]
|
||||
{
|
||||
new Rectangle2D(6059, 3697, 53, 56)
|
||||
},
|
||||
new Rectangle2D(6099, 3718, 5, 7),
|
||||
new Rectangle2D(6097, 3729, 2, 2));
|
||||
|
||||
HavenTrammel = new ArenaDefinition("New Haven (T)", 1,
|
||||
new Point3D(3793, 2770, 6),
|
||||
new Point3D(3790, 2783, 6),
|
||||
new Point3D(3760, 2769, 12),
|
||||
new Point3D(3783, 2761, 10),
|
||||
17102,
|
||||
17099,
|
||||
new Rectangle2D[]
|
||||
{
|
||||
new Rectangle2D(3760, 2766, 25, 1),
|
||||
new Rectangle2D(3760, 2772, 25, 1),
|
||||
new Rectangle2D(3765, 2761, 1, 16),
|
||||
new Rectangle2D(3772, 2761, 1, 16),
|
||||
new Rectangle2D(3780, 2761, 1, 16),
|
||||
},
|
||||
new Rectangle2D[]
|
||||
{
|
||||
new Rectangle2D(3760, 2767, 4, 4),
|
||||
new Rectangle2D(3781, 2767, 3, 4),
|
||||
new Rectangle2D(3766, 2761, 4, 4),
|
||||
new Rectangle2D(3773, 2761, 4, 4),
|
||||
new Rectangle2D(3766, 2773, 4, 4),
|
||||
new Rectangle2D(3773, 2773, 4, 4),
|
||||
new Rectangle2D(3760, 2761, 3, 3),
|
||||
new Rectangle2D(3781, 2761, 3, 3),
|
||||
new Rectangle2D(3781, 2773, 3, 3),
|
||||
new Rectangle2D(3760, 2773, 3, 3),
|
||||
},
|
||||
new Point3D(3792, 2768, 6),
|
||||
new Rectangle2D[]
|
||||
{
|
||||
new Rectangle2D(3760, 2761, 25, 16)
|
||||
},
|
||||
new Rectangle2D[]
|
||||
{
|
||||
new Rectangle2D(3740, 2747, 63, 51)
|
||||
},
|
||||
new Rectangle2D(3791, 2766, 4, 9),
|
||||
new Rectangle2D(3790, 2781, 2, 5));
|
||||
|
||||
HavenFelucca = new ArenaDefinition("New Haven (F)", 0,
|
||||
new Point3D(3782, 2766, 5),
|
||||
new Point3D(3779, 2778, 5),
|
||||
new Point3D(3749, 2765, 12),
|
||||
new Point3D(3772, 2757, 10),
|
||||
17102,
|
||||
17099,
|
||||
new Rectangle2D[]
|
||||
{
|
||||
new Rectangle2D(3749, 2762, 25, 1),
|
||||
new Rectangle2D(3749, 2768, 25, 1),
|
||||
new Rectangle2D(3754, 2757, 1, 16),
|
||||
new Rectangle2D(3761, 2757, 1, 16),
|
||||
new Rectangle2D(3769, 2757, 1, 16),
|
||||
},
|
||||
new Rectangle2D[]
|
||||
{
|
||||
new Rectangle2D(3749, 2763, 4, 4),
|
||||
new Rectangle2D(3770, 2763, 3, 4),
|
||||
new Rectangle2D(3755, 2757, 4, 4),
|
||||
new Rectangle2D(3762, 2757, 4, 4),
|
||||
new Rectangle2D(3755, 2769, 4, 4),
|
||||
new Rectangle2D(3762, 2769, 4, 4),
|
||||
new Rectangle2D(3749, 2757, 3, 3),
|
||||
new Rectangle2D(3770, 2757, 3, 3),
|
||||
new Rectangle2D(3770, 2769, 3, 3),
|
||||
new Rectangle2D(3759, 2769, 3, 3),
|
||||
},
|
||||
new Point3D(3781, 2764, 5),
|
||||
new Rectangle2D[]
|
||||
{
|
||||
new Rectangle2D(3749, 2757, 25, 16)
|
||||
},
|
||||
new Rectangle2D[]
|
||||
{
|
||||
new Rectangle2D(3735, 2747, 68, 51)
|
||||
},
|
||||
new Rectangle2D(3780, 2763, 4, 9),
|
||||
new Rectangle2D(3779, 2776, 2, 5));
|
||||
|
||||
_Definitions[0] = LostLandsTrammel;
|
||||
_Definitions[1] = LostLandsFelucca;
|
||||
_Definitions[2] = HavenTrammel;
|
||||
_Definitions[3] = HavenFelucca;
|
||||
}
|
||||
}
|
||||
}
|
||||
1562
Scripts/Services/PVP Arena System/Gumps.cs
Normal file
1562
Scripts/Services/PVP Arena System/Gumps.cs
Normal file
File diff suppressed because it is too large
Load Diff
512
Scripts/Services/PVP Arena System/PVPArena.cs
Normal file
512
Scripts/Services/PVP Arena System/PVPArena.cs
Normal file
@@ -0,0 +1,512 @@
|
||||
using Server;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using System.Linq;
|
||||
using Server.Regions;
|
||||
|
||||
namespace Server.Engines.ArenaSystem
|
||||
{
|
||||
[PropertyObject]
|
||||
public class PVPArena
|
||||
{
|
||||
public static TimeSpan PendingDuelExpirationTime = TimeSpan.FromMinutes(10);
|
||||
public static TimeSpan BookedDuelBegin = TimeSpan.FromSeconds(10);
|
||||
public static int StartRank = 10000;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public ArenaManager Manager { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public ArenaStone Stone { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public ArenaExitBanner Banner1 { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public ArenaExitBanner Banner2 { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public ArenaDefinition Definition { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool InUse { get { return CurrentDuel != null; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public ArenaDuel CurrentDuel { get; set; }
|
||||
|
||||
public ArenaRegion Region { get; set; }
|
||||
public GuardedRegion GuardRegion { get; set; }
|
||||
|
||||
public Dictionary<ArenaDuel, DateTime> PendingDuels { get; set; }
|
||||
public List<ArenaDuel> BookedDuels { get; set; }
|
||||
public List<Item> Blockers { get; set; }
|
||||
|
||||
public List<ArenaStats> TeamRankings { get; set; }
|
||||
public List<ArenaStats> SurvivalRankings { get; set; }
|
||||
|
||||
public PVPArena(ArenaDefinition definition)
|
||||
{
|
||||
Definition = definition;
|
||||
|
||||
PendingDuels = new Dictionary<ArenaDuel, DateTime>();
|
||||
BookedDuels = new List<ArenaDuel>();
|
||||
Blockers = new List<Item>();
|
||||
|
||||
TeamRankings = new List<ArenaStats>();
|
||||
SurvivalRankings = new List<ArenaStats>();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "...";
|
||||
}
|
||||
|
||||
public void ConfigureArena()
|
||||
{
|
||||
if (Manager == null)
|
||||
{
|
||||
Manager = new ArenaManager(this);
|
||||
Manager.MoveToWorld(Definition.ManagerLocation, Definition.Map);
|
||||
}
|
||||
|
||||
if (Stone == null)
|
||||
{
|
||||
Stone = new ArenaStone(this);
|
||||
Stone.MoveToWorld(Definition.StoneLocation, Definition.Map);
|
||||
}
|
||||
|
||||
if (Banner1 == null)
|
||||
{
|
||||
Banner1 = new ArenaExitBanner(Definition.BannerID1, this);
|
||||
Banner1.MoveToWorld(Definition.BannerLocation1, Definition.Map);
|
||||
}
|
||||
|
||||
if (Banner2 == null)
|
||||
{
|
||||
Banner2 = new ArenaExitBanner(Definition.BannerID2, this);
|
||||
Banner2.MoveToWorld(Definition.BannerLocation2, Definition.Map);
|
||||
}
|
||||
|
||||
if (Region == null)
|
||||
{
|
||||
Region = new ArenaRegion(this);
|
||||
Region.Register();
|
||||
}
|
||||
|
||||
if (GuardRegion == null)
|
||||
{
|
||||
GuardRegion = new GuardedArenaRegion(String.Format("{0}_Guarded", Definition.Name), Definition.Map, Definition.GuardBounds);
|
||||
GuardRegion.Register();
|
||||
}
|
||||
}
|
||||
|
||||
public void Unregister()
|
||||
{
|
||||
if (Region != null)
|
||||
{
|
||||
Region.Unregister();
|
||||
Region = null;
|
||||
}
|
||||
|
||||
if (GuardRegion != null)
|
||||
{
|
||||
GuardRegion.Unregister();
|
||||
GuardRegion = null;
|
||||
}
|
||||
|
||||
if (Manager != null)
|
||||
{
|
||||
Manager.Delete();
|
||||
}
|
||||
|
||||
if (Stone != null && !Stone.Deleted)
|
||||
{
|
||||
Stone.Delete();
|
||||
}
|
||||
|
||||
if (Banner1 != null)
|
||||
{
|
||||
Banner1.Delete();
|
||||
}
|
||||
|
||||
if (Banner2 != null)
|
||||
{
|
||||
Banner2.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
private List<ArenaDuel> _Remove = new List<ArenaDuel>();
|
||||
|
||||
public void OnTick()
|
||||
{
|
||||
if (CurrentDuel != null)
|
||||
{
|
||||
CurrentDuel.OnTick();
|
||||
}
|
||||
|
||||
foreach (var kvp in PendingDuels)
|
||||
{
|
||||
if (kvp.Value < DateTime.UtcNow)
|
||||
{
|
||||
_Remove.Add(kvp.Key);
|
||||
}
|
||||
}
|
||||
|
||||
if (_Remove.Count > 0)
|
||||
{
|
||||
foreach (var duel in _Remove)
|
||||
{
|
||||
if (PendingDuels.ContainsKey(duel))
|
||||
PendingDuels.Remove(duel);
|
||||
}
|
||||
|
||||
_Remove.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void AddPendingDuel(ArenaDuel duel)
|
||||
{
|
||||
if (!PendingDuels.ContainsKey(duel))
|
||||
{
|
||||
PendingDuels[duel] = DateTime.UtcNow + PendingDuelExpirationTime;
|
||||
}
|
||||
}
|
||||
|
||||
public void RemovePendingDuel(ArenaDuel duel, bool cancel = false)
|
||||
{
|
||||
if(PendingDuels.ContainsKey(duel))
|
||||
{
|
||||
PendingDuels.Remove(duel);
|
||||
|
||||
if (cancel)
|
||||
{
|
||||
PVPArenaSystem.SendParticipantMessage(duel, 1115947); // The session owner has canceled the duel.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ArenaDuel GetPendingDuel(Mobile m)
|
||||
{
|
||||
return PendingDuels.Keys.FirstOrDefault(d => m is PlayerMobile && d.IsParticipant((PlayerMobile)m));
|
||||
}
|
||||
|
||||
public List<ArenaDuel> GetPendingPublic()
|
||||
{
|
||||
return PendingDuels.Keys.Where(d => d.RoomType == RoomType.Public && d.ParticipantCount < d.Entries).ToList();
|
||||
}
|
||||
|
||||
public void TryBeginDuel(ArenaDuel duel)
|
||||
{
|
||||
if (PendingDuels.ContainsKey(duel))
|
||||
{
|
||||
PendingDuels.Remove(duel);
|
||||
}
|
||||
|
||||
if (CurrentDuel == null && BookedDuels.Count == 0)
|
||||
{
|
||||
CurrentDuel = duel;
|
||||
duel.DoPreDuel();
|
||||
}
|
||||
else
|
||||
{
|
||||
BookedDuels.Add(duel);
|
||||
PVPArenaSystem.SendParticipantMessage(duel, 1115960); // There are currently no open arenas. Your duel session has been added to the booking queue.
|
||||
}
|
||||
}
|
||||
|
||||
public void OnDuelEnd(ArenaDuel duel)
|
||||
{
|
||||
CurrentDuel = null;
|
||||
|
||||
foreach (var corpse in Region.GetEnumeratedItems().OfType<Corpse>())
|
||||
{
|
||||
if (corpse.Owner != null && corpse.Owner.InRange(corpse.Location, 30))
|
||||
{
|
||||
corpse.MoveToWorld(corpse.Owner.Location, corpse.Owner.Map);
|
||||
}
|
||||
else
|
||||
{
|
||||
corpse.MoveToWorld(GetRandomRemovalLocation(), Definition.Map);
|
||||
}
|
||||
}
|
||||
|
||||
if (BookedDuels.Count > 0)
|
||||
{
|
||||
var newDuel = BookedDuels[0];
|
||||
CurrentDuel = newDuel;
|
||||
|
||||
PVPArenaSystem.SendParticipantMessage(newDuel, 1153141); // Your session has been booked. Please wait a few moments to start the fight.
|
||||
|
||||
Timer.DelayCall(BookedDuelBegin, () =>
|
||||
{
|
||||
newDuel.DoPreDuel();
|
||||
});
|
||||
|
||||
BookedDuels.Remove(newDuel);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemovePlayer(Mobile m, bool winner = false)
|
||||
{
|
||||
Map map = Definition.Map;
|
||||
Point3D p = GetRandomRemovalLocation(m);
|
||||
|
||||
m.MoveToWorld(p, map);
|
||||
m.Delta(MobileDelta.Noto);
|
||||
|
||||
// lets remove pets, too
|
||||
if (m is PlayerMobile && ((PlayerMobile)m).AllFollowers.Count > 0)
|
||||
{
|
||||
foreach (var mob in ((PlayerMobile)m).AllFollowers.Where(pet => pet.Region.IsPartOf<ArenaRegion>()))
|
||||
{
|
||||
mob.MoveToWorld(p, map);
|
||||
mob.Delta(MobileDelta.Noto);
|
||||
}
|
||||
}
|
||||
|
||||
if(winner)
|
||||
{
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
Timer.DelayCall(TimeSpan.FromMilliseconds(i * 1000), () =>
|
||||
{
|
||||
m.FixedParticles(0x373A, 10, 15, 5018, 0x36, 0, EffectLayer.Waist);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (!m.Alive)
|
||||
{
|
||||
IPooledEnumerable eable = map.GetMobilesInRange(m.Location, 5);
|
||||
|
||||
foreach(Mobile mob in eable)
|
||||
{
|
||||
if (mob is ArenaManager)
|
||||
{
|
||||
((ArenaManager)mob).OfferResurrection(m);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
}
|
||||
|
||||
private Point3D GetRandomRemovalLocation(Mobile m = null)
|
||||
{
|
||||
Rectangle2D rec = (m == null || m.Alive) ? Definition.EjectLocation : Definition.DeadEjectLocation;
|
||||
Point3D loc = (m == null || m.Alive) ? Definition.StoneLocation : Definition.ManagerLocation;
|
||||
Point3D p = loc;
|
||||
|
||||
Map map = Definition.Map;
|
||||
|
||||
while (p == loc || !map.CanSpawnMobile(p.X, p.Y, p.Z))
|
||||
{
|
||||
p = map.GetRandomSpawnPoint(rec);
|
||||
|
||||
if (m == null || m.Alive)
|
||||
p.Z = Definition.StoneLocation.Z;
|
||||
else
|
||||
p.Z = Definition.ManagerLocation.Z;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
public void RecordRankings(ArenaDuel duel, ArenaTeam winners)
|
||||
{
|
||||
List<ArenaStats> rankings;
|
||||
|
||||
if (duel.BattleMode == BattleMode.Team)
|
||||
rankings = TeamRankings;
|
||||
else
|
||||
rankings = SurvivalRankings;
|
||||
|
||||
foreach (var part in duel.GetParticipants())
|
||||
{
|
||||
var pm = part.Key;
|
||||
ArenaStats stats = rankings.FirstOrDefault(r => r.Owner == pm);
|
||||
|
||||
if (stats == null)
|
||||
{
|
||||
stats = new ArenaStats(pm);
|
||||
rankings.Add(stats);
|
||||
}
|
||||
|
||||
var team = duel.GetTeam(pm);
|
||||
|
||||
if (team != winners)
|
||||
{
|
||||
stats.Ranking -= 33;
|
||||
}
|
||||
else
|
||||
{
|
||||
stats.Ranking += 33;
|
||||
}
|
||||
}
|
||||
|
||||
rankings.Sort();
|
||||
}
|
||||
|
||||
public void Serialize(GenericWriter writer)
|
||||
{
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(SurvivalRankings.Count);
|
||||
foreach (var ranking in SurvivalRankings)
|
||||
{
|
||||
ranking.Serialize(writer);
|
||||
}
|
||||
|
||||
writer.Write(TeamRankings.Count);
|
||||
foreach (var ranking in TeamRankings)
|
||||
{
|
||||
ranking.Serialize(writer);
|
||||
}
|
||||
|
||||
writer.Write(Blockers.Count);
|
||||
foreach (var blocker in Blockers)
|
||||
{
|
||||
writer.Write(blocker);
|
||||
}
|
||||
|
||||
writer.Write(Stone);
|
||||
writer.Write(Manager);
|
||||
writer.Write(Banner1);
|
||||
writer.Write(Banner2);
|
||||
|
||||
writer.Write(PendingDuels.Count);
|
||||
foreach (var kvp in PendingDuels)
|
||||
{
|
||||
kvp.Key.Serialize(writer);
|
||||
writer.WriteDeltaTime(kvp.Value);
|
||||
}
|
||||
|
||||
writer.Write(BookedDuels.Count);
|
||||
foreach (var duel in BookedDuels)
|
||||
{
|
||||
duel.Serialize(writer);
|
||||
}
|
||||
|
||||
if (CurrentDuel != null)
|
||||
{
|
||||
writer.Write(1);
|
||||
CurrentDuel.Serialize(writer);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write(0);
|
||||
}
|
||||
}
|
||||
|
||||
public void Deserialize(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadInt();
|
||||
|
||||
int count = reader.ReadInt();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
ArenaStats stats = new ArenaStats(reader);
|
||||
|
||||
if (stats.Owner != null)
|
||||
SurvivalRankings.Add(stats);
|
||||
}
|
||||
|
||||
count = reader.ReadInt();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
ArenaStats stats = new ArenaStats(reader);
|
||||
|
||||
if (stats.Owner != null)
|
||||
TeamRankings.Add(stats);
|
||||
}
|
||||
|
||||
count = reader.ReadInt();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Item blocker = reader.ReadItem();
|
||||
|
||||
if (blocker != null)
|
||||
Blockers.Add(blocker);
|
||||
}
|
||||
|
||||
Stone = reader.ReadItem() as ArenaStone;
|
||||
Manager = reader.ReadMobile() as ArenaManager;
|
||||
Banner1 = reader.ReadItem() as ArenaExitBanner;
|
||||
Banner2 = reader.ReadItem() as ArenaExitBanner;
|
||||
|
||||
count = reader.ReadInt();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
ArenaDuel duel = new ArenaDuel(reader, this);
|
||||
DateTime dt = reader.ReadDeltaTime();
|
||||
|
||||
PendingDuels[duel] = dt;
|
||||
}
|
||||
|
||||
count = reader.ReadInt();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
BookedDuels.Add(new ArenaDuel(reader, this));
|
||||
}
|
||||
|
||||
if (reader.ReadInt() == 1)
|
||||
{
|
||||
CurrentDuel = new ArenaDuel(reader, this);
|
||||
}
|
||||
|
||||
if (Stone != null)
|
||||
Stone.Arena = this;
|
||||
|
||||
if (Manager != null)
|
||||
Manager.Arena = this;
|
||||
|
||||
if (Banner1 != null)
|
||||
Banner1.Arena = this;
|
||||
|
||||
if (Banner2 != null)
|
||||
Banner2.Arena = this;
|
||||
}
|
||||
}
|
||||
|
||||
public class ArenaStats : IComparable<ArenaStats>
|
||||
{
|
||||
public PlayerMobile Owner { get; set; }
|
||||
public int Ranking { get; set; }
|
||||
|
||||
public ArenaStats(PlayerMobile pm)
|
||||
{
|
||||
Owner = pm;
|
||||
Ranking = 10000;
|
||||
}
|
||||
|
||||
public int CompareTo(ArenaStats stats)
|
||||
{
|
||||
if(Ranking > stats.Ranking)
|
||||
return -1;
|
||||
|
||||
if(Ranking < stats.Ranking)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public ArenaStats(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Owner = reader.ReadMobile() as PlayerMobile;
|
||||
Ranking = reader.ReadInt();
|
||||
}
|
||||
|
||||
public void Serialize(GenericWriter writer)
|
||||
{
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(Owner);
|
||||
writer.Write(Ranking);
|
||||
}
|
||||
}
|
||||
}
|
||||
646
Scripts/Services/PVP Arena System/PVPArenaSystem.cs
Normal file
646
Scripts/Services/PVP Arena System/PVPArenaSystem.cs
Normal file
@@ -0,0 +1,646 @@
|
||||
using Server;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Engines.Points;
|
||||
using System.Linq;
|
||||
using Server.Commands;
|
||||
using Server.Gumps;
|
||||
|
||||
//TODO: Party: 1152064 You cannot invite other players in an arena to your party!
|
||||
namespace Server.Engines.ArenaSystem
|
||||
{
|
||||
public class PVPArenaSystem : PointsSystem
|
||||
{
|
||||
public static PVPArenaSystem Instance { get; set; }
|
||||
public static bool Enabled { get { return Core.HS; } }
|
||||
public static bool BlockSameIP { get { return true; } }
|
||||
|
||||
public override PointsType Loyalty { get { return PointsType.PVPArena; } }
|
||||
public override TextDefinition Name { get { return m_Name; } }
|
||||
public override bool AutoAdd { get { return true; } }
|
||||
public override double MaxPoints { get { return double.MaxValue; } }
|
||||
|
||||
public override bool ShowOnLoyaltyGump { get { return false; } }
|
||||
private TextDefinition m_Name = new TextDefinition("Arena Stats");
|
||||
|
||||
public static List<PVPArena> Arenas { get; set; }
|
||||
public static List<string> BlockedArenas { get; set; }
|
||||
|
||||
public static bool SystemInitialized { get; set; }
|
||||
|
||||
public PVPArenaSystem()
|
||||
{
|
||||
Instance = this;
|
||||
|
||||
if (Enabled)
|
||||
{
|
||||
CommandSystem.Register("ResetArenaStats", AccessLevel.Administrator, ResetStats_OnTarget);
|
||||
CommandSystem.Register("ArenaSetup", AccessLevel.Administrator, ArenaSetup);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnTick()
|
||||
{
|
||||
Arenas.ForEach(a => a.OnTick());
|
||||
}
|
||||
|
||||
public List<ArenaDuel> GetBookedDuels()
|
||||
{
|
||||
List<ArenaDuel> booked = new List<ArenaDuel>();
|
||||
|
||||
foreach (var arena in Arenas.Where(a => a.BookedDuels.Count > 0))
|
||||
{
|
||||
booked.AddRange(arena.BookedDuels);
|
||||
}
|
||||
|
||||
return booked;
|
||||
}
|
||||
|
||||
public ArenaDuel GetBookedDuel(PlayerMobile pm)
|
||||
{
|
||||
foreach (var arena in Arenas.Where(a => a.BookedDuels.Count > 0))
|
||||
{
|
||||
foreach (var duel in arena.BookedDuels.Where(d => d.IsParticipant(pm)))
|
||||
{
|
||||
return duel;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public override void SendMessage(PlayerMobile from, double old, double points, bool quest)
|
||||
{
|
||||
}
|
||||
|
||||
public override TextDefinition GetTitle(PlayerMobile from)
|
||||
{
|
||||
return new TextDefinition("Arena Stats");
|
||||
}
|
||||
|
||||
public override PointsEntry GetSystemEntry(PlayerMobile pm)
|
||||
{
|
||||
return new PlayerStatsEntry(pm);
|
||||
}
|
||||
|
||||
public void Register(PVPArena arena)
|
||||
{
|
||||
if (Arenas == null)
|
||||
Arenas = new List<PVPArena>();
|
||||
|
||||
if (!Arenas.Contains(arena))
|
||||
Arenas.Add(arena);
|
||||
}
|
||||
|
||||
public void Unregister(PVPArena arena)
|
||||
{
|
||||
if (Arenas != null)
|
||||
{
|
||||
Arenas.Remove(arena);
|
||||
}
|
||||
|
||||
arena.Unregister();
|
||||
}
|
||||
|
||||
public void AddBlockedArena(PVPArena arena)
|
||||
{
|
||||
if (BlockedArenas == null)
|
||||
{
|
||||
BlockedArenas = new List<string>();
|
||||
}
|
||||
|
||||
if (!IsBlocked(arena.Definition))
|
||||
{
|
||||
Utility.WriteConsoleColor(ConsoleColor.Green, "Adding blocked EA PVP Arena: {0}", arena.Definition.Name);
|
||||
BlockedArenas.Add(arena.Definition.Name);
|
||||
Unregister(arena);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveBlockedArena(ArenaDefinition def)
|
||||
{
|
||||
if (BlockedArenas == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BlockedArenas.Remove(def.Name);
|
||||
|
||||
if (Arenas == null || Arenas.Count == 0)
|
||||
{
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), () => Instance.OnTick());
|
||||
}
|
||||
|
||||
var arena = new PVPArena(def);
|
||||
Instance.Register(arena);
|
||||
Utility.WriteConsoleColor(ConsoleColor.Green, "Removing blocked EA PVP Arena: {0}", arena.Definition.Name);
|
||||
arena.ConfigureArena();
|
||||
}
|
||||
|
||||
public bool IsBlocked(ArenaDefinition def)
|
||||
{
|
||||
return BlockedArenas != null && BlockedArenas.Contains(def.Name);
|
||||
}
|
||||
|
||||
public static bool IsEnemy(Mobile source, Mobile target)
|
||||
{
|
||||
var sourceRegion = Region.Find(source.Location, source.Map) as ArenaRegion;
|
||||
var targetRegion = Region.Find(target.Location, target.Map) as ArenaRegion;
|
||||
|
||||
if (sourceRegion != null && sourceRegion.Arena.CurrentDuel != null && sourceRegion == targetRegion)
|
||||
{
|
||||
return sourceRegion.Arena.CurrentDuel.IsEnemy(source, target);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool IsFriendly(Mobile source, Mobile target)
|
||||
{
|
||||
var sourceRegion = Region.Find(source.Location, source.Map) as ArenaRegion;
|
||||
var targetRegion = Region.Find(target.Location, target.Map) as ArenaRegion;
|
||||
|
||||
if (sourceRegion != null && sourceRegion.Arena.CurrentDuel != null && sourceRegion == targetRegion)
|
||||
{
|
||||
return sourceRegion.Arena.CurrentDuel.IsFriendly(source, target);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(2);
|
||||
|
||||
writer.Write(BlockedArenas == null ? 0 : BlockedArenas.Count);
|
||||
|
||||
if (BlockedArenas != null)
|
||||
{
|
||||
for (int i = 0; i < BlockedArenas.Count; i++)
|
||||
{
|
||||
writer.Write(BlockedArenas[i]);
|
||||
}
|
||||
}
|
||||
|
||||
writer.Write(Arenas == null ? 0 : Arenas.Count);
|
||||
|
||||
if (Arenas != null)
|
||||
{
|
||||
for (int i = 0; i < Arenas.Count; i++)
|
||||
{
|
||||
writer.Write(Arenas[i].Definition.Name);
|
||||
Arenas[i].Serialize(writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
SystemInitialized = true;
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
if (version < 2)
|
||||
{
|
||||
InitializeArenas();
|
||||
}
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 2:
|
||||
case 1:
|
||||
int c = reader.ReadInt();
|
||||
|
||||
for (int i = 0; i < c; i++)
|
||||
{
|
||||
if (BlockedArenas == null)
|
||||
BlockedArenas = new List<string>();
|
||||
|
||||
BlockedArenas.Add(reader.ReadString());
|
||||
}
|
||||
goto case 0;
|
||||
case 0:
|
||||
int count = reader.ReadInt();
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (Arenas == null)
|
||||
Arenas = new List<PVPArena>();
|
||||
|
||||
if (version >= 2)
|
||||
{
|
||||
var arena = new PVPArena(GetDefinition(reader.ReadString()));
|
||||
Register(arena);
|
||||
arena.Deserialize(reader);
|
||||
}
|
||||
else
|
||||
{
|
||||
Arenas[i].Deserialize(reader);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private ArenaDefinition GetDefinition(string name)
|
||||
{
|
||||
var def = ArenaDefinition.Definitions.FirstOrDefault(d => d.Name == name);
|
||||
|
||||
if (def == null)
|
||||
{
|
||||
return ArenaDefinition.Definitions[0];
|
||||
}
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
public static void SendMessage(Mobile from, string message, int hue = 0x1F)
|
||||
{
|
||||
from.SendMessage(hue, message);
|
||||
}
|
||||
|
||||
public static void SendMessage(Mobile from, int message, string args = "", int hue = 0x1F)
|
||||
{
|
||||
from.SendLocalizedMessage(message, args, hue);
|
||||
}
|
||||
|
||||
public static void SendParticipantMessage(ArenaDuel duel, int message, bool inRegion = false, string args = "", int hue = 0x1F)
|
||||
{
|
||||
foreach (var part in duel.GetParticipants(inRegion))
|
||||
{
|
||||
SendMessage(part.Key, message, args, hue);
|
||||
}
|
||||
}
|
||||
|
||||
public void CheckTitle(PlayerMobile pm)
|
||||
{
|
||||
var entry = GetPlayerEntry<PlayerStatsEntry>(pm);
|
||||
int title = 0;
|
||||
|
||||
switch (entry.TotalDuels)
|
||||
{
|
||||
case 1: title = 1152068 + (int)ArenaTitle.FledglingGladiator; break;
|
||||
case 50: title = 1152068 + (int)ArenaTitle.BuddingGladiator; break;
|
||||
case 100: title = 1152068 + (int)ArenaTitle.Gladiator; break;
|
||||
case 250: title = 1152068 + (int)ArenaTitle.WellKnownGladiator; break;
|
||||
case 500: title = 1152068 + (int)ArenaTitle.VeteranGladiator; break;
|
||||
}
|
||||
|
||||
if (title > 0)
|
||||
{
|
||||
pm.AddRewardTitle(title);
|
||||
pm.SendLocalizedMessage(1152067, String.Format("#{0}", title.ToString())); // You have gotten a new subtitle, ~1_VAL~, in reward for your duel!
|
||||
}
|
||||
}
|
||||
|
||||
public static bool HasSameIP(Mobile m, ArenaDuel duel)
|
||||
{
|
||||
if (duel == null || m.AccessLevel > AccessLevel.Player)
|
||||
return false;
|
||||
|
||||
foreach (var kvp in duel.GetParticipants())
|
||||
{
|
||||
if (IsSameIP(m, kvp.Key))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool IsSameIP(Mobile one, Mobile two)
|
||||
{
|
||||
if (one.NetState == null || two.NetState == null || one.AccessLevel > AccessLevel.Player || two.AccessLevel > AccessLevel.Player)
|
||||
return false;
|
||||
|
||||
var oneAddress = one.NetState.Address;
|
||||
var twoAddress = two.NetState.Address;
|
||||
|
||||
return one.NetState.Address == two.NetState.Address;
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
if (Enabled)
|
||||
{
|
||||
if (!SystemInitialized)
|
||||
{
|
||||
InitializeArenas();
|
||||
SystemInitialized = true;
|
||||
}
|
||||
|
||||
if (Arenas != null)
|
||||
{
|
||||
foreach (var arena in Arenas)
|
||||
{
|
||||
arena.ConfigureArena();
|
||||
}
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), () => Instance.OnTick());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void InitializeArenas()
|
||||
{
|
||||
if (CanInitialize(ArenaDefinition.LostLandsTrammel))
|
||||
{
|
||||
Instance.Register(new PVPArena(ArenaDefinition.LostLandsTrammel));
|
||||
}
|
||||
|
||||
if (CanInitialize(ArenaDefinition.LostLandsFelucca))
|
||||
{
|
||||
Instance.Register(new PVPArena(ArenaDefinition.LostLandsFelucca));
|
||||
}
|
||||
|
||||
if (CanInitialize(ArenaDefinition.HavenTrammel))
|
||||
{
|
||||
Instance.Register(new PVPArena(ArenaDefinition.HavenTrammel));
|
||||
}
|
||||
|
||||
if (CanInitialize(ArenaDefinition.HavenFelucca))
|
||||
{
|
||||
Instance.Register(new PVPArena(ArenaDefinition.HavenFelucca));
|
||||
}
|
||||
}
|
||||
|
||||
private static bool CanInitialize(ArenaDefinition def)
|
||||
{
|
||||
return !Instance.IsBlocked(def) && (Arenas == null || !Arenas.Any(arena => arena.Definition == def));
|
||||
}
|
||||
|
||||
[Usage("ArenaSetup")]
|
||||
[Description("Gives gump for arena setup.")]
|
||||
public static void ArenaSetup(CommandEventArgs e)
|
||||
{
|
||||
var pm = e.Mobile as PlayerMobile;
|
||||
|
||||
if(pm != null)
|
||||
{
|
||||
BaseGump.SendGump(new PVPArenaSystemSetupGump(pm));
|
||||
}
|
||||
}
|
||||
|
||||
[Usage("ResetArenaStats")]
|
||||
[Description("Target an arena stone to reset/wipe the stats associated with that arena.")]
|
||||
public static void ResetStats_OnTarget(CommandEventArgs e)
|
||||
{
|
||||
Mobile m = e.Mobile;
|
||||
|
||||
m.BeginTarget(-1, false, Server.Targeting.TargetFlags.None, (fro, targeted) =>
|
||||
{
|
||||
if (m is PlayerMobile && targeted is ArenaStone)
|
||||
{
|
||||
var stone = (ArenaStone)targeted;
|
||||
|
||||
if (stone.Arena != null)
|
||||
{
|
||||
var arena = stone.Arena;
|
||||
|
||||
BaseGump.SendGump(new GenericConfirmCallbackGump<PVPArena>((PlayerMobile)m,
|
||||
String.Format("Reset {0} Statistics?", arena.Definition.Name),
|
||||
"By selecting yes, you will permanently wipe the stats associated to this arena.",
|
||||
arena,
|
||||
null,
|
||||
(from, a) =>
|
||||
{
|
||||
ColUtility.Free(a.TeamRankings);
|
||||
ColUtility.Free(a.SurvivalRankings);
|
||||
from.SendMessage("Arena stats cleared.");
|
||||
}));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class PlayerStatsEntry : PointsEntry
|
||||
{
|
||||
public int SurvivalWins { get; set; }
|
||||
public int SurvivalLosses { get; set; }
|
||||
public int SurvivalDraws { get; set; }
|
||||
|
||||
public int TeamWins { get; set; }
|
||||
public int TeamLosses { get; set; }
|
||||
public int TeamDraws { get; set; }
|
||||
|
||||
public int Kills { get; set; }
|
||||
public int Deaths { get; set; }
|
||||
|
||||
public bool IgnoreInvites { get; set; }
|
||||
public bool OpenStats { get; set; }
|
||||
|
||||
public int TotalDuels { get { return SurvivalWins + SurvivalLosses + SurvivalDraws + TeamWins + TeamLosses + TeamDraws; } }
|
||||
|
||||
public List<DuelRecord> Record { get; set; }
|
||||
|
||||
public DuelProfile Profile { get; set; }
|
||||
|
||||
public PlayerStatsEntry(PlayerMobile pm)
|
||||
: base(pm)
|
||||
{
|
||||
IgnoreInvites = true;
|
||||
OpenStats = true;
|
||||
|
||||
Record = new List<DuelRecord>();
|
||||
}
|
||||
|
||||
public void HandleDeath(Mobile m, bool killedBy)
|
||||
{
|
||||
Record.Add(new DuelRecord(m, killedBy));
|
||||
|
||||
if (Record.Count > 12)
|
||||
{
|
||||
Record.RemoveAt(12);
|
||||
}
|
||||
}
|
||||
|
||||
// Rating, seems to start at 10000, then +33 for win, -33 for loss
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
|
||||
if (Profile != null)
|
||||
{
|
||||
writer.Write(1);
|
||||
Profile.Serialize(writer);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
writer.Write(Record.Count);
|
||||
for (int i = 0; i < Record.Count; i++)
|
||||
{
|
||||
Record[i].Serialize(writer);
|
||||
}
|
||||
|
||||
writer.Write(OpenStats);
|
||||
writer.Write(IgnoreInvites);
|
||||
|
||||
writer.Write(SurvivalWins);
|
||||
writer.Write(SurvivalLosses);
|
||||
writer.Write(SurvivalDraws);
|
||||
|
||||
writer.Write(TeamWins);
|
||||
writer.Write(TeamLosses);
|
||||
writer.Write(TeamDraws);
|
||||
|
||||
writer.Write(Kills);
|
||||
writer.Write(Deaths);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Record = new List<DuelRecord>();
|
||||
|
||||
if (reader.ReadInt() == 1)
|
||||
{
|
||||
Profile = new DuelProfile(reader);
|
||||
}
|
||||
|
||||
int count = reader.ReadInt();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Record.Add(new DuelRecord(reader));
|
||||
}
|
||||
|
||||
OpenStats = reader.ReadBool();
|
||||
IgnoreInvites = reader.ReadBool();
|
||||
|
||||
SurvivalWins = reader.ReadInt();
|
||||
SurvivalLosses = reader.ReadInt();
|
||||
SurvivalDraws = reader.ReadInt();
|
||||
|
||||
TeamWins = reader.ReadInt();
|
||||
TeamLosses = reader.ReadInt();
|
||||
TeamDraws = reader.ReadInt();
|
||||
|
||||
Kills = reader.ReadInt();
|
||||
Deaths = reader.ReadInt();
|
||||
}
|
||||
|
||||
public class DuelRecord
|
||||
{
|
||||
public Mobile Opponent { get; set; }
|
||||
public bool KilledBy { get; set; }
|
||||
public DateTime DuelDate { get; set; }
|
||||
|
||||
public DuelRecord(Mobile opponent, bool killedBy)
|
||||
{
|
||||
Opponent = opponent;
|
||||
KilledBy = killedBy;
|
||||
DuelDate = DateTime.Now;
|
||||
}
|
||||
|
||||
public DuelRecord(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Opponent = reader.ReadMobile();
|
||||
KilledBy = reader.ReadBool();
|
||||
DuelDate = reader.ReadDateTime();
|
||||
}
|
||||
|
||||
public void Serialize(GenericWriter writer)
|
||||
{
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(Opponent);
|
||||
writer.Write(KilledBy);
|
||||
writer.Write(DuelDate);
|
||||
}
|
||||
}
|
||||
|
||||
public class DuelProfile
|
||||
{
|
||||
public int Entries { get; set; }
|
||||
public RoomType RoomType { get; set; }
|
||||
public BattleMode BattleMode { get; set; }
|
||||
public bool Ranked { get; set; }
|
||||
public TimeLimit TimeLimit { get; set; }
|
||||
public EntryFee EntryFee { get; set; }
|
||||
public int PetSlots { get; set; }
|
||||
public bool RidingFlyingAllowed { get; set; }
|
||||
public bool RangedWeaponsAllowed { get; set; }
|
||||
public bool SummonSpellsAllowed { get; set; }
|
||||
public bool FieldSpellsAllowed { get; set; }
|
||||
public PotionRules PotionRules { get; set; }
|
||||
|
||||
public DuelProfile(ArenaDuel duel)
|
||||
{
|
||||
Entries = duel.Entries;
|
||||
RoomType = duel.RoomType;
|
||||
BattleMode = duel.BattleMode;
|
||||
Ranked = duel.Ranked;
|
||||
TimeLimit = duel.TimeLimit;
|
||||
EntryFee = duel.EntryFee;
|
||||
PetSlots = duel.PetSlots;
|
||||
RidingFlyingAllowed = duel.RidingFlyingAllowed;
|
||||
RangedWeaponsAllowed = duel.RangedWeaponsAllowed;
|
||||
SummonSpellsAllowed = duel.SummonSpellsAllowed;
|
||||
FieldSpellsAllowed = duel.FieldSpellsAllowed;
|
||||
PotionRules = duel.PotionRules;
|
||||
}
|
||||
|
||||
public DuelProfile(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Entries = reader.ReadInt();
|
||||
RoomType = (RoomType)reader.ReadInt();
|
||||
BattleMode = (BattleMode)reader.ReadInt();
|
||||
Ranked = reader.ReadBool();
|
||||
TimeLimit = (TimeLimit)reader.ReadInt();
|
||||
EntryFee = (EntryFee)reader.ReadInt();
|
||||
PetSlots = reader.ReadInt();
|
||||
RidingFlyingAllowed = reader.ReadBool();
|
||||
RangedWeaponsAllowed = reader.ReadBool();
|
||||
SummonSpellsAllowed = reader.ReadBool();
|
||||
FieldSpellsAllowed = reader.ReadBool();
|
||||
PotionRules = (PotionRules)reader.ReadInt();
|
||||
}
|
||||
|
||||
public void Serialize(GenericWriter writer)
|
||||
{
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(Entries);
|
||||
writer.Write((int)RoomType);
|
||||
writer.Write((int)BattleMode);
|
||||
writer.Write(Ranked);
|
||||
writer.Write((int)TimeLimit);
|
||||
writer.Write((int)EntryFee);
|
||||
writer.Write(PetSlots);
|
||||
writer.Write(RidingFlyingAllowed);
|
||||
writer.Write(RangedWeaponsAllowed);
|
||||
writer.Write(SummonSpellsAllowed);
|
||||
writer.Write(FieldSpellsAllowed);
|
||||
writer.Write((int)PotionRules);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public enum ArenaTitle
|
||||
{
|
||||
FledglingGladiator = 0,
|
||||
BuddingGladiator = 1,
|
||||
Gladiator = 3,
|
||||
WellKnownGladiator = 4,
|
||||
VeteranGladiator =5
|
||||
}
|
||||
}
|
||||
200
Scripts/Services/PVP Arena System/Region.cs
Normal file
200
Scripts/Services/PVP Arena System/Region.cs
Normal file
@@ -0,0 +1,200 @@
|
||||
using Server;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Regions;
|
||||
using Server.Spells;
|
||||
using Server.Spells.Eighth;
|
||||
using Server.Spells.Seventh;
|
||||
using Server.Spells.Sixth;
|
||||
using Server.Spells.Fifth;
|
||||
using Server.Spells.Fourth;
|
||||
using Server.Spells.Third;
|
||||
using Server.Spells.Mysticism;
|
||||
using Server.Spells.Spellweaving;
|
||||
using Server.Spells.Necromancy;
|
||||
using Server.Spells.Ninjitsu;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Engines.ArenaSystem
|
||||
{
|
||||
public class ArenaRegion : BaseRegion
|
||||
{
|
||||
public PVPArena Arena { get; set; }
|
||||
|
||||
public ArenaRegion(PVPArena arena)
|
||||
: base(String.Format("Duel Arena {0}", arena.Definition.Name),
|
||||
arena.Definition.Map,
|
||||
Region.DefaultPriority,
|
||||
arena.Definition.RegionBounds)
|
||||
{
|
||||
Arena = arena;
|
||||
}
|
||||
|
||||
public override bool OnDoubleClick(Mobile m, object o)
|
||||
{
|
||||
if (Arena.CurrentDuel != null)
|
||||
{
|
||||
var duel = Arena.CurrentDuel;
|
||||
|
||||
if (o is BasePotion && duel.PotionRules != PotionRules.All)
|
||||
{
|
||||
if (duel.PotionRules == PotionRules.None || o is BaseHealPotion)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (o is Corpse && ((Corpse)o).Owner != m)
|
||||
{
|
||||
m.SendLocalizedMessage(1010054); // You cannot loot that corpse!!
|
||||
return false;
|
||||
}
|
||||
|
||||
if (o is BallOfSummoning)
|
||||
{
|
||||
MessageHelper.SendLocalizedMessageTo((BallOfSummoning)o, m, 1054125, 0x5); // The Crystal Ball fills with a blue mist. Your pet is not responding to the summons.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (o is BraceletOfBinding)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.OnDoubleClick(m, o);
|
||||
}
|
||||
|
||||
public override bool AllowFlying(Mobile from)
|
||||
{
|
||||
if (Arena.CurrentDuel != null && !Arena.CurrentDuel.RidingFlyingAllowed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.AllowFlying(from);
|
||||
}
|
||||
|
||||
public override bool OnBeginSpellCast(Mobile m, ISpell spell)
|
||||
{
|
||||
if (Arena.CurrentDuel != null)
|
||||
{
|
||||
var duel = Arena.CurrentDuel;
|
||||
|
||||
if (duel.InPreFight)
|
||||
{
|
||||
m.SendLocalizedMessage(502629); // You cannot cast spells here.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!duel.RidingFlyingAllowed && spell is FlySpell)
|
||||
{
|
||||
m.SendLocalizedMessage(1115997); // The rules prohibit riding a mount or flying.
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!duel.FieldSpellsAllowed && (spell is FireFieldSpell || spell is ParalyzeFieldSpell || spell is PoisonFieldSpell || spell is EnergyFieldSpell
|
||||
|| spell is WallOfStoneSpell))
|
||||
{
|
||||
m.SendLocalizedMessage(1010391); // A magical aura surrounds you and prevents the spell.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return base.OnBeginSpellCast(m, spell);
|
||||
}
|
||||
|
||||
public override bool CheckTravel(Mobile traveller, Point3D p, TravelCheckType type)
|
||||
{
|
||||
if (type == TravelCheckType.TeleportTo)
|
||||
{
|
||||
if (Region.Find(traveller.Location, traveller.Map) != this || traveller.Z != p.Z)
|
||||
{
|
||||
traveller.SendLocalizedMessage(501035); // You cannot teleport from here to the destination.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return type > TravelCheckType.Mark;
|
||||
}
|
||||
|
||||
public override void OnDeath(Mobile m)
|
||||
{
|
||||
if (Arena != null && Arena.CurrentDuel != null && Arena.CurrentDuel.HasBegun && !Arena.CurrentDuel.InPreFight)
|
||||
{
|
||||
Arena.CurrentDuel.HandleDeath(m);
|
||||
}
|
||||
|
||||
base.OnDeath(m);
|
||||
}
|
||||
|
||||
public override bool AllowHarmful(Mobile from, IDamageable target)
|
||||
{
|
||||
if (Arena != null && Arena.CurrentDuel != null && Arena.CurrentDuel.Complete)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnResurrect(Mobile m)
|
||||
{
|
||||
bool res = base.OnResurrect(m);
|
||||
|
||||
if (Arena != null)
|
||||
{
|
||||
Timer.DelayCall<Mobile>(TimeSpan.FromSeconds(.2), mob => Arena.RemovePlayer(mob), m);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public bool AllowItemEquip(PlayerMobile pm, Item item)
|
||||
{
|
||||
ArenaDuel duel = Arena.CurrentDuel;
|
||||
|
||||
if (duel != null && !duel.RangedWeaponsAllowed && item is BaseRanged)
|
||||
{
|
||||
pm.SendLocalizedMessage(1115996); // The rules prohibit the use of ranged weapons!
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public class GuardedArenaRegion : GuardedRegion
|
||||
{
|
||||
public GuardedArenaRegion(string name, Map map, Rectangle2D[] rec)
|
||||
: base(name, map, 1, rec)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool AllowHarmful(Mobile from, IDamageable target)
|
||||
{
|
||||
Region theirs = Region.Find(target.Location, target.Map);
|
||||
|
||||
if (theirs is ArenaRegion)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.AllowHarmful(from, target);
|
||||
}
|
||||
|
||||
public override bool AllowBeneficial(Mobile from, Mobile target)
|
||||
{
|
||||
Region theirs = Region.Find(target.Location, target.Map);
|
||||
|
||||
if (theirs is ArenaRegion)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.AllowBeneficial(from, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user