Formats UO Content (#201)
This commit is contained in:
parent
86b7b3aed1
commit
ad3775c4d7
3249 changed files with 431083 additions and 440981 deletions
|
|
@ -1,274 +1,289 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class AcceptDuelGump : Gump
|
||||
{
|
||||
private const int LabelColor32 = 0xFFFFFF;
|
||||
private const int BlackColor32 = 0x000008;
|
||||
|
||||
private static readonly Dictionary<Mobile, List<IgnoreEntry>> m_IgnoreLists = new Dictionary<Mobile, List<IgnoreEntry>>();
|
||||
|
||||
private bool m_Active = true;
|
||||
private readonly Mobile m_Challenger;
|
||||
private readonly Mobile m_Challenged;
|
||||
private readonly DuelContext m_Context;
|
||||
private readonly Participant m_Participant;
|
||||
private readonly int m_Slot;
|
||||
|
||||
public AcceptDuelGump(Mobile challenger, Mobile challenged, DuelContext context, Participant p, int slot) : base(50,
|
||||
50)
|
||||
{
|
||||
m_Challenger = challenger;
|
||||
m_Challenged = challenged;
|
||||
m_Context = context;
|
||||
m_Participant = p;
|
||||
m_Slot = slot;
|
||||
|
||||
challenged.CloseGump<AcceptDuelGump>();
|
||||
|
||||
Closable = false;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
// AddBackground( 0, 0, 400, 220, 9150 );
|
||||
AddBackground(1, 1, 398, 218, 3600);
|
||||
// AddBackground( 16, 15, 369, 189, 9100 );
|
||||
|
||||
AddImageTiled(16, 15, 369, 189, 3604);
|
||||
AddAlphaRegion(16, 15, 369, 189);
|
||||
|
||||
AddImage(215, -43, 0xEE40);
|
||||
// AddImage( 330, 141, 0x8BA );
|
||||
|
||||
AddHtml(22 - 1, 22, 294, 20, Color(Center("Duel Challenge"), BlackColor32));
|
||||
AddHtml(22 + 1, 22, 294, 20, Color(Center("Duel Challenge"), BlackColor32));
|
||||
AddHtml(22, 22 - 1, 294, 20, Color(Center("Duel Challenge"), BlackColor32));
|
||||
AddHtml(22, 22 + 1, 294, 20, Color(Center("Duel Challenge"), BlackColor32));
|
||||
AddHtml(22, 22, 294, 20, Color(Center("Duel Challenge"), LabelColor32));
|
||||
|
||||
string fmt;
|
||||
|
||||
if (p.Contains(challenger))
|
||||
fmt = "You have been asked to join sides with {0} in a duel. Do you accept?";
|
||||
else
|
||||
fmt = "You have been challenged to a duel from {0}. Do you accept?";
|
||||
|
||||
AddHtml(22 - 1, 50, 294, 40, Color(string.Format(fmt, challenger.Name), BlackColor32));
|
||||
AddHtml(22 + 1, 50, 294, 40, Color(string.Format(fmt, challenger.Name), BlackColor32));
|
||||
AddHtml(22, 50 - 1, 294, 40, Color(string.Format(fmt, challenger.Name), BlackColor32));
|
||||
AddHtml(22, 50 + 1, 294, 40, Color(string.Format(fmt, challenger.Name), BlackColor32));
|
||||
AddHtml(22, 50, 294, 40, Color(string.Format(fmt, challenger.Name), 0xB0C868));
|
||||
|
||||
AddImageTiled(32, 88, 264, 1, 9107);
|
||||
AddImageTiled(42, 90, 264, 1, 9157);
|
||||
|
||||
AddRadio(24, 100, 9727, 9730, true, 1);
|
||||
AddHtml(60 - 1, 105, 250, 20, Color("Yes, I will fight this duel.", BlackColor32));
|
||||
AddHtml(60 + 1, 105, 250, 20, Color("Yes, I will fight this duel.", BlackColor32));
|
||||
AddHtml(60, 105 - 1, 250, 20, Color("Yes, I will fight this duel.", BlackColor32));
|
||||
AddHtml(60, 105 + 1, 250, 20, Color("Yes, I will fight this duel.", BlackColor32));
|
||||
AddHtml(60, 105, 250, 20, Color("Yes, I will fight this duel.", LabelColor32));
|
||||
|
||||
AddRadio(24, 135, 9727, 9730, false, 2);
|
||||
AddHtml(60 - 1, 140, 250, 20, Color("No, I do not wish to fight.", BlackColor32));
|
||||
AddHtml(60 + 1, 140, 250, 20, Color("No, I do not wish to fight.", BlackColor32));
|
||||
AddHtml(60, 140 - 1, 250, 20, Color("No, I do not wish to fight.", BlackColor32));
|
||||
AddHtml(60, 140 + 1, 250, 20, Color("No, I do not wish to fight.", BlackColor32));
|
||||
AddHtml(60, 140, 250, 20, Color("No, I do not wish to fight.", LabelColor32));
|
||||
|
||||
AddRadio(24, 170, 9727, 9730, false, 3);
|
||||
AddHtml(60 - 1, 175, 250, 20, Color("No, knave. Do not ask again.", BlackColor32));
|
||||
AddHtml(60 + 1, 175, 250, 20, Color("No, knave. Do not ask again.", BlackColor32));
|
||||
AddHtml(60, 175 - 1, 250, 20, Color("No, knave. Do not ask again.", BlackColor32));
|
||||
AddHtml(60, 175 + 1, 250, 20, Color("No, knave. Do not ask again.", BlackColor32));
|
||||
AddHtml(60, 175, 250, 20, Color("No, knave. Do not ask again.", LabelColor32));
|
||||
|
||||
AddButton(314, 173, 247, 248, 1);
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(15.0), AutoReject);
|
||||
}
|
||||
|
||||
public string Center(string text) => $"<CENTER>{text}</CENTER>";
|
||||
|
||||
public string Color(string text, int color) => $"<BASEFONT COLOR=#{color:X6}>{text}</BASEFONT>";
|
||||
|
||||
public void AutoReject()
|
||||
{
|
||||
if (!m_Active)
|
||||
return;
|
||||
|
||||
m_Active = false;
|
||||
|
||||
m_Challenged.CloseGump<AcceptDuelGump>();
|
||||
|
||||
m_Challenger.SendMessage("{0} seems unresponsive.", m_Challenged.Name);
|
||||
m_Challenged.SendMessage("You decline the challenge.");
|
||||
}
|
||||
|
||||
public static void BeginIgnore(Mobile source, Mobile toIgnore)
|
||||
{
|
||||
if (!m_IgnoreLists.TryGetValue(source, out List<IgnoreEntry> list))
|
||||
m_IgnoreLists[source] = list = new List<IgnoreEntry>();
|
||||
|
||||
for (int i = 0; i < list.Count; ++i)
|
||||
{
|
||||
IgnoreEntry ie = list[i];
|
||||
|
||||
if (ie.Ignored == toIgnore)
|
||||
{
|
||||
ie.Refresh();
|
||||
return;
|
||||
}
|
||||
|
||||
if (ie.Expired)
|
||||
list.RemoveAt(i--);
|
||||
}
|
||||
|
||||
list.Add(new IgnoreEntry(toIgnore));
|
||||
}
|
||||
|
||||
public static bool IsIgnored(Mobile source, Mobile check)
|
||||
{
|
||||
if (!m_IgnoreLists.TryGetValue(source, out List<IgnoreEntry> list))
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < list.Count; ++i)
|
||||
{
|
||||
IgnoreEntry ie = list[i];
|
||||
|
||||
if (ie.Expired)
|
||||
list.RemoveAt(i--);
|
||||
else if (ie.Ignored == check)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (info.ButtonID != 1 || !m_Active || !m_Context.Registered)
|
||||
return;
|
||||
|
||||
m_Active = false;
|
||||
|
||||
if (!m_Context.Participants.Contains(m_Participant))
|
||||
return;
|
||||
|
||||
if (info.IsSwitched(1))
|
||||
{
|
||||
if (!(m_Challenged is PlayerMobile pm))
|
||||
return;
|
||||
|
||||
if (pm.DuelContext != null)
|
||||
{
|
||||
if (pm.DuelContext.Initiator == pm)
|
||||
pm.SendMessage(0x22, "You have already started a duel.");
|
||||
else
|
||||
pm.SendMessage(0x22, "You have already been challenged in a duel.");
|
||||
|
||||
m_Challenger.SendMessage("{0} cannot fight because they are already assigned to another duel.", pm.Name);
|
||||
}
|
||||
else if (DuelContext.CheckCombat(pm))
|
||||
{
|
||||
pm.SendMessage(0x22,
|
||||
"You have recently been in combat with another player and must wait before starting a duel.");
|
||||
m_Challenger.SendMessage(
|
||||
"{0} cannot fight because they have recently been in combat with another player.", pm.Name);
|
||||
}
|
||||
else if (TournamentController.IsActive)
|
||||
{
|
||||
pm.SendMessage(0x22, "A tournament is currently active and you may not duel.");
|
||||
m_Challenger.SendMessage(0x22, "A tournament is currently active and you may not duel.");
|
||||
}
|
||||
else
|
||||
{
|
||||
bool added = false;
|
||||
|
||||
if (m_Slot >= 0 && m_Slot < m_Participant.Players.Length && m_Participant.Players[m_Slot] == null)
|
||||
{
|
||||
added = true;
|
||||
m_Participant.Players[m_Slot] = new DuelPlayer(m_Challenged, m_Participant);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < m_Participant.Players.Length; ++i)
|
||||
if (m_Participant.Players[i] == null)
|
||||
{
|
||||
added = true;
|
||||
m_Participant.Players[i] = new DuelPlayer(m_Challenged, m_Participant);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (added)
|
||||
{
|
||||
m_Challenger.SendMessage("{0} has accepted the request.", m_Challenged.Name);
|
||||
m_Challenged.SendMessage("You have accepted the request from {0}.", m_Challenger.Name);
|
||||
|
||||
NetState ns = m_Challenger.NetState;
|
||||
|
||||
if (ns != null)
|
||||
foreach (Gump g in ns.Gumps)
|
||||
{
|
||||
if (g is ParticipantGump pg && pg.Participant == m_Participant)
|
||||
{
|
||||
m_Challenger.SendGump(new ParticipantGump(m_Challenger, m_Context, m_Participant));
|
||||
break;
|
||||
}
|
||||
|
||||
if (g is DuelContextGump dcg && dcg.Context == m_Context)
|
||||
{
|
||||
m_Challenger.SendGump(new DuelContextGump(m_Challenger, m_Context));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Challenger.SendMessage("The participant list was full and so {0} could not join.",
|
||||
m_Challenged.Name);
|
||||
m_Challenged.SendMessage(
|
||||
"The participant list was full and so you could not join the fight {1} {0}.", m_Challenger.Name,
|
||||
m_Participant.Contains(m_Challenger) ? "with" : "against");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (info.IsSwitched(3))
|
||||
BeginIgnore(m_Challenged, m_Challenger);
|
||||
|
||||
m_Challenger.SendMessage("{0} does not wish to fight.", m_Challenged.Name);
|
||||
m_Challenged.SendMessage("You chose not to fight {1} {0}.", m_Challenger.Name,
|
||||
m_Participant.Contains(m_Challenger) ? "with" : "against");
|
||||
}
|
||||
}
|
||||
|
||||
private class IgnoreEntry
|
||||
{
|
||||
private static readonly TimeSpan ExpireDelay = TimeSpan.FromMinutes(15.0);
|
||||
public DateTime m_Expire;
|
||||
public readonly Mobile m_Ignored;
|
||||
|
||||
public IgnoreEntry(Mobile ignored)
|
||||
{
|
||||
m_Ignored = ignored;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
public Mobile Ignored => m_Ignored;
|
||||
public bool Expired => DateTime.UtcNow >= m_Expire;
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
m_Expire = DateTime.UtcNow + ExpireDelay;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class AcceptDuelGump : Gump
|
||||
{
|
||||
private const int LabelColor32 = 0xFFFFFF;
|
||||
private const int BlackColor32 = 0x000008;
|
||||
|
||||
private static readonly Dictionary<Mobile, List<IgnoreEntry>> m_IgnoreLists =
|
||||
new Dictionary<Mobile, List<IgnoreEntry>>();
|
||||
|
||||
private readonly Mobile m_Challenged;
|
||||
private readonly Mobile m_Challenger;
|
||||
private readonly DuelContext m_Context;
|
||||
private readonly Participant m_Participant;
|
||||
private readonly int m_Slot;
|
||||
|
||||
private bool m_Active = true;
|
||||
|
||||
public AcceptDuelGump(Mobile challenger, Mobile challenged, DuelContext context, Participant p, int slot) : base(
|
||||
50,
|
||||
50
|
||||
)
|
||||
{
|
||||
m_Challenger = challenger;
|
||||
m_Challenged = challenged;
|
||||
m_Context = context;
|
||||
m_Participant = p;
|
||||
m_Slot = slot;
|
||||
|
||||
challenged.CloseGump<AcceptDuelGump>();
|
||||
|
||||
Closable = false;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
// AddBackground( 0, 0, 400, 220, 9150 );
|
||||
AddBackground(1, 1, 398, 218, 3600);
|
||||
// AddBackground( 16, 15, 369, 189, 9100 );
|
||||
|
||||
AddImageTiled(16, 15, 369, 189, 3604);
|
||||
AddAlphaRegion(16, 15, 369, 189);
|
||||
|
||||
AddImage(215, -43, 0xEE40);
|
||||
// AddImage( 330, 141, 0x8BA );
|
||||
|
||||
AddHtml(22 - 1, 22, 294, 20, Color(Center("Duel Challenge"), BlackColor32));
|
||||
AddHtml(22 + 1, 22, 294, 20, Color(Center("Duel Challenge"), BlackColor32));
|
||||
AddHtml(22, 22 - 1, 294, 20, Color(Center("Duel Challenge"), BlackColor32));
|
||||
AddHtml(22, 22 + 1, 294, 20, Color(Center("Duel Challenge"), BlackColor32));
|
||||
AddHtml(22, 22, 294, 20, Color(Center("Duel Challenge"), LabelColor32));
|
||||
|
||||
string fmt;
|
||||
|
||||
if (p.Contains(challenger))
|
||||
fmt = "You have been asked to join sides with {0} in a duel. Do you accept?";
|
||||
else
|
||||
fmt = "You have been challenged to a duel from {0}. Do you accept?";
|
||||
|
||||
AddHtml(22 - 1, 50, 294, 40, Color(string.Format(fmt, challenger.Name), BlackColor32));
|
||||
AddHtml(22 + 1, 50, 294, 40, Color(string.Format(fmt, challenger.Name), BlackColor32));
|
||||
AddHtml(22, 50 - 1, 294, 40, Color(string.Format(fmt, challenger.Name), BlackColor32));
|
||||
AddHtml(22, 50 + 1, 294, 40, Color(string.Format(fmt, challenger.Name), BlackColor32));
|
||||
AddHtml(22, 50, 294, 40, Color(string.Format(fmt, challenger.Name), 0xB0C868));
|
||||
|
||||
AddImageTiled(32, 88, 264, 1, 9107);
|
||||
AddImageTiled(42, 90, 264, 1, 9157);
|
||||
|
||||
AddRadio(24, 100, 9727, 9730, true, 1);
|
||||
AddHtml(60 - 1, 105, 250, 20, Color("Yes, I will fight this duel.", BlackColor32));
|
||||
AddHtml(60 + 1, 105, 250, 20, Color("Yes, I will fight this duel.", BlackColor32));
|
||||
AddHtml(60, 105 - 1, 250, 20, Color("Yes, I will fight this duel.", BlackColor32));
|
||||
AddHtml(60, 105 + 1, 250, 20, Color("Yes, I will fight this duel.", BlackColor32));
|
||||
AddHtml(60, 105, 250, 20, Color("Yes, I will fight this duel.", LabelColor32));
|
||||
|
||||
AddRadio(24, 135, 9727, 9730, false, 2);
|
||||
AddHtml(60 - 1, 140, 250, 20, Color("No, I do not wish to fight.", BlackColor32));
|
||||
AddHtml(60 + 1, 140, 250, 20, Color("No, I do not wish to fight.", BlackColor32));
|
||||
AddHtml(60, 140 - 1, 250, 20, Color("No, I do not wish to fight.", BlackColor32));
|
||||
AddHtml(60, 140 + 1, 250, 20, Color("No, I do not wish to fight.", BlackColor32));
|
||||
AddHtml(60, 140, 250, 20, Color("No, I do not wish to fight.", LabelColor32));
|
||||
|
||||
AddRadio(24, 170, 9727, 9730, false, 3);
|
||||
AddHtml(60 - 1, 175, 250, 20, Color("No, knave. Do not ask again.", BlackColor32));
|
||||
AddHtml(60 + 1, 175, 250, 20, Color("No, knave. Do not ask again.", BlackColor32));
|
||||
AddHtml(60, 175 - 1, 250, 20, Color("No, knave. Do not ask again.", BlackColor32));
|
||||
AddHtml(60, 175 + 1, 250, 20, Color("No, knave. Do not ask again.", BlackColor32));
|
||||
AddHtml(60, 175, 250, 20, Color("No, knave. Do not ask again.", LabelColor32));
|
||||
|
||||
AddButton(314, 173, 247, 248, 1);
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(15.0), AutoReject);
|
||||
}
|
||||
|
||||
public string Center(string text) => $"<CENTER>{text}</CENTER>";
|
||||
|
||||
public string Color(string text, int color) => $"<BASEFONT COLOR=#{color:X6}>{text}</BASEFONT>";
|
||||
|
||||
public void AutoReject()
|
||||
{
|
||||
if (!m_Active)
|
||||
return;
|
||||
|
||||
m_Active = false;
|
||||
|
||||
m_Challenged.CloseGump<AcceptDuelGump>();
|
||||
|
||||
m_Challenger.SendMessage("{0} seems unresponsive.", m_Challenged.Name);
|
||||
m_Challenged.SendMessage("You decline the challenge.");
|
||||
}
|
||||
|
||||
public static void BeginIgnore(Mobile source, Mobile toIgnore)
|
||||
{
|
||||
if (!m_IgnoreLists.TryGetValue(source, out var list))
|
||||
m_IgnoreLists[source] = list = new List<IgnoreEntry>();
|
||||
|
||||
for (var i = 0; i < list.Count; ++i)
|
||||
{
|
||||
var ie = list[i];
|
||||
|
||||
if (ie.Ignored == toIgnore)
|
||||
{
|
||||
ie.Refresh();
|
||||
return;
|
||||
}
|
||||
|
||||
if (ie.Expired)
|
||||
list.RemoveAt(i--);
|
||||
}
|
||||
|
||||
list.Add(new IgnoreEntry(toIgnore));
|
||||
}
|
||||
|
||||
public static bool IsIgnored(Mobile source, Mobile check)
|
||||
{
|
||||
if (!m_IgnoreLists.TryGetValue(source, out var list))
|
||||
return false;
|
||||
|
||||
for (var i = 0; i < list.Count; ++i)
|
||||
{
|
||||
var ie = list[i];
|
||||
|
||||
if (ie.Expired)
|
||||
list.RemoveAt(i--);
|
||||
else if (ie.Ignored == check)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (info.ButtonID != 1 || !m_Active || !m_Context.Registered)
|
||||
return;
|
||||
|
||||
m_Active = false;
|
||||
|
||||
if (!m_Context.Participants.Contains(m_Participant))
|
||||
return;
|
||||
|
||||
if (info.IsSwitched(1))
|
||||
{
|
||||
if (!(m_Challenged is PlayerMobile pm))
|
||||
return;
|
||||
|
||||
if (pm.DuelContext != null)
|
||||
{
|
||||
if (pm.DuelContext.Initiator == pm)
|
||||
pm.SendMessage(0x22, "You have already started a duel.");
|
||||
else
|
||||
pm.SendMessage(0x22, "You have already been challenged in a duel.");
|
||||
|
||||
m_Challenger.SendMessage("{0} cannot fight because they are already assigned to another duel.", pm.Name);
|
||||
}
|
||||
else if (DuelContext.CheckCombat(pm))
|
||||
{
|
||||
pm.SendMessage(
|
||||
0x22,
|
||||
"You have recently been in combat with another player and must wait before starting a duel."
|
||||
);
|
||||
m_Challenger.SendMessage(
|
||||
"{0} cannot fight because they have recently been in combat with another player.",
|
||||
pm.Name
|
||||
);
|
||||
}
|
||||
else if (TournamentController.IsActive)
|
||||
{
|
||||
pm.SendMessage(0x22, "A tournament is currently active and you may not duel.");
|
||||
m_Challenger.SendMessage(0x22, "A tournament is currently active and you may not duel.");
|
||||
}
|
||||
else
|
||||
{
|
||||
var added = false;
|
||||
|
||||
if (m_Slot >= 0 && m_Slot < m_Participant.Players.Length && m_Participant.Players[m_Slot] == null)
|
||||
{
|
||||
added = true;
|
||||
m_Participant.Players[m_Slot] = new DuelPlayer(m_Challenged, m_Participant);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var i = 0; i < m_Participant.Players.Length; ++i)
|
||||
if (m_Participant.Players[i] == null)
|
||||
{
|
||||
added = true;
|
||||
m_Participant.Players[i] = new DuelPlayer(m_Challenged, m_Participant);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (added)
|
||||
{
|
||||
m_Challenger.SendMessage("{0} has accepted the request.", m_Challenged.Name);
|
||||
m_Challenged.SendMessage("You have accepted the request from {0}.", m_Challenger.Name);
|
||||
|
||||
var ns = m_Challenger.NetState;
|
||||
|
||||
if (ns != null)
|
||||
foreach (var g in ns.Gumps)
|
||||
{
|
||||
if (g is ParticipantGump pg && pg.Participant == m_Participant)
|
||||
{
|
||||
m_Challenger.SendGump(new ParticipantGump(m_Challenger, m_Context, m_Participant));
|
||||
break;
|
||||
}
|
||||
|
||||
if (g is DuelContextGump dcg && dcg.Context == m_Context)
|
||||
{
|
||||
m_Challenger.SendGump(new DuelContextGump(m_Challenger, m_Context));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Challenger.SendMessage(
|
||||
"The participant list was full and so {0} could not join.",
|
||||
m_Challenged.Name
|
||||
);
|
||||
m_Challenged.SendMessage(
|
||||
"The participant list was full and so you could not join the fight {1} {0}.",
|
||||
m_Challenger.Name,
|
||||
m_Participant.Contains(m_Challenger) ? "with" : "against"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (info.IsSwitched(3))
|
||||
BeginIgnore(m_Challenged, m_Challenger);
|
||||
|
||||
m_Challenger.SendMessage("{0} does not wish to fight.", m_Challenged.Name);
|
||||
m_Challenged.SendMessage(
|
||||
"You chose not to fight {1} {0}.",
|
||||
m_Challenger.Name,
|
||||
m_Participant.Contains(m_Challenger) ? "with" : "against"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private class IgnoreEntry
|
||||
{
|
||||
private static readonly TimeSpan ExpireDelay = TimeSpan.FromMinutes(15.0);
|
||||
public readonly Mobile m_Ignored;
|
||||
public DateTime m_Expire;
|
||||
|
||||
public IgnoreEntry(Mobile ignored)
|
||||
{
|
||||
m_Ignored = ignored;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
public Mobile Ignored => m_Ignored;
|
||||
public bool Expired => DateTime.UtcNow >= m_Expire;
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
m_Expire = DateTime.UtcNow + ExpireDelay;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,89 +1,89 @@
|
|||
using Server.Items;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public enum DuelTeleporterType
|
||||
{
|
||||
Squares = 6095,
|
||||
Buds = 6104,
|
||||
Flowers = 6113,
|
||||
Spikes = 6122,
|
||||
Arrows = 6140,
|
||||
Links = 6149
|
||||
}
|
||||
|
||||
public class DuelTeleporterAddon : BaseAddon
|
||||
{
|
||||
[Constructible]
|
||||
public DuelTeleporterAddon(DuelTeleporterType type = DuelTeleporterType.Squares)
|
||||
{
|
||||
int itemID = (int)type;
|
||||
|
||||
AddComponent(new AddonComponent(itemID + 0), -1, -1, 5);
|
||||
AddComponent(new AddonComponent(itemID + 1), -1, 0, 5);
|
||||
AddComponent(new AddonComponent(itemID + 2), 0, -1, 5);
|
||||
AddComponent(new AddonComponent(itemID + 3), -1, +1, 5);
|
||||
AddComponent(new AddonComponent(itemID + 4), 0, 0, 5);
|
||||
AddComponent(new AddonComponent(itemID + 5), +1, -1, 5);
|
||||
AddComponent(new AddonComponent(itemID + 6), 0, +1, 5);
|
||||
AddComponent(new AddonComponent(itemID + 7), +1, 0, 5);
|
||||
AddComponent(new AddonComponent(itemID + 8), +1, +1, 5);
|
||||
|
||||
AddComponent(new AddonComponent(0x759), -2, -2, 0);
|
||||
AddComponent(new AddonComponent(0x75A), +2, +2, 0);
|
||||
AddComponent(new AddonComponent(0x75B), -2, +2, 0);
|
||||
AddComponent(new AddonComponent(0x75C), +2, -2, 0);
|
||||
|
||||
AddComponent(new AddonComponent(0x751), -1, +2, 0);
|
||||
AddComponent(new AddonComponent(0x751), 0, +2, 0);
|
||||
AddComponent(new AddonComponent(0x751), +1, +2, 0);
|
||||
|
||||
AddComponent(new AddonComponent(0x752), +2, -1, 0);
|
||||
AddComponent(new AddonComponent(0x752), +2, 0, 0);
|
||||
AddComponent(new AddonComponent(0x752), +2, +1, 0);
|
||||
|
||||
AddComponent(new AddonComponent(0x753), -1, -2, 0);
|
||||
AddComponent(new AddonComponent(0x753), 0, -2, 0);
|
||||
AddComponent(new AddonComponent(0x753), +1, -2, 0);
|
||||
|
||||
AddComponent(new AddonComponent(0x754), -2, -1, 0);
|
||||
AddComponent(new AddonComponent(0x754), -2, 0, 0);
|
||||
AddComponent(new AddonComponent(0x754), -2, +1, 0);
|
||||
}
|
||||
|
||||
public DuelTeleporterAddon(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DuelTeleporterType Type
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Components.Count > 0)
|
||||
return (DuelTeleporterType)Components[0].ItemID;
|
||||
|
||||
return DuelTeleporterType.Squares;
|
||||
}
|
||||
set
|
||||
{
|
||||
for (int i = 0; i < Components.Count && i < 9; ++i)
|
||||
Components[i].ItemID = i + (int)value;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public enum DuelTeleporterType
|
||||
{
|
||||
Squares = 6095,
|
||||
Buds = 6104,
|
||||
Flowers = 6113,
|
||||
Spikes = 6122,
|
||||
Arrows = 6140,
|
||||
Links = 6149
|
||||
}
|
||||
|
||||
public class DuelTeleporterAddon : BaseAddon
|
||||
{
|
||||
[Constructible]
|
||||
public DuelTeleporterAddon(DuelTeleporterType type = DuelTeleporterType.Squares)
|
||||
{
|
||||
var itemID = (int)type;
|
||||
|
||||
AddComponent(new AddonComponent(itemID + 0), -1, -1, 5);
|
||||
AddComponent(new AddonComponent(itemID + 1), -1, 0, 5);
|
||||
AddComponent(new AddonComponent(itemID + 2), 0, -1, 5);
|
||||
AddComponent(new AddonComponent(itemID + 3), -1, +1, 5);
|
||||
AddComponent(new AddonComponent(itemID + 4), 0, 0, 5);
|
||||
AddComponent(new AddonComponent(itemID + 5), +1, -1, 5);
|
||||
AddComponent(new AddonComponent(itemID + 6), 0, +1, 5);
|
||||
AddComponent(new AddonComponent(itemID + 7), +1, 0, 5);
|
||||
AddComponent(new AddonComponent(itemID + 8), +1, +1, 5);
|
||||
|
||||
AddComponent(new AddonComponent(0x759), -2, -2, 0);
|
||||
AddComponent(new AddonComponent(0x75A), +2, +2, 0);
|
||||
AddComponent(new AddonComponent(0x75B), -2, +2, 0);
|
||||
AddComponent(new AddonComponent(0x75C), +2, -2, 0);
|
||||
|
||||
AddComponent(new AddonComponent(0x751), -1, +2, 0);
|
||||
AddComponent(new AddonComponent(0x751), 0, +2, 0);
|
||||
AddComponent(new AddonComponent(0x751), +1, +2, 0);
|
||||
|
||||
AddComponent(new AddonComponent(0x752), +2, -1, 0);
|
||||
AddComponent(new AddonComponent(0x752), +2, 0, 0);
|
||||
AddComponent(new AddonComponent(0x752), +2, +1, 0);
|
||||
|
||||
AddComponent(new AddonComponent(0x753), -1, -2, 0);
|
||||
AddComponent(new AddonComponent(0x753), 0, -2, 0);
|
||||
AddComponent(new AddonComponent(0x753), +1, -2, 0);
|
||||
|
||||
AddComponent(new AddonComponent(0x754), -2, -1, 0);
|
||||
AddComponent(new AddonComponent(0x754), -2, 0, 0);
|
||||
AddComponent(new AddonComponent(0x754), -2, +1, 0);
|
||||
}
|
||||
|
||||
public DuelTeleporterAddon(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DuelTeleporterType Type
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Components.Count > 0)
|
||||
return (DuelTeleporterType)Components[0].ItemID;
|
||||
|
||||
return DuelTeleporterType.Squares;
|
||||
}
|
||||
set
|
||||
{
|
||||
for (var i = 0; i < Components.Count && i < 9; ++i)
|
||||
Components[i].ItemID = i + (int)value;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,68 +1,68 @@
|
|||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public abstract class EventController : Item
|
||||
{
|
||||
public EventController()
|
||||
: base(0x1B7A)
|
||||
{
|
||||
Visible = false;
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
public EventController(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public abstract string Title { get; }
|
||||
public abstract EventGame Construct(DuelContext dc);
|
||||
|
||||
public abstract string GetTeamName(int teamID);
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (from.AccessLevel >= AccessLevel.GameMaster)
|
||||
from.SendGump(new PropertiesGump(from, this));
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class EventGame
|
||||
{
|
||||
protected DuelContext m_Context;
|
||||
|
||||
public EventGame(DuelContext context) => m_Context = context;
|
||||
|
||||
public DuelContext Context => m_Context;
|
||||
|
||||
public virtual bool FreeConsume => true;
|
||||
|
||||
public virtual bool OnDeath(Mobile mob, Container corpse) => true;
|
||||
|
||||
public virtual bool CantDoAnything(Mobile mob) => false;
|
||||
|
||||
public virtual void OnStart()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void OnStop()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public abstract class EventController : Item
|
||||
{
|
||||
public EventController()
|
||||
: base(0x1B7A)
|
||||
{
|
||||
Visible = false;
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
public EventController(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public abstract string Title { get; }
|
||||
public abstract EventGame Construct(DuelContext dc);
|
||||
|
||||
public abstract string GetTeamName(int teamID);
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.ReadInt();
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (from.AccessLevel >= AccessLevel.GameMaster)
|
||||
from.SendGump(new PropertiesGump(from, this));
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class EventGame
|
||||
{
|
||||
protected DuelContext m_Context;
|
||||
|
||||
public EventGame(DuelContext context) => m_Context = context;
|
||||
|
||||
public DuelContext Context => m_Context;
|
||||
|
||||
public virtual bool FreeConsume => true;
|
||||
|
||||
public virtual bool OnDeath(Mobile mob, Container corpse) => true;
|
||||
|
||||
public virtual bool CantDoAnything(Mobile mob) => false;
|
||||
|
||||
public virtual void OnStart()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void OnStop()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,122 +1,129 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class TourneyMatch
|
||||
{
|
||||
public TourneyMatch(List<TourneyParticipant> participants)
|
||||
{
|
||||
Participants = participants;
|
||||
|
||||
for (int i = 0; i < participants.Count; ++i)
|
||||
{
|
||||
TourneyParticipant part = participants[i];
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.Append("Matched in a duel against ");
|
||||
|
||||
if (participants.Count > 2)
|
||||
sb.AppendFormat("{0} other {1}: ", participants.Count - 1,
|
||||
part.Players.Count == 1 ? "players" : "teams");
|
||||
|
||||
bool hasAppended = false;
|
||||
|
||||
for (int j = 0; j < participants.Count; ++j)
|
||||
{
|
||||
if (i == j)
|
||||
continue;
|
||||
|
||||
if (hasAppended)
|
||||
sb.Append(", ");
|
||||
|
||||
sb.Append(participants[j].NameList);
|
||||
hasAppended = true;
|
||||
}
|
||||
|
||||
sb.Append(".");
|
||||
|
||||
part.AddLog(sb.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public List<TourneyParticipant> Participants { get; set; }
|
||||
|
||||
public TourneyParticipant Winner { get; set; }
|
||||
|
||||
public DuelContext Context { get; set; }
|
||||
|
||||
public bool InProgress => Context?.Registered == true;
|
||||
|
||||
public void Start(Arena arena, Tournament tourney)
|
||||
{
|
||||
TourneyParticipant first = Participants[0];
|
||||
|
||||
DuelContext dc = new DuelContext(first.Players[0], tourney.Ruleset.Layout, false);
|
||||
dc.Ruleset.Options.SetAll(false);
|
||||
dc.Ruleset.Options.Or(tourney.Ruleset.Options);
|
||||
|
||||
for (int i = 0; i < Participants.Count; ++i)
|
||||
{
|
||||
TourneyParticipant tourneyPart = Participants[i];
|
||||
Participant duelPart = new Participant(dc, tourneyPart.Players.Count)
|
||||
{
|
||||
TourneyPart = tourneyPart
|
||||
};
|
||||
|
||||
for (int j = 0; j < tourneyPart.Players.Count; ++j)
|
||||
duelPart.Add(tourneyPart.Players[j]);
|
||||
|
||||
for (int j = 0; j < duelPart.Players.Length; ++j)
|
||||
if (duelPart.Players[j] != null)
|
||||
duelPart.Players[j].Ready = true;
|
||||
|
||||
dc.Participants.Add(duelPart);
|
||||
}
|
||||
|
||||
if (tourney.EventController != null)
|
||||
dc.m_EventGame = tourney.EventController.Construct(dc);
|
||||
|
||||
dc.m_Tournament = tourney;
|
||||
dc.m_Match = this;
|
||||
|
||||
dc.m_OverrideArena = arena;
|
||||
|
||||
if (tourney.SuddenDeath > TimeSpan.Zero &&
|
||||
(tourney.SuddenDeathRounds == 0 || tourney.Pyramid.Levels.Count <= tourney.SuddenDeathRounds))
|
||||
dc.StartSuddenDeath(tourney.SuddenDeath);
|
||||
|
||||
dc.SendReadyGump(0);
|
||||
|
||||
if (dc.StartedBeginCountdown)
|
||||
{
|
||||
Context = dc;
|
||||
|
||||
for (int i = 0; i < Participants.Count; ++i)
|
||||
{
|
||||
TourneyParticipant p = Participants[i];
|
||||
|
||||
for (int j = 0; j < p.Players.Count; ++j)
|
||||
{
|
||||
Mobile mob = p.Players[j];
|
||||
|
||||
foreach (Mobile view in mob.GetMobilesInRange(18))
|
||||
if (!mob.CanSee(view))
|
||||
mob.Send(view.RemovePacket);
|
||||
|
||||
mob.LocalOverheadMessage(MessageType.Emote, 0x3B2, false,
|
||||
"* Your mind focuses intently on the fight and all other distractions fade away *");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dc.Unregister();
|
||||
dc.StopCountdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class TourneyMatch
|
||||
{
|
||||
public TourneyMatch(List<TourneyParticipant> participants)
|
||||
{
|
||||
Participants = participants;
|
||||
|
||||
for (var i = 0; i < participants.Count; ++i)
|
||||
{
|
||||
var part = participants[i];
|
||||
|
||||
var sb = new StringBuilder();
|
||||
|
||||
sb.Append("Matched in a duel against ");
|
||||
|
||||
if (participants.Count > 2)
|
||||
sb.AppendFormat(
|
||||
"{0} other {1}: ",
|
||||
participants.Count - 1,
|
||||
part.Players.Count == 1 ? "players" : "teams"
|
||||
);
|
||||
|
||||
var hasAppended = false;
|
||||
|
||||
for (var j = 0; j < participants.Count; ++j)
|
||||
{
|
||||
if (i == j)
|
||||
continue;
|
||||
|
||||
if (hasAppended)
|
||||
sb.Append(", ");
|
||||
|
||||
sb.Append(participants[j].NameList);
|
||||
hasAppended = true;
|
||||
}
|
||||
|
||||
sb.Append(".");
|
||||
|
||||
part.AddLog(sb.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public List<TourneyParticipant> Participants { get; set; }
|
||||
|
||||
public TourneyParticipant Winner { get; set; }
|
||||
|
||||
public DuelContext Context { get; set; }
|
||||
|
||||
public bool InProgress => Context?.Registered == true;
|
||||
|
||||
public void Start(Arena arena, Tournament tourney)
|
||||
{
|
||||
var first = Participants[0];
|
||||
|
||||
var dc = new DuelContext(first.Players[0], tourney.Ruleset.Layout, false);
|
||||
dc.Ruleset.Options.SetAll(false);
|
||||
dc.Ruleset.Options.Or(tourney.Ruleset.Options);
|
||||
|
||||
for (var i = 0; i < Participants.Count; ++i)
|
||||
{
|
||||
var tourneyPart = Participants[i];
|
||||
var duelPart = new Participant(dc, tourneyPart.Players.Count)
|
||||
{
|
||||
TourneyPart = tourneyPart
|
||||
};
|
||||
|
||||
for (var j = 0; j < tourneyPart.Players.Count; ++j)
|
||||
duelPart.Add(tourneyPart.Players[j]);
|
||||
|
||||
for (var j = 0; j < duelPart.Players.Length; ++j)
|
||||
if (duelPart.Players[j] != null)
|
||||
duelPart.Players[j].Ready = true;
|
||||
|
||||
dc.Participants.Add(duelPart);
|
||||
}
|
||||
|
||||
if (tourney.EventController != null)
|
||||
dc.m_EventGame = tourney.EventController.Construct(dc);
|
||||
|
||||
dc.m_Tournament = tourney;
|
||||
dc.m_Match = this;
|
||||
|
||||
dc.m_OverrideArena = arena;
|
||||
|
||||
if (tourney.SuddenDeath > TimeSpan.Zero &&
|
||||
(tourney.SuddenDeathRounds == 0 || tourney.Pyramid.Levels.Count <= tourney.SuddenDeathRounds))
|
||||
dc.StartSuddenDeath(tourney.SuddenDeath);
|
||||
|
||||
dc.SendReadyGump(0);
|
||||
|
||||
if (dc.StartedBeginCountdown)
|
||||
{
|
||||
Context = dc;
|
||||
|
||||
for (var i = 0; i < Participants.Count; ++i)
|
||||
{
|
||||
var p = Participants[i];
|
||||
|
||||
for (var j = 0; j < p.Players.Count; ++j)
|
||||
{
|
||||
var mob = p.Players[j];
|
||||
|
||||
foreach (var view in mob.GetMobilesInRange(18))
|
||||
if (!mob.CanSee(view))
|
||||
mob.Send(view.RemovePacket);
|
||||
|
||||
mob.LocalOverheadMessage(
|
||||
MessageType.Emote,
|
||||
0x3B2,
|
||||
false,
|
||||
"* Your mind focuses intently on the fight and all other distractions fade away *"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dc.Unregister();
|
||||
dc.StopCountdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,349 +1,412 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class AcceptTeamGump : Gump
|
||||
{
|
||||
private const int BlackColor32 = 0x000008;
|
||||
private const int LabelColor32 = 0xFFFFFF;
|
||||
private bool m_Active;
|
||||
|
||||
private readonly Mobile m_From;
|
||||
private readonly List<Mobile> m_Players;
|
||||
private readonly Mobile m_Registrar;
|
||||
private readonly Mobile m_Requested;
|
||||
private readonly Tournament m_Tournament;
|
||||
|
||||
public AcceptTeamGump(Mobile from, Mobile requested, Tournament tourney, Mobile registrar, List<Mobile> players) : base(50, 50)
|
||||
{
|
||||
m_From = from;
|
||||
m_Requested = requested;
|
||||
m_Tournament = tourney;
|
||||
m_Registrar = registrar;
|
||||
m_Players = players;
|
||||
|
||||
m_Active = true;
|
||||
|
||||
Ruleset ruleset = tourney.Ruleset;
|
||||
Ruleset basedef = ruleset.Base;
|
||||
|
||||
int height = 185 + 35 + 60 + 12;
|
||||
|
||||
int changes = 0;
|
||||
|
||||
BitArray defs;
|
||||
|
||||
if (ruleset.Flavors.Count > 0)
|
||||
{
|
||||
defs = new BitArray(basedef.Options);
|
||||
|
||||
for (int i = 0; i < ruleset.Flavors.Count; ++i)
|
||||
defs.Or(ruleset.Flavors[i].Options);
|
||||
|
||||
height += ruleset.Flavors.Count * 18;
|
||||
}
|
||||
else
|
||||
{
|
||||
defs = basedef.Options;
|
||||
}
|
||||
|
||||
BitArray opts = ruleset.Options;
|
||||
|
||||
for (int i = 0; i < opts.Length; ++i)
|
||||
if (defs[i] != opts[i])
|
||||
++changes;
|
||||
|
||||
height += changes * 22;
|
||||
|
||||
height += 10 + 22 + 25 + 25;
|
||||
|
||||
Closable = false;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
AddBackground(1, 1, 398, height, 3600);
|
||||
|
||||
AddImageTiled(16, 15, 369, height - 29, 3604);
|
||||
AddAlphaRegion(16, 15, 369, height - 29);
|
||||
|
||||
AddImage(215, -43, 0xEE40);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
if (tourney.TourneyType == TourneyType.FreeForAll)
|
||||
{
|
||||
sb.Append("FFA");
|
||||
}
|
||||
else if (tourney.TourneyType == TourneyType.RandomTeam)
|
||||
{
|
||||
sb.Append(tourney.ParticipantsPerMatch);
|
||||
sb.Append("-Team");
|
||||
}
|
||||
else if (tourney.TourneyType == TourneyType.Faction)
|
||||
{
|
||||
sb.Append(tourney.ParticipantsPerMatch);
|
||||
sb.Append("-Team Faction");
|
||||
}
|
||||
else if (tourney.TourneyType == TourneyType.RedVsBlue)
|
||||
{
|
||||
sb.Append("Red v Blue");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < tourney.ParticipantsPerMatch; ++i)
|
||||
{
|
||||
if (sb.Length > 0)
|
||||
sb.Append('v');
|
||||
|
||||
sb.Append(tourney.PlayersPerParticipant);
|
||||
}
|
||||
}
|
||||
|
||||
if (tourney.EventController != null)
|
||||
sb.Append(' ').Append(tourney.EventController.Title);
|
||||
|
||||
sb.Append(" Tournament Invitation");
|
||||
|
||||
AddBorderedText(22, 22, 294, 20, Center(sb.ToString()), LabelColor32, BlackColor32);
|
||||
|
||||
AddBorderedText(22, 50, 294, 40,
|
||||
$"You have been asked to partner with {from.Name} in a tournament. Do you accept?",
|
||||
0xB0C868, BlackColor32);
|
||||
|
||||
AddImageTiled(32, 88, 264, 1, 9107);
|
||||
AddImageTiled(42, 90, 264, 1, 9157);
|
||||
|
||||
int y = 100;
|
||||
|
||||
var groupText = tourney.GroupType switch
|
||||
{
|
||||
GroupingType.HighVsLow => "High vs Low",
|
||||
GroupingType.Nearest => "Closest opponent",
|
||||
GroupingType.Random => "Random",
|
||||
_ => null
|
||||
};
|
||||
|
||||
AddBorderedText(35, y, 190, 20, $"Grouping: {groupText}", LabelColor32, BlackColor32);
|
||||
y += 20;
|
||||
|
||||
var tieText = tourney.TieType switch
|
||||
{
|
||||
TieType.Random => "Random",
|
||||
TieType.Highest => "Highest advances",
|
||||
TieType.Lowest => "Lowest advances",
|
||||
TieType.FullAdvancement => tourney.ParticipantsPerMatch == 2 ? "Both advance" : "Everyone advances",
|
||||
TieType.FullElimination => tourney.ParticipantsPerMatch == 2 ? "Both eliminated" : "Everyone eliminated",
|
||||
_ => null
|
||||
};
|
||||
|
||||
AddBorderedText(35, y, 190, 20, $"Tiebreaker: {tieText}", LabelColor32, BlackColor32);
|
||||
y += 20;
|
||||
|
||||
string sdText = "Off";
|
||||
|
||||
if (tourney.SuddenDeath > TimeSpan.Zero)
|
||||
{
|
||||
sdText = $"{(int)tourney.SuddenDeath.TotalMinutes}:{tourney.SuddenDeath.Seconds:D2}";
|
||||
|
||||
if (tourney.SuddenDeathRounds > 0)
|
||||
sdText = $"{sdText} (first {tourney.SuddenDeathRounds} rounds)";
|
||||
else
|
||||
sdText = $"{sdText} (all rounds)";
|
||||
}
|
||||
|
||||
AddBorderedText(35, y, 240, 20, $"Sudden Death: {sdText}", LabelColor32, BlackColor32);
|
||||
y += 20;
|
||||
|
||||
y += 6;
|
||||
AddImageTiled(32, y - 1, 264, 1, 9107);
|
||||
AddImageTiled(42, y + 1, 264, 1, 9157);
|
||||
y += 6;
|
||||
|
||||
AddBorderedText(35, y, 190, 20, $"Ruleset: {basedef.Title}", LabelColor32, BlackColor32);
|
||||
y += 20;
|
||||
|
||||
for (int i = 0; i < ruleset.Flavors.Count; ++i, y += 18)
|
||||
AddBorderedText(35, y, 190, 20, $" + {ruleset.Flavors[i].Title}", LabelColor32, BlackColor32);
|
||||
|
||||
y += 4;
|
||||
|
||||
if (changes > 0)
|
||||
{
|
||||
AddBorderedText(35, y, 190, 20, "Modifications:", LabelColor32, BlackColor32);
|
||||
y += 20;
|
||||
|
||||
for (int i = 0; i < opts.Length; ++i)
|
||||
if (defs[i] != opts[i])
|
||||
{
|
||||
string name = ruleset.Layout.FindByIndex(i);
|
||||
|
||||
if (name != null) // sanity
|
||||
{
|
||||
AddImage(35, y, opts[i] ? 0xD3 : 0xD2);
|
||||
AddBorderedText(60, y, 165, 22, name, LabelColor32, BlackColor32);
|
||||
}
|
||||
|
||||
y += 22;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddBorderedText(35, y, 190, 20, "Modifications: None", LabelColor32, BlackColor32);
|
||||
y += 20;
|
||||
}
|
||||
|
||||
y += 8;
|
||||
AddImageTiled(32, y - 1, 264, 1, 9107);
|
||||
AddImageTiled(42, y + 1, 264, 1, 9157);
|
||||
y += 8;
|
||||
|
||||
AddRadio(24, y, 9727, 9730, true, 1);
|
||||
AddBorderedText(60, y + 5, 250, 20, "Yes, I will join them.", LabelColor32, BlackColor32);
|
||||
y += 35;
|
||||
|
||||
AddRadio(24, y, 9727, 9730, false, 2);
|
||||
AddBorderedText(60, y + 5, 250, 20, "No, I do not wish to fight.", LabelColor32, BlackColor32);
|
||||
y += 35;
|
||||
|
||||
AddRadio(24, y, 9727, 9730, false, 3);
|
||||
AddBorderedText(60, y + 5, 270, 20, "No, most certainly not. Do not ask again.", LabelColor32, BlackColor32);
|
||||
y += 35;
|
||||
|
||||
y -= 3;
|
||||
AddButton(314, y, 247, 248, 1);
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(15.0), AutoReject);
|
||||
}
|
||||
|
||||
public string Center(string text) => $"<CENTER>{text}</CENTER>";
|
||||
|
||||
public string Color(string text, int color) => $"<BASEFONT COLOR=#{color:X6}>{text}</BASEFONT>";
|
||||
|
||||
private void AddBorderedText(int x, int y, int width, int height, string text, int color, int borderColor)
|
||||
{
|
||||
AddColoredText(x - 1, y - 1, width, height, text, borderColor);
|
||||
AddColoredText(x - 1, y + 1, width, height, text, borderColor);
|
||||
AddColoredText(x + 1, y - 1, width, height, text, borderColor);
|
||||
AddColoredText(x + 1, y + 1, width, height, text, borderColor);
|
||||
AddColoredText(x, y, width, height, text, color);
|
||||
}
|
||||
|
||||
private void AddColoredText(int x, int y, int width, int height, string text, int color)
|
||||
{
|
||||
if (color == 0)
|
||||
AddHtml(x, y, width, height, text);
|
||||
else
|
||||
AddHtml(x, y, width, height, Color(text, color));
|
||||
}
|
||||
|
||||
public void AutoReject()
|
||||
{
|
||||
if (!m_Active)
|
||||
return;
|
||||
|
||||
m_Active = false;
|
||||
|
||||
m_Requested.CloseGump<AcceptTeamGump>();
|
||||
m_From.SendGump(new ConfirmSignupGump(m_From, m_Registrar, m_Tournament, m_Players));
|
||||
|
||||
if (m_Registrar != null)
|
||||
{
|
||||
m_Registrar.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x22, false, $"{m_Requested.Name} seems unresponsive.", m_From.NetState);
|
||||
|
||||
m_Registrar.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x22, false, $"You have declined the partnership with {m_From.Name}.", m_Requested.NetState);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
Mobile from = m_From;
|
||||
Mobile mob = m_Requested;
|
||||
|
||||
if (info.ButtonID != 1 || !m_Active)
|
||||
return;
|
||||
|
||||
m_Active = false;
|
||||
|
||||
if (info.IsSwitched(1))
|
||||
{
|
||||
if (!(mob is PlayerMobile pm))
|
||||
return;
|
||||
|
||||
if (AcceptDuelGump.IsIgnored(mob, from) || mob.Blessed)
|
||||
{
|
||||
m_From.SendGump(new ConfirmSignupGump(m_From, m_Registrar, m_Tournament, m_Players));
|
||||
|
||||
m_Registrar?.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x22, false, "They ignore your invitation.", from.NetState);
|
||||
}
|
||||
else if (pm.DuelContext != null)
|
||||
{
|
||||
m_From.SendGump(new ConfirmSignupGump(m_From, m_Registrar, m_Tournament, m_Players));
|
||||
|
||||
m_Registrar?.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x22, false, "They are already assigned to another duel.", from.NetState);
|
||||
}
|
||||
else if (m_Players.Contains(mob))
|
||||
{
|
||||
m_From.SendGump(new ConfirmSignupGump(m_From, m_Registrar, m_Tournament, m_Players));
|
||||
|
||||
m_Registrar?.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x22, false, "You have already named them as a team member.", from.NetState);
|
||||
}
|
||||
else if (m_Tournament.HasParticipant(mob))
|
||||
{
|
||||
m_From.SendGump(new ConfirmSignupGump(m_From, m_Registrar, m_Tournament, m_Players));
|
||||
|
||||
m_Registrar?.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x22, false, "They have already entered this tournament.", from.NetState);
|
||||
}
|
||||
else if (m_Players.Count >= m_Tournament.PlayersPerParticipant)
|
||||
{
|
||||
m_From.SendGump(new ConfirmSignupGump(m_From, m_Registrar, m_Tournament, m_Players));
|
||||
|
||||
m_Registrar?.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x22, false, "Your team is full.", from.NetState);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Players.Add(mob);
|
||||
|
||||
m_From.SendGump(new ConfirmSignupGump(m_From, m_Registrar, m_Tournament, m_Players));
|
||||
|
||||
if (m_Registrar != null)
|
||||
{
|
||||
m_Registrar.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x59, false, $"{mob.Name} has accepted your offer of partnership.", from.NetState);
|
||||
|
||||
m_Registrar.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x59, false, $"You have accepted the partnership with {from.Name}.", mob.NetState);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (info.IsSwitched(3))
|
||||
AcceptDuelGump.BeginIgnore(m_Requested, m_From);
|
||||
|
||||
m_From.SendGump(new ConfirmSignupGump(m_From, m_Registrar, m_Tournament, m_Players));
|
||||
|
||||
if (m_Registrar != null)
|
||||
{
|
||||
m_Registrar.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x22, false, $"{mob.Name} has declined your offer of partnership.", from.NetState);
|
||||
|
||||
m_Registrar.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x22, false, $"You have declined the partnership with {from.Name}.", mob.NetState);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class AcceptTeamGump : Gump
|
||||
{
|
||||
private const int BlackColor32 = 0x000008;
|
||||
private const int LabelColor32 = 0xFFFFFF;
|
||||
|
||||
private readonly Mobile m_From;
|
||||
private readonly List<Mobile> m_Players;
|
||||
private readonly Mobile m_Registrar;
|
||||
private readonly Mobile m_Requested;
|
||||
private readonly Tournament m_Tournament;
|
||||
private bool m_Active;
|
||||
|
||||
public AcceptTeamGump(
|
||||
Mobile from, Mobile requested, Tournament tourney, Mobile registrar, List<Mobile> players
|
||||
) : base(50, 50)
|
||||
{
|
||||
m_From = from;
|
||||
m_Requested = requested;
|
||||
m_Tournament = tourney;
|
||||
m_Registrar = registrar;
|
||||
m_Players = players;
|
||||
|
||||
m_Active = true;
|
||||
|
||||
var ruleset = tourney.Ruleset;
|
||||
var basedef = ruleset.Base;
|
||||
|
||||
var height = 185 + 35 + 60 + 12;
|
||||
|
||||
var changes = 0;
|
||||
|
||||
BitArray defs;
|
||||
|
||||
if (ruleset.Flavors.Count > 0)
|
||||
{
|
||||
defs = new BitArray(basedef.Options);
|
||||
|
||||
for (var i = 0; i < ruleset.Flavors.Count; ++i)
|
||||
defs.Or(ruleset.Flavors[i].Options);
|
||||
|
||||
height += ruleset.Flavors.Count * 18;
|
||||
}
|
||||
else
|
||||
{
|
||||
defs = basedef.Options;
|
||||
}
|
||||
|
||||
var opts = ruleset.Options;
|
||||
|
||||
for (var i = 0; i < opts.Length; ++i)
|
||||
if (defs[i] != opts[i])
|
||||
++changes;
|
||||
|
||||
height += changes * 22;
|
||||
|
||||
height += 10 + 22 + 25 + 25;
|
||||
|
||||
Closable = false;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
AddBackground(1, 1, 398, height, 3600);
|
||||
|
||||
AddImageTiled(16, 15, 369, height - 29, 3604);
|
||||
AddAlphaRegion(16, 15, 369, height - 29);
|
||||
|
||||
AddImage(215, -43, 0xEE40);
|
||||
|
||||
var sb = new StringBuilder();
|
||||
|
||||
if (tourney.TourneyType == TourneyType.FreeForAll)
|
||||
{
|
||||
sb.Append("FFA");
|
||||
}
|
||||
else if (tourney.TourneyType == TourneyType.RandomTeam)
|
||||
{
|
||||
sb.Append(tourney.ParticipantsPerMatch);
|
||||
sb.Append("-Team");
|
||||
}
|
||||
else if (tourney.TourneyType == TourneyType.Faction)
|
||||
{
|
||||
sb.Append(tourney.ParticipantsPerMatch);
|
||||
sb.Append("-Team Faction");
|
||||
}
|
||||
else if (tourney.TourneyType == TourneyType.RedVsBlue)
|
||||
{
|
||||
sb.Append("Red v Blue");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var i = 0; i < tourney.ParticipantsPerMatch; ++i)
|
||||
{
|
||||
if (sb.Length > 0)
|
||||
sb.Append('v');
|
||||
|
||||
sb.Append(tourney.PlayersPerParticipant);
|
||||
}
|
||||
}
|
||||
|
||||
if (tourney.EventController != null)
|
||||
sb.Append(' ').Append(tourney.EventController.Title);
|
||||
|
||||
sb.Append(" Tournament Invitation");
|
||||
|
||||
AddBorderedText(22, 22, 294, 20, Center(sb.ToString()), LabelColor32, BlackColor32);
|
||||
|
||||
AddBorderedText(
|
||||
22,
|
||||
50,
|
||||
294,
|
||||
40,
|
||||
$"You have been asked to partner with {from.Name} in a tournament. Do you accept?",
|
||||
0xB0C868,
|
||||
BlackColor32
|
||||
);
|
||||
|
||||
AddImageTiled(32, 88, 264, 1, 9107);
|
||||
AddImageTiled(42, 90, 264, 1, 9157);
|
||||
|
||||
var y = 100;
|
||||
|
||||
var groupText = tourney.GroupType switch
|
||||
{
|
||||
GroupingType.HighVsLow => "High vs Low",
|
||||
GroupingType.Nearest => "Closest opponent",
|
||||
GroupingType.Random => "Random",
|
||||
_ => null
|
||||
};
|
||||
|
||||
AddBorderedText(35, y, 190, 20, $"Grouping: {groupText}", LabelColor32, BlackColor32);
|
||||
y += 20;
|
||||
|
||||
var tieText = tourney.TieType switch
|
||||
{
|
||||
TieType.Random => "Random",
|
||||
TieType.Highest => "Highest advances",
|
||||
TieType.Lowest => "Lowest advances",
|
||||
TieType.FullAdvancement => tourney.ParticipantsPerMatch == 2 ? "Both advance" : "Everyone advances",
|
||||
TieType.FullElimination => tourney.ParticipantsPerMatch == 2 ? "Both eliminated" : "Everyone eliminated",
|
||||
_ => null
|
||||
};
|
||||
|
||||
AddBorderedText(35, y, 190, 20, $"Tiebreaker: {tieText}", LabelColor32, BlackColor32);
|
||||
y += 20;
|
||||
|
||||
var sdText = "Off";
|
||||
|
||||
if (tourney.SuddenDeath > TimeSpan.Zero)
|
||||
{
|
||||
sdText = $"{(int)tourney.SuddenDeath.TotalMinutes}:{tourney.SuddenDeath.Seconds:D2}";
|
||||
|
||||
if (tourney.SuddenDeathRounds > 0)
|
||||
sdText = $"{sdText} (first {tourney.SuddenDeathRounds} rounds)";
|
||||
else
|
||||
sdText = $"{sdText} (all rounds)";
|
||||
}
|
||||
|
||||
AddBorderedText(35, y, 240, 20, $"Sudden Death: {sdText}", LabelColor32, BlackColor32);
|
||||
y += 20;
|
||||
|
||||
y += 6;
|
||||
AddImageTiled(32, y - 1, 264, 1, 9107);
|
||||
AddImageTiled(42, y + 1, 264, 1, 9157);
|
||||
y += 6;
|
||||
|
||||
AddBorderedText(35, y, 190, 20, $"Ruleset: {basedef.Title}", LabelColor32, BlackColor32);
|
||||
y += 20;
|
||||
|
||||
for (var i = 0; i < ruleset.Flavors.Count; ++i, y += 18)
|
||||
AddBorderedText(35, y, 190, 20, $" + {ruleset.Flavors[i].Title}", LabelColor32, BlackColor32);
|
||||
|
||||
y += 4;
|
||||
|
||||
if (changes > 0)
|
||||
{
|
||||
AddBorderedText(35, y, 190, 20, "Modifications:", LabelColor32, BlackColor32);
|
||||
y += 20;
|
||||
|
||||
for (var i = 0; i < opts.Length; ++i)
|
||||
if (defs[i] != opts[i])
|
||||
{
|
||||
var name = ruleset.Layout.FindByIndex(i);
|
||||
|
||||
if (name != null) // sanity
|
||||
{
|
||||
AddImage(35, y, opts[i] ? 0xD3 : 0xD2);
|
||||
AddBorderedText(60, y, 165, 22, name, LabelColor32, BlackColor32);
|
||||
}
|
||||
|
||||
y += 22;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddBorderedText(35, y, 190, 20, "Modifications: None", LabelColor32, BlackColor32);
|
||||
y += 20;
|
||||
}
|
||||
|
||||
y += 8;
|
||||
AddImageTiled(32, y - 1, 264, 1, 9107);
|
||||
AddImageTiled(42, y + 1, 264, 1, 9157);
|
||||
y += 8;
|
||||
|
||||
AddRadio(24, y, 9727, 9730, true, 1);
|
||||
AddBorderedText(60, y + 5, 250, 20, "Yes, I will join them.", LabelColor32, BlackColor32);
|
||||
y += 35;
|
||||
|
||||
AddRadio(24, y, 9727, 9730, false, 2);
|
||||
AddBorderedText(60, y + 5, 250, 20, "No, I do not wish to fight.", LabelColor32, BlackColor32);
|
||||
y += 35;
|
||||
|
||||
AddRadio(24, y, 9727, 9730, false, 3);
|
||||
AddBorderedText(60, y + 5, 270, 20, "No, most certainly not. Do not ask again.", LabelColor32, BlackColor32);
|
||||
y += 35;
|
||||
|
||||
y -= 3;
|
||||
AddButton(314, y, 247, 248, 1);
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(15.0), AutoReject);
|
||||
}
|
||||
|
||||
public string Center(string text) => $"<CENTER>{text}</CENTER>";
|
||||
|
||||
public string Color(string text, int color) => $"<BASEFONT COLOR=#{color:X6}>{text}</BASEFONT>";
|
||||
|
||||
private void AddBorderedText(int x, int y, int width, int height, string text, int color, int borderColor)
|
||||
{
|
||||
AddColoredText(x - 1, y - 1, width, height, text, borderColor);
|
||||
AddColoredText(x - 1, y + 1, width, height, text, borderColor);
|
||||
AddColoredText(x + 1, y - 1, width, height, text, borderColor);
|
||||
AddColoredText(x + 1, y + 1, width, height, text, borderColor);
|
||||
AddColoredText(x, y, width, height, text, color);
|
||||
}
|
||||
|
||||
private void AddColoredText(int x, int y, int width, int height, string text, int color)
|
||||
{
|
||||
if (color == 0)
|
||||
AddHtml(x, y, width, height, text);
|
||||
else
|
||||
AddHtml(x, y, width, height, Color(text, color));
|
||||
}
|
||||
|
||||
public void AutoReject()
|
||||
{
|
||||
if (!m_Active)
|
||||
return;
|
||||
|
||||
m_Active = false;
|
||||
|
||||
m_Requested.CloseGump<AcceptTeamGump>();
|
||||
m_From.SendGump(new ConfirmSignupGump(m_From, m_Registrar, m_Tournament, m_Players));
|
||||
|
||||
if (m_Registrar != null)
|
||||
{
|
||||
m_Registrar.PrivateOverheadMessage(
|
||||
MessageType.Regular,
|
||||
0x22,
|
||||
false,
|
||||
$"{m_Requested.Name} seems unresponsive.",
|
||||
m_From.NetState
|
||||
);
|
||||
|
||||
m_Registrar.PrivateOverheadMessage(
|
||||
MessageType.Regular,
|
||||
0x22,
|
||||
false,
|
||||
$"You have declined the partnership with {m_From.Name}.",
|
||||
m_Requested.NetState
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
var from = m_From;
|
||||
var mob = m_Requested;
|
||||
|
||||
if (info.ButtonID != 1 || !m_Active)
|
||||
return;
|
||||
|
||||
m_Active = false;
|
||||
|
||||
if (info.IsSwitched(1))
|
||||
{
|
||||
if (!(mob is PlayerMobile pm))
|
||||
return;
|
||||
|
||||
if (AcceptDuelGump.IsIgnored(mob, from) || mob.Blessed)
|
||||
{
|
||||
m_From.SendGump(new ConfirmSignupGump(m_From, m_Registrar, m_Tournament, m_Players));
|
||||
|
||||
m_Registrar?.PrivateOverheadMessage(
|
||||
MessageType.Regular,
|
||||
0x22,
|
||||
false,
|
||||
"They ignore your invitation.",
|
||||
from.NetState
|
||||
);
|
||||
}
|
||||
else if (pm.DuelContext != null)
|
||||
{
|
||||
m_From.SendGump(new ConfirmSignupGump(m_From, m_Registrar, m_Tournament, m_Players));
|
||||
|
||||
m_Registrar?.PrivateOverheadMessage(
|
||||
MessageType.Regular,
|
||||
0x22,
|
||||
false,
|
||||
"They are already assigned to another duel.",
|
||||
from.NetState
|
||||
);
|
||||
}
|
||||
else if (m_Players.Contains(mob))
|
||||
{
|
||||
m_From.SendGump(new ConfirmSignupGump(m_From, m_Registrar, m_Tournament, m_Players));
|
||||
|
||||
m_Registrar?.PrivateOverheadMessage(
|
||||
MessageType.Regular,
|
||||
0x22,
|
||||
false,
|
||||
"You have already named them as a team member.",
|
||||
from.NetState
|
||||
);
|
||||
}
|
||||
else if (m_Tournament.HasParticipant(mob))
|
||||
{
|
||||
m_From.SendGump(new ConfirmSignupGump(m_From, m_Registrar, m_Tournament, m_Players));
|
||||
|
||||
m_Registrar?.PrivateOverheadMessage(
|
||||
MessageType.Regular,
|
||||
0x22,
|
||||
false,
|
||||
"They have already entered this tournament.",
|
||||
from.NetState
|
||||
);
|
||||
}
|
||||
else if (m_Players.Count >= m_Tournament.PlayersPerParticipant)
|
||||
{
|
||||
m_From.SendGump(new ConfirmSignupGump(m_From, m_Registrar, m_Tournament, m_Players));
|
||||
|
||||
m_Registrar?.PrivateOverheadMessage(
|
||||
MessageType.Regular,
|
||||
0x22,
|
||||
false,
|
||||
"Your team is full.",
|
||||
from.NetState
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Players.Add(mob);
|
||||
|
||||
m_From.SendGump(new ConfirmSignupGump(m_From, m_Registrar, m_Tournament, m_Players));
|
||||
|
||||
if (m_Registrar != null)
|
||||
{
|
||||
m_Registrar.PrivateOverheadMessage(
|
||||
MessageType.Regular,
|
||||
0x59,
|
||||
false,
|
||||
$"{mob.Name} has accepted your offer of partnership.",
|
||||
from.NetState
|
||||
);
|
||||
|
||||
m_Registrar.PrivateOverheadMessage(
|
||||
MessageType.Regular,
|
||||
0x59,
|
||||
false,
|
||||
$"You have accepted the partnership with {from.Name}.",
|
||||
mob.NetState
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (info.IsSwitched(3))
|
||||
AcceptDuelGump.BeginIgnore(m_Requested, m_From);
|
||||
|
||||
m_From.SendGump(new ConfirmSignupGump(m_From, m_Registrar, m_Tournament, m_Players));
|
||||
|
||||
if (m_Registrar != null)
|
||||
{
|
||||
m_Registrar.PrivateOverheadMessage(
|
||||
MessageType.Regular,
|
||||
0x22,
|
||||
false,
|
||||
$"{mob.Name} has declined your offer of partnership.",
|
||||
from.NetState
|
||||
);
|
||||
|
||||
m_Registrar.PrivateOverheadMessage(
|
||||
MessageType.Regular,
|
||||
0x22,
|
||||
false,
|
||||
$"You have declined the partnership with {from.Name}.",
|
||||
mob.NetState
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,276 +1,278 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class ArenasMoongate : Item
|
||||
{
|
||||
[Constructible]
|
||||
public ArenasMoongate() : base(0x1FD4)
|
||||
{
|
||||
Movable = false;
|
||||
Light = LightType.Circle300;
|
||||
}
|
||||
|
||||
public ArenasMoongate(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "arena moongate";
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
Light = LightType.Circle300;
|
||||
}
|
||||
|
||||
public bool UseGate(Mobile from)
|
||||
{
|
||||
if (DuelContext.CheckCombat(from))
|
||||
{
|
||||
from.SendMessage(0x22, "You have recently been in combat with another player and cannot use this moongate.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (from.Spell != null)
|
||||
{
|
||||
from.SendLocalizedMessage(1049616); // You are too busy to do that at the moment.
|
||||
return false;
|
||||
}
|
||||
|
||||
from.CloseGump<ArenaGump>();
|
||||
from.SendGump(new ArenaGump(from, this));
|
||||
|
||||
if (!from.Hidden || from.AccessLevel == AccessLevel.Player)
|
||||
Effects.PlaySound(from.Location, from.Map, 0x20E);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (from.InRange(GetWorldLocation(), 1))
|
||||
UseGate(from);
|
||||
else
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that
|
||||
}
|
||||
|
||||
public override bool OnMoveOver(Mobile m) => !m.Player || UseGate(m);
|
||||
}
|
||||
|
||||
public class ArenaGump : Gump
|
||||
{
|
||||
private readonly List<Arena> m_Arenas;
|
||||
|
||||
private int m_ColumnX = 12;
|
||||
private readonly Mobile m_From;
|
||||
private readonly ArenasMoongate m_Gate;
|
||||
|
||||
public ArenaGump(Mobile from, ArenasMoongate gate) : base(50, 50)
|
||||
{
|
||||
m_From = from;
|
||||
m_Gate = gate;
|
||||
m_Arenas = Arena.Arenas;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
int height = 12 + 20 + m_Arenas.Count * 31 + 24 + 12;
|
||||
|
||||
AddBackground(0, 0, 499 + 40, height, 0x2436);
|
||||
|
||||
List<Arena> list = m_Arenas;
|
||||
|
||||
for (int i = 1; i < list.Count; i += 2)
|
||||
AddImageTiled(12, 32 + i * 31, 475 + 40, 30, 0x2430);
|
||||
|
||||
AddAlphaRegion(10, 10, 479 + 40, height - 20);
|
||||
|
||||
AddColumnHeader(35, null);
|
||||
AddColumnHeader(115, "Arena");
|
||||
AddColumnHeader(325, "Participants");
|
||||
AddColumnHeader(40, "Obs");
|
||||
|
||||
AddButton(499 + 40 - 12 - 63 - 4 - 63, height - 12 - 24, 247, 248, 1);
|
||||
AddButton(499 + 40 - 12 - 63, height - 12 - 24, 241, 242, 2);
|
||||
|
||||
for (int i = 0; i < list.Count; ++i)
|
||||
{
|
||||
Arena ar = list[i];
|
||||
|
||||
int x = 12;
|
||||
int y = 32 + i * 31;
|
||||
|
||||
int color = ar.Players.Count > 0 ? 0xCCFFCC : 0xCCCCCC;
|
||||
|
||||
AddRadio(x + 3, y + 1, 9727, 9730, false, i);
|
||||
x += 35;
|
||||
|
||||
AddBorderedText(x + 5, y + 5, 115 - 5, ar.Name ?? "(no name)", color, 0);
|
||||
x += 115;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
if (ar.Players.Count > 0)
|
||||
{
|
||||
Ladder ladder = Ladder.Instance;
|
||||
|
||||
if (ladder == null)
|
||||
continue;
|
||||
|
||||
LadderEntry p1 = null, p2 = null, p3 = null, p4 = null;
|
||||
|
||||
for (int j = 0; j < ar.Players.Count; ++j)
|
||||
{
|
||||
Mobile mob = ar.Players[j];
|
||||
LadderEntry c = ladder.Find(mob);
|
||||
|
||||
if (p1 == null || c.Index < p1.Index)
|
||||
{
|
||||
p4 = p3;
|
||||
p3 = p2;
|
||||
p2 = p1;
|
||||
p1 = c;
|
||||
}
|
||||
else if (p2 == null || c.Index < p2.Index)
|
||||
{
|
||||
p4 = p3;
|
||||
p3 = p2;
|
||||
p2 = c;
|
||||
}
|
||||
else if (p3 == null || c.Index < p3.Index)
|
||||
{
|
||||
p4 = p3;
|
||||
p3 = c;
|
||||
}
|
||||
else if (p4 == null || c.Index < p4.Index)
|
||||
{
|
||||
p4 = c;
|
||||
}
|
||||
}
|
||||
|
||||
Append(sb, p1);
|
||||
Append(sb, p2);
|
||||
Append(sb, p3);
|
||||
Append(sb, p4);
|
||||
|
||||
if (ar.Players.Count > 4)
|
||||
sb.Append(", ...");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append("Empty");
|
||||
}
|
||||
|
||||
AddBorderedText(x + 5, y + 5, 325 - 5, sb.ToString(), color, 0);
|
||||
x += 325;
|
||||
|
||||
AddBorderedText(x, y + 5, 40, Center(ar.Spectators.ToString()), color, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private void Append(StringBuilder sb, LadderEntry le)
|
||||
{
|
||||
if (le == null)
|
||||
return;
|
||||
|
||||
if (sb.Length > 0)
|
||||
sb.Append(", ");
|
||||
|
||||
sb.Append(le.Mobile.Name);
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (info.ButtonID != 1)
|
||||
return;
|
||||
|
||||
int[] switches = info.Switches;
|
||||
|
||||
if (switches.Length == 0)
|
||||
return;
|
||||
|
||||
int opt = switches[0];
|
||||
|
||||
if (opt < 0 || opt >= m_Arenas.Count)
|
||||
return;
|
||||
|
||||
Arena arena = m_Arenas[opt];
|
||||
|
||||
if (!m_From.InRange(m_Gate.GetWorldLocation(), 1) || m_From.Map != m_Gate.Map)
|
||||
{
|
||||
m_From.SendLocalizedMessage(1019002); // You are too far away to use the gate.
|
||||
}
|
||||
else if (DuelContext.CheckCombat(m_From))
|
||||
{
|
||||
m_From.SendMessage(0x22,
|
||||
"You have recently been in combat with another player and cannot use this moongate.");
|
||||
}
|
||||
else if (m_From.Spell != null)
|
||||
{
|
||||
m_From.SendLocalizedMessage(1049616); // You are too busy to do that at the moment.
|
||||
}
|
||||
else if (m_From.Map == arena.Facet && arena.Zone.Contains(m_From))
|
||||
{
|
||||
m_From.SendLocalizedMessage(1019003); // You are already there.
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseCreature.TeleportPets(m_From, arena.GateIn, arena.Facet);
|
||||
|
||||
m_From.Combatant = null;
|
||||
m_From.Warmode = false;
|
||||
m_From.Hidden = true;
|
||||
|
||||
m_From.MoveToWorld(arena.GateIn, arena.Facet);
|
||||
|
||||
Effects.PlaySound(arena.GateIn, arena.Facet, 0x1FE);
|
||||
}
|
||||
}
|
||||
|
||||
public string Center(string text) => $"<CENTER>{text}</CENTER>";
|
||||
|
||||
public string Color(string text, int color) => $"<BASEFONT COLOR=#{color:X6}>{text}</BASEFONT>";
|
||||
|
||||
private void AddBorderedText(int x, int y, int width, string text, int color, int borderColor)
|
||||
{
|
||||
/*AddColoredText( x - 1, y, width, text, borderColor );
|
||||
AddColoredText( x + 1, y, width, text, borderColor );
|
||||
AddColoredText( x, y - 1, width, text, borderColor );
|
||||
AddColoredText( x, y + 1, width, text, borderColor );*/
|
||||
/*AddColoredText( x - 1, y - 1, width, text, borderColor );
|
||||
AddColoredText( x + 1, y + 1, width, text, borderColor );*/
|
||||
AddColoredText(x, y, width, text, color);
|
||||
}
|
||||
|
||||
private void AddColoredText(int x, int y, int width, string text, int color)
|
||||
{
|
||||
if (color == 0)
|
||||
AddHtml(x, y, width, 20, text);
|
||||
else
|
||||
AddHtml(x, y, width, 20, Color(text, color));
|
||||
}
|
||||
|
||||
private void AddColumnHeader(int width, string name)
|
||||
{
|
||||
AddBackground(m_ColumnX, 12, width, 20, 0x242C);
|
||||
AddImageTiled(m_ColumnX + 2, 14, width - 4, 16, 0x2430);
|
||||
|
||||
if (name != null)
|
||||
AddBorderedText(m_ColumnX, 13, width, Center(name), 0xFFFFFF, 0);
|
||||
|
||||
m_ColumnX += width;
|
||||
}
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class ArenasMoongate : Item
|
||||
{
|
||||
[Constructible]
|
||||
public ArenasMoongate() : base(0x1FD4)
|
||||
{
|
||||
Movable = false;
|
||||
Light = LightType.Circle300;
|
||||
}
|
||||
|
||||
public ArenasMoongate(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "arena moongate";
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.ReadInt();
|
||||
Light = LightType.Circle300;
|
||||
}
|
||||
|
||||
public bool UseGate(Mobile from)
|
||||
{
|
||||
if (DuelContext.CheckCombat(from))
|
||||
{
|
||||
from.SendMessage(0x22, "You have recently been in combat with another player and cannot use this moongate.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (from.Spell != null)
|
||||
{
|
||||
from.SendLocalizedMessage(1049616); // You are too busy to do that at the moment.
|
||||
return false;
|
||||
}
|
||||
|
||||
from.CloseGump<ArenaGump>();
|
||||
from.SendGump(new ArenaGump(from, this));
|
||||
|
||||
if (!from.Hidden || from.AccessLevel == AccessLevel.Player)
|
||||
Effects.PlaySound(from.Location, from.Map, 0x20E);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (from.InRange(GetWorldLocation(), 1))
|
||||
UseGate(from);
|
||||
else
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that
|
||||
}
|
||||
|
||||
public override bool OnMoveOver(Mobile m) => !m.Player || UseGate(m);
|
||||
}
|
||||
|
||||
public class ArenaGump : Gump
|
||||
{
|
||||
private readonly List<Arena> m_Arenas;
|
||||
private readonly Mobile m_From;
|
||||
private readonly ArenasMoongate m_Gate;
|
||||
|
||||
private int m_ColumnX = 12;
|
||||
|
||||
public ArenaGump(Mobile from, ArenasMoongate gate) : base(50, 50)
|
||||
{
|
||||
m_From = from;
|
||||
m_Gate = gate;
|
||||
m_Arenas = Arena.Arenas;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
var height = 12 + 20 + m_Arenas.Count * 31 + 24 + 12;
|
||||
|
||||
AddBackground(0, 0, 499 + 40, height, 0x2436);
|
||||
|
||||
var list = m_Arenas;
|
||||
|
||||
for (var i = 1; i < list.Count; i += 2)
|
||||
AddImageTiled(12, 32 + i * 31, 475 + 40, 30, 0x2430);
|
||||
|
||||
AddAlphaRegion(10, 10, 479 + 40, height - 20);
|
||||
|
||||
AddColumnHeader(35, null);
|
||||
AddColumnHeader(115, "Arena");
|
||||
AddColumnHeader(325, "Participants");
|
||||
AddColumnHeader(40, "Obs");
|
||||
|
||||
AddButton(499 + 40 - 12 - 63 - 4 - 63, height - 12 - 24, 247, 248, 1);
|
||||
AddButton(499 + 40 - 12 - 63, height - 12 - 24, 241, 242, 2);
|
||||
|
||||
for (var i = 0; i < list.Count; ++i)
|
||||
{
|
||||
var ar = list[i];
|
||||
|
||||
var x = 12;
|
||||
var y = 32 + i * 31;
|
||||
|
||||
var color = ar.Players.Count > 0 ? 0xCCFFCC : 0xCCCCCC;
|
||||
|
||||
AddRadio(x + 3, y + 1, 9727, 9730, false, i);
|
||||
x += 35;
|
||||
|
||||
AddBorderedText(x + 5, y + 5, 115 - 5, ar.Name ?? "(no name)", color, 0);
|
||||
x += 115;
|
||||
|
||||
var sb = new StringBuilder();
|
||||
|
||||
if (ar.Players.Count > 0)
|
||||
{
|
||||
var ladder = Ladder.Instance;
|
||||
|
||||
if (ladder == null)
|
||||
continue;
|
||||
|
||||
LadderEntry p1 = null, p2 = null, p3 = null, p4 = null;
|
||||
|
||||
for (var j = 0; j < ar.Players.Count; ++j)
|
||||
{
|
||||
var mob = ar.Players[j];
|
||||
var c = ladder.Find(mob);
|
||||
|
||||
if (p1 == null || c.Index < p1.Index)
|
||||
{
|
||||
p4 = p3;
|
||||
p3 = p2;
|
||||
p2 = p1;
|
||||
p1 = c;
|
||||
}
|
||||
else if (p2 == null || c.Index < p2.Index)
|
||||
{
|
||||
p4 = p3;
|
||||
p3 = p2;
|
||||
p2 = c;
|
||||
}
|
||||
else if (p3 == null || c.Index < p3.Index)
|
||||
{
|
||||
p4 = p3;
|
||||
p3 = c;
|
||||
}
|
||||
else if (p4 == null || c.Index < p4.Index)
|
||||
{
|
||||
p4 = c;
|
||||
}
|
||||
}
|
||||
|
||||
Append(sb, p1);
|
||||
Append(sb, p2);
|
||||
Append(sb, p3);
|
||||
Append(sb, p4);
|
||||
|
||||
if (ar.Players.Count > 4)
|
||||
sb.Append(", ...");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append("Empty");
|
||||
}
|
||||
|
||||
AddBorderedText(x + 5, y + 5, 325 - 5, sb.ToString(), color, 0);
|
||||
x += 325;
|
||||
|
||||
AddBorderedText(x, y + 5, 40, Center(ar.Spectators.ToString()), color, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private void Append(StringBuilder sb, LadderEntry le)
|
||||
{
|
||||
if (le == null)
|
||||
return;
|
||||
|
||||
if (sb.Length > 0)
|
||||
sb.Append(", ");
|
||||
|
||||
sb.Append(le.Mobile.Name);
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (info.ButtonID != 1)
|
||||
return;
|
||||
|
||||
var switches = info.Switches;
|
||||
|
||||
if (switches.Length == 0)
|
||||
return;
|
||||
|
||||
var opt = switches[0];
|
||||
|
||||
if (opt < 0 || opt >= m_Arenas.Count)
|
||||
return;
|
||||
|
||||
var arena = m_Arenas[opt];
|
||||
|
||||
if (!m_From.InRange(m_Gate.GetWorldLocation(), 1) || m_From.Map != m_Gate.Map)
|
||||
{
|
||||
m_From.SendLocalizedMessage(1019002); // You are too far away to use the gate.
|
||||
}
|
||||
else if (DuelContext.CheckCombat(m_From))
|
||||
{
|
||||
m_From.SendMessage(
|
||||
0x22,
|
||||
"You have recently been in combat with another player and cannot use this moongate."
|
||||
);
|
||||
}
|
||||
else if (m_From.Spell != null)
|
||||
{
|
||||
m_From.SendLocalizedMessage(1049616); // You are too busy to do that at the moment.
|
||||
}
|
||||
else if (m_From.Map == arena.Facet && arena.Zone.Contains(m_From))
|
||||
{
|
||||
m_From.SendLocalizedMessage(1019003); // You are already there.
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseCreature.TeleportPets(m_From, arena.GateIn, arena.Facet);
|
||||
|
||||
m_From.Combatant = null;
|
||||
m_From.Warmode = false;
|
||||
m_From.Hidden = true;
|
||||
|
||||
m_From.MoveToWorld(arena.GateIn, arena.Facet);
|
||||
|
||||
Effects.PlaySound(arena.GateIn, arena.Facet, 0x1FE);
|
||||
}
|
||||
}
|
||||
|
||||
public string Center(string text) => $"<CENTER>{text}</CENTER>";
|
||||
|
||||
public string Color(string text, int color) => $"<BASEFONT COLOR=#{color:X6}>{text}</BASEFONT>";
|
||||
|
||||
private void AddBorderedText(int x, int y, int width, string text, int color, int borderColor)
|
||||
{
|
||||
/*AddColoredText( x - 1, y, width, text, borderColor );
|
||||
AddColoredText( x + 1, y, width, text, borderColor );
|
||||
AddColoredText( x, y - 1, width, text, borderColor );
|
||||
AddColoredText( x, y + 1, width, text, borderColor );*/
|
||||
/*AddColoredText( x - 1, y - 1, width, text, borderColor );
|
||||
AddColoredText( x + 1, y + 1, width, text, borderColor );*/
|
||||
AddColoredText(x, y, width, text, color);
|
||||
}
|
||||
|
||||
private void AddColoredText(int x, int y, int width, string text, int color)
|
||||
{
|
||||
if (color == 0)
|
||||
AddHtml(x, y, width, 20, text);
|
||||
else
|
||||
AddHtml(x, y, width, 20, Color(text, color));
|
||||
}
|
||||
|
||||
private void AddColumnHeader(int width, string name)
|
||||
{
|
||||
AddBackground(m_ColumnX, 12, width, 20, 0x242C);
|
||||
AddImageTiled(m_ColumnX + 2, 14, width - 4, 16, 0x2430);
|
||||
|
||||
if (name != null)
|
||||
AddBorderedText(m_ColumnX, 13, width, Center(name), 0xFFFFFF, 0);
|
||||
|
||||
m_ColumnX += width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,66 +1,96 @@
|
|||
using Server.Gumps;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class BeginGump : Gump
|
||||
{
|
||||
private const int LabelColor32 = 0xFFFFFF;
|
||||
private const int BlackColor32 = 0x000008;
|
||||
|
||||
public BeginGump(int count) : base(50, 50)
|
||||
{
|
||||
AddPage(0);
|
||||
|
||||
const int offset = 50;
|
||||
|
||||
AddBackground(1, 1, 398, 202 - offset, 3600);
|
||||
|
||||
AddImageTiled(16, 15, 369, 173 - offset, 3604);
|
||||
AddAlphaRegion(16, 15, 369, 173 - offset);
|
||||
|
||||
AddImage(215, -43, 0xEE40);
|
||||
|
||||
AddHtml(22 - 1, 22, 294, 20, Color(Center("Duel Countdown"), BlackColor32));
|
||||
AddHtml(22 + 1, 22, 294, 20, Color(Center("Duel Countdown"), BlackColor32));
|
||||
AddHtml(22, 22 - 1, 294, 20, Color(Center("Duel Countdown"), BlackColor32));
|
||||
AddHtml(22, 22 + 1, 294, 20, Color(Center("Duel Countdown"), BlackColor32));
|
||||
AddHtml(22, 22, 294, 20, Color(Center("Duel Countdown"), LabelColor32));
|
||||
|
||||
AddHtml(22 - 1, 50, 294, 80,
|
||||
Color(
|
||||
"The arranged duel is about to begin. During this countdown period you may not cast spells and you may not move. This message will close automatically when the period ends.",
|
||||
BlackColor32));
|
||||
AddHtml(22 + 1, 50, 294, 80,
|
||||
Color(
|
||||
"The arranged duel is about to begin. During this countdown period you may not cast spells and you may not move. This message will close automatically when the period ends.",
|
||||
BlackColor32));
|
||||
AddHtml(22, 50 - 1, 294, 80,
|
||||
Color(
|
||||
"The arranged duel is about to begin. During this countdown period you may not cast spells and you may not move. This message will close automatically when the period ends.",
|
||||
BlackColor32));
|
||||
AddHtml(22, 50 + 1, 294, 80,
|
||||
Color(
|
||||
"The arranged duel is about to begin. During this countdown period you may not cast spells and you may not move. This message will close automatically when the period ends.",
|
||||
BlackColor32));
|
||||
AddHtml(22, 50, 294, 80,
|
||||
Color(
|
||||
"The arranged duel is about to begin. During this countdown period you may not cast spells and you may not move. This message will close automatically when the period ends.",
|
||||
0xFFCC66));
|
||||
|
||||
/*AddImageTiled( 32, 128, 264, 1, 9107 );
|
||||
AddImageTiled( 42, 130, 264, 1, 9157 );
|
||||
|
||||
AddHtml( 60-1, 140, 250, 20, Color( String.Format( "Duel will begin in <BASEFONT COLOR=#{2:X6}>{0} <BASEFONT COLOR=#{2:X6}>second{1}.", count, count==1?"":"s", BlackColor32 ), BlackColor32 ), false, false );
|
||||
AddHtml( 60+1, 140, 250, 20, Color( String.Format( "Duel will begin in <BASEFONT COLOR=#{2:X6}>{0} <BASEFONT COLOR=#{2:X6}>second{1}.", count, count==1?"":"s", BlackColor32 ), BlackColor32 ), false, false );
|
||||
AddHtml( 60, 140-1, 250, 20, Color( String.Format( "Duel will begin in <BASEFONT COLOR=#{2:X6}>{0} <BASEFONT COLOR=#{2:X6}>second{1}.", count, count==1?"":"s", BlackColor32 ), BlackColor32 ), false, false );
|
||||
AddHtml( 60, 140+1, 250, 20, Color( String.Format( "Duel will begin in <BASEFONT COLOR=#{2:X6}>{0} <BASEFONT COLOR=#{2:X6}>second{1}.", count, count==1?"":"s", BlackColor32 ), BlackColor32 ), false, false );
|
||||
AddHtml( 60, 140, 250, 20, Color( String.Format( "Duel will begin in <BASEFONT COLOR=#FF6666>{0} <BASEFONT COLOR=#{2:X6}>second{1}.", count, count==1?"":"s", 0x66AACC ), 0x66AACC ), false, false );*/
|
||||
|
||||
AddButton(314 - 50, 157 - offset, 247, 248, 1);
|
||||
}
|
||||
|
||||
public string Center(string text) => $"<CENTER>{text}</CENTER>";
|
||||
|
||||
public string Color(string text, int color) => $"<BASEFONT COLOR=#{color:X6}>{text}</BASEFONT>";
|
||||
}
|
||||
}
|
||||
using Server.Gumps;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class BeginGump : Gump
|
||||
{
|
||||
private const int LabelColor32 = 0xFFFFFF;
|
||||
private const int BlackColor32 = 0x000008;
|
||||
|
||||
public BeginGump(int count) : base(50, 50)
|
||||
{
|
||||
AddPage(0);
|
||||
|
||||
const int offset = 50;
|
||||
|
||||
AddBackground(1, 1, 398, 202 - offset, 3600);
|
||||
|
||||
AddImageTiled(16, 15, 369, 173 - offset, 3604);
|
||||
AddAlphaRegion(16, 15, 369, 173 - offset);
|
||||
|
||||
AddImage(215, -43, 0xEE40);
|
||||
|
||||
AddHtml(22 - 1, 22, 294, 20, Color(Center("Duel Countdown"), BlackColor32));
|
||||
AddHtml(22 + 1, 22, 294, 20, Color(Center("Duel Countdown"), BlackColor32));
|
||||
AddHtml(22, 22 - 1, 294, 20, Color(Center("Duel Countdown"), BlackColor32));
|
||||
AddHtml(22, 22 + 1, 294, 20, Color(Center("Duel Countdown"), BlackColor32));
|
||||
AddHtml(22, 22, 294, 20, Color(Center("Duel Countdown"), LabelColor32));
|
||||
|
||||
AddHtml(
|
||||
22 - 1,
|
||||
50,
|
||||
294,
|
||||
80,
|
||||
Color(
|
||||
"The arranged duel is about to begin. During this countdown period you may not cast spells and you may not move. This message will close automatically when the period ends.",
|
||||
BlackColor32
|
||||
)
|
||||
);
|
||||
AddHtml(
|
||||
22 + 1,
|
||||
50,
|
||||
294,
|
||||
80,
|
||||
Color(
|
||||
"The arranged duel is about to begin. During this countdown period you may not cast spells and you may not move. This message will close automatically when the period ends.",
|
||||
BlackColor32
|
||||
)
|
||||
);
|
||||
AddHtml(
|
||||
22,
|
||||
50 - 1,
|
||||
294,
|
||||
80,
|
||||
Color(
|
||||
"The arranged duel is about to begin. During this countdown period you may not cast spells and you may not move. This message will close automatically when the period ends.",
|
||||
BlackColor32
|
||||
)
|
||||
);
|
||||
AddHtml(
|
||||
22,
|
||||
50 + 1,
|
||||
294,
|
||||
80,
|
||||
Color(
|
||||
"The arranged duel is about to begin. During this countdown period you may not cast spells and you may not move. This message will close automatically when the period ends.",
|
||||
BlackColor32
|
||||
)
|
||||
);
|
||||
AddHtml(
|
||||
22,
|
||||
50,
|
||||
294,
|
||||
80,
|
||||
Color(
|
||||
"The arranged duel is about to begin. During this countdown period you may not cast spells and you may not move. This message will close automatically when the period ends.",
|
||||
0xFFCC66
|
||||
)
|
||||
);
|
||||
|
||||
/*AddImageTiled( 32, 128, 264, 1, 9107 );
|
||||
AddImageTiled( 42, 130, 264, 1, 9157 );
|
||||
|
||||
AddHtml( 60-1, 140, 250, 20, Color( String.Format( "Duel will begin in <BASEFONT COLOR=#{2:X6}>{0} <BASEFONT COLOR=#{2:X6}>second{1}.", count, count==1?"":"s", BlackColor32 ), BlackColor32 ), false, false );
|
||||
AddHtml( 60+1, 140, 250, 20, Color( String.Format( "Duel will begin in <BASEFONT COLOR=#{2:X6}>{0} <BASEFONT COLOR=#{2:X6}>second{1}.", count, count==1?"":"s", BlackColor32 ), BlackColor32 ), false, false );
|
||||
AddHtml( 60, 140-1, 250, 20, Color( String.Format( "Duel will begin in <BASEFONT COLOR=#{2:X6}>{0} <BASEFONT COLOR=#{2:X6}>second{1}.", count, count==1?"":"s", BlackColor32 ), BlackColor32 ), false, false );
|
||||
AddHtml( 60, 140+1, 250, 20, Color( String.Format( "Duel will begin in <BASEFONT COLOR=#{2:X6}>{0} <BASEFONT COLOR=#{2:X6}>second{1}.", count, count==1?"":"s", BlackColor32 ), BlackColor32 ), false, false );
|
||||
AddHtml( 60, 140, 250, 20, Color( String.Format( "Duel will begin in <BASEFONT COLOR=#FF6666>{0} <BASEFONT COLOR=#{2:X6}>second{1}.", count, count==1?"":"s", 0x66AACC ), 0x66AACC ), false, false );*/
|
||||
|
||||
AddButton(314 - 50, 157 - offset, 247, 248, 1);
|
||||
}
|
||||
|
||||
public string Center(string text) => $"<CENTER>{text}</CENTER>";
|
||||
|
||||
public string Color(string text, int color) => $"<BASEFONT COLOR=#{color:X6}>{text}</BASEFONT>";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,136 +1,147 @@
|
|||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class DuelContextGump : Gump
|
||||
{
|
||||
public DuelContextGump(Mobile from, DuelContext context) : base(50, 50)
|
||||
{
|
||||
From = from;
|
||||
Context = context;
|
||||
|
||||
from.CloseGump<RulesetGump>();
|
||||
from.CloseGump<DuelContextGump>();
|
||||
from.CloseGump<ParticipantGump>();
|
||||
|
||||
int count = context.Participants.Count;
|
||||
|
||||
if (count < 3)
|
||||
count = 3;
|
||||
|
||||
int height = 35 + 10 + 22 + 30 + 22 + 22 + 2 + count * 22 + 2 + 30;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
AddBackground(0, 0, 300, height, 9250);
|
||||
AddBackground(10, 10, 280, height - 20, 0xDAC);
|
||||
|
||||
AddHtml(35, 25, 230, 20, Center("Duel Setup"));
|
||||
|
||||
int x = 35;
|
||||
int y = 47;
|
||||
|
||||
AddGoldenButtonLabeled(x, y, 1, "Rules");
|
||||
y += 22;
|
||||
AddGoldenButtonLabeled(x, y, 2, "Start");
|
||||
y += 22;
|
||||
AddGoldenButtonLabeled(x, y, 3, "Add Participant");
|
||||
y += 30;
|
||||
|
||||
AddHtml(35, y, 230, 20, Center("Participants"));
|
||||
y += 22;
|
||||
|
||||
for (int i = 0; i < context.Participants.Count; ++i)
|
||||
{
|
||||
Participant p = context.Participants[i];
|
||||
|
||||
AddGoldenButtonLabeled(x, y, 4 + i,
|
||||
string.Format(p.Count == 1 ? "Player {0}: {3}" : "Team {0}: {1}/{2}: {3}", 1 + i, p.FilledSlots, p.Count,
|
||||
p.NameList));
|
||||
y += 22;
|
||||
}
|
||||
}
|
||||
|
||||
public Mobile From { get; }
|
||||
|
||||
public DuelContext Context { get; }
|
||||
|
||||
public string Center(string text) => $"<CENTER>{text}</CENTER>";
|
||||
|
||||
public void AddGoldenButton(int x, int y, int bid)
|
||||
{
|
||||
AddButton(x, y, 0xD2, 0xD2, bid);
|
||||
AddButton(x + 3, y + 3, 0xD8, 0xD8, bid);
|
||||
}
|
||||
|
||||
public void AddGoldenButtonLabeled(int x, int y, int bid, string text)
|
||||
{
|
||||
AddGoldenButton(x, y, bid);
|
||||
AddHtml(x + 25, y, 200, 20, text);
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (!Context.Registered)
|
||||
return;
|
||||
|
||||
int index = info.ButtonID;
|
||||
|
||||
switch (index)
|
||||
{
|
||||
case -1: // CloseGump
|
||||
{
|
||||
break;
|
||||
}
|
||||
case 0: // closed
|
||||
{
|
||||
Context.Unregister();
|
||||
break;
|
||||
}
|
||||
case 1: // Rules
|
||||
{
|
||||
// m_From.SendGump( new RulesetGump( m_From, m_Context.Ruleset, m_Context.Ruleset.Layout, m_Context ) );
|
||||
From.SendGump(new PickRulesetGump(From, Context, Context.Ruleset));
|
||||
break;
|
||||
}
|
||||
case 2: // Start
|
||||
{
|
||||
if (Context.CheckFull())
|
||||
{
|
||||
Context.CloseAllGumps();
|
||||
Context.SendReadyUpGump();
|
||||
// m_Context.SendReadyGump();
|
||||
}
|
||||
else
|
||||
{
|
||||
From.SendMessage("You cannot start the duel before all participating players have been assigned.");
|
||||
From.SendGump(new DuelContextGump(From, Context));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 3: // New Participant
|
||||
{
|
||||
if (Context.Participants.Count < 10)
|
||||
Context.Participants.Add(new Participant(Context, 1));
|
||||
else
|
||||
From.SendMessage("The number of participating parties may not be increased further.");
|
||||
|
||||
From.SendGump(new DuelContextGump(From, Context));
|
||||
|
||||
break;
|
||||
}
|
||||
default: // Participant
|
||||
{
|
||||
index -= 4;
|
||||
|
||||
if (index >= 0 && index < Context.Participants.Count)
|
||||
From.SendGump(new ParticipantGump(From, Context, Context.Participants[index]));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class DuelContextGump : Gump
|
||||
{
|
||||
public DuelContextGump(Mobile from, DuelContext context) : base(50, 50)
|
||||
{
|
||||
From = from;
|
||||
Context = context;
|
||||
|
||||
from.CloseGump<RulesetGump>();
|
||||
from.CloseGump<DuelContextGump>();
|
||||
from.CloseGump<ParticipantGump>();
|
||||
|
||||
var count = context.Participants.Count;
|
||||
|
||||
if (count < 3)
|
||||
count = 3;
|
||||
|
||||
var height = 35 + 10 + 22 + 30 + 22 + 22 + 2 + count * 22 + 2 + 30;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
AddBackground(0, 0, 300, height, 9250);
|
||||
AddBackground(10, 10, 280, height - 20, 0xDAC);
|
||||
|
||||
AddHtml(35, 25, 230, 20, Center("Duel Setup"));
|
||||
|
||||
var x = 35;
|
||||
var y = 47;
|
||||
|
||||
AddGoldenButtonLabeled(x, y, 1, "Rules");
|
||||
y += 22;
|
||||
AddGoldenButtonLabeled(x, y, 2, "Start");
|
||||
y += 22;
|
||||
AddGoldenButtonLabeled(x, y, 3, "Add Participant");
|
||||
y += 30;
|
||||
|
||||
AddHtml(35, y, 230, 20, Center("Participants"));
|
||||
y += 22;
|
||||
|
||||
for (var i = 0; i < context.Participants.Count; ++i)
|
||||
{
|
||||
var p = context.Participants[i];
|
||||
|
||||
AddGoldenButtonLabeled(
|
||||
x,
|
||||
y,
|
||||
4 + i,
|
||||
string.Format(
|
||||
p.Count == 1 ? "Player {0}: {3}" : "Team {0}: {1}/{2}: {3}",
|
||||
1 + i,
|
||||
p.FilledSlots,
|
||||
p.Count,
|
||||
p.NameList
|
||||
)
|
||||
);
|
||||
y += 22;
|
||||
}
|
||||
}
|
||||
|
||||
public Mobile From { get; }
|
||||
|
||||
public DuelContext Context { get; }
|
||||
|
||||
public string Center(string text) => $"<CENTER>{text}</CENTER>";
|
||||
|
||||
public void AddGoldenButton(int x, int y, int bid)
|
||||
{
|
||||
AddButton(x, y, 0xD2, 0xD2, bid);
|
||||
AddButton(x + 3, y + 3, 0xD8, 0xD8, bid);
|
||||
}
|
||||
|
||||
public void AddGoldenButtonLabeled(int x, int y, int bid, string text)
|
||||
{
|
||||
AddGoldenButton(x, y, bid);
|
||||
AddHtml(x + 25, y, 200, 20, text);
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (!Context.Registered)
|
||||
return;
|
||||
|
||||
var index = info.ButtonID;
|
||||
|
||||
switch (index)
|
||||
{
|
||||
case -1: // CloseGump
|
||||
{
|
||||
break;
|
||||
}
|
||||
case 0: // closed
|
||||
{
|
||||
Context.Unregister();
|
||||
break;
|
||||
}
|
||||
case 1: // Rules
|
||||
{
|
||||
// m_From.SendGump( new RulesetGump( m_From, m_Context.Ruleset, m_Context.Ruleset.Layout, m_Context ) );
|
||||
From.SendGump(new PickRulesetGump(From, Context, Context.Ruleset));
|
||||
break;
|
||||
}
|
||||
case 2: // Start
|
||||
{
|
||||
if (Context.CheckFull())
|
||||
{
|
||||
Context.CloseAllGumps();
|
||||
Context.SendReadyUpGump();
|
||||
// m_Context.SendReadyGump();
|
||||
}
|
||||
else
|
||||
{
|
||||
From.SendMessage(
|
||||
"You cannot start the duel before all participating players have been assigned."
|
||||
);
|
||||
From.SendGump(new DuelContextGump(From, Context));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 3: // New Participant
|
||||
{
|
||||
if (Context.Participants.Count < 10)
|
||||
Context.Participants.Add(new Participant(Context, 1));
|
||||
else
|
||||
From.SendMessage("The number of participating parties may not be increased further.");
|
||||
|
||||
From.SendGump(new DuelContextGump(From, Context));
|
||||
|
||||
break;
|
||||
}
|
||||
default: // Participant
|
||||
{
|
||||
index -= 4;
|
||||
|
||||
if (index >= 0 && index < Context.Participants.Count)
|
||||
From.SendGump(new ParticipantGump(From, Context, Context.Participants[index]));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,239 +1,246 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class LadderItem : Item
|
||||
{
|
||||
[Constructible]
|
||||
public LadderItem() : base(0x117F) => Movable = false;
|
||||
|
||||
public LadderItem(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public LadderController Ladder { get; set; }
|
||||
|
||||
public override string DefaultName => "1v1 leaderboard";
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1);
|
||||
|
||||
writer.Write(Ladder);
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
Ladder = reader.ReadItem<LadderController>();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (from.InRange(GetWorldLocation(), 2))
|
||||
{
|
||||
Ladder ladder = ConPVP.Ladder.Instance ?? Ladder.Ladder;
|
||||
|
||||
if (ladder != null)
|
||||
{
|
||||
from.CloseGump<LadderGump>();
|
||||
from.SendGump(new LadderGump(ladder));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class LadderGump : Gump
|
||||
{
|
||||
private int m_ColumnX = 12;
|
||||
private readonly Ladder m_Ladder;
|
||||
|
||||
private readonly List<LadderEntry> m_List;
|
||||
private readonly int m_Page;
|
||||
|
||||
public LadderGump(Ladder ladder, int page = 0) : base(50, 50)
|
||||
{
|
||||
m_Ladder = ladder;
|
||||
m_Page = page;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
m_List = new List<LadderEntry>(ladder.Entries);
|
||||
|
||||
int lc = Math.Min(m_List.Count, 150);
|
||||
|
||||
int start = page * 15;
|
||||
int end = start + 15;
|
||||
|
||||
if (end > lc)
|
||||
end = lc;
|
||||
|
||||
int ct = end - start;
|
||||
|
||||
int height = 12 + 20 + ct * 20 + 23 + 12;
|
||||
|
||||
AddBackground(0, 0, 499, height, 0x2436);
|
||||
|
||||
for (int i = start + 1; i < end; i += 2)
|
||||
AddImageTiled(12, 32 + (i - start) * 20, 475, 20, 0x2430);
|
||||
|
||||
AddAlphaRegion(10, 10, 479, height - 20);
|
||||
|
||||
if (page > 0)
|
||||
AddButton(446, height - 12 - 2 - 16, 0x15E3, 0x15E7, 1);
|
||||
else
|
||||
AddImage(446, height - 12 - 2 - 16, 0x2626);
|
||||
|
||||
if ((page + 1) * 15 < lc)
|
||||
AddButton(466, height - 12 - 2 - 16, 0x15E1, 0x15E5, 2);
|
||||
else
|
||||
AddImage(466, height - 12 - 2 - 16, 0x2622);
|
||||
|
||||
AddHtml(16, height - 12 - 2 - 18, 400, 20,
|
||||
Color(string.Format("Top {3} of {0:N0} duelists, page {1} of {2}", m_List.Count, page + 1, (lc + 14) / 15, lc),
|
||||
0xFFC000));
|
||||
|
||||
AddColumnHeader(75, "Rank");
|
||||
AddColumnHeader(115, "Level");
|
||||
AddColumnHeader(50, "Guild");
|
||||
AddColumnHeader(115, "Name");
|
||||
AddColumnHeader(60, "Wins");
|
||||
AddColumnHeader(60, "Losses");
|
||||
|
||||
for (int i = start; i < end && i < lc; ++i)
|
||||
{
|
||||
LadderEntry entry = m_List[i];
|
||||
|
||||
int y = 32 + (i - start) * 20;
|
||||
int x = 12;
|
||||
|
||||
AddBorderedText(x, y, 75, Center(Rank(i + 1)), 0xFFFFFF, 0);
|
||||
x += 75;
|
||||
|
||||
/*AddImage( 20, y + 5, 0x2616, 0x96C );
|
||||
AddImage( 22, y + 5, 0x2616, 0x96C );
|
||||
AddImage( 20, y + 7, 0x2616, 0x96C );
|
||||
AddImage( 22, y + 7, 0x2616, 0x96C );
|
||||
|
||||
AddImage( 21, y + 6, 0x2616, 0x454 );*/
|
||||
|
||||
AddImage(x + 3, y + 4, 0x805);
|
||||
|
||||
int xp = entry.Experience;
|
||||
int level = Ladder.GetLevel(xp);
|
||||
|
||||
Ladder.GetLevelInfo(level, out int xpBase, out int xpAdvance);
|
||||
|
||||
int width;
|
||||
|
||||
int xpOffset = xp - xpBase;
|
||||
|
||||
if (xpOffset >= xpAdvance)
|
||||
width = 109; // level 50
|
||||
else
|
||||
width = (109 * xpOffset + xpAdvance / 2) / (xpAdvance - 1);
|
||||
|
||||
// AddImageTiled( 21, y + 6, width, 8, 0x2617 );
|
||||
AddImageTiled(x + 3, y + 4, width, 11, 0x806);
|
||||
AddBorderedText(x, y, 115, Center(level.ToString()), 0xFFFFFF, 0);
|
||||
x += 115;
|
||||
|
||||
Mobile mob = entry.Mobile;
|
||||
|
||||
if (mob.Guild != null)
|
||||
AddBorderedText(x, y, 50, Center(mob.Guild.Abbreviation), 0xFFFFFF, 0);
|
||||
|
||||
x += 50;
|
||||
|
||||
AddBorderedText(x + 5, y, 115 - 5, mob.Name, 0xFFFFFF, 0);
|
||||
x += 115;
|
||||
|
||||
AddBorderedText(x, y, 60, Center(entry.Wins.ToString()), 0xFFFFFF, 0);
|
||||
x += 60;
|
||||
|
||||
AddBorderedText(x, y, 60, Center(entry.Losses.ToString()), 0xFFFFFF, 0);
|
||||
x += 60;
|
||||
|
||||
// AddBorderedText( 292 + 15, y, 115 - 30, String.Format( "{0} <DIV ALIGN=CENTER>/</DIV> <DIV ALIGN=RIGHT>{1}</DIV>", entry.Wins, entry.Losses ), 0xFFC000, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
public static string Rank(int num)
|
||||
{
|
||||
string numStr = num.ToString("N0");
|
||||
|
||||
if (num % 100 > 10 && num % 100 < 20)
|
||||
return $"{numStr}th";
|
||||
|
||||
return (num % 10) switch
|
||||
{
|
||||
1 => $"{numStr}st",
|
||||
2 => $"{numStr}nd",
|
||||
3 => $"{numStr}rd",
|
||||
_ => $"{numStr}th"
|
||||
};
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
Mobile from = sender.Mobile;
|
||||
|
||||
if (info.ButtonID == 1 && m_Page > 0)
|
||||
from.SendGump(new LadderGump(m_Ladder, m_Page - 1));
|
||||
else if (info.ButtonID == 2 && (m_Page + 1) * 15 < Math.Min(m_List.Count, 150))
|
||||
from.SendGump(new LadderGump(m_Ladder, m_Page + 1));
|
||||
}
|
||||
|
||||
public string Center(string text) => $"<CENTER>{text}</CENTER>";
|
||||
|
||||
public string Color(string text, int color) => $"<BASEFONT COLOR=#{color:X6}>{text}</BASEFONT>";
|
||||
|
||||
private void AddBorderedText(int x, int y, int width, string text, int color, int borderColor)
|
||||
{
|
||||
/*AddColoredText( x - 1, y, width, text, borderColor );
|
||||
AddColoredText( x + 1, y, width, text, borderColor );
|
||||
AddColoredText( x, y - 1, width, text, borderColor );
|
||||
AddColoredText( x, y + 1, width, text, borderColor );*/
|
||||
/*AddColoredText( x - 1, y - 1, width, text, borderColor );
|
||||
AddColoredText( x + 1, y + 1, width, text, borderColor );*/
|
||||
AddColoredText(x, y, width, text, color);
|
||||
}
|
||||
|
||||
private void AddColoredText(int x, int y, int width, string text, int color)
|
||||
{
|
||||
if (color == 0)
|
||||
AddHtml(x, y, width, 20, text);
|
||||
else
|
||||
AddHtml(x, y, width, 20, Color(text, color));
|
||||
}
|
||||
|
||||
private void AddColumnHeader(int width, string name)
|
||||
{
|
||||
AddBackground(m_ColumnX, 12, width, 20, 0x242C);
|
||||
AddImageTiled(m_ColumnX + 2, 14, width - 4, 16, 0x2430);
|
||||
AddBorderedText(m_ColumnX, 13, width, Center(name), 0xFFFFFF, 0);
|
||||
|
||||
m_ColumnX += width;
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class LadderItem : Item
|
||||
{
|
||||
[Constructible]
|
||||
public LadderItem() : base(0x117F) => Movable = false;
|
||||
|
||||
public LadderItem(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public LadderController Ladder { get; set; }
|
||||
|
||||
public override string DefaultName => "1v1 leaderboard";
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1);
|
||||
|
||||
writer.Write(Ladder);
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
Ladder = reader.ReadItem<LadderController>();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (from.InRange(GetWorldLocation(), 2))
|
||||
{
|
||||
var ladder = ConPVP.Ladder.Instance ?? Ladder.Ladder;
|
||||
|
||||
if (ladder != null)
|
||||
{
|
||||
from.CloseGump<LadderGump>();
|
||||
from.SendGump(new LadderGump(ladder));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class LadderGump : Gump
|
||||
{
|
||||
private readonly Ladder m_Ladder;
|
||||
|
||||
private readonly List<LadderEntry> m_List;
|
||||
private readonly int m_Page;
|
||||
private int m_ColumnX = 12;
|
||||
|
||||
public LadderGump(Ladder ladder, int page = 0) : base(50, 50)
|
||||
{
|
||||
m_Ladder = ladder;
|
||||
m_Page = page;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
m_List = new List<LadderEntry>(ladder.Entries);
|
||||
|
||||
var lc = Math.Min(m_List.Count, 150);
|
||||
|
||||
var start = page * 15;
|
||||
var end = start + 15;
|
||||
|
||||
if (end > lc)
|
||||
end = lc;
|
||||
|
||||
var ct = end - start;
|
||||
|
||||
var height = 12 + 20 + ct * 20 + 23 + 12;
|
||||
|
||||
AddBackground(0, 0, 499, height, 0x2436);
|
||||
|
||||
for (var i = start + 1; i < end; i += 2)
|
||||
AddImageTiled(12, 32 + (i - start) * 20, 475, 20, 0x2430);
|
||||
|
||||
AddAlphaRegion(10, 10, 479, height - 20);
|
||||
|
||||
if (page > 0)
|
||||
AddButton(446, height - 12 - 2 - 16, 0x15E3, 0x15E7, 1);
|
||||
else
|
||||
AddImage(446, height - 12 - 2 - 16, 0x2626);
|
||||
|
||||
if ((page + 1) * 15 < lc)
|
||||
AddButton(466, height - 12 - 2 - 16, 0x15E1, 0x15E5, 2);
|
||||
else
|
||||
AddImage(466, height - 12 - 2 - 16, 0x2622);
|
||||
|
||||
AddHtml(
|
||||
16,
|
||||
height - 12 - 2 - 18,
|
||||
400,
|
||||
20,
|
||||
Color(
|
||||
string.Format("Top {3} of {0:N0} duelists, page {1} of {2}", m_List.Count, page + 1, (lc + 14) / 15, lc),
|
||||
0xFFC000
|
||||
)
|
||||
);
|
||||
|
||||
AddColumnHeader(75, "Rank");
|
||||
AddColumnHeader(115, "Level");
|
||||
AddColumnHeader(50, "Guild");
|
||||
AddColumnHeader(115, "Name");
|
||||
AddColumnHeader(60, "Wins");
|
||||
AddColumnHeader(60, "Losses");
|
||||
|
||||
for (var i = start; i < end && i < lc; ++i)
|
||||
{
|
||||
var entry = m_List[i];
|
||||
|
||||
var y = 32 + (i - start) * 20;
|
||||
var x = 12;
|
||||
|
||||
AddBorderedText(x, y, 75, Center(Rank(i + 1)), 0xFFFFFF, 0);
|
||||
x += 75;
|
||||
|
||||
/*AddImage( 20, y + 5, 0x2616, 0x96C );
|
||||
AddImage( 22, y + 5, 0x2616, 0x96C );
|
||||
AddImage( 20, y + 7, 0x2616, 0x96C );
|
||||
AddImage( 22, y + 7, 0x2616, 0x96C );
|
||||
|
||||
AddImage( 21, y + 6, 0x2616, 0x454 );*/
|
||||
|
||||
AddImage(x + 3, y + 4, 0x805);
|
||||
|
||||
var xp = entry.Experience;
|
||||
var level = Ladder.GetLevel(xp);
|
||||
|
||||
Ladder.GetLevelInfo(level, out var xpBase, out var xpAdvance);
|
||||
|
||||
int width;
|
||||
|
||||
var xpOffset = xp - xpBase;
|
||||
|
||||
if (xpOffset >= xpAdvance)
|
||||
width = 109; // level 50
|
||||
else
|
||||
width = (109 * xpOffset + xpAdvance / 2) / (xpAdvance - 1);
|
||||
|
||||
// AddImageTiled( 21, y + 6, width, 8, 0x2617 );
|
||||
AddImageTiled(x + 3, y + 4, width, 11, 0x806);
|
||||
AddBorderedText(x, y, 115, Center(level.ToString()), 0xFFFFFF, 0);
|
||||
x += 115;
|
||||
|
||||
var mob = entry.Mobile;
|
||||
|
||||
if (mob.Guild != null)
|
||||
AddBorderedText(x, y, 50, Center(mob.Guild.Abbreviation), 0xFFFFFF, 0);
|
||||
|
||||
x += 50;
|
||||
|
||||
AddBorderedText(x + 5, y, 115 - 5, mob.Name, 0xFFFFFF, 0);
|
||||
x += 115;
|
||||
|
||||
AddBorderedText(x, y, 60, Center(entry.Wins.ToString()), 0xFFFFFF, 0);
|
||||
x += 60;
|
||||
|
||||
AddBorderedText(x, y, 60, Center(entry.Losses.ToString()), 0xFFFFFF, 0);
|
||||
x += 60;
|
||||
|
||||
// AddBorderedText( 292 + 15, y, 115 - 30, String.Format( "{0} <DIV ALIGN=CENTER>/</DIV> <DIV ALIGN=RIGHT>{1}</DIV>", entry.Wins, entry.Losses ), 0xFFC000, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
public static string Rank(int num)
|
||||
{
|
||||
var numStr = num.ToString("N0");
|
||||
|
||||
if (num % 100 > 10 && num % 100 < 20)
|
||||
return $"{numStr}th";
|
||||
|
||||
return (num % 10) switch
|
||||
{
|
||||
1 => $"{numStr}st",
|
||||
2 => $"{numStr}nd",
|
||||
3 => $"{numStr}rd",
|
||||
_ => $"{numStr}th"
|
||||
};
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
var from = sender.Mobile;
|
||||
|
||||
if (info.ButtonID == 1 && m_Page > 0)
|
||||
from.SendGump(new LadderGump(m_Ladder, m_Page - 1));
|
||||
else if (info.ButtonID == 2 && (m_Page + 1) * 15 < Math.Min(m_List.Count, 150))
|
||||
from.SendGump(new LadderGump(m_Ladder, m_Page + 1));
|
||||
}
|
||||
|
||||
public string Center(string text) => $"<CENTER>{text}</CENTER>";
|
||||
|
||||
public string Color(string text, int color) => $"<BASEFONT COLOR=#{color:X6}>{text}</BASEFONT>";
|
||||
|
||||
private void AddBorderedText(int x, int y, int width, string text, int color, int borderColor)
|
||||
{
|
||||
/*AddColoredText( x - 1, y, width, text, borderColor );
|
||||
AddColoredText( x + 1, y, width, text, borderColor );
|
||||
AddColoredText( x, y - 1, width, text, borderColor );
|
||||
AddColoredText( x, y + 1, width, text, borderColor );*/
|
||||
/*AddColoredText( x - 1, y - 1, width, text, borderColor );
|
||||
AddColoredText( x + 1, y + 1, width, text, borderColor );*/
|
||||
AddColoredText(x, y, width, text, color);
|
||||
}
|
||||
|
||||
private void AddColoredText(int x, int y, int width, string text, int color)
|
||||
{
|
||||
if (color == 0)
|
||||
AddHtml(x, y, width, 20, text);
|
||||
else
|
||||
AddHtml(x, y, width, 20, Color(text, color));
|
||||
}
|
||||
|
||||
private void AddColumnHeader(int width, string name)
|
||||
{
|
||||
AddBackground(m_ColumnX, 12, width, 20, 0x242C);
|
||||
AddImageTiled(m_ColumnX + 2, 14, width - 4, 16, 0x2430);
|
||||
AddBorderedText(m_ColumnX, 13, width, Center(name), 0xFFFFFF, 0);
|
||||
|
||||
m_ColumnX += width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,250 +1,255 @@
|
|||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class ParticipantGump : Gump
|
||||
{
|
||||
public ParticipantGump(Mobile from, DuelContext context, Participant p) : base(50, 50)
|
||||
{
|
||||
From = from;
|
||||
Context = context;
|
||||
Participant = p;
|
||||
|
||||
from.CloseGump<RulesetGump>();
|
||||
from.CloseGump<DuelContextGump>();
|
||||
from.CloseGump<ParticipantGump>();
|
||||
|
||||
int count = p.Players.Length;
|
||||
|
||||
if (count < 4)
|
||||
count = 4;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
int height = 35 + 10 + 22 + 22 + 30 + 22 + 2 + count * 22 + 2 + 30;
|
||||
|
||||
AddBackground(0, 0, 300, height, 9250);
|
||||
AddBackground(10, 10, 280, height - 20, 0xDAC);
|
||||
|
||||
AddButton(240, 25, 0xFB1, 0xFB3, 3);
|
||||
|
||||
// AddButton( 223, 54, 0x265A, 0x265A, 4, );
|
||||
|
||||
AddHtml(35, 25, 230, 20, Center("Participant Setup"));
|
||||
|
||||
int x = 35;
|
||||
int y = 47;
|
||||
|
||||
AddHtml(x, y, 200, 20, $"Team Size: {p.Players.Length}");
|
||||
y += 22;
|
||||
|
||||
AddGoldenButtonLabeled(x + 20, y, 1, "Increase");
|
||||
y += 22;
|
||||
AddGoldenButtonLabeled(x + 20, y, 2, "Decrease");
|
||||
y += 30;
|
||||
|
||||
AddHtml(35, y, 230, 20, Center("Players"));
|
||||
y += 22;
|
||||
|
||||
for (int i = 0; i < p.Players.Length; ++i)
|
||||
{
|
||||
DuelPlayer pl = p.Players[i];
|
||||
|
||||
AddGoldenButtonLabeled(x, y, 5 + i, $"{1 + i}: {(pl == null ? "Empty" : pl.Mobile.Name)}");
|
||||
y += 22;
|
||||
}
|
||||
}
|
||||
|
||||
public Mobile From { get; }
|
||||
|
||||
public DuelContext Context { get; }
|
||||
|
||||
public Participant Participant { get; }
|
||||
|
||||
public string Center(string text) => $"<CENTER>{text}</CENTER>";
|
||||
|
||||
public void AddGoldenButton(int x, int y, int bid)
|
||||
{
|
||||
AddButton(x, y, 0xD2, 0xD2, bid);
|
||||
AddButton(x + 3, y + 3, 0xD8, 0xD8, bid);
|
||||
}
|
||||
|
||||
public void AddGoldenButtonLabeled(int x, int y, int bid, string text)
|
||||
{
|
||||
AddGoldenButton(x, y, bid);
|
||||
AddHtml(x + 25, y, 200, 20, text);
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (!Context.Registered)
|
||||
return;
|
||||
|
||||
int bid = info.ButtonID;
|
||||
|
||||
if (bid == 0)
|
||||
{
|
||||
From.SendGump(new DuelContextGump(From, Context));
|
||||
}
|
||||
else if (bid == 1)
|
||||
{
|
||||
if (Participant.Count < 8)
|
||||
Participant.Resize(Participant.Count + 1);
|
||||
else
|
||||
From.SendMessage("You may not raise the team size any further.");
|
||||
|
||||
From.SendGump(new ParticipantGump(From, Context, Participant));
|
||||
}
|
||||
else if (bid == 2)
|
||||
{
|
||||
if (Participant.Count > 1 && Participant.Count > Participant.FilledSlots)
|
||||
Participant.Resize(Participant.Count - 1);
|
||||
else
|
||||
From.SendMessage("You may not lower the team size any further.");
|
||||
|
||||
From.SendGump(new ParticipantGump(From, Context, Participant));
|
||||
}
|
||||
else if (bid == 3)
|
||||
{
|
||||
if (Participant.FilledSlots > 0)
|
||||
{
|
||||
From.SendMessage("There is at least one currently active player. You must remove them first.");
|
||||
From.SendGump(new ParticipantGump(From, Context, Participant));
|
||||
}
|
||||
else if (Context.Participants.Count > 2)
|
||||
{
|
||||
/*Container cont = m_Participant.Stakes;
|
||||
|
||||
if (cont != null)
|
||||
cont.Delete();*/
|
||||
|
||||
Context.Participants.Remove(Participant);
|
||||
From.SendGump(new DuelContextGump(From, Context));
|
||||
}
|
||||
else
|
||||
{
|
||||
From.SendMessage("Duels must have at least two participating parties.");
|
||||
From.SendGump(new ParticipantGump(From, Context, Participant));
|
||||
}
|
||||
}
|
||||
/*else if (bid == 4)
|
||||
{
|
||||
m_From.SendGump( new ParticipantGump( m_From, m_Context, m_Participant ) );
|
||||
|
||||
Container cont = m_Participant.Stakes;
|
||||
|
||||
if (cont != null && !cont.Deleted)
|
||||
{
|
||||
cont.DisplayTo( m_From );
|
||||
|
||||
Item[] checks = cont.FindItemsByType( typeof( BankCheck ) );
|
||||
|
||||
int gold = cont.TotalGold;
|
||||
|
||||
for ( int i = 0; i < checks.Length; ++i )
|
||||
gold += ((BankCheck)checks[i]).Worth;
|
||||
|
||||
m_From.SendMessage( "This container has {0} item{1} and {2} stone{3}. In gold or check form there is a total of {4:D}gp.", cont.TotalItems, cont.TotalItems==1?"":"s", cont.TotalWeight, cont.TotalWeight==1?"":"s", gold );
|
||||
}
|
||||
}*/
|
||||
else
|
||||
{
|
||||
bid -= 5;
|
||||
|
||||
if (bid >= 0 && bid < Participant.Players.Length)
|
||||
{
|
||||
if (Participant.Players[bid] == null)
|
||||
{
|
||||
From.Target = new ParticipantTarget(Context, Participant, bid);
|
||||
From.SendMessage("Target a player.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Participant.Players[bid].Mobile.SendMessage("You have been removed from the duel.");
|
||||
|
||||
if (Participant.Players[bid].Mobile is PlayerMobile)
|
||||
((PlayerMobile)Participant.Players[bid].Mobile).DuelPlayer = null;
|
||||
|
||||
Participant.Players[bid] = null;
|
||||
From.SendMessage("They have been removed from the duel.");
|
||||
From.SendGump(new ParticipantGump(From, Context, Participant));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ParticipantTarget : Target
|
||||
{
|
||||
private readonly DuelContext m_Context;
|
||||
private readonly int m_Index;
|
||||
private readonly Participant m_Participant;
|
||||
|
||||
public ParticipantTarget(DuelContext context, Participant p, int index) : base(12, false, TargetFlags.None)
|
||||
{
|
||||
m_Context = context;
|
||||
m_Participant = p;
|
||||
m_Index = index;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (!m_Context.Registered)
|
||||
return;
|
||||
|
||||
int index = m_Index;
|
||||
|
||||
if (index < 0 || index >= m_Participant.Players.Length)
|
||||
return;
|
||||
|
||||
if (!(targeted is Mobile mob))
|
||||
{
|
||||
from.SendMessage("That is not a player.");
|
||||
}
|
||||
else if (!mob.Player)
|
||||
{
|
||||
if (mob.Body.IsHuman)
|
||||
mob.SayTo(from, 1005443); // Nay, I would rather stay here and watch a nail rust.
|
||||
else
|
||||
mob.SayTo(from, 1005444); // The creature ignores your offer.
|
||||
}
|
||||
else if (AcceptDuelGump.IsIgnored(mob, from) || mob.Blessed)
|
||||
{
|
||||
from.SendMessage("They ignore your offer.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(mob is PlayerMobile pm))
|
||||
return;
|
||||
|
||||
if (pm.DuelContext != null)
|
||||
{
|
||||
from.SendMessage("{0} cannot fight because they are already assigned to another duel.", pm.Name);
|
||||
}
|
||||
else if (DuelContext.CheckCombat(pm))
|
||||
{
|
||||
from.SendMessage("{0} cannot fight because they have recently been in combat with another player.",
|
||||
pm.Name);
|
||||
}
|
||||
else if (mob.HasGump<AcceptDuelGump>())
|
||||
{
|
||||
from.SendMessage("{0} has already been offered a duel.");
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendMessage("You send {0} to {1}.",
|
||||
m_Participant.Find(from) == null ? "a challenge" : "an invitation", mob.Name);
|
||||
mob.SendGump(new AcceptDuelGump(from, mob, m_Context, m_Participant, m_Index));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnTargetFinish(Mobile from)
|
||||
{
|
||||
from.SendGump(new ParticipantGump(from, m_Context, m_Participant));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class ParticipantGump : Gump
|
||||
{
|
||||
public ParticipantGump(Mobile from, DuelContext context, Participant p) : base(50, 50)
|
||||
{
|
||||
From = from;
|
||||
Context = context;
|
||||
Participant = p;
|
||||
|
||||
from.CloseGump<RulesetGump>();
|
||||
from.CloseGump<DuelContextGump>();
|
||||
from.CloseGump<ParticipantGump>();
|
||||
|
||||
var count = p.Players.Length;
|
||||
|
||||
if (count < 4)
|
||||
count = 4;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
var height = 35 + 10 + 22 + 22 + 30 + 22 + 2 + count * 22 + 2 + 30;
|
||||
|
||||
AddBackground(0, 0, 300, height, 9250);
|
||||
AddBackground(10, 10, 280, height - 20, 0xDAC);
|
||||
|
||||
AddButton(240, 25, 0xFB1, 0xFB3, 3);
|
||||
|
||||
// AddButton( 223, 54, 0x265A, 0x265A, 4, );
|
||||
|
||||
AddHtml(35, 25, 230, 20, Center("Participant Setup"));
|
||||
|
||||
var x = 35;
|
||||
var y = 47;
|
||||
|
||||
AddHtml(x, y, 200, 20, $"Team Size: {p.Players.Length}");
|
||||
y += 22;
|
||||
|
||||
AddGoldenButtonLabeled(x + 20, y, 1, "Increase");
|
||||
y += 22;
|
||||
AddGoldenButtonLabeled(x + 20, y, 2, "Decrease");
|
||||
y += 30;
|
||||
|
||||
AddHtml(35, y, 230, 20, Center("Players"));
|
||||
y += 22;
|
||||
|
||||
for (var i = 0; i < p.Players.Length; ++i)
|
||||
{
|
||||
var pl = p.Players[i];
|
||||
|
||||
AddGoldenButtonLabeled(x, y, 5 + i, $"{1 + i}: {(pl == null ? "Empty" : pl.Mobile.Name)}");
|
||||
y += 22;
|
||||
}
|
||||
}
|
||||
|
||||
public Mobile From { get; }
|
||||
|
||||
public DuelContext Context { get; }
|
||||
|
||||
public Participant Participant { get; }
|
||||
|
||||
public string Center(string text) => $"<CENTER>{text}</CENTER>";
|
||||
|
||||
public void AddGoldenButton(int x, int y, int bid)
|
||||
{
|
||||
AddButton(x, y, 0xD2, 0xD2, bid);
|
||||
AddButton(x + 3, y + 3, 0xD8, 0xD8, bid);
|
||||
}
|
||||
|
||||
public void AddGoldenButtonLabeled(int x, int y, int bid, string text)
|
||||
{
|
||||
AddGoldenButton(x, y, bid);
|
||||
AddHtml(x + 25, y, 200, 20, text);
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (!Context.Registered)
|
||||
return;
|
||||
|
||||
var bid = info.ButtonID;
|
||||
|
||||
if (bid == 0)
|
||||
{
|
||||
From.SendGump(new DuelContextGump(From, Context));
|
||||
}
|
||||
else if (bid == 1)
|
||||
{
|
||||
if (Participant.Count < 8)
|
||||
Participant.Resize(Participant.Count + 1);
|
||||
else
|
||||
From.SendMessage("You may not raise the team size any further.");
|
||||
|
||||
From.SendGump(new ParticipantGump(From, Context, Participant));
|
||||
}
|
||||
else if (bid == 2)
|
||||
{
|
||||
if (Participant.Count > 1 && Participant.Count > Participant.FilledSlots)
|
||||
Participant.Resize(Participant.Count - 1);
|
||||
else
|
||||
From.SendMessage("You may not lower the team size any further.");
|
||||
|
||||
From.SendGump(new ParticipantGump(From, Context, Participant));
|
||||
}
|
||||
else if (bid == 3)
|
||||
{
|
||||
if (Participant.FilledSlots > 0)
|
||||
{
|
||||
From.SendMessage("There is at least one currently active player. You must remove them first.");
|
||||
From.SendGump(new ParticipantGump(From, Context, Participant));
|
||||
}
|
||||
else if (Context.Participants.Count > 2)
|
||||
{
|
||||
/*Container cont = m_Participant.Stakes;
|
||||
|
||||
if (cont != null)
|
||||
cont.Delete();*/
|
||||
|
||||
Context.Participants.Remove(Participant);
|
||||
From.SendGump(new DuelContextGump(From, Context));
|
||||
}
|
||||
else
|
||||
{
|
||||
From.SendMessage("Duels must have at least two participating parties.");
|
||||
From.SendGump(new ParticipantGump(From, Context, Participant));
|
||||
}
|
||||
}
|
||||
/*else if (bid == 4)
|
||||
{
|
||||
m_From.SendGump( new ParticipantGump( m_From, m_Context, m_Participant ) );
|
||||
|
||||
Container cont = m_Participant.Stakes;
|
||||
|
||||
if (cont != null && !cont.Deleted)
|
||||
{
|
||||
cont.DisplayTo( m_From );
|
||||
|
||||
Item[] checks = cont.FindItemsByType( typeof( BankCheck ) );
|
||||
|
||||
int gold = cont.TotalGold;
|
||||
|
||||
for ( int i = 0; i < checks.Length; ++i )
|
||||
gold += ((BankCheck)checks[i]).Worth;
|
||||
|
||||
m_From.SendMessage( "This container has {0} item{1} and {2} stone{3}. In gold or check form there is a total of {4:D}gp.", cont.TotalItems, cont.TotalItems==1?"":"s", cont.TotalWeight, cont.TotalWeight==1?"":"s", gold );
|
||||
}
|
||||
}*/
|
||||
else
|
||||
{
|
||||
bid -= 5;
|
||||
|
||||
if (bid >= 0 && bid < Participant.Players.Length)
|
||||
{
|
||||
if (Participant.Players[bid] == null)
|
||||
{
|
||||
From.Target = new ParticipantTarget(Context, Participant, bid);
|
||||
From.SendMessage("Target a player.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Participant.Players[bid].Mobile.SendMessage("You have been removed from the duel.");
|
||||
|
||||
if (Participant.Players[bid].Mobile is PlayerMobile)
|
||||
((PlayerMobile)Participant.Players[bid].Mobile).DuelPlayer = null;
|
||||
|
||||
Participant.Players[bid] = null;
|
||||
From.SendMessage("They have been removed from the duel.");
|
||||
From.SendGump(new ParticipantGump(From, Context, Participant));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ParticipantTarget : Target
|
||||
{
|
||||
private readonly DuelContext m_Context;
|
||||
private readonly int m_Index;
|
||||
private readonly Participant m_Participant;
|
||||
|
||||
public ParticipantTarget(DuelContext context, Participant p, int index) : base(12, false, TargetFlags.None)
|
||||
{
|
||||
m_Context = context;
|
||||
m_Participant = p;
|
||||
m_Index = index;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (!m_Context.Registered)
|
||||
return;
|
||||
|
||||
var index = m_Index;
|
||||
|
||||
if (index < 0 || index >= m_Participant.Players.Length)
|
||||
return;
|
||||
|
||||
if (!(targeted is Mobile mob))
|
||||
{
|
||||
from.SendMessage("That is not a player.");
|
||||
}
|
||||
else if (!mob.Player)
|
||||
{
|
||||
if (mob.Body.IsHuman)
|
||||
mob.SayTo(from, 1005443); // Nay, I would rather stay here and watch a nail rust.
|
||||
else
|
||||
mob.SayTo(from, 1005444); // The creature ignores your offer.
|
||||
}
|
||||
else if (AcceptDuelGump.IsIgnored(mob, from) || mob.Blessed)
|
||||
{
|
||||
from.SendMessage("They ignore your offer.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(mob is PlayerMobile pm))
|
||||
return;
|
||||
|
||||
if (pm.DuelContext != null)
|
||||
{
|
||||
from.SendMessage("{0} cannot fight because they are already assigned to another duel.", pm.Name);
|
||||
}
|
||||
else if (DuelContext.CheckCombat(pm))
|
||||
{
|
||||
from.SendMessage(
|
||||
"{0} cannot fight because they have recently been in combat with another player.",
|
||||
pm.Name
|
||||
);
|
||||
}
|
||||
else if (mob.HasGump<AcceptDuelGump>())
|
||||
{
|
||||
from.SendMessage("{0} has already been offered a duel.");
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendMessage(
|
||||
"You send {0} to {1}.",
|
||||
m_Participant.Find(from) == null ? "a challenge" : "an invitation",
|
||||
mob.Name
|
||||
);
|
||||
mob.SendGump(new AcceptDuelGump(from, mob, m_Context, m_Participant, m_Index));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnTargetFinish(Mobile from)
|
||||
{
|
||||
from.SendGump(new ParticipantGump(from, m_Context, m_Participant));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,123 +1,123 @@
|
|||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class PickRulesetGump : Gump
|
||||
{
|
||||
private readonly DuelContext m_Context;
|
||||
private readonly Ruleset[] m_Defaults;
|
||||
private readonly Ruleset[] m_Flavors;
|
||||
private readonly Mobile m_From;
|
||||
private readonly Ruleset m_Ruleset;
|
||||
|
||||
public PickRulesetGump(Mobile from, DuelContext context, Ruleset ruleset) : base(50, 50)
|
||||
{
|
||||
m_From = from;
|
||||
m_Context = context;
|
||||
m_Ruleset = ruleset;
|
||||
m_Defaults = ruleset.Layout.Defaults;
|
||||
m_Flavors = ruleset.Layout.Flavors;
|
||||
|
||||
int height = 25 + 20 + (m_Defaults.Length + 1) * 22 + 6 + 20 + m_Flavors.Length * 22 + 25;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
AddBackground(0, 0, 260, height, 9250);
|
||||
AddBackground(10, 10, 240, height - 20, 0xDAC);
|
||||
|
||||
AddHtml(35, 25, 190, 20, Center("Rules"));
|
||||
|
||||
int y = 25 + 20;
|
||||
|
||||
for (int i = 0; i < m_Defaults.Length; ++i)
|
||||
{
|
||||
Ruleset cur = m_Defaults[i];
|
||||
|
||||
AddHtml(35 + 14, y, 176, 20, cur.Title);
|
||||
|
||||
if (ruleset.Base == cur && !ruleset.Changed)
|
||||
AddImage(35, y + 4, 0x939);
|
||||
else if (ruleset.Base == cur)
|
||||
AddButton(35, y + 4, 0x93A, 0x939, 2 + i);
|
||||
else
|
||||
AddButton(35, y + 4, 0x938, 0x939, 2 + i);
|
||||
|
||||
y += 22;
|
||||
}
|
||||
|
||||
AddHtml(35 + 14, y, 176, 20, "Custom");
|
||||
AddButton(35, y + 4, ruleset.Changed ? 0x939 : 0x938, 0x939, 1);
|
||||
|
||||
y += 22;
|
||||
y += 6;
|
||||
|
||||
AddHtml(35, y, 190, 20, Center("Flavors"));
|
||||
y += 20;
|
||||
|
||||
for (int i = 0; i < m_Flavors.Length; ++i)
|
||||
{
|
||||
Ruleset cur = m_Flavors[i];
|
||||
|
||||
AddHtml(35 + 14, y, 176, 20, cur.Title);
|
||||
|
||||
if (ruleset.Flavors.Contains(cur))
|
||||
AddButton(35, y + 4, 0x939, 0x938, 2 + m_Defaults.Length + i);
|
||||
else
|
||||
AddButton(35, y + 4, 0x938, 0x939, 2 + m_Defaults.Length + i);
|
||||
|
||||
y += 22;
|
||||
}
|
||||
}
|
||||
|
||||
public string Center(string text) => $"<CENTER>{text}</CENTER>";
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (m_Context?.Registered == false)
|
||||
return;
|
||||
|
||||
switch (info.ButtonID)
|
||||
{
|
||||
case 0: // closed
|
||||
{
|
||||
if (m_Context != null)
|
||||
m_From.SendGump(new DuelContextGump(m_From, m_Context));
|
||||
|
||||
break;
|
||||
}
|
||||
case 1: // customize
|
||||
{
|
||||
m_From.SendGump(new RulesetGump(m_From, m_Ruleset, m_Ruleset.Layout, m_Context));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
int idx = info.ButtonID - 2;
|
||||
|
||||
if (idx >= 0 && idx < m_Defaults.Length)
|
||||
{
|
||||
m_Ruleset.ApplyDefault(m_Defaults[idx]);
|
||||
m_From.SendGump(new PickRulesetGump(m_From, m_Context, m_Ruleset));
|
||||
}
|
||||
else
|
||||
{
|
||||
idx -= m_Defaults.Length;
|
||||
|
||||
if (idx >= 0 && idx < m_Flavors.Length)
|
||||
{
|
||||
if (m_Ruleset.Flavors.Contains(m_Flavors[idx]))
|
||||
m_Ruleset.RemoveFlavor(m_Flavors[idx]);
|
||||
else
|
||||
m_Ruleset.AddFlavor(m_Flavors[idx]);
|
||||
|
||||
m_From.SendGump(new PickRulesetGump(m_From, m_Context, m_Ruleset));
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class PickRulesetGump : Gump
|
||||
{
|
||||
private readonly DuelContext m_Context;
|
||||
private readonly Ruleset[] m_Defaults;
|
||||
private readonly Ruleset[] m_Flavors;
|
||||
private readonly Mobile m_From;
|
||||
private readonly Ruleset m_Ruleset;
|
||||
|
||||
public PickRulesetGump(Mobile from, DuelContext context, Ruleset ruleset) : base(50, 50)
|
||||
{
|
||||
m_From = from;
|
||||
m_Context = context;
|
||||
m_Ruleset = ruleset;
|
||||
m_Defaults = ruleset.Layout.Defaults;
|
||||
m_Flavors = ruleset.Layout.Flavors;
|
||||
|
||||
var height = 25 + 20 + (m_Defaults.Length + 1) * 22 + 6 + 20 + m_Flavors.Length * 22 + 25;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
AddBackground(0, 0, 260, height, 9250);
|
||||
AddBackground(10, 10, 240, height - 20, 0xDAC);
|
||||
|
||||
AddHtml(35, 25, 190, 20, Center("Rules"));
|
||||
|
||||
var y = 25 + 20;
|
||||
|
||||
for (var i = 0; i < m_Defaults.Length; ++i)
|
||||
{
|
||||
var cur = m_Defaults[i];
|
||||
|
||||
AddHtml(35 + 14, y, 176, 20, cur.Title);
|
||||
|
||||
if (ruleset.Base == cur && !ruleset.Changed)
|
||||
AddImage(35, y + 4, 0x939);
|
||||
else if (ruleset.Base == cur)
|
||||
AddButton(35, y + 4, 0x93A, 0x939, 2 + i);
|
||||
else
|
||||
AddButton(35, y + 4, 0x938, 0x939, 2 + i);
|
||||
|
||||
y += 22;
|
||||
}
|
||||
|
||||
AddHtml(35 + 14, y, 176, 20, "Custom");
|
||||
AddButton(35, y + 4, ruleset.Changed ? 0x939 : 0x938, 0x939, 1);
|
||||
|
||||
y += 22;
|
||||
y += 6;
|
||||
|
||||
AddHtml(35, y, 190, 20, Center("Flavors"));
|
||||
y += 20;
|
||||
|
||||
for (var i = 0; i < m_Flavors.Length; ++i)
|
||||
{
|
||||
var cur = m_Flavors[i];
|
||||
|
||||
AddHtml(35 + 14, y, 176, 20, cur.Title);
|
||||
|
||||
if (ruleset.Flavors.Contains(cur))
|
||||
AddButton(35, y + 4, 0x939, 0x938, 2 + m_Defaults.Length + i);
|
||||
else
|
||||
AddButton(35, y + 4, 0x938, 0x939, 2 + m_Defaults.Length + i);
|
||||
|
||||
y += 22;
|
||||
}
|
||||
}
|
||||
|
||||
public string Center(string text) => $"<CENTER>{text}</CENTER>";
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (m_Context?.Registered == false)
|
||||
return;
|
||||
|
||||
switch (info.ButtonID)
|
||||
{
|
||||
case 0: // closed
|
||||
{
|
||||
if (m_Context != null)
|
||||
m_From.SendGump(new DuelContextGump(m_From, m_Context));
|
||||
|
||||
break;
|
||||
}
|
||||
case 1: // customize
|
||||
{
|
||||
m_From.SendGump(new RulesetGump(m_From, m_Ruleset, m_Ruleset.Layout, m_Context));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
var idx = info.ButtonID - 2;
|
||||
|
||||
if (idx >= 0 && idx < m_Defaults.Length)
|
||||
{
|
||||
m_Ruleset.ApplyDefault(m_Defaults[idx]);
|
||||
m_From.SendGump(new PickRulesetGump(m_From, m_Context, m_Ruleset));
|
||||
}
|
||||
else
|
||||
{
|
||||
idx -= m_Defaults.Length;
|
||||
|
||||
if (idx >= 0 && idx < m_Flavors.Length)
|
||||
{
|
||||
if (m_Ruleset.Flavors.Contains(m_Flavors[idx]))
|
||||
m_Ruleset.RemoveFlavor(m_Flavors[idx]);
|
||||
else
|
||||
m_Ruleset.AddFlavor(m_Flavors[idx]);
|
||||
|
||||
m_From.SendGump(new PickRulesetGump(m_From, m_Context, m_Ruleset));
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,106 +1,105 @@
|
|||
using System.Collections.Generic;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class ReadyGump : Gump
|
||||
{
|
||||
private DuelContext m_Context;
|
||||
private int m_Count;
|
||||
private Mobile m_From;
|
||||
|
||||
public ReadyGump(Mobile from, DuelContext context, int count) : base(50, 50)
|
||||
{
|
||||
m_From = from;
|
||||
m_Context = context;
|
||||
m_Count = count;
|
||||
|
||||
List<Participant> parts = context.Participants;
|
||||
|
||||
int height = 25 + 20;
|
||||
|
||||
for (int i = 0; i < parts.Count; ++i)
|
||||
{
|
||||
Participant p = parts[i];
|
||||
|
||||
height += 4;
|
||||
|
||||
if (p.Players.Length > 1)
|
||||
height += 22;
|
||||
|
||||
height += p.Players.Length * 22;
|
||||
}
|
||||
|
||||
height += 25;
|
||||
|
||||
Closable = false;
|
||||
Draggable = false;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
AddBackground(0, 0, 260, height, 9250);
|
||||
AddBackground(10, 10, 240, height - 20, 0xDAC);
|
||||
|
||||
if (count == -1)
|
||||
{
|
||||
AddHtml(35, 25, 190, 20, Center("Ready"));
|
||||
}
|
||||
else
|
||||
{
|
||||
AddHtml(35, 25, 190, 20, Center("Starting"));
|
||||
AddHtml(35, 25, 190, 20, $"<DIV ALIGN=RIGHT>{count}");
|
||||
}
|
||||
|
||||
int y = 25 + 20;
|
||||
|
||||
for (int i = 0; i < parts.Count; ++i)
|
||||
{
|
||||
Participant p = parts[i];
|
||||
|
||||
y += 4;
|
||||
|
||||
bool isAllReady = true;
|
||||
int yStore = y;
|
||||
int offset = 0;
|
||||
|
||||
if (p.Players.Length > 1)
|
||||
{
|
||||
AddHtml(35 + 14, y, 176, 20, $"Participant #{i + 1}");
|
||||
y += 22;
|
||||
offset = 10;
|
||||
}
|
||||
|
||||
for (int j = 0; j < p.Players.Length; ++j)
|
||||
{
|
||||
DuelPlayer pl = p.Players[j];
|
||||
|
||||
if (pl?.Ready == true)
|
||||
{
|
||||
AddImage(35 + offset, y + 4, 0x939);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddImage(35 + offset, y + 4, 0x938);
|
||||
isAllReady = false;
|
||||
}
|
||||
|
||||
string name = pl == null ? "(Empty)" : pl.Mobile.Name;
|
||||
|
||||
AddHtml(35 + offset + 14, y, 166, 20, name);
|
||||
|
||||
y += 22;
|
||||
}
|
||||
|
||||
if (p.Players.Length > 1)
|
||||
AddImage(35, yStore + 4, isAllReady ? 0x939 : 0x938);
|
||||
}
|
||||
}
|
||||
|
||||
public string Center(string text) => $"<CENTER>{text}</CENTER>";
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class ReadyGump : Gump
|
||||
{
|
||||
private DuelContext m_Context;
|
||||
private int m_Count;
|
||||
private Mobile m_From;
|
||||
|
||||
public ReadyGump(Mobile from, DuelContext context, int count) : base(50, 50)
|
||||
{
|
||||
m_From = from;
|
||||
m_Context = context;
|
||||
m_Count = count;
|
||||
|
||||
var parts = context.Participants;
|
||||
|
||||
var height = 25 + 20;
|
||||
|
||||
for (var i = 0; i < parts.Count; ++i)
|
||||
{
|
||||
var p = parts[i];
|
||||
|
||||
height += 4;
|
||||
|
||||
if (p.Players.Length > 1)
|
||||
height += 22;
|
||||
|
||||
height += p.Players.Length * 22;
|
||||
}
|
||||
|
||||
height += 25;
|
||||
|
||||
Closable = false;
|
||||
Draggable = false;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
AddBackground(0, 0, 260, height, 9250);
|
||||
AddBackground(10, 10, 240, height - 20, 0xDAC);
|
||||
|
||||
if (count == -1)
|
||||
{
|
||||
AddHtml(35, 25, 190, 20, Center("Ready"));
|
||||
}
|
||||
else
|
||||
{
|
||||
AddHtml(35, 25, 190, 20, Center("Starting"));
|
||||
AddHtml(35, 25, 190, 20, $"<DIV ALIGN=RIGHT>{count}");
|
||||
}
|
||||
|
||||
var y = 25 + 20;
|
||||
|
||||
for (var i = 0; i < parts.Count; ++i)
|
||||
{
|
||||
var p = parts[i];
|
||||
|
||||
y += 4;
|
||||
|
||||
var isAllReady = true;
|
||||
var yStore = y;
|
||||
var offset = 0;
|
||||
|
||||
if (p.Players.Length > 1)
|
||||
{
|
||||
AddHtml(35 + 14, y, 176, 20, $"Participant #{i + 1}");
|
||||
y += 22;
|
||||
offset = 10;
|
||||
}
|
||||
|
||||
for (var j = 0; j < p.Players.Length; ++j)
|
||||
{
|
||||
var pl = p.Players[j];
|
||||
|
||||
if (pl?.Ready == true)
|
||||
{
|
||||
AddImage(35 + offset, y + 4, 0x939);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddImage(35 + offset, y + 4, 0x938);
|
||||
isAllReady = false;
|
||||
}
|
||||
|
||||
var name = pl == null ? "(Empty)" : pl.Mobile.Name;
|
||||
|
||||
AddHtml(35 + offset + 14, y, 166, 20, name);
|
||||
|
||||
y += 22;
|
||||
}
|
||||
|
||||
if (p.Players.Length > 1)
|
||||
AddImage(35, yStore + 4, isAllReady ? 0x939 : 0x938);
|
||||
}
|
||||
}
|
||||
|
||||
public string Center(string text) => $"<CENTER>{text}</CENTER>";
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,222 +1,221 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class ReadyUpGump : Gump
|
||||
{
|
||||
private readonly DuelContext m_Context;
|
||||
private readonly Mobile m_From;
|
||||
|
||||
public ReadyUpGump(Mobile from, DuelContext context) : base(50, 50)
|
||||
{
|
||||
m_From = from;
|
||||
m_Context = context;
|
||||
|
||||
Closable = false;
|
||||
AddPage(0);
|
||||
|
||||
if (context.Rematch)
|
||||
{
|
||||
int height = 25 + 20 + 10 + 22 + 25;
|
||||
|
||||
AddBackground(0, 0, 210, height, 9250);
|
||||
AddBackground(10, 10, 190, height - 20, 0xDAC);
|
||||
|
||||
AddHtml(35, 25, 140, 20, Center("Rematch?"));
|
||||
|
||||
AddButton(35, 55, 247, 248, 1);
|
||||
AddButton(115, 55, 242, 241, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddPage(1);
|
||||
|
||||
List<Participant> parts = context.Participants;
|
||||
|
||||
int height = 25 + 20;
|
||||
|
||||
for (int i = 0; i < parts.Count; ++i)
|
||||
{
|
||||
Participant p = parts[i];
|
||||
|
||||
height += 4;
|
||||
|
||||
if (p.Players.Length > 1)
|
||||
height += 22;
|
||||
|
||||
height += p.Players.Length * 22;
|
||||
}
|
||||
|
||||
height += 10 + 22 + 25;
|
||||
|
||||
AddBackground(0, 0, 260, height, 9250);
|
||||
AddBackground(10, 10, 240, height - 20, 0xDAC);
|
||||
|
||||
AddHtml(35, 25, 190, 20, Center("Participants"));
|
||||
|
||||
int y = 20 + 25;
|
||||
|
||||
for (int i = 0; i < parts.Count; ++i)
|
||||
{
|
||||
Participant p = parts[i];
|
||||
|
||||
y += 4;
|
||||
|
||||
int offset = 0;
|
||||
|
||||
if (p.Players.Length > 1)
|
||||
{
|
||||
AddHtml(35, y, 176, 20, $"Team #{i + 1}");
|
||||
y += 22;
|
||||
offset = 10;
|
||||
}
|
||||
|
||||
for (int j = 0; j < p.Players.Length; ++j)
|
||||
{
|
||||
DuelPlayer pl = p.Players[j];
|
||||
|
||||
string name = pl == null ? "(Empty)" : pl.Mobile.Name;
|
||||
|
||||
AddHtml(35 + offset, y, 166, 20, name);
|
||||
|
||||
y += 22;
|
||||
}
|
||||
}
|
||||
|
||||
y += 8;
|
||||
|
||||
AddHtml(35, y, 176, 20, "Continue?");
|
||||
|
||||
y -= 2;
|
||||
|
||||
AddButton(102, y, 247, 248, 0, GumpButtonType.Page, 2);
|
||||
AddButton(169, y, 242, 241, 2);
|
||||
|
||||
AddPage(2);
|
||||
|
||||
Ruleset ruleset = context.Ruleset;
|
||||
Ruleset basedef = ruleset.Base;
|
||||
|
||||
height = 25 + 20 + 5 + 20 + 20 + 4;
|
||||
|
||||
int changes = 0;
|
||||
|
||||
BitArray defs;
|
||||
|
||||
if (ruleset.Flavors.Count > 0)
|
||||
{
|
||||
defs = new BitArray(basedef.Options);
|
||||
|
||||
for (int i = 0; i < ruleset.Flavors.Count; ++i)
|
||||
defs.Or(ruleset.Flavors[i].Options);
|
||||
|
||||
height += ruleset.Flavors.Count * 18;
|
||||
}
|
||||
else
|
||||
{
|
||||
defs = basedef.Options;
|
||||
}
|
||||
|
||||
BitArray opts = ruleset.Options;
|
||||
|
||||
for (int i = 0; i < opts.Length; ++i)
|
||||
if (defs[i] != opts[i])
|
||||
++changes;
|
||||
|
||||
height += changes * 22;
|
||||
|
||||
height += 10 + 22 + 25;
|
||||
|
||||
AddBackground(0, 0, 260, height, 9250);
|
||||
AddBackground(10, 10, 240, height - 20, 0xDAC);
|
||||
|
||||
AddHtml(35, 25, 190, 20, Center("Rules"));
|
||||
|
||||
AddHtml(35, 50, 190, 20, $"Set: {basedef.Title}");
|
||||
|
||||
y = 70;
|
||||
|
||||
for (int i = 0; i < ruleset.Flavors.Count; ++i, y += 18)
|
||||
AddHtml(35, y, 190, 20, $" + {ruleset.Flavors[i].Title}");
|
||||
|
||||
y += 4;
|
||||
|
||||
if (changes > 0)
|
||||
{
|
||||
AddHtml(35, y, 190, 20, "Modifications:");
|
||||
y += 20;
|
||||
|
||||
for (int i = 0; i < opts.Length; ++i)
|
||||
if (defs[i] != opts[i])
|
||||
{
|
||||
string name = ruleset.Layout.FindByIndex(i);
|
||||
|
||||
if (name != null) // sanity
|
||||
{
|
||||
AddImage(35, y, opts[i] ? 0xD3 : 0xD2);
|
||||
AddHtml(60, y, 165, 22, name);
|
||||
}
|
||||
|
||||
y += 22;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddHtml(35, y, 190, 20, "Modifications: None");
|
||||
y += 20;
|
||||
}
|
||||
|
||||
y += 8;
|
||||
|
||||
AddHtml(35, y, 176, 20, "Continue?");
|
||||
|
||||
y -= 2;
|
||||
|
||||
AddButton(102, y, 247, 248, 1);
|
||||
AddButton(169, y, 242, 241, 3);
|
||||
}
|
||||
}
|
||||
|
||||
public string Center(string text) => $"<CENTER>{text}</CENTER>";
|
||||
|
||||
public void AddGoldenButton(int x, int y, int bid)
|
||||
{
|
||||
AddButton(x, y, 0xD2, 0xD2, bid);
|
||||
AddButton(x + 3, y + 3, 0xD8, 0xD8, bid);
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (!m_Context.Registered || !m_Context.ReadyWait)
|
||||
return;
|
||||
|
||||
switch (info.ButtonID)
|
||||
{
|
||||
case 1: // okay
|
||||
{
|
||||
if (!(m_From is PlayerMobile pm))
|
||||
break;
|
||||
|
||||
pm.DuelPlayer.Ready = true;
|
||||
m_Context.SendReadyGump();
|
||||
|
||||
break;
|
||||
}
|
||||
case 2: // reject participants
|
||||
{
|
||||
m_Context.RejectReady(m_From, "participants");
|
||||
break;
|
||||
}
|
||||
case 3: // reject rules
|
||||
{
|
||||
m_Context.RejectReady(m_From, "rules");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
using System.Collections;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class ReadyUpGump : Gump
|
||||
{
|
||||
private readonly DuelContext m_Context;
|
||||
private readonly Mobile m_From;
|
||||
|
||||
public ReadyUpGump(Mobile from, DuelContext context) : base(50, 50)
|
||||
{
|
||||
m_From = from;
|
||||
m_Context = context;
|
||||
|
||||
Closable = false;
|
||||
AddPage(0);
|
||||
|
||||
if (context.Rematch)
|
||||
{
|
||||
var height = 25 + 20 + 10 + 22 + 25;
|
||||
|
||||
AddBackground(0, 0, 210, height, 9250);
|
||||
AddBackground(10, 10, 190, height - 20, 0xDAC);
|
||||
|
||||
AddHtml(35, 25, 140, 20, Center("Rematch?"));
|
||||
|
||||
AddButton(35, 55, 247, 248, 1);
|
||||
AddButton(115, 55, 242, 241, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddPage(1);
|
||||
|
||||
var parts = context.Participants;
|
||||
|
||||
var height = 25 + 20;
|
||||
|
||||
for (var i = 0; i < parts.Count; ++i)
|
||||
{
|
||||
var p = parts[i];
|
||||
|
||||
height += 4;
|
||||
|
||||
if (p.Players.Length > 1)
|
||||
height += 22;
|
||||
|
||||
height += p.Players.Length * 22;
|
||||
}
|
||||
|
||||
height += 10 + 22 + 25;
|
||||
|
||||
AddBackground(0, 0, 260, height, 9250);
|
||||
AddBackground(10, 10, 240, height - 20, 0xDAC);
|
||||
|
||||
AddHtml(35, 25, 190, 20, Center("Participants"));
|
||||
|
||||
var y = 20 + 25;
|
||||
|
||||
for (var i = 0; i < parts.Count; ++i)
|
||||
{
|
||||
var p = parts[i];
|
||||
|
||||
y += 4;
|
||||
|
||||
var offset = 0;
|
||||
|
||||
if (p.Players.Length > 1)
|
||||
{
|
||||
AddHtml(35, y, 176, 20, $"Team #{i + 1}");
|
||||
y += 22;
|
||||
offset = 10;
|
||||
}
|
||||
|
||||
for (var j = 0; j < p.Players.Length; ++j)
|
||||
{
|
||||
var pl = p.Players[j];
|
||||
|
||||
var name = pl == null ? "(Empty)" : pl.Mobile.Name;
|
||||
|
||||
AddHtml(35 + offset, y, 166, 20, name);
|
||||
|
||||
y += 22;
|
||||
}
|
||||
}
|
||||
|
||||
y += 8;
|
||||
|
||||
AddHtml(35, y, 176, 20, "Continue?");
|
||||
|
||||
y -= 2;
|
||||
|
||||
AddButton(102, y, 247, 248, 0, GumpButtonType.Page, 2);
|
||||
AddButton(169, y, 242, 241, 2);
|
||||
|
||||
AddPage(2);
|
||||
|
||||
var ruleset = context.Ruleset;
|
||||
var basedef = ruleset.Base;
|
||||
|
||||
height = 25 + 20 + 5 + 20 + 20 + 4;
|
||||
|
||||
var changes = 0;
|
||||
|
||||
BitArray defs;
|
||||
|
||||
if (ruleset.Flavors.Count > 0)
|
||||
{
|
||||
defs = new BitArray(basedef.Options);
|
||||
|
||||
for (var i = 0; i < ruleset.Flavors.Count; ++i)
|
||||
defs.Or(ruleset.Flavors[i].Options);
|
||||
|
||||
height += ruleset.Flavors.Count * 18;
|
||||
}
|
||||
else
|
||||
{
|
||||
defs = basedef.Options;
|
||||
}
|
||||
|
||||
var opts = ruleset.Options;
|
||||
|
||||
for (var i = 0; i < opts.Length; ++i)
|
||||
if (defs[i] != opts[i])
|
||||
++changes;
|
||||
|
||||
height += changes * 22;
|
||||
|
||||
height += 10 + 22 + 25;
|
||||
|
||||
AddBackground(0, 0, 260, height, 9250);
|
||||
AddBackground(10, 10, 240, height - 20, 0xDAC);
|
||||
|
||||
AddHtml(35, 25, 190, 20, Center("Rules"));
|
||||
|
||||
AddHtml(35, 50, 190, 20, $"Set: {basedef.Title}");
|
||||
|
||||
y = 70;
|
||||
|
||||
for (var i = 0; i < ruleset.Flavors.Count; ++i, y += 18)
|
||||
AddHtml(35, y, 190, 20, $" + {ruleset.Flavors[i].Title}");
|
||||
|
||||
y += 4;
|
||||
|
||||
if (changes > 0)
|
||||
{
|
||||
AddHtml(35, y, 190, 20, "Modifications:");
|
||||
y += 20;
|
||||
|
||||
for (var i = 0; i < opts.Length; ++i)
|
||||
if (defs[i] != opts[i])
|
||||
{
|
||||
var name = ruleset.Layout.FindByIndex(i);
|
||||
|
||||
if (name != null) // sanity
|
||||
{
|
||||
AddImage(35, y, opts[i] ? 0xD3 : 0xD2);
|
||||
AddHtml(60, y, 165, 22, name);
|
||||
}
|
||||
|
||||
y += 22;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddHtml(35, y, 190, 20, "Modifications: None");
|
||||
y += 20;
|
||||
}
|
||||
|
||||
y += 8;
|
||||
|
||||
AddHtml(35, y, 176, 20, "Continue?");
|
||||
|
||||
y -= 2;
|
||||
|
||||
AddButton(102, y, 247, 248, 1);
|
||||
AddButton(169, y, 242, 241, 3);
|
||||
}
|
||||
}
|
||||
|
||||
public string Center(string text) => $"<CENTER>{text}</CENTER>";
|
||||
|
||||
public void AddGoldenButton(int x, int y, int bid)
|
||||
{
|
||||
AddButton(x, y, 0xD2, 0xD2, bid);
|
||||
AddButton(x + 3, y + 3, 0xD8, 0xD8, bid);
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (!m_Context.Registered || !m_Context.ReadyWait)
|
||||
return;
|
||||
|
||||
switch (info.ButtonID)
|
||||
{
|
||||
case 1: // okay
|
||||
{
|
||||
if (!(m_From is PlayerMobile pm))
|
||||
break;
|
||||
|
||||
pm.DuelPlayer.Ready = true;
|
||||
m_Context.SendReadyGump();
|
||||
|
||||
break;
|
||||
}
|
||||
case 2: // reject participants
|
||||
{
|
||||
m_Context.RejectReady(m_From, "participants");
|
||||
break;
|
||||
}
|
||||
case 3: // reject rules
|
||||
{
|
||||
m_Context.RejectReady(m_From, "rules");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,123 +1,123 @@
|
|||
using System.Collections;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class RulesetGump : Gump
|
||||
{
|
||||
private readonly DuelContext m_DuelContext;
|
||||
private readonly Mobile m_From;
|
||||
private readonly RulesetLayout m_Page;
|
||||
private readonly bool m_ReadOnly;
|
||||
private readonly Ruleset m_Ruleset;
|
||||
|
||||
public RulesetGump(Mobile from, Ruleset ruleset, RulesetLayout page, DuelContext duelContext, bool readOnly = false)
|
||||
: base(readOnly ? 310 : 50, 50)
|
||||
{
|
||||
m_From = from;
|
||||
m_Ruleset = ruleset;
|
||||
m_Page = page;
|
||||
m_DuelContext = duelContext;
|
||||
m_ReadOnly = readOnly;
|
||||
|
||||
Draggable = !readOnly;
|
||||
|
||||
from.CloseGump<RulesetGump>();
|
||||
from.CloseGump<DuelContextGump>();
|
||||
from.CloseGump<ParticipantGump>();
|
||||
|
||||
RulesetLayout depthCounter = page;
|
||||
|
||||
while (depthCounter != null)
|
||||
depthCounter = depthCounter.Parent;
|
||||
|
||||
int count = page.Children.Length + page.Options.Length;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
int height = 35 + 10 + 2 + count * 22 + 2 + 30;
|
||||
|
||||
AddBackground(0, 0, 260, height, 9250);
|
||||
AddBackground(10, 10, 240, height - 20, 0xDAC);
|
||||
|
||||
AddHtml(35, 25, 190, 20, Center(page.Title));
|
||||
|
||||
int x = 35;
|
||||
int y = 47;
|
||||
|
||||
for (int i = 0; i < page.Children.Length; ++i)
|
||||
{
|
||||
AddGoldenButton(x, y, 1 + i);
|
||||
AddHtml(x + 25, y, 250, 22, page.Children[i].Title);
|
||||
|
||||
y += 22;
|
||||
}
|
||||
|
||||
for (int i = 0; i < page.Options.Length; ++i)
|
||||
{
|
||||
bool enabled = ruleset.Options[page.Offset + i];
|
||||
|
||||
if (readOnly)
|
||||
AddImage(x, y, enabled ? 0xD3 : 0xD2);
|
||||
else
|
||||
AddCheck(x, y, 0xD2, 0xD3, enabled, i);
|
||||
|
||||
AddHtml(x + 25, y, 250, 22, page.Options[i]);
|
||||
|
||||
y += 22;
|
||||
}
|
||||
}
|
||||
|
||||
public string Center(string text) => $"<CENTER>{text}</CENTER>";
|
||||
|
||||
public void AddGoldenButton(int x, int y, int bid)
|
||||
{
|
||||
AddButton(x, y, 0xD2, 0xD2, bid);
|
||||
AddButton(x + 3, y + 3, 0xD8, 0xD8, bid);
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (m_DuelContext?.Registered == false)
|
||||
return;
|
||||
|
||||
if (!m_ReadOnly)
|
||||
{
|
||||
BitArray opts = new BitArray(m_Page.Options.Length);
|
||||
|
||||
for (int i = 0; i < info.Switches.Length; ++i)
|
||||
{
|
||||
int sid = info.Switches[i];
|
||||
|
||||
if (sid >= 0 && sid < m_Page.Options.Length)
|
||||
opts[sid] = true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < opts.Length; ++i)
|
||||
if (m_Ruleset.Options[m_Page.Offset + i] != opts[i])
|
||||
{
|
||||
m_Ruleset.Options[m_Page.Offset + i] = opts[i];
|
||||
m_Ruleset.Changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
int bid = info.ButtonID;
|
||||
|
||||
if (bid == 0)
|
||||
{
|
||||
if (m_Page.Parent != null)
|
||||
m_From.SendGump(new RulesetGump(m_From, m_Ruleset, m_Page.Parent, m_DuelContext, m_ReadOnly));
|
||||
else if (!m_ReadOnly)
|
||||
m_From.SendGump(new PickRulesetGump(m_From, m_DuelContext, m_Ruleset));
|
||||
}
|
||||
else
|
||||
{
|
||||
bid -= 1;
|
||||
|
||||
if (bid >= 0 && bid < m_Page.Children.Length)
|
||||
m_From.SendGump(new RulesetGump(m_From, m_Ruleset, m_Page.Children[bid], m_DuelContext, m_ReadOnly));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
using System.Collections;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class RulesetGump : Gump
|
||||
{
|
||||
private readonly DuelContext m_DuelContext;
|
||||
private readonly Mobile m_From;
|
||||
private readonly RulesetLayout m_Page;
|
||||
private readonly bool m_ReadOnly;
|
||||
private readonly Ruleset m_Ruleset;
|
||||
|
||||
public RulesetGump(Mobile from, Ruleset ruleset, RulesetLayout page, DuelContext duelContext, bool readOnly = false)
|
||||
: base(readOnly ? 310 : 50, 50)
|
||||
{
|
||||
m_From = from;
|
||||
m_Ruleset = ruleset;
|
||||
m_Page = page;
|
||||
m_DuelContext = duelContext;
|
||||
m_ReadOnly = readOnly;
|
||||
|
||||
Draggable = !readOnly;
|
||||
|
||||
from.CloseGump<RulesetGump>();
|
||||
from.CloseGump<DuelContextGump>();
|
||||
from.CloseGump<ParticipantGump>();
|
||||
|
||||
var depthCounter = page;
|
||||
|
||||
while (depthCounter != null)
|
||||
depthCounter = depthCounter.Parent;
|
||||
|
||||
var count = page.Children.Length + page.Options.Length;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
var height = 35 + 10 + 2 + count * 22 + 2 + 30;
|
||||
|
||||
AddBackground(0, 0, 260, height, 9250);
|
||||
AddBackground(10, 10, 240, height - 20, 0xDAC);
|
||||
|
||||
AddHtml(35, 25, 190, 20, Center(page.Title));
|
||||
|
||||
var x = 35;
|
||||
var y = 47;
|
||||
|
||||
for (var i = 0; i < page.Children.Length; ++i)
|
||||
{
|
||||
AddGoldenButton(x, y, 1 + i);
|
||||
AddHtml(x + 25, y, 250, 22, page.Children[i].Title);
|
||||
|
||||
y += 22;
|
||||
}
|
||||
|
||||
for (var i = 0; i < page.Options.Length; ++i)
|
||||
{
|
||||
var enabled = ruleset.Options[page.Offset + i];
|
||||
|
||||
if (readOnly)
|
||||
AddImage(x, y, enabled ? 0xD3 : 0xD2);
|
||||
else
|
||||
AddCheck(x, y, 0xD2, 0xD3, enabled, i);
|
||||
|
||||
AddHtml(x + 25, y, 250, 22, page.Options[i]);
|
||||
|
||||
y += 22;
|
||||
}
|
||||
}
|
||||
|
||||
public string Center(string text) => $"<CENTER>{text}</CENTER>";
|
||||
|
||||
public void AddGoldenButton(int x, int y, int bid)
|
||||
{
|
||||
AddButton(x, y, 0xD2, 0xD2, bid);
|
||||
AddButton(x + 3, y + 3, 0xD8, 0xD8, bid);
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (m_DuelContext?.Registered == false)
|
||||
return;
|
||||
|
||||
if (!m_ReadOnly)
|
||||
{
|
||||
var opts = new BitArray(m_Page.Options.Length);
|
||||
|
||||
for (var i = 0; i < info.Switches.Length; ++i)
|
||||
{
|
||||
var sid = info.Switches[i];
|
||||
|
||||
if (sid >= 0 && sid < m_Page.Options.Length)
|
||||
opts[sid] = true;
|
||||
}
|
||||
|
||||
for (var i = 0; i < opts.Length; ++i)
|
||||
if (m_Ruleset.Options[m_Page.Offset + i] != opts[i])
|
||||
{
|
||||
m_Ruleset.Options[m_Page.Offset + i] = opts[i];
|
||||
m_Ruleset.Changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
var bid = info.ButtonID;
|
||||
|
||||
if (bid == 0)
|
||||
{
|
||||
if (m_Page.Parent != null)
|
||||
m_From.SendGump(new RulesetGump(m_From, m_Ruleset, m_Page.Parent, m_DuelContext, m_ReadOnly));
|
||||
else if (!m_ReadOnly)
|
||||
m_From.SendGump(new PickRulesetGump(m_From, m_DuelContext, m_Ruleset));
|
||||
}
|
||||
else
|
||||
{
|
||||
bid -= 1;
|
||||
|
||||
if (bid >= 0 && bid < m_Page.Children.Length)
|
||||
m_From.SendGump(new RulesetGump(m_From, m_Ruleset, m_Page.Children[bid], m_DuelContext, m_ReadOnly));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,357 +1,357 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class LadderController : Item
|
||||
{
|
||||
[Constructible]
|
||||
public LadderController() : base(0x1B7A)
|
||||
{
|
||||
Visible = false;
|
||||
Movable = false;
|
||||
|
||||
Ladder = new Ladder();
|
||||
|
||||
Ladder.Instance ??= Ladder;
|
||||
}
|
||||
|
||||
public LadderController(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.Administrator)]
|
||||
public Ladder Ladder { get; private set; }
|
||||
|
||||
public override string DefaultName => "ladder controller";
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
if (Ladder.Instance == Ladder)
|
||||
Ladder.Instance = null;
|
||||
|
||||
base.Delete();
|
||||
}
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1);
|
||||
|
||||
Ladder.Serialize(writer);
|
||||
|
||||
writer.Write(Ladder.Instance == Ladder);
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
case 0:
|
||||
{
|
||||
Ladder = new Ladder(reader);
|
||||
|
||||
if (version < 1 || reader.ReadBool())
|
||||
Ladder.Instance = Ladder;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Ladder
|
||||
{
|
||||
private static readonly int[] m_ShortLevels =
|
||||
{
|
||||
1,
|
||||
2,
|
||||
3, 3,
|
||||
4, 4,
|
||||
5, 5, 5,
|
||||
6, 6, 6,
|
||||
7, 7, 7, 7,
|
||||
8, 8, 8, 8,
|
||||
9, 9, 9, 9, 9
|
||||
};
|
||||
|
||||
private static readonly int[] m_BaseXP =
|
||||
{
|
||||
0, 100, 200, 400, 600, 900, 1200, 1600, 2000, 2500
|
||||
};
|
||||
|
||||
private static readonly int[] m_LossFactors =
|
||||
{
|
||||
10,
|
||||
11, 11,
|
||||
25, 25,
|
||||
43, 43,
|
||||
67, 67
|
||||
};
|
||||
|
||||
private static readonly int[,] m_OffsetScalar =
|
||||
{
|
||||
/* { win, los } */
|
||||
/* -6 */ { 175, 25 },
|
||||
/* -5 */ { 165, 35 },
|
||||
/* -4 */ { 155, 45 },
|
||||
/* -3 */ { 145, 55 },
|
||||
/* -2 */ { 130, 70 },
|
||||
/* -1 */ { 115, 85 },
|
||||
/* 0 */ { 100, 100 },
|
||||
/* +1 */ { 90, 110 },
|
||||
/* +2 */ { 80, 120 },
|
||||
/* +3 */ { 70, 130 },
|
||||
/* +4 */ { 60, 140 },
|
||||
/* +5 */ { 50, 150 },
|
||||
/* +6 */ { 40, 160 }
|
||||
};
|
||||
|
||||
public List<LadderEntry> Entries { get; } = new List<LadderEntry>();
|
||||
|
||||
private readonly Dictionary<Mobile, LadderEntry> m_Table;
|
||||
|
||||
public Ladder() => m_Table = new Dictionary<Mobile, LadderEntry>();
|
||||
|
||||
public Ladder(IGenericReader reader)
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
case 0:
|
||||
{
|
||||
int count = reader.ReadEncodedInt();
|
||||
|
||||
m_Table = new Dictionary<Mobile, LadderEntry>(count);
|
||||
Entries = new List<LadderEntry>(count);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
LadderEntry entry = new LadderEntry(reader, this, version);
|
||||
|
||||
if (entry.Mobile != null)
|
||||
{
|
||||
m_Table[entry.Mobile] = entry;
|
||||
entry.Index = Entries.Count;
|
||||
Entries.Add(entry);
|
||||
}
|
||||
}
|
||||
|
||||
if (version == 0)
|
||||
{
|
||||
Entries.Sort();
|
||||
|
||||
for (int i = 0; i < Entries.Count; ++i)
|
||||
{
|
||||
LadderEntry entry = Entries[i];
|
||||
|
||||
entry.Index = i;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Ladder Instance { get; set; }
|
||||
|
||||
public static int GetLevel(int xp)
|
||||
{
|
||||
if (xp >= 22500)
|
||||
return 50;
|
||||
if (xp >= 2500)
|
||||
return 10 + (xp - 2500) / 500;
|
||||
|
||||
return m_ShortLevels[Math.Max(xp, 0) / 100];
|
||||
}
|
||||
|
||||
public static void GetLevelInfo(int level, out int xpBase, out int xpAdvance)
|
||||
{
|
||||
if (level >= 10)
|
||||
{
|
||||
xpBase = 2500 + (level - 10) * 500;
|
||||
xpAdvance = 500;
|
||||
}
|
||||
else
|
||||
{
|
||||
xpBase = m_BaseXP[level - 1];
|
||||
xpAdvance = m_BaseXP[level] - xpBase;
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetLossFactor(int level)
|
||||
{
|
||||
if (level >= 10)
|
||||
return 100;
|
||||
|
||||
return m_LossFactors[level - 1];
|
||||
}
|
||||
|
||||
public static int GetOffsetScalar(int ourLevel, int theirLevel, bool win)
|
||||
{
|
||||
int x = ourLevel - theirLevel;
|
||||
|
||||
if (x < -6 || x > +6)
|
||||
return 0;
|
||||
|
||||
int y = win ? 0 : 1;
|
||||
|
||||
return m_OffsetScalar[x + 6, y];
|
||||
}
|
||||
|
||||
public static int GetExperienceGain(LadderEntry us, LadderEntry them, bool weWon)
|
||||
{
|
||||
if (us == null || them == null)
|
||||
return 0;
|
||||
|
||||
int ourLevel = GetLevel(us.Experience);
|
||||
int theirLevel = GetLevel(them.Experience);
|
||||
|
||||
int scalar = GetOffsetScalar(ourLevel, theirLevel, weWon);
|
||||
|
||||
if (scalar == 0)
|
||||
return 0;
|
||||
|
||||
int xp = 25 * scalar;
|
||||
|
||||
if (!weWon)
|
||||
xp = xp * GetLossFactor(ourLevel) / 100;
|
||||
|
||||
xp /= 100;
|
||||
|
||||
if (xp <= 0)
|
||||
xp = 1;
|
||||
|
||||
return xp * (weWon ? 1 : -1);
|
||||
}
|
||||
|
||||
private int Swap(int idx, int newIdx)
|
||||
{
|
||||
LadderEntry hold = Entries[idx];
|
||||
|
||||
Entries[idx] = Entries[newIdx];
|
||||
Entries[newIdx] = hold;
|
||||
|
||||
Entries[idx].Index = idx;
|
||||
Entries[newIdx].Index = newIdx;
|
||||
|
||||
return newIdx;
|
||||
}
|
||||
|
||||
public void UpdateEntry(LadderEntry entry)
|
||||
{
|
||||
int index = entry.Index;
|
||||
|
||||
if (index >= 0 && index < Entries.Count)
|
||||
{
|
||||
while (index - 1 >= 0 && entry.CompareTo(Entries[index - 1]) < 0)
|
||||
index = Swap(index, index - 1);
|
||||
|
||||
while (index + 1 < Entries.Count && entry.CompareTo(Entries[index + 1]) > 0)
|
||||
index = Swap(index, index + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public LadderEntry Find(Mobile mob)
|
||||
{
|
||||
if (m_Table.TryGetValue(mob, out LadderEntry entry))
|
||||
{
|
||||
m_Table[mob] = entry = new LadderEntry(mob, this);
|
||||
entry.Index = Entries.Count;
|
||||
Entries.Add(entry);
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
public LadderEntry FindNoCreate(Mobile mob)
|
||||
{
|
||||
m_Table.TryGetValue(mob, out LadderEntry entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
public void Serialize(IGenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(1); // version;
|
||||
|
||||
writer.WriteEncodedInt(Entries.Count);
|
||||
|
||||
for (int i = 0; i < Entries.Count; ++i)
|
||||
Entries[i].Serialize(writer);
|
||||
}
|
||||
}
|
||||
|
||||
public class LadderEntry : IComparable<LadderEntry>
|
||||
{
|
||||
private int m_Experience;
|
||||
private readonly Ladder m_Ladder;
|
||||
|
||||
public LadderEntry(Mobile mob, Ladder ladder)
|
||||
{
|
||||
m_Ladder = ladder;
|
||||
Mobile = mob;
|
||||
}
|
||||
|
||||
public LadderEntry(IGenericReader reader, Ladder ladder, int version)
|
||||
{
|
||||
m_Ladder = ladder;
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
case 0:
|
||||
{
|
||||
Mobile = reader.ReadMobile();
|
||||
m_Experience = reader.ReadEncodedInt();
|
||||
Wins = reader.ReadEncodedInt();
|
||||
Losses = reader.ReadEncodedInt();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Mobile Mobile { get; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)]
|
||||
public int Experience
|
||||
{
|
||||
get => m_Experience;
|
||||
set
|
||||
{
|
||||
m_Experience = value;
|
||||
m_Ladder.UpdateEntry(this);
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)]
|
||||
public int Wins { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)]
|
||||
public int Losses { get; set; }
|
||||
|
||||
public int Index { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Rank => Index;
|
||||
|
||||
public int CompareTo(LadderEntry l) => (l?.m_Experience ?? 0) - m_Experience;
|
||||
|
||||
public void Serialize(IGenericWriter writer)
|
||||
{
|
||||
writer.Write(Mobile);
|
||||
writer.WriteEncodedInt(m_Experience);
|
||||
writer.WriteEncodedInt(Wins);
|
||||
writer.WriteEncodedInt(Losses);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class LadderController : Item
|
||||
{
|
||||
[Constructible]
|
||||
public LadderController() : base(0x1B7A)
|
||||
{
|
||||
Visible = false;
|
||||
Movable = false;
|
||||
|
||||
Ladder = new Ladder();
|
||||
|
||||
Ladder.Instance ??= Ladder;
|
||||
}
|
||||
|
||||
public LadderController(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.Administrator)]
|
||||
public Ladder Ladder { get; private set; }
|
||||
|
||||
public override string DefaultName => "ladder controller";
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
if (Ladder.Instance == Ladder)
|
||||
Ladder.Instance = null;
|
||||
|
||||
base.Delete();
|
||||
}
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1);
|
||||
|
||||
Ladder.Serialize(writer);
|
||||
|
||||
writer.Write(Ladder.Instance == Ladder);
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
case 0:
|
||||
{
|
||||
Ladder = new Ladder(reader);
|
||||
|
||||
if (version < 1 || reader.ReadBool())
|
||||
Ladder.Instance = Ladder;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Ladder
|
||||
{
|
||||
private static readonly int[] m_ShortLevels =
|
||||
{
|
||||
1,
|
||||
2,
|
||||
3, 3,
|
||||
4, 4,
|
||||
5, 5, 5,
|
||||
6, 6, 6,
|
||||
7, 7, 7, 7,
|
||||
8, 8, 8, 8,
|
||||
9, 9, 9, 9, 9
|
||||
};
|
||||
|
||||
private static readonly int[] m_BaseXP =
|
||||
{
|
||||
0, 100, 200, 400, 600, 900, 1200, 1600, 2000, 2500
|
||||
};
|
||||
|
||||
private static readonly int[] m_LossFactors =
|
||||
{
|
||||
10,
|
||||
11, 11,
|
||||
25, 25,
|
||||
43, 43,
|
||||
67, 67
|
||||
};
|
||||
|
||||
private static readonly int[,] m_OffsetScalar =
|
||||
{
|
||||
/* { win, los } */
|
||||
/* -6 */ { 175, 25 },
|
||||
/* -5 */ { 165, 35 },
|
||||
/* -4 */ { 155, 45 },
|
||||
/* -3 */ { 145, 55 },
|
||||
/* -2 */ { 130, 70 },
|
||||
/* -1 */ { 115, 85 },
|
||||
/* 0 */ { 100, 100 },
|
||||
/* +1 */ { 90, 110 },
|
||||
/* +2 */ { 80, 120 },
|
||||
/* +3 */ { 70, 130 },
|
||||
/* +4 */ { 60, 140 },
|
||||
/* +5 */ { 50, 150 },
|
||||
/* +6 */ { 40, 160 }
|
||||
};
|
||||
|
||||
private readonly Dictionary<Mobile, LadderEntry> m_Table;
|
||||
|
||||
public Ladder() => m_Table = new Dictionary<Mobile, LadderEntry>();
|
||||
|
||||
public Ladder(IGenericReader reader)
|
||||
{
|
||||
var version = reader.ReadEncodedInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
case 0:
|
||||
{
|
||||
var count = reader.ReadEncodedInt();
|
||||
|
||||
m_Table = new Dictionary<Mobile, LadderEntry>(count);
|
||||
Entries = new List<LadderEntry>(count);
|
||||
|
||||
for (var i = 0; i < count; ++i)
|
||||
{
|
||||
var entry = new LadderEntry(reader, this, version);
|
||||
|
||||
if (entry.Mobile != null)
|
||||
{
|
||||
m_Table[entry.Mobile] = entry;
|
||||
entry.Index = Entries.Count;
|
||||
Entries.Add(entry);
|
||||
}
|
||||
}
|
||||
|
||||
if (version == 0)
|
||||
{
|
||||
Entries.Sort();
|
||||
|
||||
for (var i = 0; i < Entries.Count; ++i)
|
||||
{
|
||||
var entry = Entries[i];
|
||||
|
||||
entry.Index = i;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<LadderEntry> Entries { get; } = new List<LadderEntry>();
|
||||
|
||||
public static Ladder Instance { get; set; }
|
||||
|
||||
public static int GetLevel(int xp)
|
||||
{
|
||||
if (xp >= 22500)
|
||||
return 50;
|
||||
if (xp >= 2500)
|
||||
return 10 + (xp - 2500) / 500;
|
||||
|
||||
return m_ShortLevels[Math.Max(xp, 0) / 100];
|
||||
}
|
||||
|
||||
public static void GetLevelInfo(int level, out int xpBase, out int xpAdvance)
|
||||
{
|
||||
if (level >= 10)
|
||||
{
|
||||
xpBase = 2500 + (level - 10) * 500;
|
||||
xpAdvance = 500;
|
||||
}
|
||||
else
|
||||
{
|
||||
xpBase = m_BaseXP[level - 1];
|
||||
xpAdvance = m_BaseXP[level] - xpBase;
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetLossFactor(int level)
|
||||
{
|
||||
if (level >= 10)
|
||||
return 100;
|
||||
|
||||
return m_LossFactors[level - 1];
|
||||
}
|
||||
|
||||
public static int GetOffsetScalar(int ourLevel, int theirLevel, bool win)
|
||||
{
|
||||
var x = ourLevel - theirLevel;
|
||||
|
||||
if (x < -6 || x > +6)
|
||||
return 0;
|
||||
|
||||
var y = win ? 0 : 1;
|
||||
|
||||
return m_OffsetScalar[x + 6, y];
|
||||
}
|
||||
|
||||
public static int GetExperienceGain(LadderEntry us, LadderEntry them, bool weWon)
|
||||
{
|
||||
if (us == null || them == null)
|
||||
return 0;
|
||||
|
||||
var ourLevel = GetLevel(us.Experience);
|
||||
var theirLevel = GetLevel(them.Experience);
|
||||
|
||||
var scalar = GetOffsetScalar(ourLevel, theirLevel, weWon);
|
||||
|
||||
if (scalar == 0)
|
||||
return 0;
|
||||
|
||||
var xp = 25 * scalar;
|
||||
|
||||
if (!weWon)
|
||||
xp = xp * GetLossFactor(ourLevel) / 100;
|
||||
|
||||
xp /= 100;
|
||||
|
||||
if (xp <= 0)
|
||||
xp = 1;
|
||||
|
||||
return xp * (weWon ? 1 : -1);
|
||||
}
|
||||
|
||||
private int Swap(int idx, int newIdx)
|
||||
{
|
||||
var hold = Entries[idx];
|
||||
|
||||
Entries[idx] = Entries[newIdx];
|
||||
Entries[newIdx] = hold;
|
||||
|
||||
Entries[idx].Index = idx;
|
||||
Entries[newIdx].Index = newIdx;
|
||||
|
||||
return newIdx;
|
||||
}
|
||||
|
||||
public void UpdateEntry(LadderEntry entry)
|
||||
{
|
||||
var index = entry.Index;
|
||||
|
||||
if (index >= 0 && index < Entries.Count)
|
||||
{
|
||||
while (index - 1 >= 0 && entry.CompareTo(Entries[index - 1]) < 0)
|
||||
index = Swap(index, index - 1);
|
||||
|
||||
while (index + 1 < Entries.Count && entry.CompareTo(Entries[index + 1]) > 0)
|
||||
index = Swap(index, index + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public LadderEntry Find(Mobile mob)
|
||||
{
|
||||
if (m_Table.TryGetValue(mob, out var entry))
|
||||
{
|
||||
m_Table[mob] = entry = new LadderEntry(mob, this);
|
||||
entry.Index = Entries.Count;
|
||||
Entries.Add(entry);
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
public LadderEntry FindNoCreate(Mobile mob)
|
||||
{
|
||||
m_Table.TryGetValue(mob, out var entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
public void Serialize(IGenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(1); // version;
|
||||
|
||||
writer.WriteEncodedInt(Entries.Count);
|
||||
|
||||
for (var i = 0; i < Entries.Count; ++i)
|
||||
Entries[i].Serialize(writer);
|
||||
}
|
||||
}
|
||||
|
||||
public class LadderEntry : IComparable<LadderEntry>
|
||||
{
|
||||
private readonly Ladder m_Ladder;
|
||||
private int m_Experience;
|
||||
|
||||
public LadderEntry(Mobile mob, Ladder ladder)
|
||||
{
|
||||
m_Ladder = ladder;
|
||||
Mobile = mob;
|
||||
}
|
||||
|
||||
public LadderEntry(IGenericReader reader, Ladder ladder, int version)
|
||||
{
|
||||
m_Ladder = ladder;
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
case 0:
|
||||
{
|
||||
Mobile = reader.ReadMobile();
|
||||
m_Experience = reader.ReadEncodedInt();
|
||||
Wins = reader.ReadEncodedInt();
|
||||
Losses = reader.ReadEncodedInt();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Mobile Mobile { get; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)]
|
||||
public int Experience
|
||||
{
|
||||
get => m_Experience;
|
||||
set
|
||||
{
|
||||
m_Experience = value;
|
||||
m_Ladder.UpdateEntry(this);
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)]
|
||||
public int Wins { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)]
|
||||
public int Losses { get; set; }
|
||||
|
||||
public int Index { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Rank => Index;
|
||||
|
||||
public int CompareTo(LadderEntry l) => (l?.m_Experience ?? 0) - m_Experience;
|
||||
|
||||
public void Serialize(IGenericWriter writer)
|
||||
{
|
||||
writer.Write(Mobile);
|
||||
writer.WriteEncodedInt(m_Experience);
|
||||
writer.WriteEncodedInt(Wins);
|
||||
writer.WriteEncodedInt(Losses);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,225 +1,233 @@
|
|||
using System;
|
||||
using System.Text;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class Participant
|
||||
{
|
||||
public Participant(DuelContext context, int count)
|
||||
{
|
||||
Context = context;
|
||||
// m_Stakes = new StakesContainer( context, this );
|
||||
Resize(count);
|
||||
}
|
||||
|
||||
public int Count => Players.Length;
|
||||
public DuelPlayer[] Players { get; private set; }
|
||||
|
||||
public DuelContext Context { get; }
|
||||
|
||||
public TourneyParticipant TourneyPart { get; set; }
|
||||
|
||||
public int FilledSlots
|
||||
{
|
||||
get
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
for (int i = 0; i < Players.Length; ++i)
|
||||
if (Players[i] != null)
|
||||
++count;
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasOpenSlot
|
||||
{
|
||||
get
|
||||
{
|
||||
for (int i = 0; i < Players.Length; ++i)
|
||||
if (Players[i] == null)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Eliminated
|
||||
{
|
||||
get
|
||||
{
|
||||
for (int i = 0; i < Players.Length; ++i)
|
||||
if (Players[i]?.Eliminated == false)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public string NameList
|
||||
{
|
||||
get
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < Players.Length; ++i)
|
||||
{
|
||||
if (Players[i] == null)
|
||||
continue;
|
||||
|
||||
Mobile mob = Players[i].Mobile;
|
||||
|
||||
if (sb.Length > 0)
|
||||
sb.Append(", ");
|
||||
|
||||
sb.Append(mob.Name);
|
||||
}
|
||||
|
||||
return sb.Length == 0 ? "Empty" : sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public DuelPlayer Find(Mobile mob)
|
||||
{
|
||||
if (mob is PlayerMobile pm)
|
||||
{
|
||||
if (pm.DuelContext == Context && pm.DuelPlayer.Participant == this)
|
||||
return pm.DuelPlayer;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
for (int i = 0; i < Players.Length; ++i)
|
||||
if (Players[i]?.Mobile == mob)
|
||||
return Players[i];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool Contains(Mobile mob) => Find(mob) != null;
|
||||
|
||||
public void Broadcast(int hue, string message, string nonLocalOverhead, string localOverhead)
|
||||
{
|
||||
for (int i = 0; i < Players.Length; ++i)
|
||||
if (Players[i] != null)
|
||||
{
|
||||
if (message != null)
|
||||
Players[i].Mobile.SendMessage(hue, message);
|
||||
|
||||
if (nonLocalOverhead != null)
|
||||
Players[i].Mobile.NonlocalOverheadMessage(MessageType.Regular, hue, false,
|
||||
string.Format(nonLocalOverhead, Players[i].Mobile.Name,
|
||||
Players[i].Mobile.Female ? "her" : "his"));
|
||||
|
||||
if (localOverhead != null)
|
||||
Players[i].Mobile.LocalOverheadMessage(MessageType.Regular, hue, false, localOverhead);
|
||||
}
|
||||
}
|
||||
|
||||
public void Nullify(DuelPlayer player)
|
||||
{
|
||||
if (player == null)
|
||||
return;
|
||||
|
||||
int index = Array.IndexOf(Players, player);
|
||||
|
||||
if (index == -1)
|
||||
return;
|
||||
|
||||
Players[index] = null;
|
||||
}
|
||||
|
||||
public void Remove(DuelPlayer player)
|
||||
{
|
||||
if (player == null)
|
||||
return;
|
||||
|
||||
int index = Array.IndexOf(Players, player);
|
||||
|
||||
if (index == -1)
|
||||
return;
|
||||
|
||||
DuelPlayer[] old = Players;
|
||||
Players = new DuelPlayer[old.Length - 1];
|
||||
|
||||
for (int i = 0; i < index; ++i)
|
||||
Players[i] = old[i];
|
||||
|
||||
for (int i = index + 1; i < old.Length; ++i)
|
||||
Players[i - 1] = old[i];
|
||||
}
|
||||
|
||||
public void Remove(Mobile player)
|
||||
{
|
||||
Remove(Find(player));
|
||||
}
|
||||
|
||||
public void Add(Mobile player)
|
||||
{
|
||||
if (Contains(player))
|
||||
return;
|
||||
|
||||
for (int i = 0; i < Players.Length; ++i)
|
||||
if (Players[i] == null)
|
||||
{
|
||||
Players[i] = new DuelPlayer(player, this);
|
||||
return;
|
||||
}
|
||||
|
||||
Resize(Players.Length + 1);
|
||||
Players[^1] = new DuelPlayer(player, this);
|
||||
}
|
||||
|
||||
public void Resize(int count)
|
||||
{
|
||||
DuelPlayer[] old = Players;
|
||||
Players = new DuelPlayer[count];
|
||||
|
||||
if (old != null)
|
||||
{
|
||||
int ct = 0;
|
||||
|
||||
for (int i = 0; i < old.Length; ++i)
|
||||
if (old[i] != null && ct < count)
|
||||
Players[ct++] = old[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class DuelPlayer
|
||||
{
|
||||
private bool m_Eliminated;
|
||||
|
||||
public DuelPlayer(Mobile mob, Participant p)
|
||||
{
|
||||
Mobile = mob;
|
||||
Participant = p;
|
||||
|
||||
if (mob is PlayerMobile mobile)
|
||||
mobile.DuelPlayer = this;
|
||||
}
|
||||
|
||||
public Mobile Mobile { get; }
|
||||
|
||||
public bool Ready { get; set; }
|
||||
|
||||
public bool Eliminated
|
||||
{
|
||||
get => m_Eliminated;
|
||||
set
|
||||
{
|
||||
m_Eliminated = value;
|
||||
if (Participant.Context.m_Tournament != null && m_Eliminated)
|
||||
{
|
||||
Participant.Context.m_Tournament.OnEliminated(this);
|
||||
Mobile.SendEverything();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Participant Participant { get; set; }
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Text;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class Participant
|
||||
{
|
||||
public Participant(DuelContext context, int count)
|
||||
{
|
||||
Context = context;
|
||||
// m_Stakes = new StakesContainer( context, this );
|
||||
Resize(count);
|
||||
}
|
||||
|
||||
public int Count => Players.Length;
|
||||
public DuelPlayer[] Players { get; private set; }
|
||||
|
||||
public DuelContext Context { get; }
|
||||
|
||||
public TourneyParticipant TourneyPart { get; set; }
|
||||
|
||||
public int FilledSlots
|
||||
{
|
||||
get
|
||||
{
|
||||
var count = 0;
|
||||
|
||||
for (var i = 0; i < Players.Length; ++i)
|
||||
if (Players[i] != null)
|
||||
++count;
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasOpenSlot
|
||||
{
|
||||
get
|
||||
{
|
||||
for (var i = 0; i < Players.Length; ++i)
|
||||
if (Players[i] == null)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Eliminated
|
||||
{
|
||||
get
|
||||
{
|
||||
for (var i = 0; i < Players.Length; ++i)
|
||||
if (Players[i]?.Eliminated == false)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public string NameList
|
||||
{
|
||||
get
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
|
||||
for (var i = 0; i < Players.Length; ++i)
|
||||
{
|
||||
if (Players[i] == null)
|
||||
continue;
|
||||
|
||||
var mob = Players[i].Mobile;
|
||||
|
||||
if (sb.Length > 0)
|
||||
sb.Append(", ");
|
||||
|
||||
sb.Append(mob.Name);
|
||||
}
|
||||
|
||||
return sb.Length == 0 ? "Empty" : sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public DuelPlayer Find(Mobile mob)
|
||||
{
|
||||
if (mob is PlayerMobile pm)
|
||||
{
|
||||
if (pm.DuelContext == Context && pm.DuelPlayer.Participant == this)
|
||||
return pm.DuelPlayer;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
for (var i = 0; i < Players.Length; ++i)
|
||||
if (Players[i]?.Mobile == mob)
|
||||
return Players[i];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool Contains(Mobile mob) => Find(mob) != null;
|
||||
|
||||
public void Broadcast(int hue, string message, string nonLocalOverhead, string localOverhead)
|
||||
{
|
||||
for (var i = 0; i < Players.Length; ++i)
|
||||
if (Players[i] != null)
|
||||
{
|
||||
if (message != null)
|
||||
Players[i].Mobile.SendMessage(hue, message);
|
||||
|
||||
if (nonLocalOverhead != null)
|
||||
Players[i]
|
||||
.Mobile.NonlocalOverheadMessage(
|
||||
MessageType.Regular,
|
||||
hue,
|
||||
false,
|
||||
string.Format(
|
||||
nonLocalOverhead,
|
||||
Players[i].Mobile.Name,
|
||||
Players[i].Mobile.Female ? "her" : "his"
|
||||
)
|
||||
);
|
||||
|
||||
if (localOverhead != null)
|
||||
Players[i].Mobile.LocalOverheadMessage(MessageType.Regular, hue, false, localOverhead);
|
||||
}
|
||||
}
|
||||
|
||||
public void Nullify(DuelPlayer player)
|
||||
{
|
||||
if (player == null)
|
||||
return;
|
||||
|
||||
var index = Array.IndexOf(Players, player);
|
||||
|
||||
if (index == -1)
|
||||
return;
|
||||
|
||||
Players[index] = null;
|
||||
}
|
||||
|
||||
public void Remove(DuelPlayer player)
|
||||
{
|
||||
if (player == null)
|
||||
return;
|
||||
|
||||
var index = Array.IndexOf(Players, player);
|
||||
|
||||
if (index == -1)
|
||||
return;
|
||||
|
||||
var old = Players;
|
||||
Players = new DuelPlayer[old.Length - 1];
|
||||
|
||||
for (var i = 0; i < index; ++i)
|
||||
Players[i] = old[i];
|
||||
|
||||
for (var i = index + 1; i < old.Length; ++i)
|
||||
Players[i - 1] = old[i];
|
||||
}
|
||||
|
||||
public void Remove(Mobile player)
|
||||
{
|
||||
Remove(Find(player));
|
||||
}
|
||||
|
||||
public void Add(Mobile player)
|
||||
{
|
||||
if (Contains(player))
|
||||
return;
|
||||
|
||||
for (var i = 0; i < Players.Length; ++i)
|
||||
if (Players[i] == null)
|
||||
{
|
||||
Players[i] = new DuelPlayer(player, this);
|
||||
return;
|
||||
}
|
||||
|
||||
Resize(Players.Length + 1);
|
||||
Players[^1] = new DuelPlayer(player, this);
|
||||
}
|
||||
|
||||
public void Resize(int count)
|
||||
{
|
||||
var old = Players;
|
||||
Players = new DuelPlayer[count];
|
||||
|
||||
if (old != null)
|
||||
{
|
||||
var ct = 0;
|
||||
|
||||
for (var i = 0; i < old.Length; ++i)
|
||||
if (old[i] != null && ct < count)
|
||||
Players[ct++] = old[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class DuelPlayer
|
||||
{
|
||||
private bool m_Eliminated;
|
||||
|
||||
public DuelPlayer(Mobile mob, Participant p)
|
||||
{
|
||||
Mobile = mob;
|
||||
Participant = p;
|
||||
|
||||
if (mob is PlayerMobile mobile)
|
||||
mobile.DuelPlayer = this;
|
||||
}
|
||||
|
||||
public Mobile Mobile { get; }
|
||||
|
||||
public bool Ready { get; set; }
|
||||
|
||||
public bool Eliminated
|
||||
{
|
||||
get => m_Eliminated;
|
||||
set
|
||||
{
|
||||
m_Eliminated = value;
|
||||
if (Participant.Context.m_Tournament != null && m_Eliminated)
|
||||
{
|
||||
Participant.Context.m_Tournament.OnEliminated(this);
|
||||
Mobile.SendEverything();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Participant Participant { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,271 +1,271 @@
|
|||
using System.Collections.Generic;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class PreferencesController : Item
|
||||
{
|
||||
[Constructible]
|
||||
public PreferencesController() : base(0x1B7A)
|
||||
{
|
||||
Visible = false;
|
||||
Movable = false;
|
||||
|
||||
Preferences = new Preferences();
|
||||
|
||||
if (Preferences.Instance == null)
|
||||
Preferences.Instance = Preferences;
|
||||
else
|
||||
Delete();
|
||||
}
|
||||
|
||||
public PreferencesController(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.Administrator)]
|
||||
public Preferences Preferences { get; private set; }
|
||||
|
||||
public override string DefaultName => "preferences controller";
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
if (Preferences.Instance != Preferences)
|
||||
base.Delete();
|
||||
}
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
|
||||
Preferences.Serialize(writer);
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
Preferences = new Preferences(reader);
|
||||
Preferences.Instance = Preferences;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Preferences
|
||||
{
|
||||
private readonly Dictionary<Mobile, PreferencesEntry> m_Table;
|
||||
|
||||
public Preferences()
|
||||
{
|
||||
m_Table = new Dictionary<Mobile, PreferencesEntry>();
|
||||
Entries = new List<PreferencesEntry>();
|
||||
}
|
||||
|
||||
public Preferences(IGenericReader reader)
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
int count = reader.ReadEncodedInt();
|
||||
|
||||
m_Table = new Dictionary<Mobile, PreferencesEntry>(count);
|
||||
Entries = new List<PreferencesEntry>(count);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
PreferencesEntry entry = new PreferencesEntry(reader, version);
|
||||
|
||||
if (entry.Mobile != null)
|
||||
{
|
||||
m_Table[entry.Mobile] = entry;
|
||||
Entries.Add(entry);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<PreferencesEntry> Entries { get; }
|
||||
|
||||
public static Preferences Instance { get; set; }
|
||||
|
||||
public PreferencesEntry Find(Mobile mob)
|
||||
{
|
||||
if (m_Table.TryGetValue(mob, out PreferencesEntry entry))
|
||||
{
|
||||
m_Table[mob] = entry = new PreferencesEntry(mob);
|
||||
Entries.Add(entry);
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
public void Serialize(IGenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(0); // version;
|
||||
|
||||
writer.WriteEncodedInt(Entries.Count);
|
||||
|
||||
for (int i = 0; i < Entries.Count; ++i)
|
||||
Entries[i].Serialize(writer);
|
||||
}
|
||||
}
|
||||
|
||||
public class PreferencesEntry
|
||||
{
|
||||
public PreferencesEntry(Mobile mob)
|
||||
{
|
||||
Mobile = mob;
|
||||
Disliked = new List<string>();
|
||||
}
|
||||
|
||||
public PreferencesEntry(IGenericReader reader, int version)
|
||||
{
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
Mobile = reader.ReadMobile();
|
||||
|
||||
int count = reader.ReadEncodedInt();
|
||||
|
||||
Disliked = new List<string>(count);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
Disliked.Add(reader.ReadString());
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Mobile Mobile { get; }
|
||||
|
||||
public List<string> Disliked { get; }
|
||||
|
||||
public void Serialize(IGenericWriter writer)
|
||||
{
|
||||
writer.Write(Mobile);
|
||||
|
||||
writer.WriteEncodedInt(Disliked.Count);
|
||||
|
||||
for (int i = 0; i < Disliked.Count; ++i)
|
||||
writer.Write(Disliked[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public class PreferencesGump : Gump
|
||||
{
|
||||
private int m_ColumnX = 12;
|
||||
private readonly PreferencesEntry m_Entry;
|
||||
|
||||
public PreferencesGump(Mobile from, Preferences prefs) : base(50, 50)
|
||||
{
|
||||
m_Entry = prefs.Find(from);
|
||||
|
||||
if (m_Entry == null)
|
||||
return;
|
||||
|
||||
List<Arena> arenas = Arena.Arenas;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
int height = 12 + 20 + arenas.Count * 31 + 24 + 12;
|
||||
|
||||
AddBackground(0, 0, 499 + 40 - 365, height, 0x2436);
|
||||
|
||||
for (int i = 1; i < arenas.Count; i += 2)
|
||||
AddImageTiled(12, 32 + i * 31, 475 + 40 - 365, 30, 0x2430);
|
||||
|
||||
AddAlphaRegion(10, 10, 479 + 40 - 365, height - 20);
|
||||
|
||||
AddColumnHeader(35, null);
|
||||
AddColumnHeader(115, "Arena");
|
||||
|
||||
AddButton(499 + 40 - 365 - 12 - 63 - 4 - 63, height - 12 - 24, 247, 248, 1);
|
||||
AddButton(499 + 40 - 365 - 12 - 63, height - 12 - 24, 241, 242, 2);
|
||||
|
||||
for (int i = 0; i < arenas.Count; ++i)
|
||||
{
|
||||
Arena ar = arenas[i];
|
||||
|
||||
string name = ar.Name ?? "(no name)";
|
||||
|
||||
int x = 12;
|
||||
int y = 32 + i * 31;
|
||||
|
||||
int color = 0xCCFFCC;
|
||||
|
||||
AddCheck(x + 3, y + 1, 9730, 9727, m_Entry.Disliked.Contains(name), i);
|
||||
x += 35;
|
||||
|
||||
AddBorderedText(x + 5, y + 5, 115 - 5, name, color, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (m_Entry == null)
|
||||
return;
|
||||
|
||||
if (info.ButtonID != 1)
|
||||
return;
|
||||
|
||||
m_Entry.Disliked.Clear();
|
||||
|
||||
List<Arena> arenas = Arena.Arenas;
|
||||
|
||||
for (int i = 0; i < info.Switches.Length; ++i)
|
||||
{
|
||||
int idx = info.Switches[i];
|
||||
|
||||
if (idx >= 0 && idx < arenas.Count)
|
||||
m_Entry.Disliked.Add(arenas[idx].Name);
|
||||
}
|
||||
}
|
||||
|
||||
public string Center(string text) => $"<CENTER>{text}</CENTER>";
|
||||
|
||||
public string Color(string text, int color) => $"<BASEFONT COLOR=#{color:X6}>{text}</BASEFONT>";
|
||||
|
||||
private void AddBorderedText(int x, int y, int width, string text, int color, int borderColor)
|
||||
{
|
||||
AddColoredText(x, y, width, text, color);
|
||||
}
|
||||
|
||||
private void AddColoredText(int x, int y, int width, string text, int color)
|
||||
{
|
||||
if (color == 0)
|
||||
AddHtml(x, y, width, 20, text);
|
||||
else
|
||||
AddHtml(x, y, width, 20, Color(text, color));
|
||||
}
|
||||
|
||||
private void AddColumnHeader(int width, string name)
|
||||
{
|
||||
AddBackground(m_ColumnX, 12, width, 20, 0x242C);
|
||||
AddImageTiled(m_ColumnX + 2, 14, width - 4, 16, 0x2430);
|
||||
|
||||
if (name != null)
|
||||
AddBorderedText(m_ColumnX, 13, width, Center(name), 0xFFFFFF, 0);
|
||||
|
||||
m_ColumnX += width;
|
||||
}
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class PreferencesController : Item
|
||||
{
|
||||
[Constructible]
|
||||
public PreferencesController() : base(0x1B7A)
|
||||
{
|
||||
Visible = false;
|
||||
Movable = false;
|
||||
|
||||
Preferences = new Preferences();
|
||||
|
||||
if (Preferences.Instance == null)
|
||||
Preferences.Instance = Preferences;
|
||||
else
|
||||
Delete();
|
||||
}
|
||||
|
||||
public PreferencesController(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.Administrator)]
|
||||
public Preferences Preferences { get; private set; }
|
||||
|
||||
public override string DefaultName => "preferences controller";
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
if (Preferences.Instance != Preferences)
|
||||
base.Delete();
|
||||
}
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
|
||||
Preferences.Serialize(writer);
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
Preferences = new Preferences(reader);
|
||||
Preferences.Instance = Preferences;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Preferences
|
||||
{
|
||||
private readonly Dictionary<Mobile, PreferencesEntry> m_Table;
|
||||
|
||||
public Preferences()
|
||||
{
|
||||
m_Table = new Dictionary<Mobile, PreferencesEntry>();
|
||||
Entries = new List<PreferencesEntry>();
|
||||
}
|
||||
|
||||
public Preferences(IGenericReader reader)
|
||||
{
|
||||
var version = reader.ReadEncodedInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
var count = reader.ReadEncodedInt();
|
||||
|
||||
m_Table = new Dictionary<Mobile, PreferencesEntry>(count);
|
||||
Entries = new List<PreferencesEntry>(count);
|
||||
|
||||
for (var i = 0; i < count; ++i)
|
||||
{
|
||||
var entry = new PreferencesEntry(reader, version);
|
||||
|
||||
if (entry.Mobile != null)
|
||||
{
|
||||
m_Table[entry.Mobile] = entry;
|
||||
Entries.Add(entry);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<PreferencesEntry> Entries { get; }
|
||||
|
||||
public static Preferences Instance { get; set; }
|
||||
|
||||
public PreferencesEntry Find(Mobile mob)
|
||||
{
|
||||
if (m_Table.TryGetValue(mob, out var entry))
|
||||
{
|
||||
m_Table[mob] = entry = new PreferencesEntry(mob);
|
||||
Entries.Add(entry);
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
public void Serialize(IGenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(0); // version;
|
||||
|
||||
writer.WriteEncodedInt(Entries.Count);
|
||||
|
||||
for (var i = 0; i < Entries.Count; ++i)
|
||||
Entries[i].Serialize(writer);
|
||||
}
|
||||
}
|
||||
|
||||
public class PreferencesEntry
|
||||
{
|
||||
public PreferencesEntry(Mobile mob)
|
||||
{
|
||||
Mobile = mob;
|
||||
Disliked = new List<string>();
|
||||
}
|
||||
|
||||
public PreferencesEntry(IGenericReader reader, int version)
|
||||
{
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
Mobile = reader.ReadMobile();
|
||||
|
||||
var count = reader.ReadEncodedInt();
|
||||
|
||||
Disliked = new List<string>(count);
|
||||
|
||||
for (var i = 0; i < count; ++i)
|
||||
Disliked.Add(reader.ReadString());
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Mobile Mobile { get; }
|
||||
|
||||
public List<string> Disliked { get; }
|
||||
|
||||
public void Serialize(IGenericWriter writer)
|
||||
{
|
||||
writer.Write(Mobile);
|
||||
|
||||
writer.WriteEncodedInt(Disliked.Count);
|
||||
|
||||
for (var i = 0; i < Disliked.Count; ++i)
|
||||
writer.Write(Disliked[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public class PreferencesGump : Gump
|
||||
{
|
||||
private readonly PreferencesEntry m_Entry;
|
||||
private int m_ColumnX = 12;
|
||||
|
||||
public PreferencesGump(Mobile from, Preferences prefs) : base(50, 50)
|
||||
{
|
||||
m_Entry = prefs.Find(from);
|
||||
|
||||
if (m_Entry == null)
|
||||
return;
|
||||
|
||||
var arenas = Arena.Arenas;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
var height = 12 + 20 + arenas.Count * 31 + 24 + 12;
|
||||
|
||||
AddBackground(0, 0, 499 + 40 - 365, height, 0x2436);
|
||||
|
||||
for (var i = 1; i < arenas.Count; i += 2)
|
||||
AddImageTiled(12, 32 + i * 31, 475 + 40 - 365, 30, 0x2430);
|
||||
|
||||
AddAlphaRegion(10, 10, 479 + 40 - 365, height - 20);
|
||||
|
||||
AddColumnHeader(35, null);
|
||||
AddColumnHeader(115, "Arena");
|
||||
|
||||
AddButton(499 + 40 - 365 - 12 - 63 - 4 - 63, height - 12 - 24, 247, 248, 1);
|
||||
AddButton(499 + 40 - 365 - 12 - 63, height - 12 - 24, 241, 242, 2);
|
||||
|
||||
for (var i = 0; i < arenas.Count; ++i)
|
||||
{
|
||||
var ar = arenas[i];
|
||||
|
||||
var name = ar.Name ?? "(no name)";
|
||||
|
||||
var x = 12;
|
||||
var y = 32 + i * 31;
|
||||
|
||||
var color = 0xCCFFCC;
|
||||
|
||||
AddCheck(x + 3, y + 1, 9730, 9727, m_Entry.Disliked.Contains(name), i);
|
||||
x += 35;
|
||||
|
||||
AddBorderedText(x + 5, y + 5, 115 - 5, name, color, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (m_Entry == null)
|
||||
return;
|
||||
|
||||
if (info.ButtonID != 1)
|
||||
return;
|
||||
|
||||
m_Entry.Disliked.Clear();
|
||||
|
||||
var arenas = Arena.Arenas;
|
||||
|
||||
for (var i = 0; i < info.Switches.Length; ++i)
|
||||
{
|
||||
var idx = info.Switches[i];
|
||||
|
||||
if (idx >= 0 && idx < arenas.Count)
|
||||
m_Entry.Disliked.Add(arenas[idx].Name);
|
||||
}
|
||||
}
|
||||
|
||||
public string Center(string text) => $"<CENTER>{text}</CENTER>";
|
||||
|
||||
public string Color(string text, int color) => $"<BASEFONT COLOR=#{color:X6}>{text}</BASEFONT>";
|
||||
|
||||
private void AddBorderedText(int x, int y, int width, string text, int color, int borderColor)
|
||||
{
|
||||
AddColoredText(x, y, width, text, color);
|
||||
}
|
||||
|
||||
private void AddColoredText(int x, int y, int width, string text, int color)
|
||||
{
|
||||
if (color == 0)
|
||||
AddHtml(x, y, width, 20, text);
|
||||
else
|
||||
AddHtml(x, y, width, 20, Color(text, color));
|
||||
}
|
||||
|
||||
private void AddColumnHeader(int width, string name)
|
||||
{
|
||||
AddBackground(m_ColumnX, 12, width, 20, 0x242C);
|
||||
AddImageTiled(m_ColumnX + 2, 14, width - 4, 16, 0x2430);
|
||||
|
||||
if (name != null)
|
||||
AddBorderedText(m_ColumnX, 13, width, Center(name), 0xFFFFFF, 0);
|
||||
|
||||
m_ColumnX += width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,102 +1,102 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class Ruleset
|
||||
{
|
||||
public Ruleset(RulesetLayout layout)
|
||||
{
|
||||
Layout = layout;
|
||||
Options = new BitArray(layout.TotalLength);
|
||||
}
|
||||
|
||||
public RulesetLayout Layout { get; }
|
||||
|
||||
public BitArray Options { get; private set; }
|
||||
|
||||
public string Title { get; set; }
|
||||
|
||||
public Ruleset Base { get; private set; }
|
||||
|
||||
public List<Ruleset> Flavors { get; } = new List<Ruleset>();
|
||||
|
||||
public bool Changed { get; set; }
|
||||
|
||||
public void ApplyDefault(Ruleset newDefault)
|
||||
{
|
||||
Base = newDefault;
|
||||
Changed = false;
|
||||
|
||||
Options = new BitArray(newDefault.Options);
|
||||
|
||||
ApplyFlavorsTo(this);
|
||||
}
|
||||
|
||||
public void ApplyFlavorsTo(Ruleset ruleset)
|
||||
{
|
||||
for (int i = 0; i < Flavors.Count; ++i)
|
||||
{
|
||||
Ruleset flavor = Flavors[i];
|
||||
|
||||
Options.Or(flavor.Options);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddFlavor(Ruleset flavor)
|
||||
{
|
||||
if (Flavors.Contains(flavor))
|
||||
return;
|
||||
|
||||
Flavors.Add(flavor);
|
||||
Options.Or(flavor.Options);
|
||||
}
|
||||
|
||||
public void RemoveFlavor(Ruleset flavor)
|
||||
{
|
||||
if (!Flavors.Contains(flavor))
|
||||
return;
|
||||
|
||||
Flavors.Remove(flavor);
|
||||
Options.And(flavor.Options.Not());
|
||||
flavor.Options.Not();
|
||||
}
|
||||
|
||||
public void SetOptionRange(string title, bool value)
|
||||
{
|
||||
RulesetLayout layout = Layout.FindByTitle(title);
|
||||
|
||||
if (layout == null)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < layout.TotalLength; ++i)
|
||||
Options[i + layout.Offset] = value;
|
||||
|
||||
Changed = true;
|
||||
}
|
||||
|
||||
public bool GetOption(string title, string option)
|
||||
{
|
||||
int index = 0;
|
||||
RulesetLayout layout = Layout.FindByOption(title, option, ref index);
|
||||
|
||||
if (layout == null)
|
||||
return true;
|
||||
|
||||
return Options[layout.Offset + index];
|
||||
}
|
||||
|
||||
public void SetOption(string title, string option, bool value)
|
||||
{
|
||||
int index = 0;
|
||||
RulesetLayout layout = Layout.FindByOption(title, option, ref index);
|
||||
|
||||
if (layout == null)
|
||||
return;
|
||||
|
||||
Options[layout.Offset + index] = value;
|
||||
|
||||
Changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class Ruleset
|
||||
{
|
||||
public Ruleset(RulesetLayout layout)
|
||||
{
|
||||
Layout = layout;
|
||||
Options = new BitArray(layout.TotalLength);
|
||||
}
|
||||
|
||||
public RulesetLayout Layout { get; }
|
||||
|
||||
public BitArray Options { get; private set; }
|
||||
|
||||
public string Title { get; set; }
|
||||
|
||||
public Ruleset Base { get; private set; }
|
||||
|
||||
public List<Ruleset> Flavors { get; } = new List<Ruleset>();
|
||||
|
||||
public bool Changed { get; set; }
|
||||
|
||||
public void ApplyDefault(Ruleset newDefault)
|
||||
{
|
||||
Base = newDefault;
|
||||
Changed = false;
|
||||
|
||||
Options = new BitArray(newDefault.Options);
|
||||
|
||||
ApplyFlavorsTo(this);
|
||||
}
|
||||
|
||||
public void ApplyFlavorsTo(Ruleset ruleset)
|
||||
{
|
||||
for (var i = 0; i < Flavors.Count; ++i)
|
||||
{
|
||||
var flavor = Flavors[i];
|
||||
|
||||
Options.Or(flavor.Options);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddFlavor(Ruleset flavor)
|
||||
{
|
||||
if (Flavors.Contains(flavor))
|
||||
return;
|
||||
|
||||
Flavors.Add(flavor);
|
||||
Options.Or(flavor.Options);
|
||||
}
|
||||
|
||||
public void RemoveFlavor(Ruleset flavor)
|
||||
{
|
||||
if (!Flavors.Contains(flavor))
|
||||
return;
|
||||
|
||||
Flavors.Remove(flavor);
|
||||
Options.And(flavor.Options.Not());
|
||||
flavor.Options.Not();
|
||||
}
|
||||
|
||||
public void SetOptionRange(string title, bool value)
|
||||
{
|
||||
var layout = Layout.FindByTitle(title);
|
||||
|
||||
if (layout == null)
|
||||
return;
|
||||
|
||||
for (var i = 0; i < layout.TotalLength; ++i)
|
||||
Options[i + layout.Offset] = value;
|
||||
|
||||
Changed = true;
|
||||
}
|
||||
|
||||
public bool GetOption(string title, string option)
|
||||
{
|
||||
var index = 0;
|
||||
var layout = Layout.FindByOption(title, option, ref index);
|
||||
|
||||
if (layout == null)
|
||||
return true;
|
||||
|
||||
return Options[layout.Offset + index];
|
||||
}
|
||||
|
||||
public void SetOption(string title, string option, bool value)
|
||||
{
|
||||
var index = 0;
|
||||
var layout = Layout.FindByOption(title, option, ref index);
|
||||
|
||||
if (layout == null)
|
||||
return;
|
||||
|
||||
Options[layout.Offset + index] = value;
|
||||
|
||||
Changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,60 +1,60 @@
|
|||
using Server.Factions;
|
||||
using Server.Mobiles;
|
||||
using Server.Regions;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class SafeZone : GuardedRegion
|
||||
{
|
||||
public static readonly int SafeZonePriority = HouseRegion.HousePriority + 1;
|
||||
|
||||
/*public override bool AllowReds => true;*/
|
||||
|
||||
public SafeZone(Rectangle2D area, Point3D goloc, Map map, bool isGuarded) : base(null, map, SafeZonePriority, area)
|
||||
{
|
||||
GoLocation = goloc;
|
||||
|
||||
Disabled = !isGuarded;
|
||||
|
||||
Register();
|
||||
}
|
||||
|
||||
public override bool AllowHousing(Mobile from, Point3D p) => from.AccessLevel >= AccessLevel.GameMaster && base.AllowHousing(from, p);
|
||||
|
||||
public override bool OnMoveInto(Mobile m, Direction d, Point3D newLocation, Point3D oldLocation)
|
||||
{
|
||||
if (m.Player && Sigil.ExistsOn(m))
|
||||
{
|
||||
m.SendMessage(0x22, "You are holding a sigil and cannot enter this zone.");
|
||||
return false;
|
||||
}
|
||||
|
||||
PlayerMobile pm = m as PlayerMobile ??
|
||||
(m is BaseCreature bc && bc.Summoned ?
|
||||
bc.SummonMaster as PlayerMobile : null);
|
||||
|
||||
if (pm?.DuelContext?.StartedBeginCountdown == true)
|
||||
return true;
|
||||
|
||||
if (DuelContext.CheckCombat(m))
|
||||
{
|
||||
m.SendMessage(0x22, "You have recently been in combat and cannot enter this zone.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.OnMoveInto(m, d, newLocation, oldLocation);
|
||||
}
|
||||
|
||||
public override void OnEnter(Mobile m)
|
||||
{
|
||||
m.SendMessage("You have entered a dueling safezone. No combat other than duels are allowed in this zone.");
|
||||
}
|
||||
|
||||
public override void OnExit(Mobile m)
|
||||
{
|
||||
m.SendMessage("You have left a dueling safezone. Combat is now unrestricted.");
|
||||
}
|
||||
|
||||
public override bool CanUseStuckMenu(Mobile m) => false;
|
||||
}
|
||||
}
|
||||
using Server.Factions;
|
||||
using Server.Mobiles;
|
||||
using Server.Regions;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class SafeZone : GuardedRegion
|
||||
{
|
||||
public static readonly int SafeZonePriority = HouseRegion.HousePriority + 1;
|
||||
|
||||
/*public override bool AllowReds => true;*/
|
||||
|
||||
public SafeZone(Rectangle2D area, Point3D goloc, Map map, bool isGuarded) : base(null, map, SafeZonePriority, area)
|
||||
{
|
||||
GoLocation = goloc;
|
||||
|
||||
Disabled = !isGuarded;
|
||||
|
||||
Register();
|
||||
}
|
||||
|
||||
public override bool AllowHousing(Mobile from, Point3D p) =>
|
||||
from.AccessLevel >= AccessLevel.GameMaster && base.AllowHousing(from, p);
|
||||
|
||||
public override bool OnMoveInto(Mobile m, Direction d, Point3D newLocation, Point3D oldLocation)
|
||||
{
|
||||
if (m.Player && Sigil.ExistsOn(m))
|
||||
{
|
||||
m.SendMessage(0x22, "You are holding a sigil and cannot enter this zone.");
|
||||
return false;
|
||||
}
|
||||
|
||||
var pm = m as PlayerMobile ??
|
||||
(m is BaseCreature bc && bc.Summoned ? bc.SummonMaster as PlayerMobile : null);
|
||||
|
||||
if (pm?.DuelContext?.StartedBeginCountdown == true)
|
||||
return true;
|
||||
|
||||
if (DuelContext.CheckCombat(m))
|
||||
{
|
||||
m.SendMessage(0x22, "You have recently been in combat and cannot enter this zone.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.OnMoveInto(m, d, newLocation, oldLocation);
|
||||
}
|
||||
|
||||
public override void OnEnter(Mobile m)
|
||||
{
|
||||
m.SendMessage("You have entered a dueling safezone. No combat other than duels are allowed in this zone.");
|
||||
}
|
||||
|
||||
public override void OnExit(Mobile m)
|
||||
{
|
||||
m.SendMessage("You have left a dueling safezone. Combat is now unrestricted.");
|
||||
}
|
||||
|
||||
public override bool CanUseStuckMenu(Mobile m) => false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,62 +1,62 @@
|
|||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class TournamentBracketItem : Item
|
||||
{
|
||||
[Constructible]
|
||||
public TournamentBracketItem() : base(3774) => Movable = false;
|
||||
|
||||
public TournamentBracketItem(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TournamentController Tournament { get; set; }
|
||||
|
||||
public override string DefaultName => "tournament bracket";
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!from.InRange(GetWorldLocation(), 2))
|
||||
{
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that
|
||||
}
|
||||
else
|
||||
{
|
||||
Tournament tourney = Tournament?.Tournament;
|
||||
|
||||
if (tourney != null)
|
||||
{
|
||||
from.CloseGump<TournamentBracketGump>();
|
||||
from.SendGump(new TournamentBracketGump(from, tourney, TourneyBracketGumpType.Index));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(Tournament);
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
Tournament = reader.ReadItem() as TournamentController;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class TournamentBracketItem : Item
|
||||
{
|
||||
[Constructible]
|
||||
public TournamentBracketItem() : base(3774) => Movable = false;
|
||||
|
||||
public TournamentBracketItem(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TournamentController Tournament { get; set; }
|
||||
|
||||
public override string DefaultName => "tournament bracket";
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!from.InRange(GetWorldLocation(), 2))
|
||||
{
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that
|
||||
}
|
||||
else
|
||||
{
|
||||
var tourney = Tournament?.Tournament;
|
||||
|
||||
if (tourney != null)
|
||||
{
|
||||
from.CloseGump<TournamentBracketGump>();
|
||||
from.SendGump(new TournamentBracketGump(from, tourney, TourneyBracketGumpType.Index));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(Tournament);
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
Tournament = reader.ReadItem() as TournamentController;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,137 +1,139 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.ContextMenus;
|
||||
using Server.Gumps;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class TournamentController : Item
|
||||
{
|
||||
private static readonly List<TournamentController> m_Instances = new List<TournamentController>();
|
||||
|
||||
[Constructible]
|
||||
public TournamentController() : base(0x1B7A)
|
||||
{
|
||||
Visible = false;
|
||||
Movable = false;
|
||||
|
||||
Tournament = new Tournament();
|
||||
m_Instances.Add(this);
|
||||
}
|
||||
|
||||
public TournamentController(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Tournament Tournament { get; private set; }
|
||||
|
||||
public static bool IsActive
|
||||
{
|
||||
get
|
||||
{
|
||||
for (int i = 0; i < m_Instances.Count; ++i)
|
||||
{
|
||||
TournamentController controller = m_Instances[i];
|
||||
|
||||
if (controller?.Deleted == false && controller.Tournament != null &&
|
||||
controller.Tournament.Stage != TournamentStage.Inactive)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override string DefaultName => "tournament controller";
|
||||
|
||||
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
|
||||
{
|
||||
base.GetContextMenuEntries(from, list);
|
||||
|
||||
if (from.AccessLevel >= AccessLevel.GameMaster && Tournament != null)
|
||||
{
|
||||
list.Add(new EditEntry(Tournament));
|
||||
|
||||
if (Tournament.CurrentStage == TournamentStage.Inactive)
|
||||
list.Add(new StartEntry(Tournament));
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (from.AccessLevel >= AccessLevel.GameMaster && Tournament != null)
|
||||
{
|
||||
from.CloseGump<PickRulesetGump>();
|
||||
from.CloseGump<RulesetGump>();
|
||||
from.SendGump(new PickRulesetGump(from, null, Tournament.Ruleset));
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
|
||||
Tournament.Serialize(writer);
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
Tournament = new Tournament(reader);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_Instances.Add(this);
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
base.OnDelete();
|
||||
|
||||
m_Instances.Remove(this);
|
||||
}
|
||||
|
||||
private class EditEntry : ContextMenuEntry
|
||||
{
|
||||
private readonly Tournament m_Tournament;
|
||||
|
||||
public EditEntry(Tournament tourney) : base(5101) => m_Tournament = tourney;
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
Owner.From.SendGump(new PropertiesGump(Owner.From, m_Tournament));
|
||||
}
|
||||
}
|
||||
|
||||
private class StartEntry : ContextMenuEntry
|
||||
{
|
||||
private readonly Tournament m_Tournament;
|
||||
|
||||
public StartEntry(Tournament tourney) : base(5113) => m_Tournament = tourney;
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
if (m_Tournament.Stage == TournamentStage.Inactive)
|
||||
{
|
||||
m_Tournament.SignupStart = DateTime.UtcNow;
|
||||
m_Tournament.Stage = TournamentStage.Signup;
|
||||
m_Tournament.Participants.Clear();
|
||||
m_Tournament.Pyramid.Levels.Clear();
|
||||
m_Tournament.Alert("Hear ye! Hear ye!",
|
||||
"Tournament signup has opened. You can enter by signing up with the registrar.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.ContextMenus;
|
||||
using Server.Gumps;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class TournamentController : Item
|
||||
{
|
||||
private static readonly List<TournamentController> m_Instances = new List<TournamentController>();
|
||||
|
||||
[Constructible]
|
||||
public TournamentController() : base(0x1B7A)
|
||||
{
|
||||
Visible = false;
|
||||
Movable = false;
|
||||
|
||||
Tournament = new Tournament();
|
||||
m_Instances.Add(this);
|
||||
}
|
||||
|
||||
public TournamentController(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Tournament Tournament { get; private set; }
|
||||
|
||||
public static bool IsActive
|
||||
{
|
||||
get
|
||||
{
|
||||
for (var i = 0; i < m_Instances.Count; ++i)
|
||||
{
|
||||
var controller = m_Instances[i];
|
||||
|
||||
if (controller?.Deleted == false && controller.Tournament != null &&
|
||||
controller.Tournament.Stage != TournamentStage.Inactive)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override string DefaultName => "tournament controller";
|
||||
|
||||
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
|
||||
{
|
||||
base.GetContextMenuEntries(from, list);
|
||||
|
||||
if (from.AccessLevel >= AccessLevel.GameMaster && Tournament != null)
|
||||
{
|
||||
list.Add(new EditEntry(Tournament));
|
||||
|
||||
if (Tournament.CurrentStage == TournamentStage.Inactive)
|
||||
list.Add(new StartEntry(Tournament));
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (from.AccessLevel >= AccessLevel.GameMaster && Tournament != null)
|
||||
{
|
||||
from.CloseGump<PickRulesetGump>();
|
||||
from.CloseGump<RulesetGump>();
|
||||
from.SendGump(new PickRulesetGump(from, null, Tournament.Ruleset));
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
|
||||
Tournament.Serialize(writer);
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
Tournament = new Tournament(reader);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_Instances.Add(this);
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
base.OnDelete();
|
||||
|
||||
m_Instances.Remove(this);
|
||||
}
|
||||
|
||||
private class EditEntry : ContextMenuEntry
|
||||
{
|
||||
private readonly Tournament m_Tournament;
|
||||
|
||||
public EditEntry(Tournament tourney) : base(5101) => m_Tournament = tourney;
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
Owner.From.SendGump(new PropertiesGump(Owner.From, m_Tournament));
|
||||
}
|
||||
}
|
||||
|
||||
private class StartEntry : ContextMenuEntry
|
||||
{
|
||||
private readonly Tournament m_Tournament;
|
||||
|
||||
public StartEntry(Tournament tourney) : base(5113) => m_Tournament = tourney;
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
if (m_Tournament.Stage == TournamentStage.Inactive)
|
||||
{
|
||||
m_Tournament.SignupStart = DateTime.UtcNow;
|
||||
m_Tournament.Stage = TournamentStage.Signup;
|
||||
m_Tournament.Participants.Clear();
|
||||
m_Tournament.Pyramid.Levels.Clear();
|
||||
m_Tournament.Alert(
|
||||
"Hear ye! Hear ye!",
|
||||
"Tournament signup has opened. You can enter by signing up with the registrar."
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,180 +1,183 @@
|
|||
using System.Collections.Generic;
|
||||
using Server.Ethics;
|
||||
using Server.Factions;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class TourneyPyramid
|
||||
{
|
||||
public TourneyPyramid() => Levels = new List<PyramidLevel>();
|
||||
|
||||
public List<PyramidLevel> Levels { get; set; }
|
||||
|
||||
public void AddLevel(int partsPerMatch, List<TourneyParticipant> participants, GroupingType groupType, TourneyType tourneyType)
|
||||
{
|
||||
List<TourneyParticipant> copy = new List<TourneyParticipant>(participants);
|
||||
|
||||
if (groupType == GroupingType.Nearest || groupType == GroupingType.HighVsLow)
|
||||
copy.Sort();
|
||||
|
||||
PyramidLevel level = new PyramidLevel();
|
||||
|
||||
switch (tourneyType)
|
||||
{
|
||||
case TourneyType.RedVsBlue:
|
||||
{
|
||||
TourneyParticipant[] parts = new TourneyParticipant[2];
|
||||
|
||||
for (int i = 0; i < parts.Length; ++i)
|
||||
parts[i] = new TourneyParticipant(new List<Mobile>());
|
||||
|
||||
for (int i = 0; i < copy.Count; ++i)
|
||||
{
|
||||
List<Mobile> players = copy[i].Players;
|
||||
|
||||
for (int j = 0; j < players.Count; ++j)
|
||||
{
|
||||
Mobile mob = players[j];
|
||||
|
||||
if (mob.Kills >= 5)
|
||||
parts[0].Players.Add(mob);
|
||||
else
|
||||
parts[1].Players.Add(mob);
|
||||
}
|
||||
}
|
||||
|
||||
level.Matches.Add(new TourneyMatch(new List<TourneyParticipant>(parts)));
|
||||
break;
|
||||
}
|
||||
case TourneyType.Faction:
|
||||
{
|
||||
TourneyParticipant[] parts = new TourneyParticipant[partsPerMatch];
|
||||
|
||||
for (int i = 0; i < parts.Length; ++i)
|
||||
parts[i] = new TourneyParticipant(new List<Mobile>());
|
||||
|
||||
for (int i = 0; i < copy.Count; ++i)
|
||||
{
|
||||
List<Mobile> players = copy[i].Players;
|
||||
|
||||
for (int j = 0; j < players.Count; ++j)
|
||||
{
|
||||
Mobile mob = players[j];
|
||||
|
||||
int index = -1;
|
||||
|
||||
if (partsPerMatch == 4)
|
||||
{
|
||||
Faction fac = Faction.Find(mob);
|
||||
|
||||
if (fac != null)
|
||||
index = fac.Definition.Sort;
|
||||
}
|
||||
else if (partsPerMatch == 2)
|
||||
{
|
||||
if (Ethic.Evil.IsEligible(mob))
|
||||
index = 0;
|
||||
else if (Ethic.Hero.IsEligible(mob)) index = 1;
|
||||
}
|
||||
|
||||
if (index < 0 || index >= partsPerMatch) index = i % partsPerMatch;
|
||||
|
||||
parts[index].Players.Add(mob);
|
||||
}
|
||||
}
|
||||
|
||||
level.Matches.Add(new TourneyMatch(new List<TourneyParticipant>(parts)));
|
||||
break;
|
||||
}
|
||||
case TourneyType.RandomTeam:
|
||||
{
|
||||
TourneyParticipant[] parts = new TourneyParticipant[partsPerMatch];
|
||||
|
||||
for (int i = 0; i < partsPerMatch; ++i)
|
||||
parts[i] = new TourneyParticipant(new List<Mobile>());
|
||||
|
||||
for (int i = 0; i < copy.Count; ++i)
|
||||
parts[i % parts.Length].Players.AddRange(copy[i].Players);
|
||||
|
||||
level.Matches.Add(new TourneyMatch(new List<TourneyParticipant>(parts)));
|
||||
break;
|
||||
}
|
||||
case TourneyType.FreeForAll:
|
||||
{
|
||||
level.Matches.Add(new TourneyMatch(copy));
|
||||
break;
|
||||
}
|
||||
case TourneyType.Standard:
|
||||
{
|
||||
if (partsPerMatch >= 2 && participants.Count % partsPerMatch == 1)
|
||||
{
|
||||
int lowAdvances = int.MaxValue;
|
||||
|
||||
for (int i = 0; i < participants.Count; ++i)
|
||||
{
|
||||
TourneyParticipant p = participants[i];
|
||||
|
||||
if (p.FreeAdvances < lowAdvances)
|
||||
lowAdvances = p.FreeAdvances;
|
||||
}
|
||||
|
||||
List<TourneyParticipant> toAdvance = new List<TourneyParticipant>();
|
||||
|
||||
for (int i = 0; i < participants.Count; ++i)
|
||||
{
|
||||
TourneyParticipant p = participants[i];
|
||||
|
||||
if (p.FreeAdvances == lowAdvances)
|
||||
toAdvance.Add(p);
|
||||
}
|
||||
|
||||
if (toAdvance.Count == 0)
|
||||
toAdvance = copy; // sanity
|
||||
|
||||
var random = toAdvance.RandomElement();
|
||||
|
||||
random.AddLog(
|
||||
"Advanced automatically due to an odd number of challengers.");
|
||||
level.FreeAdvance = random;
|
||||
++level.FreeAdvance.FreeAdvances;
|
||||
copy.Remove(random);
|
||||
}
|
||||
|
||||
while (copy.Count >= partsPerMatch)
|
||||
{
|
||||
List<TourneyParticipant> thisMatch = new List<TourneyParticipant>();
|
||||
|
||||
for (int i = 0; i < partsPerMatch; ++i)
|
||||
{
|
||||
var idx = groupType switch
|
||||
{
|
||||
GroupingType.HighVsLow => i * (copy.Count - 1) / (partsPerMatch - 1),
|
||||
GroupingType.Nearest => 0,
|
||||
GroupingType.Random => Utility.Random(copy.Count),
|
||||
_ => 0
|
||||
};
|
||||
|
||||
thisMatch.Add(copy[idx]);
|
||||
copy.RemoveAt(idx);
|
||||
}
|
||||
|
||||
level.Matches.Add(new TourneyMatch(thisMatch));
|
||||
}
|
||||
|
||||
if (copy.Count > 1)
|
||||
level.Matches.Add(new TourneyMatch(copy));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Levels.Add(level);
|
||||
}
|
||||
}
|
||||
|
||||
public class PyramidLevel
|
||||
{
|
||||
public List<TourneyMatch> Matches { get; set; } = new List<TourneyMatch>();
|
||||
public TourneyParticipant FreeAdvance { get; set; }
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using Server.Ethics;
|
||||
using Server.Factions;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class TourneyPyramid
|
||||
{
|
||||
public TourneyPyramid() => Levels = new List<PyramidLevel>();
|
||||
|
||||
public List<PyramidLevel> Levels { get; set; }
|
||||
|
||||
public void AddLevel(
|
||||
int partsPerMatch, List<TourneyParticipant> participants, GroupingType groupType, TourneyType tourneyType
|
||||
)
|
||||
{
|
||||
var copy = new List<TourneyParticipant>(participants);
|
||||
|
||||
if (groupType == GroupingType.Nearest || groupType == GroupingType.HighVsLow)
|
||||
copy.Sort();
|
||||
|
||||
var level = new PyramidLevel();
|
||||
|
||||
switch (tourneyType)
|
||||
{
|
||||
case TourneyType.RedVsBlue:
|
||||
{
|
||||
var parts = new TourneyParticipant[2];
|
||||
|
||||
for (var i = 0; i < parts.Length; ++i)
|
||||
parts[i] = new TourneyParticipant(new List<Mobile>());
|
||||
|
||||
for (var i = 0; i < copy.Count; ++i)
|
||||
{
|
||||
var players = copy[i].Players;
|
||||
|
||||
for (var j = 0; j < players.Count; ++j)
|
||||
{
|
||||
var mob = players[j];
|
||||
|
||||
if (mob.Kills >= 5)
|
||||
parts[0].Players.Add(mob);
|
||||
else
|
||||
parts[1].Players.Add(mob);
|
||||
}
|
||||
}
|
||||
|
||||
level.Matches.Add(new TourneyMatch(new List<TourneyParticipant>(parts)));
|
||||
break;
|
||||
}
|
||||
case TourneyType.Faction:
|
||||
{
|
||||
var parts = new TourneyParticipant[partsPerMatch];
|
||||
|
||||
for (var i = 0; i < parts.Length; ++i)
|
||||
parts[i] = new TourneyParticipant(new List<Mobile>());
|
||||
|
||||
for (var i = 0; i < copy.Count; ++i)
|
||||
{
|
||||
var players = copy[i].Players;
|
||||
|
||||
for (var j = 0; j < players.Count; ++j)
|
||||
{
|
||||
var mob = players[j];
|
||||
|
||||
var index = -1;
|
||||
|
||||
if (partsPerMatch == 4)
|
||||
{
|
||||
var fac = Faction.Find(mob);
|
||||
|
||||
if (fac != null)
|
||||
index = fac.Definition.Sort;
|
||||
}
|
||||
else if (partsPerMatch == 2)
|
||||
{
|
||||
if (Ethic.Evil.IsEligible(mob))
|
||||
index = 0;
|
||||
else if (Ethic.Hero.IsEligible(mob)) index = 1;
|
||||
}
|
||||
|
||||
if (index < 0 || index >= partsPerMatch) index = i % partsPerMatch;
|
||||
|
||||
parts[index].Players.Add(mob);
|
||||
}
|
||||
}
|
||||
|
||||
level.Matches.Add(new TourneyMatch(new List<TourneyParticipant>(parts)));
|
||||
break;
|
||||
}
|
||||
case TourneyType.RandomTeam:
|
||||
{
|
||||
var parts = new TourneyParticipant[partsPerMatch];
|
||||
|
||||
for (var i = 0; i < partsPerMatch; ++i)
|
||||
parts[i] = new TourneyParticipant(new List<Mobile>());
|
||||
|
||||
for (var i = 0; i < copy.Count; ++i)
|
||||
parts[i % parts.Length].Players.AddRange(copy[i].Players);
|
||||
|
||||
level.Matches.Add(new TourneyMatch(new List<TourneyParticipant>(parts)));
|
||||
break;
|
||||
}
|
||||
case TourneyType.FreeForAll:
|
||||
{
|
||||
level.Matches.Add(new TourneyMatch(copy));
|
||||
break;
|
||||
}
|
||||
case TourneyType.Standard:
|
||||
{
|
||||
if (partsPerMatch >= 2 && participants.Count % partsPerMatch == 1)
|
||||
{
|
||||
var lowAdvances = int.MaxValue;
|
||||
|
||||
for (var i = 0; i < participants.Count; ++i)
|
||||
{
|
||||
var p = participants[i];
|
||||
|
||||
if (p.FreeAdvances < lowAdvances)
|
||||
lowAdvances = p.FreeAdvances;
|
||||
}
|
||||
|
||||
var toAdvance = new List<TourneyParticipant>();
|
||||
|
||||
for (var i = 0; i < participants.Count; ++i)
|
||||
{
|
||||
var p = participants[i];
|
||||
|
||||
if (p.FreeAdvances == lowAdvances)
|
||||
toAdvance.Add(p);
|
||||
}
|
||||
|
||||
if (toAdvance.Count == 0)
|
||||
toAdvance = copy; // sanity
|
||||
|
||||
var random = toAdvance.RandomElement();
|
||||
|
||||
random.AddLog(
|
||||
"Advanced automatically due to an odd number of challengers."
|
||||
);
|
||||
level.FreeAdvance = random;
|
||||
++level.FreeAdvance.FreeAdvances;
|
||||
copy.Remove(random);
|
||||
}
|
||||
|
||||
while (copy.Count >= partsPerMatch)
|
||||
{
|
||||
var thisMatch = new List<TourneyParticipant>();
|
||||
|
||||
for (var i = 0; i < partsPerMatch; ++i)
|
||||
{
|
||||
var idx = groupType switch
|
||||
{
|
||||
GroupingType.HighVsLow => i * (copy.Count - 1) / (partsPerMatch - 1),
|
||||
GroupingType.Nearest => 0,
|
||||
GroupingType.Random => Utility.Random(copy.Count),
|
||||
_ => 0
|
||||
};
|
||||
|
||||
thisMatch.Add(copy[idx]);
|
||||
copy.RemoveAt(idx);
|
||||
}
|
||||
|
||||
level.Matches.Add(new TourneyMatch(thisMatch));
|
||||
}
|
||||
|
||||
if (copy.Count > 1)
|
||||
level.Matches.Add(new TourneyMatch(copy));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Levels.Add(level);
|
||||
}
|
||||
}
|
||||
|
||||
public class PyramidLevel
|
||||
{
|
||||
public List<TourneyMatch> Matches { get; set; } = new List<TourneyMatch>();
|
||||
public TourneyParticipant FreeAdvance { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,93 +1,101 @@
|
|||
using System;
|
||||
using Server.Factions;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class TournamentRegistrar : Banker
|
||||
{
|
||||
[Constructible]
|
||||
public TournamentRegistrar()
|
||||
{
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(30.0), TimeSpan.FromSeconds(30.0), Announce_Callback);
|
||||
}
|
||||
|
||||
public TournamentRegistrar(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TournamentController Tournament { get; set; }
|
||||
|
||||
private void Announce_Callback()
|
||||
{
|
||||
Tournament tourney = Tournament?.Tournament;
|
||||
|
||||
if (tourney?.Stage == TournamentStage.Signup)
|
||||
PublicOverheadMessage(MessageType.Regular, 0x35, false,
|
||||
"Come one, come all! Do you aspire to be a fighter of great renown? Join this tournament and show the world your abilities.");
|
||||
}
|
||||
|
||||
public override void OnMovement(Mobile m, Point3D oldLocation)
|
||||
{
|
||||
base.OnMovement(m, oldLocation);
|
||||
|
||||
Tournament tourney = Tournament?.Tournament;
|
||||
|
||||
if (InRange(m, 4) && !InRange(oldLocation, 4) && tourney != null && tourney.Stage == TournamentStage.Signup &&
|
||||
m.CanBeginAction(this))
|
||||
{
|
||||
Ladder ladder = Ladder.Instance;
|
||||
|
||||
LadderEntry entry = ladder?.Find(m);
|
||||
|
||||
if (entry != null && Ladder.GetLevel(entry.Experience) < tourney.LevelRequirement)
|
||||
return;
|
||||
|
||||
if (tourney.IsFactionRestricted && Faction.Find(m) == null) return;
|
||||
|
||||
if (tourney.HasParticipant(m))
|
||||
return;
|
||||
|
||||
PrivateOverheadMessage(MessageType.Regular, 0x35, false,
|
||||
$"Hello m'{(m.Female ? "Lady" : "Lord")}. Dost thou wish to enter this tournament? You need only to write your name in this book.",
|
||||
m.NetState);
|
||||
m.BeginAction(this);
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(10.0), ReleaseLock_Callback, m);
|
||||
}
|
||||
}
|
||||
|
||||
public void ReleaseLock_Callback(Mobile m)
|
||||
{
|
||||
m.EndAction(this);
|
||||
}
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(Tournament);
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
Tournament = reader.ReadItem() as TournamentController;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(30.0), TimeSpan.FromSeconds(30.0), Announce_Callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Server.Factions;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class TournamentRegistrar : Banker
|
||||
{
|
||||
[Constructible]
|
||||
public TournamentRegistrar()
|
||||
{
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(30.0), TimeSpan.FromSeconds(30.0), Announce_Callback);
|
||||
}
|
||||
|
||||
public TournamentRegistrar(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TournamentController Tournament { get; set; }
|
||||
|
||||
private void Announce_Callback()
|
||||
{
|
||||
var tourney = Tournament?.Tournament;
|
||||
|
||||
if (tourney?.Stage == TournamentStage.Signup)
|
||||
PublicOverheadMessage(
|
||||
MessageType.Regular,
|
||||
0x35,
|
||||
false,
|
||||
"Come one, come all! Do you aspire to be a fighter of great renown? Join this tournament and show the world your abilities."
|
||||
);
|
||||
}
|
||||
|
||||
public override void OnMovement(Mobile m, Point3D oldLocation)
|
||||
{
|
||||
base.OnMovement(m, oldLocation);
|
||||
|
||||
var tourney = Tournament?.Tournament;
|
||||
|
||||
if (InRange(m, 4) && !InRange(oldLocation, 4) && tourney != null && tourney.Stage == TournamentStage.Signup &&
|
||||
m.CanBeginAction(this))
|
||||
{
|
||||
var ladder = Ladder.Instance;
|
||||
|
||||
var entry = ladder?.Find(m);
|
||||
|
||||
if (entry != null && Ladder.GetLevel(entry.Experience) < tourney.LevelRequirement)
|
||||
return;
|
||||
|
||||
if (tourney.IsFactionRestricted && Faction.Find(m) == null) return;
|
||||
|
||||
if (tourney.HasParticipant(m))
|
||||
return;
|
||||
|
||||
PrivateOverheadMessage(
|
||||
MessageType.Regular,
|
||||
0x35,
|
||||
false,
|
||||
$"Hello m'{(m.Female ? "Lady" : "Lord")}. Dost thou wish to enter this tournament? You need only to write your name in this book.",
|
||||
m.NetState
|
||||
);
|
||||
m.BeginAction(this);
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(10.0), ReleaseLock_Callback, m);
|
||||
}
|
||||
}
|
||||
|
||||
public void ReleaseLock_Callback(Mobile m)
|
||||
{
|
||||
m.EndAction(this);
|
||||
}
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(Tournament);
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
Tournament = reader.ReadItem() as TournamentController;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(30.0), TimeSpan.FromSeconds(30.0), Announce_Callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,146 +1,189 @@
|
|||
using System.Collections.Generic;
|
||||
using Server.Factions;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class TournamentSignupItem : Item
|
||||
{
|
||||
[Constructible]
|
||||
public TournamentSignupItem() : base(4029) => Movable = false;
|
||||
|
||||
public TournamentSignupItem(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TournamentController Tournament { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Mobile Registrar { get; set; }
|
||||
|
||||
public override string DefaultName => "tournament signup book";
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!from.InRange(GetWorldLocation(), 2))
|
||||
{
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that
|
||||
}
|
||||
else
|
||||
{
|
||||
Tournament tourney = Tournament?.Tournament;
|
||||
|
||||
if (tourney == null)
|
||||
return;
|
||||
|
||||
if (Registrar != null)
|
||||
Registrar.Direction = Registrar.GetDirectionTo(this);
|
||||
|
||||
switch (tourney.Stage)
|
||||
{
|
||||
case TournamentStage.Fighting:
|
||||
{
|
||||
if (Registrar != null)
|
||||
{
|
||||
if (tourney.HasParticipant(from))
|
||||
Registrar.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x35, false, "Excuse me? You are already signed up.", from.NetState);
|
||||
else
|
||||
Registrar.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x22, false, "The tournament has already begun. You are too late to signup now.",
|
||||
from.NetState);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case TournamentStage.Inactive:
|
||||
{
|
||||
Registrar?.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x35, false, "The tournament is closed.", from.NetState);
|
||||
|
||||
break;
|
||||
}
|
||||
case TournamentStage.Signup:
|
||||
{
|
||||
Ladder ladder = Ladder.Instance;
|
||||
LadderEntry entry = ladder?.Find(from);
|
||||
|
||||
if (entry != null && Ladder.GetLevel(entry.Experience) < tourney.LevelRequirement)
|
||||
{
|
||||
Registrar?.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x35, false, "You have not yet proven yourself a worthy dueler.", from.NetState);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (tourney.IsFactionRestricted && Faction.Find(from) == null)
|
||||
{
|
||||
Registrar?.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x35, false, "Only those who have declared their faction allegiance may participate.",
|
||||
from.NetState);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (from.HasGump<AcceptTeamGump>())
|
||||
{
|
||||
Registrar?.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x22, false, "You must first respond to the offer I've given you.", from.NetState);
|
||||
}
|
||||
else if (from.HasGump<AcceptDuelGump>())
|
||||
{
|
||||
Registrar?.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x22, false, "You must first cancel your duel offer.", from.NetState);
|
||||
}
|
||||
else if (from is PlayerMobile mobile && mobile.DuelContext != null)
|
||||
{
|
||||
Registrar?.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x22, false, "You are already participating in a duel.", mobile.NetState);
|
||||
}
|
||||
else if (!tourney.HasParticipant(from))
|
||||
{
|
||||
from.CloseGump<ConfirmSignupGump>();
|
||||
from.SendGump(new ConfirmSignupGump(from, Registrar, tourney, new List<Mobile> { from }));
|
||||
}
|
||||
else
|
||||
{
|
||||
Registrar?.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x35, false, "You have already entered this tournament.", from.NetState);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(Tournament);
|
||||
writer.Write(Registrar);
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
Tournament = reader.ReadItem() as TournamentController;
|
||||
Registrar = reader.ReadMobile();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using Server.Factions;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class TournamentSignupItem : Item
|
||||
{
|
||||
[Constructible]
|
||||
public TournamentSignupItem() : base(4029) => Movable = false;
|
||||
|
||||
public TournamentSignupItem(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TournamentController Tournament { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Mobile Registrar { get; set; }
|
||||
|
||||
public override string DefaultName => "tournament signup book";
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!from.InRange(GetWorldLocation(), 2))
|
||||
{
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that
|
||||
}
|
||||
else
|
||||
{
|
||||
var tourney = Tournament?.Tournament;
|
||||
|
||||
if (tourney == null)
|
||||
return;
|
||||
|
||||
if (Registrar != null)
|
||||
Registrar.Direction = Registrar.GetDirectionTo(this);
|
||||
|
||||
switch (tourney.Stage)
|
||||
{
|
||||
case TournamentStage.Fighting:
|
||||
{
|
||||
if (Registrar != null)
|
||||
{
|
||||
if (tourney.HasParticipant(from))
|
||||
Registrar.PrivateOverheadMessage(
|
||||
MessageType.Regular,
|
||||
0x35,
|
||||
false,
|
||||
"Excuse me? You are already signed up.",
|
||||
from.NetState
|
||||
);
|
||||
else
|
||||
Registrar.PrivateOverheadMessage(
|
||||
MessageType.Regular,
|
||||
0x22,
|
||||
false,
|
||||
"The tournament has already begun. You are too late to signup now.",
|
||||
from.NetState
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case TournamentStage.Inactive:
|
||||
{
|
||||
Registrar?.PrivateOverheadMessage(
|
||||
MessageType.Regular,
|
||||
0x35,
|
||||
false,
|
||||
"The tournament is closed.",
|
||||
from.NetState
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
case TournamentStage.Signup:
|
||||
{
|
||||
var ladder = Ladder.Instance;
|
||||
var entry = ladder?.Find(from);
|
||||
|
||||
if (entry != null && Ladder.GetLevel(entry.Experience) < tourney.LevelRequirement)
|
||||
{
|
||||
Registrar?.PrivateOverheadMessage(
|
||||
MessageType.Regular,
|
||||
0x35,
|
||||
false,
|
||||
"You have not yet proven yourself a worthy dueler.",
|
||||
from.NetState
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (tourney.IsFactionRestricted && Faction.Find(from) == null)
|
||||
{
|
||||
Registrar?.PrivateOverheadMessage(
|
||||
MessageType.Regular,
|
||||
0x35,
|
||||
false,
|
||||
"Only those who have declared their faction allegiance may participate.",
|
||||
from.NetState
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (from.HasGump<AcceptTeamGump>())
|
||||
{
|
||||
Registrar?.PrivateOverheadMessage(
|
||||
MessageType.Regular,
|
||||
0x22,
|
||||
false,
|
||||
"You must first respond to the offer I've given you.",
|
||||
from.NetState
|
||||
);
|
||||
}
|
||||
else if (from.HasGump<AcceptDuelGump>())
|
||||
{
|
||||
Registrar?.PrivateOverheadMessage(
|
||||
MessageType.Regular,
|
||||
0x22,
|
||||
false,
|
||||
"You must first cancel your duel offer.",
|
||||
from.NetState
|
||||
);
|
||||
}
|
||||
else if (from is PlayerMobile mobile && mobile.DuelContext != null)
|
||||
{
|
||||
Registrar?.PrivateOverheadMessage(
|
||||
MessageType.Regular,
|
||||
0x22,
|
||||
false,
|
||||
"You are already participating in a duel.",
|
||||
mobile.NetState
|
||||
);
|
||||
}
|
||||
else if (!tourney.HasParticipant(from))
|
||||
{
|
||||
from.CloseGump<ConfirmSignupGump>();
|
||||
from.SendGump(new ConfirmSignupGump(from, Registrar, tourney, new List<Mobile> { from }));
|
||||
}
|
||||
else
|
||||
{
|
||||
Registrar?.PrivateOverheadMessage(
|
||||
MessageType.Regular,
|
||||
0x35,
|
||||
false,
|
||||
"You have already entered this tournament.",
|
||||
from.NetState
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(Tournament);
|
||||
writer.Write(Registrar);
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
Tournament = reader.ReadItem() as TournamentController;
|
||||
Registrar = reader.ReadMobile();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,103 +1,103 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class TourneyParticipant : IComparable<TourneyParticipant>
|
||||
{
|
||||
public TourneyParticipant(Mobile owner)
|
||||
{
|
||||
Log = new List<string>();
|
||||
Players = new List<Mobile> { owner };
|
||||
}
|
||||
|
||||
public TourneyParticipant(List<Mobile> players)
|
||||
{
|
||||
Log = new List<string>();
|
||||
Players = players;
|
||||
}
|
||||
|
||||
public List<Mobile> Players { get; set; }
|
||||
|
||||
public List<string> Log { get; set; }
|
||||
|
||||
public int FreeAdvances { get; set; }
|
||||
|
||||
public int TotalLadderXP
|
||||
{
|
||||
get
|
||||
{
|
||||
Ladder ladder = Ladder.Instance;
|
||||
|
||||
if (ladder == null)
|
||||
return 0;
|
||||
|
||||
int total = 0;
|
||||
|
||||
for (int i = 0; i < Players.Count; ++i)
|
||||
{
|
||||
Mobile mob = Players[i];
|
||||
LadderEntry entry = ladder.Find(mob);
|
||||
|
||||
if (entry != null)
|
||||
total += entry.Experience;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
}
|
||||
|
||||
public string NameList
|
||||
{
|
||||
get
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < Players.Count; ++i)
|
||||
{
|
||||
if (Players[i] == null)
|
||||
continue;
|
||||
|
||||
Mobile mob = Players[i];
|
||||
|
||||
if (sb.Length > 0)
|
||||
{
|
||||
if (Players.Count == 2)
|
||||
sb.Append(" and ");
|
||||
else if (i + 1 < Players.Count)
|
||||
sb.Append(", ");
|
||||
else
|
||||
sb.Append(", and ");
|
||||
}
|
||||
|
||||
sb.Append(mob.Name);
|
||||
}
|
||||
|
||||
return sb.Length == 0 ? "Empty" : sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public int CompareTo(TourneyParticipant p) => p.TotalLadderXP - TotalLadderXP;
|
||||
|
||||
public void AddLog(string text)
|
||||
{
|
||||
Log.Add(text);
|
||||
}
|
||||
|
||||
public void AddLog(string format, params object[] args)
|
||||
{
|
||||
AddLog(string.Format(format, args));
|
||||
}
|
||||
|
||||
public void WonMatch(TourneyMatch match)
|
||||
{
|
||||
AddLog("Match won.");
|
||||
}
|
||||
|
||||
public void LostMatch(TourneyMatch match)
|
||||
{
|
||||
AddLog("Match lost.");
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class TourneyParticipant : IComparable<TourneyParticipant>
|
||||
{
|
||||
public TourneyParticipant(Mobile owner)
|
||||
{
|
||||
Log = new List<string>();
|
||||
Players = new List<Mobile> { owner };
|
||||
}
|
||||
|
||||
public TourneyParticipant(List<Mobile> players)
|
||||
{
|
||||
Log = new List<string>();
|
||||
Players = players;
|
||||
}
|
||||
|
||||
public List<Mobile> Players { get; set; }
|
||||
|
||||
public List<string> Log { get; set; }
|
||||
|
||||
public int FreeAdvances { get; set; }
|
||||
|
||||
public int TotalLadderXP
|
||||
{
|
||||
get
|
||||
{
|
||||
var ladder = Ladder.Instance;
|
||||
|
||||
if (ladder == null)
|
||||
return 0;
|
||||
|
||||
var total = 0;
|
||||
|
||||
for (var i = 0; i < Players.Count; ++i)
|
||||
{
|
||||
var mob = Players[i];
|
||||
var entry = ladder.Find(mob);
|
||||
|
||||
if (entry != null)
|
||||
total += entry.Experience;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
}
|
||||
|
||||
public string NameList
|
||||
{
|
||||
get
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
|
||||
for (var i = 0; i < Players.Count; ++i)
|
||||
{
|
||||
if (Players[i] == null)
|
||||
continue;
|
||||
|
||||
var mob = Players[i];
|
||||
|
||||
if (sb.Length > 0)
|
||||
{
|
||||
if (Players.Count == 2)
|
||||
sb.Append(" and ");
|
||||
else if (i + 1 < Players.Count)
|
||||
sb.Append(", ");
|
||||
else
|
||||
sb.Append(", and ");
|
||||
}
|
||||
|
||||
sb.Append(mob.Name);
|
||||
}
|
||||
|
||||
return sb.Length == 0 ? "Empty" : sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public int CompareTo(TourneyParticipant p) => p.TotalLadderXP - TotalLadderXP;
|
||||
|
||||
public void AddLog(string text)
|
||||
{
|
||||
Log.Add(text);
|
||||
}
|
||||
|
||||
public void AddLog(string format, params object[] args)
|
||||
{
|
||||
AddLog(string.Format(format, args));
|
||||
}
|
||||
|
||||
public void WonMatch(TourneyMatch match)
|
||||
{
|
||||
AddLog("Match won.");
|
||||
}
|
||||
|
||||
public void LostMatch(TourneyMatch match)
|
||||
{
|
||||
AddLog("Match lost.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,113 +1,113 @@
|
|||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public enum TrophyRank
|
||||
{
|
||||
Bronze,
|
||||
Silver,
|
||||
Gold
|
||||
}
|
||||
|
||||
[Flippable(5020, 4647)]
|
||||
public class Trophy : Item
|
||||
{
|
||||
private TrophyRank m_Rank;
|
||||
|
||||
[Constructible]
|
||||
public Trophy(string title, TrophyRank rank) : base(5020)
|
||||
{
|
||||
Title = title;
|
||||
m_Rank = rank;
|
||||
Date = DateTime.UtcNow;
|
||||
|
||||
LootType = LootType.Blessed;
|
||||
|
||||
UpdateStyle();
|
||||
}
|
||||
|
||||
public Trophy(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string Title { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TrophyRank Rank
|
||||
{
|
||||
get => m_Rank;
|
||||
set
|
||||
{
|
||||
m_Rank = value;
|
||||
UpdateStyle();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Mobile Owner { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DateTime Date { get; private set; }
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1); // version
|
||||
|
||||
writer.Write(Title);
|
||||
writer.Write((int)m_Rank);
|
||||
writer.Write(Owner);
|
||||
writer.Write(Date);
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Title = reader.ReadString();
|
||||
m_Rank = (TrophyRank)reader.ReadInt();
|
||||
Owner = reader.ReadMobile();
|
||||
Date = reader.ReadDateTime();
|
||||
|
||||
if (version == 0)
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public override void OnAdded(IEntity parent)
|
||||
{
|
||||
base.OnAdded(parent);
|
||||
|
||||
Owner ??= RootParent as Mobile;
|
||||
}
|
||||
|
||||
public override void OnSingleClick(Mobile from)
|
||||
{
|
||||
base.OnSingleClick(from);
|
||||
|
||||
if (Owner != null)
|
||||
LabelTo(from, "{0} -- {1}", Title, Owner.RawName);
|
||||
else if (Title != null)
|
||||
LabelTo(from, Title);
|
||||
|
||||
if (Date != DateTime.MinValue)
|
||||
LabelTo(from, Date.ToString("d"));
|
||||
}
|
||||
|
||||
public void UpdateStyle()
|
||||
{
|
||||
Name = $"{m_Rank.ToString().ToLower()} trophy";
|
||||
|
||||
Hue = m_Rank switch
|
||||
{
|
||||
TrophyRank.Gold => 2213,
|
||||
TrophyRank.Silver => 0,
|
||||
TrophyRank.Bronze => 2206,
|
||||
_ => Hue
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public enum TrophyRank
|
||||
{
|
||||
Bronze,
|
||||
Silver,
|
||||
Gold
|
||||
}
|
||||
|
||||
[Flippable(5020, 4647)]
|
||||
public class Trophy : Item
|
||||
{
|
||||
private TrophyRank m_Rank;
|
||||
|
||||
[Constructible]
|
||||
public Trophy(string title, TrophyRank rank) : base(5020)
|
||||
{
|
||||
Title = title;
|
||||
m_Rank = rank;
|
||||
Date = DateTime.UtcNow;
|
||||
|
||||
LootType = LootType.Blessed;
|
||||
|
||||
UpdateStyle();
|
||||
}
|
||||
|
||||
public Trophy(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string Title { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TrophyRank Rank
|
||||
{
|
||||
get => m_Rank;
|
||||
set
|
||||
{
|
||||
m_Rank = value;
|
||||
UpdateStyle();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Mobile Owner { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DateTime Date { get; private set; }
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1); // version
|
||||
|
||||
writer.Write(Title);
|
||||
writer.Write((int)m_Rank);
|
||||
writer.Write(Owner);
|
||||
writer.Write(Date);
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.ReadInt();
|
||||
|
||||
Title = reader.ReadString();
|
||||
m_Rank = (TrophyRank)reader.ReadInt();
|
||||
Owner = reader.ReadMobile();
|
||||
Date = reader.ReadDateTime();
|
||||
|
||||
if (version == 0)
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public override void OnAdded(IEntity parent)
|
||||
{
|
||||
base.OnAdded(parent);
|
||||
|
||||
Owner ??= RootParent as Mobile;
|
||||
}
|
||||
|
||||
public override void OnSingleClick(Mobile from)
|
||||
{
|
||||
base.OnSingleClick(from);
|
||||
|
||||
if (Owner != null)
|
||||
LabelTo(from, "{0} -- {1}", Title, Owner.RawName);
|
||||
else if (Title != null)
|
||||
LabelTo(from, Title);
|
||||
|
||||
if (Date != DateTime.MinValue)
|
||||
LabelTo(from, Date.ToString("d"));
|
||||
}
|
||||
|
||||
public void UpdateStyle()
|
||||
{
|
||||
Name = $"{m_Rank.ToString().ToLower()} trophy";
|
||||
|
||||
Hue = m_Rank switch
|
||||
{
|
||||
TrophyRank.Gold => 2213,
|
||||
TrophyRank.Silver => 0,
|
||||
TrophyRank.Bronze => 2206,
|
||||
_ => Hue
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue