Overwrite

Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
Unstable Kitsune
2023-11-28 23:20:26 -05:00
parent 3cd54811de
commit b918192e4e
11608 changed files with 2644205 additions and 47 deletions

File diff suppressed because it is too large Load Diff

View 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();
}
}
}

View 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();
}
}
}

View 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();
}
}
}

View 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();
}
}
}

View 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);
}
}
}
}

View 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;
}
}
}

File diff suppressed because it is too large Load Diff

View 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);
}
}
}

View 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
}
}

View 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);
}
}
}