Modernization Fixes & Updates to Default Values (#3)
This commit is contained in:
parent
445eddff68
commit
dcf64091b1
768 changed files with 10507 additions and 14196 deletions
|
|
@ -752,13 +752,14 @@ namespace Server.Accounting
|
|||
try
|
||||
{
|
||||
int index = Utility.GetXMLInt32( Utility.GetAttribute( ele, "index", "0" ), 0 );
|
||||
int serial = Utility.GetXMLInt32( Utility.GetText( ele, "0" ), 0 );
|
||||
uint serial = Utility.GetXMLUInt32( Utility.GetText( ele, "0" ), 0 );
|
||||
|
||||
if ( index >= 0 && index < list.Length )
|
||||
list[index] = World.FindMobile( serial );
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -783,7 +784,10 @@ namespace Server.Accounting
|
|||
foreach ( XmlElement comment in comments.GetElementsByTagName( "comment" ) )
|
||||
{
|
||||
try { list.Add( new AccountComment( comment ) ); }
|
||||
catch { }
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -807,7 +811,10 @@ namespace Server.Accounting
|
|||
foreach ( XmlElement tag in tags.GetElementsByTagName( "tag" ) )
|
||||
{
|
||||
try { list.Add( new AccountTag( tag ) ); }
|
||||
catch { }
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1180,8 +1187,7 @@ namespace Server.Accounting
|
|||
{
|
||||
if (amount <= 0) { return false; }
|
||||
|
||||
int gold;
|
||||
int plat = Math.DivRem(amount, AccountGold.CurrencyThreshold, out gold);
|
||||
int plat = Math.DivRem(amount, AccountGold.CurrencyThreshold, out int gold);
|
||||
TotalPlat += plat;
|
||||
TotalGold += gold;
|
||||
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ namespace Server.Accounting
|
|||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -192,6 +192,7 @@ namespace Server.Misc
|
|||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -229,7 +230,7 @@ namespace Server.Misc
|
|||
state.Send(new CharacterListUpdate(acct));
|
||||
}
|
||||
else if (m.AccessLevel == AccessLevel.Player &&
|
||||
Region.Find(m.LogoutLocation, m.LogoutMap).GetRegion(typeof(Jail)) != null
|
||||
Region.Find(m.LogoutLocation, m.LogoutMap).IsPartOf<Jail>()
|
||||
) //Don't need to check current location, if netstate is null, they're logged out
|
||||
{
|
||||
state.Send(new DeleteResult(DeleteResultType.BadRequest));
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ namespace Server.Accounting
|
|||
foreach (XmlElement account in root.GetElementsByTagName("account"))
|
||||
try
|
||||
{
|
||||
Account acct = new Account(account);
|
||||
new Account(account);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
|
@ -77,11 +77,8 @@ namespace Server.Accounting
|
|||
|
||||
using (StreamWriter op = new StreamWriter(filePath))
|
||||
{
|
||||
XmlTextWriter xml = new XmlTextWriter(op);
|
||||
XmlTextWriter xml = new XmlTextWriter(op) { Formatting = Formatting.Indented, IndentChar = '\t', Indentation = 1 };
|
||||
|
||||
xml.Formatting = Formatting.Indented;
|
||||
xml.IndentChar = '\t';
|
||||
xml.Indentation = 1;
|
||||
|
||||
xml.WriteStartDocument(true);
|
||||
|
||||
|
|
|
|||
|
|
@ -194,7 +194,8 @@ namespace Server
|
|||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is IPAddress) return obj.Equals(m_Address);
|
||||
if (obj is IPAddress)
|
||||
return obj.Equals(m_Address);
|
||||
if (obj is string s)
|
||||
{
|
||||
if (IPAddress.TryParse(s, out IPAddress otherAddress))
|
||||
|
|
@ -264,7 +265,7 @@ namespace Server
|
|||
{
|
||||
private string m_Entry;
|
||||
|
||||
private bool m_Valid = true;
|
||||
private bool m_Valid;
|
||||
|
||||
public WildcardIPFirewallEntry(string entry)
|
||||
{
|
||||
|
|
@ -276,7 +277,9 @@ namespace Server
|
|||
if (!m_Valid)
|
||||
return false; //Why process if it's invalid? it'll return false anyway after processing it.
|
||||
|
||||
return Utility.IPMatch(m_Entry, address, ref m_Valid);
|
||||
bool matched = Utility.IPMatch(m_Entry, address, out bool valid);
|
||||
m_Valid = valid;
|
||||
return matched;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Server.Items;
|
||||
using Server.Targeting;
|
||||
using CPA = Server.CommandPropertyAttribute;
|
||||
|
||||
namespace Server.Commands
|
||||
|
|
@ -54,18 +54,8 @@ namespace Server.Commands
|
|||
CommandSystem.Register("OutlineAvg", AccessLevel.GameMaster, OutlineAvg_OnCommand);
|
||||
}
|
||||
|
||||
public static void Invoke(Mobile from, Point3D start, Point3D end, string[] args)
|
||||
{
|
||||
Invoke(from, start, end, args, null, false, false);
|
||||
}
|
||||
|
||||
public static void Invoke(Mobile from, Point3D start, Point3D end, string[] args, List<Container> packs)
|
||||
{
|
||||
Invoke(from, start, end, args, packs, false, false);
|
||||
}
|
||||
|
||||
public static void Invoke(Mobile from, Point3D start, Point3D end, string[] args, List<Container> packs,
|
||||
bool outline, bool mapAvg)
|
||||
public static void Invoke(Mobile from, Point3D start, Point3D end, string[] args, List<Container> packs = null,
|
||||
bool outline = false, bool mapAvg = false)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
|
|
@ -148,13 +138,7 @@ namespace Server.Commands
|
|||
}
|
||||
|
||||
public static int BuildObjects(Mobile from, Type type, Point3D start, Point3D end, string[] args, string[,] props,
|
||||
List<Container> packs)
|
||||
{
|
||||
return BuildObjects(from, type, start, end, args, props, packs, false, false);
|
||||
}
|
||||
|
||||
public static int BuildObjects(Mobile from, Type type, Point3D start, Point3D end, string[] args, string[,] props,
|
||||
List<Container> packs, bool outline, bool mapAvg)
|
||||
List<Container> packs, bool outline = false, bool mapAvg = false)
|
||||
{
|
||||
Utility.FixPoints(ref start, ref end);
|
||||
|
||||
|
|
@ -206,10 +190,19 @@ namespace Server.Commands
|
|||
|
||||
if (!IsConstructible(ctor, from.AccessLevel))
|
||||
continue;
|
||||
|
||||
int totalParams = 0;
|
||||
|
||||
ParameterInfo[] paramList = ctor.GetParameters();
|
||||
// Handle optional constructors
|
||||
ParameterInfo[] paramList = ctor.GetParameters().Select(param =>
|
||||
{
|
||||
if (param.DefaultValue is DBNull)
|
||||
totalParams += 1;
|
||||
|
||||
if (args.Length == paramList.Length)
|
||||
return param;
|
||||
}).ToArray();
|
||||
|
||||
if (args.Length == totalParams)
|
||||
{
|
||||
object[] paramValues = ParseValues(paramList, args);
|
||||
|
||||
|
|
@ -228,27 +221,31 @@ namespace Server.Commands
|
|||
|
||||
public static object[] ParseValues(ParameterInfo[] paramList, string[] args)
|
||||
{
|
||||
object[] values = new object[args.Length];
|
||||
object[] values = new object[paramList.Length];
|
||||
|
||||
for (int i = 0; i < args.Length; ++i)
|
||||
for (int i = 0, a = 0; i < paramList.Length; ++i)
|
||||
{
|
||||
object value = ParseValue(paramList[i].ParameterType, args[i]);
|
||||
ParameterInfo param = paramList[i];
|
||||
if (param.DefaultValue is DBNull)
|
||||
{
|
||||
object value = ParseValue(param.ParameterType, args[a++], param.DefaultValue);
|
||||
if (value == null)
|
||||
return null;
|
||||
|
||||
if (value != null)
|
||||
values[i] = value;
|
||||
}
|
||||
else
|
||||
return null;
|
||||
values[i] = Type.Missing;
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
public static object ParseValue(Type type, string value)
|
||||
public static object ParseValue(Type type, string value, object defaultValue)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (IsEnum(type)) return Enum.Parse(type, value, true);
|
||||
|
||||
if (IsType(type)) return ScriptCompiler.FindTypeByName(value);
|
||||
if (IsParsable(type)) return ParseParsable(type, value);
|
||||
object obj = value;
|
||||
|
|
@ -259,12 +256,13 @@ namespace Server.Commands
|
|||
obj = Convert.ToInt64(value.Substring(2), 16);
|
||||
else if (IsUnsignedNumeric(type))
|
||||
obj = Convert.ToUInt64(value.Substring(2), 16);
|
||||
|
||||
obj = Convert.ToInt32(value.Substring(2), 16);
|
||||
else
|
||||
obj = Convert.ToInt32(value.Substring(2), 16);
|
||||
}
|
||||
|
||||
if (obj == null && !type.IsValueType)
|
||||
return null;
|
||||
|
||||
return Convert.ChangeType(obj, type);
|
||||
}
|
||||
catch
|
||||
|
|
@ -307,13 +305,7 @@ namespace Server.Commands
|
|||
}
|
||||
|
||||
public static int Build(Mobile from, Point3D start, Point3D end, ConstructorInfo ctor, object[] values,
|
||||
string[,] props, PropertyInfo[] realProps, List<Container> packs)
|
||||
{
|
||||
return Build(from, start, end, ctor, values, props, realProps, packs, false, false);
|
||||
}
|
||||
|
||||
public static int Build(Mobile from, Point3D start, Point3D end, ConstructorInfo ctor, object[] values,
|
||||
string[,] props, PropertyInfo[] realProps, List<Container> packs, bool outline, bool mapAvg)
|
||||
string[,] props, PropertyInfo[] realProps, List<Container> packs, bool outline = false, bool mapAvg = false)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -352,7 +344,8 @@ namespace Server.Commands
|
|||
|
||||
if (built is Item item)
|
||||
packs[i].DropItem(item);
|
||||
else if (built is Mobile m) m.MoveToWorld(new Point3D(start.X, start.Y, start.Z), map);
|
||||
else if (built is Mobile m)
|
||||
m.MoveToWorld(new Point3D(start.X, start.Y, start.Z), map);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -374,7 +367,8 @@ namespace Server.Commands
|
|||
|
||||
if (built is Item item)
|
||||
item.MoveToWorld(new Point3D(x, y, z), map);
|
||||
else if (built is Mobile m) m.MoveToWorld(new Point3D(x, y, z), map);
|
||||
else if (built is Mobile m)
|
||||
m.MoveToWorld(new Point3D(x, y, z), map);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -437,9 +431,8 @@ namespace Server.Commands
|
|||
from.SendMessage(sb.ToString());
|
||||
}
|
||||
|
||||
private static void TileBox_Callback(Mobile from, Map map, Point3D start, Point3D end, object state)
|
||||
private static void TileBox_Callback(Mobile from, Map map, Point3D start, Point3D end, TileState ts)
|
||||
{
|
||||
TileState ts = (TileState)state;
|
||||
bool mapAvg = false;
|
||||
|
||||
switch (ts.m_ZType)
|
||||
|
|
@ -461,10 +454,13 @@ namespace Server.Commands
|
|||
|
||||
private static void Internal_OnCommand(CommandEventArgs e, bool outline)
|
||||
{
|
||||
Mobile from = e.Mobile;
|
||||
|
||||
if (e.Length >= 1)
|
||||
BoundingBoxPicker.Begin(e.Mobile, TileBox_Callback, new TileState(TileZType.Start, 0, e.Arguments, outline));
|
||||
BoundingBoxPicker.Begin(from, (map, start, end) =>
|
||||
TileBox_Callback(from, map, start, end, new TileState(TileZType.Start, 0, e.Arguments, outline)));
|
||||
else
|
||||
e.Mobile.SendMessage("Format: {0} <type> [params] [set {{<propertyName> <value> ...}}]",
|
||||
from.SendMessage("Format: {0} <type> [params] [set {{<propertyName> <value> ...}}]",
|
||||
outline ? "Outline" : "Tile");
|
||||
}
|
||||
|
||||
|
|
@ -480,7 +476,7 @@ namespace Server.Commands
|
|||
for (int i = 0; i < subArgs.Length; ++i)
|
||||
subArgs[i] = e.Arguments[i + 5];
|
||||
|
||||
Invoke(e.Mobile, p, p2, subArgs, null, outline, false);
|
||||
Invoke(e.Mobile, p, p2, subArgs, null, outline);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -502,7 +498,7 @@ namespace Server.Commands
|
|||
for (int i = 0; i < subArgs.Length; ++i)
|
||||
subArgs[i] = e.Arguments[i + 5];
|
||||
|
||||
Invoke(e.Mobile, p, p2, subArgs, null, outline, false);
|
||||
Invoke(e.Mobile, p, p2, subArgs, null, outline);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -514,6 +510,8 @@ namespace Server.Commands
|
|||
|
||||
private static void InternalZ_OnCommand(CommandEventArgs e, bool outline)
|
||||
{
|
||||
Mobile from = e.Mobile;
|
||||
|
||||
if (e.Length >= 2)
|
||||
{
|
||||
string[] subArgs = new string[e.Length - 1];
|
||||
|
|
@ -521,23 +519,25 @@ namespace Server.Commands
|
|||
for (int i = 0; i < subArgs.Length; ++i)
|
||||
subArgs[i] = e.Arguments[i + 1];
|
||||
|
||||
BoundingBoxPicker.Begin(e.Mobile, TileBox_Callback,
|
||||
new TileState(TileZType.Fixed, e.GetInt32(0), subArgs, outline));
|
||||
BoundingBoxPicker.Begin(from, (map, start, end) =>
|
||||
TileBox_Callback(from, map, start, end, new TileState(TileZType.Fixed, e.GetInt32(0), subArgs, outline)));
|
||||
}
|
||||
else
|
||||
{
|
||||
e.Mobile.SendMessage("Format: {0}Z <z> <type> [params] [set {{<propertyName> <value> ...}}]",
|
||||
from.SendMessage("Format: {0}Z <z> <type> [params] [set {{<propertyName> <value> ...}}]",
|
||||
outline ? "Outline" : "Tile");
|
||||
}
|
||||
}
|
||||
|
||||
private static void InternalAvg_OnCommand(CommandEventArgs e, bool outline)
|
||||
{
|
||||
Mobile from = e.Mobile;
|
||||
|
||||
if (e.Length >= 1)
|
||||
BoundingBoxPicker.Begin(e.Mobile, TileBox_Callback,
|
||||
new TileState(TileZType.MapAverage, 0, e.Arguments, outline));
|
||||
BoundingBoxPicker.Begin(from, (map, start, end) =>
|
||||
TileBox_Callback(from, map, start, end, new TileState(TileZType.MapAverage, 0, e.Arguments, outline)));
|
||||
else
|
||||
e.Mobile.SendMessage("Format: {0}Avg <type> [params] [set {{<propertyName> <value> ...}}]",
|
||||
from.SendMessage("Format: {0}Avg <type> [params] [set {{<propertyName> <value> ...}}]",
|
||||
outline ? "Outline" : "Tile");
|
||||
}
|
||||
|
||||
|
|
@ -657,7 +657,7 @@ namespace Server.Commands
|
|||
|
||||
m_ParseArgs[0] = value;
|
||||
|
||||
return method.Invoke(null, m_ParseArgs);
|
||||
return method?.Invoke(null, m_ParseArgs);
|
||||
}
|
||||
|
||||
public static bool IsSignedNumeric(Type type)
|
||||
|
|
@ -678,30 +678,6 @@ namespace Server.Commands
|
|||
return false;
|
||||
}
|
||||
|
||||
public class AddTarget : Target
|
||||
{
|
||||
private string[] m_Args;
|
||||
|
||||
public AddTarget(string[] args) : base(-1, true, TargetFlags.None)
|
||||
{
|
||||
m_Args = args;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object o)
|
||||
{
|
||||
if (o is IPoint3D p)
|
||||
{
|
||||
if (p is Item item)
|
||||
p = item.GetWorldTop();
|
||||
else if (p is Mobile m)
|
||||
p = m.Location;
|
||||
|
||||
Point3D point = new Point3D(p);
|
||||
Add.Invoke(from, point, point, m_Args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private enum TileZType
|
||||
{
|
||||
Start,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Server.Commands.Generic;
|
||||
using Server.Gumps;
|
||||
|
|
@ -13,18 +14,15 @@ namespace Server.Commands
|
|||
{
|
||||
Commands = new[] { "Batch" };
|
||||
ListOptimized = true;
|
||||
|
||||
BatchCommands = new ArrayList();
|
||||
Condition = "";
|
||||
}
|
||||
|
||||
public BaseCommandImplementor Scope{ get; set; }
|
||||
|
||||
public string Condition{ get; set; }
|
||||
public string Condition{ get; set; } = "";
|
||||
|
||||
public ArrayList BatchCommands{ get; }
|
||||
public List<BatchCommand> BatchCommands{ get; } = new List<BatchCommand>();
|
||||
|
||||
public override void ExecuteList(CommandEventArgs e, ArrayList list)
|
||||
public override void ExecuteList(CommandEventArgs e, List<object> list)
|
||||
{
|
||||
if (list.Count == 0)
|
||||
{
|
||||
|
|
@ -39,7 +37,7 @@ namespace Server.Commands
|
|||
|
||||
for (int i = 0; i < BatchCommands.Count; ++i)
|
||||
{
|
||||
BatchCommand bc = (BatchCommand)BatchCommands[i];
|
||||
BatchCommand bc = BatchCommands[i];
|
||||
|
||||
bc.GetDetails(out string commandString, out string argString, out string[] args);
|
||||
|
||||
|
|
@ -68,12 +66,12 @@ namespace Server.Commands
|
|||
for (int i = 0; i < commands.Length; ++i)
|
||||
{
|
||||
BaseCommand command = commands[i];
|
||||
BatchCommand bc = (BatchCommand)BatchCommands[i];
|
||||
BatchCommand bc = BatchCommands[i];
|
||||
|
||||
if (list.Count > 20)
|
||||
CommandLogging.Enabled = false;
|
||||
|
||||
ArrayList usedList;
|
||||
List<object> usedList;
|
||||
|
||||
if (Utility.InsensitiveCompare(bc.Object, "Current") == 0)
|
||||
{
|
||||
|
|
@ -81,9 +79,9 @@ namespace Server.Commands
|
|||
}
|
||||
else
|
||||
{
|
||||
Hashtable propertyChains = new Hashtable();
|
||||
Dictionary<Type, PropertyInfo[]> propertyChains = new Dictionary<Type, PropertyInfo[]>();
|
||||
|
||||
usedList = new ArrayList(list.Count);
|
||||
usedList = new List<object>(list.Count);
|
||||
|
||||
for (int j = 0; j < list.Count; ++j)
|
||||
{
|
||||
|
|
@ -94,11 +92,11 @@ namespace Server.Commands
|
|||
|
||||
Type type = obj.GetType();
|
||||
|
||||
PropertyInfo[] chain = (PropertyInfo[])propertyChains[type];
|
||||
PropertyInfo[] chain = propertyChains[type];
|
||||
|
||||
string failReason = "";
|
||||
|
||||
if (chain == null && !propertyChains.Contains(type))
|
||||
if (chain == null)
|
||||
propertyChains[type] = chain = Properties.GetPropertyInfoChain(e.Mobile, type, bc.Object,
|
||||
PropertyAccess.Read, ref failReason);
|
||||
|
||||
|
|
@ -119,6 +117,7 @@ namespace Server.Commands
|
|||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -272,7 +271,7 @@ namespace Server.Commands
|
|||
|
||||
for (int i = 0; i < m_Batch.BatchCommands.Count; ++i)
|
||||
{
|
||||
BatchCommand bc = (BatchCommand)m_Batch.BatchCommands[i];
|
||||
BatchCommand bc = m_Batch.BatchCommands[i];
|
||||
|
||||
AddNewLine();
|
||||
|
||||
|
|
@ -420,4 +419,4 @@ namespace Server.Commands
|
|||
m_From.SendGump(new BatchGump(m_From, m_Batch));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,14 +2,14 @@ using Server.Targeting;
|
|||
|
||||
namespace Server
|
||||
{
|
||||
public delegate void BoundingBoxCallback(Mobile from, Map map, Point3D start, Point3D end, object state);
|
||||
public delegate void BoundingBoxCallback(Map map, Point3D start, Point3D end);
|
||||
|
||||
public class BoundingBoxPicker
|
||||
public static class BoundingBoxPicker
|
||||
{
|
||||
public static void Begin(Mobile from, BoundingBoxCallback callback, object state)
|
||||
public static void Begin(Mobile from, BoundingBoxCallback callback)
|
||||
{
|
||||
from.SendMessage("Target the first location of the bounding box.");
|
||||
from.Target = new PickTarget(callback, state);
|
||||
from.Target = new PickTarget(callback);
|
||||
}
|
||||
|
||||
private class PickTarget : Target
|
||||
|
|
@ -17,21 +17,18 @@ namespace Server
|
|||
private BoundingBoxCallback m_Callback;
|
||||
private bool m_First;
|
||||
private Map m_Map;
|
||||
private object m_State;
|
||||
private Point3D m_Store;
|
||||
|
||||
public PickTarget(BoundingBoxCallback callback, object state) : this(Point3D.Zero, true, null, callback, state)
|
||||
public PickTarget(BoundingBoxCallback callback) : this(Point3D.Zero, true, null, callback)
|
||||
{
|
||||
}
|
||||
|
||||
public PickTarget(Point3D store, bool first, Map map, BoundingBoxCallback callback, object state) : base(-1,
|
||||
true, TargetFlags.None)
|
||||
public PickTarget(Point3D store, bool first, Map map, BoundingBoxCallback callback) : base(-1, true, TargetFlags.None)
|
||||
{
|
||||
m_Store = store;
|
||||
m_First = first;
|
||||
m_Map = map;
|
||||
m_Callback = callback;
|
||||
m_State = state;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
|
|
@ -45,7 +42,7 @@ namespace Server
|
|||
if (m_First)
|
||||
{
|
||||
from.SendMessage("Target another location to complete the bounding box.");
|
||||
from.Target = new PickTarget(new Point3D(p), false, from.Map, m_Callback, m_State);
|
||||
from.Target = new PickTarget(new Point3D(p), false, from.Map, m_Callback);
|
||||
}
|
||||
else if (from.Map != m_Map)
|
||||
{
|
||||
|
|
@ -58,7 +55,7 @@ namespace Server
|
|||
|
||||
Utility.FixPoints(ref start, ref end);
|
||||
|
||||
m_Callback(from, m_Map, start, end, m_State);
|
||||
m_Callback(m_Map, start, end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
|
@ -63,24 +64,22 @@ namespace Server.Commands
|
|||
}
|
||||
}
|
||||
|
||||
private static PropertyInfo[] _mobProps =
|
||||
typeof(Mobile).GetProperties(BindingFlags.Public | BindingFlags.Instance)
|
||||
.Where(prop => prop.CanRead && prop.CanWrite).ToArray();
|
||||
|
||||
private static void CopyProps(Mobile to, Mobile from)
|
||||
{
|
||||
Type type = typeof(Mobile);
|
||||
|
||||
PropertyInfo[] props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
|
||||
|
||||
for (int p = 0; p < props.Length; p++)
|
||||
foreach (PropertyInfo prop in _mobProps)
|
||||
{
|
||||
PropertyInfo prop = props[p];
|
||||
|
||||
if (prop.CanRead && prop.CanWrite)
|
||||
try
|
||||
{
|
||||
prop.SetValue(to, prop.GetValue(from, null), null);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
try
|
||||
{
|
||||
prop.SetValue(to, prop.GetValue(from, null), null);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Server.Engines.Quests.Haven;
|
||||
|
|
@ -47,10 +46,10 @@ namespace Server.Commands
|
|||
|
||||
for (int i = 0; i < files.Length; ++i)
|
||||
{
|
||||
ArrayList list = DecorationList.ReadAll(files[i]);
|
||||
List<DecorationList> list = DecorationList.ReadAll(files[i]);
|
||||
|
||||
for (int j = 0; j < list.Count; ++j)
|
||||
m_Count += ((DecorationList)list[j]).Generate(maps);
|
||||
m_Count += list[j].Generate(maps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -70,10 +69,10 @@ namespace Server.Commands
|
|||
private static Type typeofCannon = typeof(Cannon);
|
||||
private static Type typeofSerpentPillar = typeof(SerpentPillar);
|
||||
|
||||
private static Queue m_DeleteQueue = new Queue();
|
||||
private static Queue<Item> m_DeleteQueue = new Queue<Item>();
|
||||
|
||||
private static string[] m_EmptyParams = new string[0];
|
||||
private ArrayList m_Entries;
|
||||
private List<DecorationEntry> m_Entries;
|
||||
private int m_ItemID;
|
||||
private string[] m_Params;
|
||||
private Type m_Type;
|
||||
|
|
@ -913,7 +912,7 @@ namespace Server.Commands
|
|||
eable.Free();
|
||||
|
||||
while (m_DeleteQueue.Count > 0)
|
||||
((Item)m_DeleteQueue.Dequeue()).Delete();
|
||||
m_DeleteQueue.Dequeue().Delete();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
@ -926,7 +925,7 @@ namespace Server.Commands
|
|||
|
||||
for (int i = 0; i < m_Entries.Count; ++i)
|
||||
{
|
||||
DecorationEntry entry = (DecorationEntry)m_Entries[i];
|
||||
DecorationEntry entry = m_Entries[i];
|
||||
Point3D loc = entry.Location;
|
||||
string extra = entry.Extra;
|
||||
|
||||
|
|
@ -970,6 +969,7 @@ namespace Server.Commands
|
|||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -983,13 +983,14 @@ namespace Server.Commands
|
|||
return count;
|
||||
}
|
||||
|
||||
public static ArrayList ReadAll(string path)
|
||||
public static List<DecorationList> ReadAll(string path)
|
||||
{
|
||||
using (StreamReader ip = new StreamReader(path))
|
||||
{
|
||||
ArrayList list = new ArrayList();
|
||||
|
||||
for (DecorationList v = Read(ip); v != null; v = Read(ip))
|
||||
List<DecorationList> list = new List<DecorationList>();
|
||||
DecorationList v;
|
||||
|
||||
while ((v = Read(ip)) != null)
|
||||
list.Add(v);
|
||||
|
||||
return list;
|
||||
|
|
@ -1042,7 +1043,7 @@ namespace Server.Commands
|
|||
list.m_Params = m_EmptyParams;
|
||||
}
|
||||
|
||||
list.m_Entries = new ArrayList();
|
||||
list.m_Entries = new List<DecorationEntry>();
|
||||
|
||||
while ((line = ip.ReadLine()) != null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -44,10 +44,10 @@ namespace Server.Commands
|
|||
|
||||
for (int i = 0; i < files.Length; ++i)
|
||||
{
|
||||
ArrayList list = DecorationListMag.ReadAll(files[i]);
|
||||
List<DecorationListMag> list = DecorationListMag.ReadAll(files[i]);
|
||||
|
||||
for (int j = 0; j < list.Count; ++j)
|
||||
m_Count += ((DecorationListMag)list[j]).Generate(maps);
|
||||
m_Count += list[j].Generate(maps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -70,7 +70,7 @@ namespace Server.Commands
|
|||
private static Queue m_DeleteQueue = new Queue();
|
||||
|
||||
private static string[] m_EmptyParams = new string[0];
|
||||
private ArrayList m_Entries;
|
||||
private List<DecorationEntryMag> m_Entries;
|
||||
private int m_ItemID;
|
||||
private string[] m_Params;
|
||||
private Type m_Type;
|
||||
|
|
@ -923,7 +923,7 @@ namespace Server.Commands
|
|||
|
||||
for (int i = 0; i < m_Entries.Count; ++i)
|
||||
{
|
||||
DecorationEntryMag entry = (DecorationEntryMag)m_Entries[i];
|
||||
DecorationEntryMag entry = m_Entries[i];
|
||||
Point3D loc = entry.Location;
|
||||
string extra = entry.Extra;
|
||||
|
||||
|
|
@ -967,6 +967,7 @@ namespace Server.Commands
|
|||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -980,13 +981,14 @@ namespace Server.Commands
|
|||
return count;
|
||||
}
|
||||
|
||||
public static ArrayList ReadAll(string path)
|
||||
public static List<DecorationListMag> ReadAll(string path)
|
||||
{
|
||||
using (StreamReader ip = new StreamReader(path))
|
||||
{
|
||||
ArrayList list = new ArrayList();
|
||||
List<DecorationListMag> list = new List<DecorationListMag>();
|
||||
|
||||
for (DecorationListMag v = Read(ip); v != null; v = Read(ip))
|
||||
DecorationListMag v;
|
||||
while ((v = Read(ip)) != null)
|
||||
list.Add(v);
|
||||
|
||||
return list;
|
||||
|
|
@ -1039,7 +1041,7 @@ namespace Server.Commands
|
|||
list.m_Params = m_EmptyParams;
|
||||
}
|
||||
|
||||
list.m_Entries = new ArrayList();
|
||||
list.m_Entries = new List<DecorationEntryMag>();
|
||||
|
||||
while ((line = ip.ReadLine()) != null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -214,7 +214,7 @@ namespace Server.Commands
|
|||
}
|
||||
}
|
||||
|
||||
public static void FormatGeneric(Type type, ref string typeName, ref string fileName, ref string linkName)
|
||||
public static void FormatGeneric(Type type, out string typeName, out string fileName, out string linkName)
|
||||
{
|
||||
string name = null;
|
||||
string fnam = null;
|
||||
|
|
@ -274,8 +274,10 @@ namespace Server.Commands
|
|||
}
|
||||
}
|
||||
|
||||
if (name == null) typeName = type.Name;
|
||||
else typeName = name;
|
||||
if (name == null)
|
||||
typeName = type.Name;
|
||||
else
|
||||
typeName = name;
|
||||
|
||||
if (fnam == null) fileName = "docs/types/" + SanitizeType(type.Name) + ".html";
|
||||
else fileName = fnam + ".html";
|
||||
|
|
@ -466,12 +468,7 @@ namespace Server.Commands
|
|||
m_Declaring = type.DeclaringType;
|
||||
m_Interfaces = type.GetInterfaces();
|
||||
|
||||
FormatGeneric(m_Type, ref m_TypeName, ref m_FileName, ref m_LinkName);
|
||||
|
||||
// Console.WriteLine( ">> inline typeinfo: "+m_TypeName );
|
||||
// m_TypeName = GetGenericTypeName( m_Type );
|
||||
// m_FileName = Docs.GetFileName( "docs/types/", GetGenericTypeName( m_Type, "-", "-" ), ".html" );
|
||||
// m_Writer = Docs.GetWriter( "docs/types/", m_FileName );
|
||||
FormatGeneric(m_Type, out m_TypeName, out m_FileName, out m_LinkName);
|
||||
}
|
||||
|
||||
public string FileName => m_FileName;
|
||||
|
|
@ -601,7 +598,7 @@ namespace Server.Commands
|
|||
append.Append(" *");
|
||||
}
|
||||
}
|
||||
else if (realType.IsArray)
|
||||
else if (realType?.IsArray == true)
|
||||
{
|
||||
do
|
||||
{
|
||||
|
|
@ -625,30 +622,16 @@ namespace Server.Commands
|
|||
string fullName = realType?.FullName ?? "(-null-)";
|
||||
string aliased = null; // = realType.Name;
|
||||
|
||||
TypeInfo info = null;
|
||||
|
||||
if (realType != null)
|
||||
if (realType != null && m_Types.TryGetValue(realType, out TypeInfo info))
|
||||
{
|
||||
m_Types.TryGetValue(realType, out info);
|
||||
}
|
||||
|
||||
if (info != null)
|
||||
{
|
||||
aliased = "<!-- DBG-0 -->" + info.LinkName(null);
|
||||
//aliased = String.Format( "<a href=\"{0}\">{1}</a>", info.m_FileName, info.m_TypeName );
|
||||
aliased = $"<!-- DBG-0 -->{info.LinkName(null)}";
|
||||
}
|
||||
else
|
||||
{
|
||||
//FormatGeneric( );
|
||||
if (realType?.IsGenericType == true)
|
||||
{
|
||||
string typeName = "";
|
||||
string fileName = "";
|
||||
string linkName = "";
|
||||
|
||||
FormatGeneric(realType, ref typeName, ref fileName, ref linkName);
|
||||
linkName = linkName.Replace("@directory@", null);
|
||||
aliased = linkName;
|
||||
FormatGeneric(realType, out _, out _, out string linkName);
|
||||
aliased = linkName.Replace("@directory@", null);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -768,7 +751,7 @@ namespace Server.Commands
|
|||
AddIndexLink(html, "commands.html", "Commands",
|
||||
"Every available command. This contains command name, usage, aliases, and description.");
|
||||
AddIndexLink(html, "objects.html", "Constructible Objects",
|
||||
"Every constructable item or npc. This contains object name and usage. Hover mouse over parameters to see type description.");
|
||||
"Every constructible item or npc. This contains object name and usage. Hover mouse over parameters to see type description.");
|
||||
AddIndexLink(html, "keywords.html", "Speech Keywords",
|
||||
"Lists speech keyword numbers and associated match patterns. These are used in some scripts for multi-language matching of client speech.");
|
||||
AddIndexLink(html, "bodies.html", "Body List",
|
||||
|
|
@ -1861,7 +1844,8 @@ namespace Server.Commands
|
|||
{
|
||||
public int Compare(SpeechEntry x, SpeechEntry y)
|
||||
{
|
||||
return x.Index.CompareTo(y.Index);
|
||||
if (x == null && y == null) return 0;
|
||||
return x?.Index.CompareTo(y?.Index) ?? 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1940,12 +1924,14 @@ namespace Server.Commands
|
|||
{
|
||||
public int Compare(DocCommandEntry a, DocCommandEntry b)
|
||||
{
|
||||
int v = b.AccessLevel.CompareTo(a.AccessLevel);
|
||||
if (a == null && b == null) return 0;
|
||||
|
||||
int v = b?.AccessLevel.CompareTo(a?.AccessLevel) ?? 1;
|
||||
|
||||
if (v == 0)
|
||||
v = a.Name.CompareTo(b.Name);
|
||||
|
||||
return v;
|
||||
if (v != 0)
|
||||
return v;
|
||||
|
||||
return a?.Name.CompareTo(b?.Name) ?? 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2198,10 +2184,7 @@ namespace Server.Commands
|
|||
|
||||
private static bool IsConstructible(Type t, out bool isItem)
|
||||
{
|
||||
if (isItem = typeofItem.IsAssignableFrom(t))
|
||||
return true;
|
||||
|
||||
return typeofMobile.IsAssignableFrom(t);
|
||||
return (isItem = typeofItem.IsAssignableFrom(t)) || typeofMobile.IsAssignableFrom(t);
|
||||
}
|
||||
|
||||
private static bool IsConstructible(ConstructorInfo ctor)
|
||||
|
|
@ -2214,14 +2197,14 @@ namespace Server.Commands
|
|||
List<TypeInfo> types = new List<TypeInfo>(m_Types.Values);
|
||||
types.Sort(new TypeComparer());
|
||||
|
||||
ArrayList items = new ArrayList(), mobiles = new ArrayList();
|
||||
List<(Type, ConstructorInfo[])> items = new List<(Type, ConstructorInfo[])>();
|
||||
List<(Type, ConstructorInfo[])> mobiles = new List<(Type, ConstructorInfo[])>();
|
||||
|
||||
for (int i = 0; i < types.Count; ++i)
|
||||
{
|
||||
Type t = types[i].m_Type;
|
||||
bool isItem;
|
||||
|
||||
if (t.IsAbstract || !IsConstructible(t, out isItem))
|
||||
if (t.IsAbstract || !IsConstructible(t, out bool isItem))
|
||||
continue;
|
||||
|
||||
ConstructorInfo[] ctors = t.GetConstructors();
|
||||
|
|
@ -2232,8 +2215,7 @@ namespace Server.Commands
|
|||
|
||||
if (anyConstructible)
|
||||
{
|
||||
(isItem ? items : mobiles).Add(t);
|
||||
(isItem ? items : mobiles).Add(ctors);
|
||||
(isItem ? items : mobiles).Add((t, ctors));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2255,8 +2237,11 @@ namespace Server.Commands
|
|||
html.WriteLine(" <table width=\"100%\" cellpadding=\"4\" cellspacing=\"1\">");
|
||||
html.WriteLine(" <tr><td class=\"header\">Item Name</td><td class=\"header\">Usage</td></tr>");
|
||||
|
||||
for (int i = 0; i < items.Count; i += 2)
|
||||
DocumentConstructibleObject(html, (Type)items[i], (ConstructorInfo[])items[i + 1]);
|
||||
items.ForEach(tuple =>
|
||||
{
|
||||
var (type, constructors) = tuple;
|
||||
DocumentConstructibleObject(html, type, constructors);
|
||||
});
|
||||
|
||||
html.WriteLine(" </table></td></tr></table><br><br>");
|
||||
|
||||
|
|
@ -2266,8 +2251,11 @@ namespace Server.Commands
|
|||
html.WriteLine(" <table width=\"100%\" cellpadding=\"4\" cellspacing=\"1\">");
|
||||
html.WriteLine(" <tr><td class=\"header\">Mobile Name</td><td class=\"header\">Usage</td></tr>");
|
||||
|
||||
for (int i = 0; i < mobiles.Count; i += 2)
|
||||
DocumentConstructibleObject(html, (Type)mobiles[i], (ConstructorInfo[])mobiles[i + 1]);
|
||||
mobiles.ForEach(tuple =>
|
||||
{
|
||||
var (type, constructors) = tuple;
|
||||
DocumentConstructibleObject(html, type, constructors);
|
||||
});
|
||||
|
||||
html.WriteLine(" </table></td></tr></table>");
|
||||
|
||||
|
|
@ -2513,12 +2501,8 @@ namespace Server.Commands
|
|||
|
||||
if (ifaceInfo == null)
|
||||
{
|
||||
string typeName = "";
|
||||
string fileName = "";
|
||||
string linkName = "";
|
||||
FormatGeneric(iface, ref typeName, ref fileName, ref linkName);
|
||||
linkName = linkName.Replace("@directory@", null);
|
||||
typeHtml.Write("<!-- DBG-2.1 -->" + linkName);
|
||||
FormatGeneric(iface, out _, out _, out string linkName);
|
||||
typeHtml.Write($"<!-- DBG-2.1 -->{linkName.Replace("@directory@", null)}");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2725,9 +2709,9 @@ namespace Server.Commands
|
|||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
BodyEntry e = (BodyEntry)obj;
|
||||
BodyEntry e = obj as BodyEntry;
|
||||
|
||||
return Body == e.Body && BodyType == e.BodyType && Name == e.Name;
|
||||
return Body == e?.Body && BodyType == e.BodyType && Name == e.Name;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
|
|
@ -2740,15 +2724,16 @@ namespace Server.Commands
|
|||
{
|
||||
public int Compare(BodyEntry a, BodyEntry b)
|
||||
{
|
||||
int v = a.BodyType.CompareTo(b.BodyType);
|
||||
if (a == null && b == null) return 0;
|
||||
int v = a?.BodyType.CompareTo(b?.BodyType) ?? 1;
|
||||
|
||||
if (v == 0)
|
||||
v = a.Body.BodyID.CompareTo(b.Body.BodyID);
|
||||
v = a?.Body.BodyID.CompareTo(b?.Body.BodyID) ?? 1;
|
||||
|
||||
if (v == 0)
|
||||
v = a.Name.CompareTo(b.Name);
|
||||
|
||||
return v;
|
||||
if (v != 0)
|
||||
return v;
|
||||
|
||||
return a?.Name.CompareTo(b?.Name) ?? 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Server.Items;
|
||||
|
||||
|
|
@ -16,7 +16,7 @@ namespace Server.Commands
|
|||
public static void Export_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
StreamWriter w = new StreamWriter(ExportFile);
|
||||
ArrayList remove = new ArrayList();
|
||||
List<Item> remove = new List<Item>();
|
||||
int count = 0;
|
||||
|
||||
e.Mobile.SendMessage("Exporting all static items to \"{0}\"...", ExportFile);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
|
@ -54,14 +54,6 @@ namespace Server.Commands
|
|||
e.Mobile.SendMessage("Categorization menu rebuilt.");
|
||||
}
|
||||
|
||||
public static void RecurseFindCategories(CategoryEntry ce, ArrayList list)
|
||||
{
|
||||
list.Add(ce);
|
||||
|
||||
for (int i = 0; i < ce.SubCategories.Length; ++i)
|
||||
RecurseFindCategories(ce.SubCategories[i], list);
|
||||
}
|
||||
|
||||
public static void Export(CategoryEntry ce, string fileName, string title)
|
||||
{
|
||||
XmlTextWriter xml = new XmlTextWriter(fileName, Encoding.UTF8);
|
||||
|
|
@ -84,18 +76,18 @@ namespace Server.Commands
|
|||
|
||||
xml.WriteAttributeString("title", ce.Title);
|
||||
|
||||
ArrayList subCats = new ArrayList(ce.SubCategories);
|
||||
List<CategoryEntry> subCats = new List<CategoryEntry>(ce.SubCategories);
|
||||
|
||||
subCats.Sort(new CategorySorter());
|
||||
|
||||
for (int i = 0; i < subCats.Count; ++i)
|
||||
RecurseExport(xml, (CategoryEntry)subCats[i]);
|
||||
RecurseExport(xml, subCats[i]);
|
||||
|
||||
ce.Matched.Sort(new CategorySorter());
|
||||
ce.Matched.Sort(new CategoryTypeSorter());
|
||||
|
||||
for (int i = 0; i < ce.Matched.Count; ++i)
|
||||
{
|
||||
CategoryTypeEntry cte = (CategoryTypeEntry)ce.Matched[i];
|
||||
CategoryTypeEntry cte = ce.Matched[i];
|
||||
|
||||
xml.WriteStartElement("object");
|
||||
|
||||
|
|
@ -148,7 +140,7 @@ namespace Server.Commands
|
|||
|
||||
public static void Load()
|
||||
{
|
||||
ArrayList types = new ArrayList();
|
||||
List<Type> types = new List<Type>();
|
||||
|
||||
AddTypes(Core.Assembly, types);
|
||||
|
||||
|
|
@ -159,7 +151,7 @@ namespace Server.Commands
|
|||
m_RootMobiles = Load(types, "Data/mobiles.cfg");
|
||||
}
|
||||
|
||||
private static CategoryEntry Load(ArrayList types, string config)
|
||||
private static CategoryEntry Load(List<Type> types, string config)
|
||||
{
|
||||
CategoryLine[] lines = CategoryLine.Load(config);
|
||||
|
||||
|
|
@ -186,7 +178,7 @@ namespace Server.Commands
|
|||
return ctor != null && ctor.IsDefined(typeofConstructible, false);
|
||||
}
|
||||
|
||||
private static void AddTypes(Assembly asm, ArrayList types)
|
||||
private static void AddTypes(Assembly asm, List<Type> types)
|
||||
{
|
||||
Type[] allTypes = asm.GetTypes();
|
||||
|
||||
|
|
@ -202,11 +194,11 @@ namespace Server.Commands
|
|||
}
|
||||
}
|
||||
|
||||
private static void Fill(CategoryEntry root, ArrayList list)
|
||||
private static void Fill(CategoryEntry root, List<Type> list)
|
||||
{
|
||||
for (int i = 0; i < list.Count; ++i)
|
||||
{
|
||||
Type type = (Type)list[i];
|
||||
Type type = list[i];
|
||||
CategoryEntry match = GetDeepestMatch(root, type);
|
||||
|
||||
if (match == null)
|
||||
|
|
@ -218,6 +210,7 @@ namespace Server.Commands
|
|||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -239,21 +232,12 @@ namespace Server.Commands
|
|||
}
|
||||
}
|
||||
|
||||
public class CategorySorter : IComparer
|
||||
public class CategorySorter : IComparer<CategoryEntry>
|
||||
{
|
||||
public int Compare(object x, object y)
|
||||
public int Compare(CategoryEntry x, CategoryEntry y)
|
||||
{
|
||||
string a = null, b = null;
|
||||
|
||||
if (x is CategoryEntry entry)
|
||||
a = entry.Title;
|
||||
else if (x is CategoryTypeEntry xTypeEntry)
|
||||
a = xTypeEntry.Type.Name;
|
||||
|
||||
if (y is CategoryEntry categoryEntry)
|
||||
b = categoryEntry.Title;
|
||||
else if (y is CategoryTypeEntry yTypeEntry)
|
||||
b = yTypeEntry.Type.Name;
|
||||
string a = x?.Title;
|
||||
string b = y?.Title;
|
||||
|
||||
if (a == null && b == null)
|
||||
return 0;
|
||||
|
|
@ -261,13 +245,27 @@ namespace Server.Commands
|
|||
if (a == null)
|
||||
return 1;
|
||||
|
||||
if (b == null)
|
||||
return -1;
|
||||
|
||||
return a.CompareTo(b);
|
||||
}
|
||||
}
|
||||
|
||||
public class CategoryTypeSorter : IComparer<CategoryTypeEntry>
|
||||
{
|
||||
public int Compare(CategoryTypeEntry x, CategoryTypeEntry y)
|
||||
{
|
||||
string a = x?.Type.Name;
|
||||
string b = y?.Type.Name;
|
||||
|
||||
if (a == null && b == null)
|
||||
return 0;
|
||||
|
||||
if (a == null)
|
||||
return 1;
|
||||
|
||||
return a.CompareTo(b);
|
||||
}
|
||||
}
|
||||
|
||||
public class CategoryTypeEntry
|
||||
{
|
||||
public CategoryTypeEntry(Type type)
|
||||
|
|
@ -283,21 +281,13 @@ namespace Server.Commands
|
|||
|
||||
public class CategoryEntry
|
||||
{
|
||||
public CategoryEntry()
|
||||
{
|
||||
Title = "(empty)";
|
||||
Matches = new Type[0];
|
||||
SubCategories = new CategoryEntry[0];
|
||||
Matched = new ArrayList();
|
||||
}
|
||||
|
||||
public CategoryEntry(CategoryEntry parent, string title, CategoryEntry[] subCats)
|
||||
public CategoryEntry(CategoryEntry parent = null, string title = "(empty)", CategoryEntry[] subCats = null)
|
||||
{
|
||||
Parent = parent;
|
||||
Title = title;
|
||||
SubCategories = subCats;
|
||||
SubCategories = subCats ?? new CategoryEntry[0];
|
||||
Matches = new Type[0];
|
||||
Matched = new ArrayList();
|
||||
Matched = new List<CategoryTypeEntry>();
|
||||
}
|
||||
|
||||
public CategoryEntry(CategoryEntry parent, CategoryLine[] lines, ref int index)
|
||||
|
|
@ -321,7 +311,7 @@ namespace Server.Commands
|
|||
text = text.Substring(start, end - start);
|
||||
string[] split = text.Split(';');
|
||||
|
||||
ArrayList list = new ArrayList();
|
||||
List<Type> list = new List<Type>();
|
||||
|
||||
for (int i = 0; i < split.Length; ++i)
|
||||
{
|
||||
|
|
@ -333,20 +323,22 @@ namespace Server.Commands
|
|||
list.Add(type);
|
||||
}
|
||||
|
||||
Matches = (Type[])list.ToArray(typeof(Type));
|
||||
Matches = list.ToArray();
|
||||
list.Clear();
|
||||
|
||||
int ourIndentation = lines[index].Indentation;
|
||||
|
||||
++index;
|
||||
|
||||
List<CategoryEntry> entryList = new List<CategoryEntry>();
|
||||
|
||||
while (index < lines.Length && lines[index].Indentation > ourIndentation)
|
||||
list.Add(new CategoryEntry(this, lines, ref index));
|
||||
entryList.Add(new CategoryEntry(this, lines, ref index));
|
||||
|
||||
SubCategories = (CategoryEntry[])list.ToArray(typeof(CategoryEntry));
|
||||
list.Clear();
|
||||
SubCategories = entryList.ToArray();
|
||||
entryList.Clear();
|
||||
|
||||
Matched = list;
|
||||
Matched = new List<CategoryTypeEntry>();
|
||||
}
|
||||
|
||||
public string Title{ get; }
|
||||
|
|
@ -357,7 +349,7 @@ namespace Server.Commands
|
|||
|
||||
public CategoryEntry[] SubCategories{ get; }
|
||||
|
||||
public ArrayList Matched{ get; }
|
||||
public List<CategoryTypeEntry> Matched{ get; }
|
||||
|
||||
public bool IsMatch(Type type)
|
||||
{
|
||||
|
|
@ -393,7 +385,7 @@ namespace Server.Commands
|
|||
|
||||
public static CategoryLine[] Load(string path)
|
||||
{
|
||||
ArrayList list = new ArrayList();
|
||||
List<CategoryLine> list = new List<CategoryLine>();
|
||||
|
||||
if (File.Exists(path))
|
||||
using (StreamReader ip = new StreamReader(path))
|
||||
|
|
@ -404,7 +396,7 @@ namespace Server.Commands
|
|||
list.Add(new CategoryLine(line));
|
||||
}
|
||||
|
||||
return (CategoryLine[])list.ToArray(typeof(CategoryLine));
|
||||
return list.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
using System.Collections;
|
||||
using Server.Gumps;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Commands.Generic
|
||||
{
|
||||
|
|
@ -13,13 +12,8 @@ namespace Server.Commands.Generic
|
|||
|
||||
public abstract class BaseCommand
|
||||
{
|
||||
private ArrayList m_Responses, m_Failures;
|
||||
|
||||
public BaseCommand()
|
||||
{
|
||||
m_Responses = new ArrayList();
|
||||
m_Failures = new ArrayList();
|
||||
}
|
||||
private List<MessageEntry> m_Responses = new List<MessageEntry>();
|
||||
private List<MessageEntry> m_Failures = new List<MessageEntry>();
|
||||
|
||||
public bool ListOptimized{ get; set; }
|
||||
|
||||
|
|
@ -50,7 +44,7 @@ namespace Server.Commands.Generic
|
|||
return mob == null || mob == from || from.AccessLevel > mob.AccessLevel;
|
||||
}
|
||||
|
||||
public virtual void ExecuteList(CommandEventArgs e, ArrayList list)
|
||||
public virtual void ExecuteList(CommandEventArgs e, List<object> list)
|
||||
{
|
||||
for (int i = 0; i < list.Count; ++i)
|
||||
Execute(e, list[i]);
|
||||
|
|
@ -69,7 +63,7 @@ namespace Server.Commands.Generic
|
|||
{
|
||||
for (int i = 0; i < m_Responses.Count; ++i)
|
||||
{
|
||||
MessageEntry entry = (MessageEntry)m_Responses[i];
|
||||
MessageEntry entry = m_Responses[i];
|
||||
|
||||
if (entry.m_Message == message)
|
||||
{
|
||||
|
|
@ -84,16 +78,11 @@ namespace Server.Commands.Generic
|
|||
m_Responses.Add(new MessageEntry(message));
|
||||
}
|
||||
|
||||
public void AddResponse(Gump gump)
|
||||
{
|
||||
m_Responses.Add(gump);
|
||||
}
|
||||
|
||||
public void LogFailure(string message)
|
||||
{
|
||||
for (int i = 0; i < m_Failures.Count; ++i)
|
||||
{
|
||||
MessageEntry entry = (MessageEntry)m_Failures[i];
|
||||
MessageEntry entry = m_Failures[i];
|
||||
|
||||
if (entry.m_Message == message)
|
||||
{
|
||||
|
|
@ -113,23 +102,16 @@ namespace Server.Commands.Generic
|
|||
if (m_Responses.Count > 0)
|
||||
for (int i = 0; i < m_Responses.Count; ++i)
|
||||
{
|
||||
object obj = m_Responses[i];
|
||||
MessageEntry entry = m_Responses[i];
|
||||
|
||||
if (obj is MessageEntry entry)
|
||||
{
|
||||
from.SendMessage(entry.ToString());
|
||||
from.SendMessage(entry.ToString());
|
||||
|
||||
if (flushToLog)
|
||||
CommandLogging.WriteLine(from, entry.ToString());
|
||||
}
|
||||
else if (obj is Gump gump)
|
||||
{
|
||||
from.SendGump(gump);
|
||||
}
|
||||
if (flushToLog)
|
||||
CommandLogging.WriteLine(from, entry.ToString());
|
||||
}
|
||||
else
|
||||
for (int i = 0; i < m_Failures.Count; ++i)
|
||||
from.SendMessage(((MessageEntry)m_Failures[i]).ToString());
|
||||
from.SendMessage(m_Failures[i].ToString());
|
||||
|
||||
m_Responses.Clear();
|
||||
m_Failures.Clear();
|
||||
|
|
@ -148,10 +130,7 @@ namespace Server.Commands.Generic
|
|||
|
||||
public override string ToString()
|
||||
{
|
||||
if (m_Count > 1)
|
||||
return $"{m_Message} ({m_Count})";
|
||||
|
||||
return m_Message;
|
||||
return m_Count > 1 ? $"{m_Message} ({m_Count})" : m_Message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server.Accounting;
|
||||
using Server.Engines.Help;
|
||||
|
|
@ -91,7 +90,7 @@ namespace Server.Commands.Generic
|
|||
ListOptimized = true;
|
||||
}
|
||||
|
||||
public override void ExecuteList(CommandEventArgs e, ArrayList list)
|
||||
public override void ExecuteList(CommandEventArgs e, List<object> list)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -184,7 +183,7 @@ namespace Server.Commands.Generic
|
|||
ListOptimized = true;
|
||||
}
|
||||
|
||||
public override void ExecuteList(CommandEventArgs e, ArrayList list)
|
||||
public override void ExecuteList(CommandEventArgs e, List<object> list)
|
||||
{
|
||||
if (list.Count == 1)
|
||||
AddResponse("There is one matching object.");
|
||||
|
|
@ -205,13 +204,8 @@ namespace Server.Commands.Generic
|
|||
Description = "Opens the web browser of a targeted player to a specified url.";
|
||||
}
|
||||
|
||||
public static void OpenBrowser_Callback(Mobile from, bool okay, object state)
|
||||
public static void OpenBrowser_Callback(Mobile from, bool okay, Mobile gm, string url, bool echo)
|
||||
{
|
||||
object[] states = (object[])state;
|
||||
Mobile gm = (Mobile)states[0];
|
||||
string url = (string)states[1];
|
||||
bool echo = (bool)states[2];
|
||||
|
||||
if (okay)
|
||||
{
|
||||
if (echo)
|
||||
|
|
@ -257,7 +251,7 @@ namespace Server.Commands.Generic
|
|||
|
||||
mob.SendGump(new WarningGump(1060637, 30720,
|
||||
$"A game master is requesting to open your web browser to the following URL:<br>{url}", 0xFFC000,
|
||||
320, 240, OpenBrowser_Callback, new object[] { from, url, echo }));
|
||||
320, 240, okay => OpenBrowser_Callback(mob, okay, from, url, echo)));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -276,7 +270,7 @@ namespace Server.Commands.Generic
|
|||
Execute(e, obj, true);
|
||||
}
|
||||
|
||||
public override void ExecuteList(CommandEventArgs e, ArrayList list)
|
||||
public override void ExecuteList(CommandEventArgs e, List<object> list)
|
||||
{
|
||||
for (int i = 0; i < list.Count; ++i)
|
||||
Execute(e, list[i], false);
|
||||
|
|
@ -406,7 +400,7 @@ namespace Server.Commands.Generic
|
|||
"Adds an item by name to the backpack of a targeted player or npc, or a targeted container. Optional constructor parameters. Optional set property list.";
|
||||
}
|
||||
|
||||
public override void ExecuteList(CommandEventArgs e, ArrayList list)
|
||||
public override void ExecuteList(CommandEventArgs e, List<object> list)
|
||||
{
|
||||
if (e.Arguments.Length == 0)
|
||||
return;
|
||||
|
|
@ -763,12 +757,8 @@ namespace Server.Commands.Generic
|
|||
Description = "Deletes a targeted item or mobile. Does not delete players.";
|
||||
}
|
||||
|
||||
private void OnConfirmCallback(Mobile from, bool okay, object state)
|
||||
private void OnConfirmCallback(Mobile from, bool okay, CommandEventArgs e, List<object> list)
|
||||
{
|
||||
object[] states = (object[])state;
|
||||
CommandEventArgs e = (CommandEventArgs)states[0];
|
||||
ArrayList list = (ArrayList)states[1];
|
||||
|
||||
bool flushToLog = false;
|
||||
|
||||
if (okay)
|
||||
|
|
@ -798,13 +788,14 @@ namespace Server.Commands.Generic
|
|||
Flush(from, flushToLog);
|
||||
}
|
||||
|
||||
public override void ExecuteList(CommandEventArgs e, ArrayList list)
|
||||
public override void ExecuteList(CommandEventArgs e, List<object> list)
|
||||
{
|
||||
if (list.Count > 1)
|
||||
{
|
||||
e.Mobile.SendGump(new WarningGump(1060637, 30720,
|
||||
Mobile from = e.Mobile;
|
||||
from.SendGump(new WarningGump(1060637, 30720,
|
||||
$"You are about to delete {list.Count} objects. This cannot be undone without a full server revert.<br><br>Continue?",
|
||||
0xFFC000, 420, 280, OnConfirmCallback, new object[] { e, list }));
|
||||
0xFFC000, 420, 280, okay => OnConfirmCallback(from, okay, e, list)));
|
||||
AddResponse("Awaiting confirmation...");
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
|
|
@ -103,8 +102,7 @@ namespace Server.Commands.Generic
|
|||
|
||||
protected override void OnTarget(Mobile from, object obj)
|
||||
{
|
||||
HouseFoundation house;
|
||||
DesignInsertResult result = ProcessInsert(obj as Item, m_StaticsOnly, out house);
|
||||
DesignInsertResult result = ProcessInsert(obj as Item, m_StaticsOnly, out HouseFoundation house);
|
||||
|
||||
switch (result)
|
||||
{
|
||||
|
|
@ -142,21 +140,17 @@ namespace Server.Commands.Generic
|
|||
|
||||
#region Area targeting mode
|
||||
|
||||
public override void ExecuteList(CommandEventArgs e, ArrayList list)
|
||||
public override void ExecuteList(CommandEventArgs e, List<object> list)
|
||||
{
|
||||
e.Mobile.SendGump(new WarningGump(1060637, 30720,
|
||||
Mobile from = e.Mobile;
|
||||
from.SendGump(new WarningGump(1060637, 30720,
|
||||
$"You are about to insert {list.Count} objects. This cannot be undone without a full server revert.<br><br>Continue?",
|
||||
0xFFC000, 420, 280, OnConfirmCallback, new object[] { e, list, e.Length < 1 || !e.GetBoolean(0) }));
|
||||
0xFFC000, 420, 280, okay => OnConfirmCallback(from, okay, list, e.Length < 1 || !e.GetBoolean(0))));
|
||||
AddResponse("Awaiting confirmation...");
|
||||
}
|
||||
|
||||
private void OnConfirmCallback(Mobile from, bool okay, object state)
|
||||
private void OnConfirmCallback(Mobile from, bool okay, List<object> list, bool staticsOnly)
|
||||
{
|
||||
object[] states = (object[])state;
|
||||
CommandEventArgs e = (CommandEventArgs)states[0];
|
||||
ArrayList list = (ArrayList)states[1];
|
||||
bool staticsOnly = (bool)states[2];
|
||||
|
||||
bool flushToLog = false;
|
||||
|
||||
if (okay)
|
||||
|
|
@ -166,8 +160,7 @@ namespace Server.Commands.Generic
|
|||
|
||||
for (int i = 0; i < list.Count; ++i)
|
||||
{
|
||||
HouseFoundation house;
|
||||
DesignInsertResult result = ProcessInsert(list[i] as Item, staticsOnly, out house);
|
||||
DesignInsertResult result = ProcessInsert(list[i] as Item, staticsOnly, out HouseFoundation house);
|
||||
|
||||
switch (result)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Server.Gumps;
|
||||
|
|
@ -20,13 +19,12 @@ namespace Server.Commands.Generic
|
|||
ListOptimized = true;
|
||||
}
|
||||
|
||||
public override void ExecuteList(CommandEventArgs e, ArrayList list)
|
||||
public override void ExecuteList(CommandEventArgs e, List<object> list)
|
||||
{
|
||||
if (list.Count > 0)
|
||||
{
|
||||
List<string> columns = new List<string>();
|
||||
List<string> columns = new List<string> { "Object" };
|
||||
|
||||
columns.Add("Object");
|
||||
|
||||
if (e.Length > 0)
|
||||
{
|
||||
|
|
@ -55,12 +53,12 @@ namespace Server.Commands.Generic
|
|||
private string[] m_Columns;
|
||||
private Mobile m_From;
|
||||
|
||||
private ArrayList m_List;
|
||||
private List<object> m_List;
|
||||
private int m_Page;
|
||||
|
||||
private object m_Select;
|
||||
|
||||
public InterfaceGump(Mobile from, string[] columns, ArrayList list, int page, object select) : base(30, 30)
|
||||
public InterfaceGump(Mobile from, string[] columns, List<object> list, int page, object select) : base(30, 30)
|
||||
{
|
||||
m_From = from;
|
||||
|
||||
|
|
@ -222,7 +220,7 @@ namespace Server.Commands.Generic
|
|||
|
||||
if (!BaseCommand.IsAccessible(m_From, obj))
|
||||
{
|
||||
m_From.SendMessage("That is not accessible.");
|
||||
m_From.SendLocalizedMessage(500447); // That is not accessible.
|
||||
m_From.SendGump(new InterfaceGump(m_From, m_Columns, m_List, m_Page, m_Select));
|
||||
break;
|
||||
}
|
||||
|
|
@ -248,10 +246,10 @@ namespace Server.Commands.Generic
|
|||
|
||||
private Item m_Item;
|
||||
|
||||
private ArrayList m_List;
|
||||
private List<object> m_List;
|
||||
private int m_Page;
|
||||
|
||||
public InterfaceItemGump(Mobile from, string[] columns, ArrayList list, int page, Item item) : base(30, 30)
|
||||
public InterfaceItemGump(Mobile from, string[] columns, List<object> list, int page, Item item) : base(30, 30)
|
||||
{
|
||||
m_From = from;
|
||||
|
||||
|
|
@ -381,12 +379,12 @@ namespace Server.Commands.Generic
|
|||
private string[] m_Columns;
|
||||
private Mobile m_From;
|
||||
|
||||
private ArrayList m_List;
|
||||
private List<object> m_List;
|
||||
|
||||
private Mobile m_Mobile;
|
||||
private int m_Page;
|
||||
|
||||
public InterfaceMobileGump(Mobile from, string[] columns, ArrayList list, int page, Mobile mob)
|
||||
public InterfaceMobileGump(Mobile from, string[] columns, List<object> list, int page, Mobile mob)
|
||||
: base(30, 30)
|
||||
{
|
||||
m_From = from;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Commands.Generic
|
||||
|
|
@ -48,7 +47,7 @@ namespace Server.Commands.Generic
|
|||
return true;
|
||||
}
|
||||
|
||||
public void Filter(ArrayList list)
|
||||
public void Filter(List<object> list)
|
||||
{
|
||||
for (int i = 0; i < Count; ++i)
|
||||
this[i].Filter(list);
|
||||
|
|
@ -127,7 +126,7 @@ namespace Server.Commands.Generic
|
|||
return true;
|
||||
}
|
||||
|
||||
public virtual void Filter(ArrayList list)
|
||||
public virtual void Filter(List<object> list)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,8 +109,8 @@ namespace Server.Commands.Generic
|
|||
}
|
||||
else
|
||||
{
|
||||
MethodInfo parseMethod = null;
|
||||
object[] parseArgs = null;
|
||||
MethodInfo parseMethod;
|
||||
object[] parseArgs;
|
||||
|
||||
MethodInfo parseNumber = Type.GetMethod(
|
||||
"Parse",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
|
|
@ -8,7 +7,7 @@ namespace Server.Commands.Generic
|
|||
{
|
||||
public static class DistinctCompiler
|
||||
{
|
||||
public static IComparer Compile(AssemblyEmitter assembly, Type objectType, Property[] props)
|
||||
public static IComparer<T> Compile<T>(AssemblyEmitter assembly, Type objectType, Property[] props)
|
||||
{
|
||||
TypeBuilder typeBuilder = assembly.DefineType(
|
||||
"__distinct",
|
||||
|
|
@ -29,7 +28,8 @@ namespace Server.Commands.Generic
|
|||
|
||||
// : base()
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes));
|
||||
il.Emit(OpCodes.Call, typeof(T).GetConstructor(Type.EmptyTypes) ??
|
||||
throw new Exception($"Could not find empty constructor for type {typeof(T).FullName}"));
|
||||
|
||||
// return;
|
||||
il.Emit(OpCodes.Ret);
|
||||
|
|
@ -39,7 +39,7 @@ namespace Server.Commands.Generic
|
|||
|
||||
#region IComparer
|
||||
|
||||
typeBuilder.AddInterfaceImplementation(typeof(IComparer));
|
||||
typeBuilder.AddInterfaceImplementation(typeof(IComparer<T>));
|
||||
|
||||
MethodBuilder compareMethod;
|
||||
|
||||
|
|
@ -52,7 +52,7 @@ namespace Server.Commands.Generic
|
|||
/* name */ "Compare",
|
||||
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
|
||||
/* return */ typeof(int),
|
||||
/* params */ new[] { typeof(object), typeof(object) });
|
||||
/* params */ new[] { typeof(T), typeof(T) });
|
||||
|
||||
LocalBuilder a = emitter.CreateLocal(objectType);
|
||||
LocalBuilder b = emitter.CreateLocal(objectType);
|
||||
|
|
@ -105,14 +105,14 @@ namespace Server.Commands.Generic
|
|||
|
||||
typeBuilder.DefineMethodOverride(
|
||||
emitter.Method,
|
||||
typeof(IComparer).GetMethod(
|
||||
typeof(IComparer<T>).GetMethod(
|
||||
"Compare",
|
||||
new[]
|
||||
{
|
||||
typeof(object),
|
||||
typeof(object)
|
||||
typeof(T),
|
||||
typeof(T)
|
||||
}
|
||||
)
|
||||
) ?? throw new Exception($"No Compare method found for type {typeof(T).FullName}")
|
||||
);
|
||||
|
||||
compareMethod = emitter.Method;
|
||||
|
|
@ -124,7 +124,7 @@ namespace Server.Commands.Generic
|
|||
|
||||
#region IEqualityComparer
|
||||
|
||||
typeBuilder.AddInterfaceImplementation(typeof(IEqualityComparer<object>));
|
||||
typeBuilder.AddInterfaceImplementation(typeof(IEqualityComparer<T>));
|
||||
|
||||
#region Equals
|
||||
|
||||
|
|
@ -135,7 +135,7 @@ namespace Server.Commands.Generic
|
|||
/* name */ "Equals",
|
||||
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
|
||||
/* return */ typeof(bool),
|
||||
/* params */ new[] { typeof(object), typeof(object) });
|
||||
/* params */ new[] { typeof(T), typeof(T) });
|
||||
|
||||
emitter.Generator.Emit(OpCodes.Ldarg_0);
|
||||
emitter.Generator.Emit(OpCodes.Ldarg_1);
|
||||
|
|
@ -151,14 +151,14 @@ namespace Server.Commands.Generic
|
|||
|
||||
typeBuilder.DefineMethodOverride(
|
||||
emitter.Method,
|
||||
typeof(IEqualityComparer<object>).GetMethod(
|
||||
typeof(IEqualityComparer<T>).GetMethod(
|
||||
"Equals",
|
||||
new[]
|
||||
{
|
||||
typeof(object),
|
||||
typeof(object)
|
||||
typeof(T),
|
||||
typeof(T)
|
||||
}
|
||||
)
|
||||
) ?? throw new Exception($"No Equals method found for type {typeof(T).FullName}")
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -173,7 +173,7 @@ namespace Server.Commands.Generic
|
|||
/* name */ "GetHashCode",
|
||||
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
|
||||
/* return */ typeof(int),
|
||||
/* params */ new[] { typeof(object) });
|
||||
/* params */ new[] { typeof(T) });
|
||||
|
||||
LocalBuilder obj = emitter.CreateLocal(objectType);
|
||||
|
||||
|
|
@ -193,7 +193,7 @@ namespace Server.Commands.Generic
|
|||
MethodInfo getHashCode = active.GetMethod("GetHashCode", Type.EmptyTypes);
|
||||
|
||||
if (getHashCode == null)
|
||||
getHashCode = typeof(object).GetMethod("GetHashCode", Type.EmptyTypes);
|
||||
getHashCode = typeof(T).GetMethod("GetHashCode", Type.EmptyTypes);
|
||||
|
||||
if (active != typeof(int))
|
||||
{
|
||||
|
|
@ -237,13 +237,13 @@ namespace Server.Commands.Generic
|
|||
|
||||
typeBuilder.DefineMethodOverride(
|
||||
emitter.Method,
|
||||
typeof(IEqualityComparer<object>).GetMethod(
|
||||
typeof(IEqualityComparer<T>).GetMethod(
|
||||
"GetHashCode",
|
||||
new[]
|
||||
{
|
||||
typeof(object)
|
||||
typeof(T)
|
||||
}
|
||||
)
|
||||
) ?? throw new Exception($"No GetHashCode method found for type {typeof(T).FullName}")
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -253,7 +253,7 @@ namespace Server.Commands.Generic
|
|||
|
||||
Type comparerType = typeBuilder.CreateType();
|
||||
|
||||
return (IComparer)Activator.CreateInstance(comparerType);
|
||||
return (IComparer<T>)Activator.CreateInstance(comparerType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
|
||||
|
|
@ -45,12 +45,12 @@ namespace Server.Commands.Generic
|
|||
|
||||
public static class SortCompiler
|
||||
{
|
||||
public static IComparer Compile(AssemblyEmitter assembly, Type objectType, OrderInfo[] orders)
|
||||
public static IComparer<T> Compile<T>(AssemblyEmitter assembly, Type objectType, OrderInfo[] orders)
|
||||
{
|
||||
TypeBuilder typeBuilder = assembly.DefineType(
|
||||
"__sort",
|
||||
TypeAttributes.Public,
|
||||
typeof(object)
|
||||
typeof(T)
|
||||
);
|
||||
|
||||
#region Constructor
|
||||
|
|
@ -66,7 +66,8 @@ namespace Server.Commands.Generic
|
|||
|
||||
// : base()
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes));
|
||||
il.Emit(OpCodes.Call, typeof(T).GetConstructor(Type.EmptyTypes) ??
|
||||
throw new Exception($"Could not find empty constructor for type {typeof(T).FullName}"));
|
||||
|
||||
// return;
|
||||
il.Emit(OpCodes.Ret);
|
||||
|
|
@ -76,12 +77,9 @@ namespace Server.Commands.Generic
|
|||
|
||||
#region IComparer
|
||||
|
||||
typeBuilder.AddInterfaceImplementation(typeof(IComparer));
|
||||
|
||||
MethodBuilder compareMethod;
|
||||
typeBuilder.AddInterfaceImplementation(typeof(IComparer<T>));
|
||||
|
||||
#region Compare
|
||||
|
||||
{
|
||||
MethodEmitter emitter = new MethodEmitter(typeBuilder);
|
||||
|
||||
|
|
@ -89,7 +87,7 @@ namespace Server.Commands.Generic
|
|||
/* name */ "Compare",
|
||||
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
|
||||
/* return */ typeof(int),
|
||||
/* params */ new[] { typeof(object), typeof(object) });
|
||||
/* params */ new[] { typeof(T), typeof(T) });
|
||||
|
||||
LocalBuilder a = emitter.CreateLocal(objectType);
|
||||
LocalBuilder b = emitter.CreateLocal(objectType);
|
||||
|
|
@ -145,17 +143,15 @@ namespace Server.Commands.Generic
|
|||
|
||||
typeBuilder.DefineMethodOverride(
|
||||
emitter.Method,
|
||||
typeof(IComparer).GetMethod(
|
||||
typeof(IComparer<T>).GetMethod(
|
||||
"Compare",
|
||||
new[]
|
||||
{
|
||||
typeof(object),
|
||||
typeof(object)
|
||||
typeof(T),
|
||||
typeof(T)
|
||||
}
|
||||
)
|
||||
) ?? throw new Exception($"No Compare method found for type {typeof(T).FullName}")
|
||||
);
|
||||
|
||||
compareMethod = emitter.Method;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
@ -163,8 +159,7 @@ namespace Server.Commands.Generic
|
|||
#endregion
|
||||
|
||||
Type comparerType = typeBuilder.CreateType();
|
||||
|
||||
return (IComparer)Activator.CreateInstance(comparerType);
|
||||
return (IComparer<T>)Activator.CreateInstance(comparerType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Commands.Generic
|
||||
|
|
@ -9,7 +8,7 @@ namespace Server.Commands.Generic
|
|||
public static ExtensionInfo ExtInfo =
|
||||
new ExtensionInfo(30, "Distinct", -1, delegate { return new DistinctExtension(); });
|
||||
|
||||
private IComparer m_Comparer;
|
||||
private IComparer<object> m_Comparer;
|
||||
|
||||
private List<Property> m_Properties;
|
||||
|
||||
|
|
@ -39,7 +38,7 @@ namespace Server.Commands.Generic
|
|||
if (assembly == null)
|
||||
assembly = new AssemblyEmitter("__dynamic", false);
|
||||
|
||||
m_Comparer = DistinctCompiler.Compile(assembly, baseType, m_Properties.ToArray());
|
||||
m_Comparer = DistinctCompiler.Compile<object>(assembly, baseType, m_Properties.ToArray());
|
||||
}
|
||||
|
||||
public override void Parse(Mobile from, string[] arguments, int offset, int size)
|
||||
|
|
@ -57,12 +56,12 @@ namespace Server.Commands.Generic
|
|||
}
|
||||
}
|
||||
|
||||
public override void Filter(ArrayList list)
|
||||
public override void Filter(List<object> list)
|
||||
{
|
||||
if (m_Comparer == null)
|
||||
throw new InvalidOperationException("The extension must first be optimized.");
|
||||
|
||||
ArrayList copy = new ArrayList(list);
|
||||
List<object> copy = new List<object>(list);
|
||||
|
||||
copy.Sort(m_Comparer);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Commands.Generic
|
||||
{
|
||||
|
|
@ -24,7 +24,7 @@ namespace Server.Commands.Generic
|
|||
throw new Exception("Limit cannot be less than zero.");
|
||||
}
|
||||
|
||||
public override void Filter(ArrayList list)
|
||||
public override void Filter(List<object> list)
|
||||
{
|
||||
if (list.Count > Limit)
|
||||
list.RemoveRange(Limit, list.Count - Limit);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Commands.Generic
|
||||
|
|
@ -8,7 +7,7 @@ namespace Server.Commands.Generic
|
|||
{
|
||||
public static ExtensionInfo ExtInfo = new ExtensionInfo(40, "Order", -1, () => new SortExtension());
|
||||
|
||||
private IComparer m_Comparer;
|
||||
private IComparer<object> m_Comparer;
|
||||
|
||||
private List<OrderInfo> m_Orders;
|
||||
|
||||
|
|
@ -38,7 +37,7 @@ namespace Server.Commands.Generic
|
|||
if (assembly == null)
|
||||
assembly = new AssemblyEmitter("__dynamic", false);
|
||||
|
||||
m_Comparer = SortCompiler.Compile(assembly, baseType, m_Orders.ToArray());
|
||||
m_Comparer = SortCompiler.Compile<object>(assembly, baseType, m_Orders.ToArray());
|
||||
}
|
||||
|
||||
public override void Parse(Mobile from, string[] arguments, int offset, int size)
|
||||
|
|
@ -93,7 +92,7 @@ namespace Server.Commands.Generic
|
|||
}
|
||||
}
|
||||
|
||||
public override void Filter(ArrayList list)
|
||||
public override void Filter(List<object> list)
|
||||
{
|
||||
if (m_Comparer == null)
|
||||
throw new InvalidOperationException("The extension must first be optimized.");
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Commands.Generic
|
||||
{
|
||||
|
|
@ -22,24 +22,18 @@ namespace Server.Commands.Generic
|
|||
|
||||
public override void Process(Mobile from, BaseCommand command, string[] args)
|
||||
{
|
||||
BoundingBoxPicker.Begin(from, OnTarget, new object[] { command, args });
|
||||
BoundingBoxPicker.Begin(from, (map, start, end) => OnTarget(from, map, start, end, command, args));
|
||||
}
|
||||
|
||||
public void OnTarget(Mobile from, Map map, Point3D start, Point3D end, object state)
|
||||
public void OnTarget(Mobile from, Map map, Point3D start, Point3D end, BaseCommand command, string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
object[] states = (object[])state;
|
||||
BaseCommand command = (BaseCommand)states[0];
|
||||
string[] args = (string[])states[1];
|
||||
|
||||
Rectangle2D rect = new Rectangle2D(start.X, start.Y, end.X - start.X + 1, end.Y - start.Y + 1);
|
||||
|
||||
Extensions ext = Extensions.Parse(from, ref args);
|
||||
|
||||
bool items, mobiles;
|
||||
|
||||
if (!CheckObjectTypes(from, command, ext, out items, out mobiles))
|
||||
if (!CheckObjectTypes(from, command, ext, out bool items, out bool mobiles))
|
||||
return;
|
||||
|
||||
IPooledEnumerable<IEntity> eable;
|
||||
|
|
@ -49,7 +43,9 @@ namespace Server.Commands.Generic
|
|||
else
|
||||
return;
|
||||
|
||||
ArrayList objs = new ArrayList();
|
||||
eable.Free();
|
||||
|
||||
List<object> objs = new List<object>();
|
||||
|
||||
foreach (IEntity obj in eable)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
|
|
@ -212,7 +211,7 @@ namespace Server.Commands.Generic
|
|||
|
||||
bool flushToLog = false;
|
||||
|
||||
if (obj is ArrayList list)
|
||||
if (obj is List<object> list)
|
||||
{
|
||||
if (list.Count > 20)
|
||||
CommandLogging.Enabled = false;
|
||||
|
|
@ -230,7 +229,7 @@ namespace Server.Commands.Generic
|
|||
else if (obj != null)
|
||||
{
|
||||
if (command.ListOptimized)
|
||||
command.ExecuteList(e, new ArrayList { obj });
|
||||
command.ExecuteList(e, new List<object>{ obj });
|
||||
else
|
||||
command.Execute(e, obj);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Server.Items;
|
||||
using Server.Targeting;
|
||||
|
||||
|
|
@ -23,21 +21,17 @@ namespace Server.Commands.Generic
|
|||
{
|
||||
if (command.ValidateArgs(this, new CommandEventArgs(from, command.Commands[0], GenerateArgString(args), args)))
|
||||
from.BeginTarget(-1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None,
|
||||
new TargetStateCallback(OnTarget), new object[] { command, args });
|
||||
(m, targeted) => OnTarget(m, targeted, command, args));
|
||||
}
|
||||
|
||||
public void OnTarget(Mobile from, object targeted, object state)
|
||||
public void OnTarget(Mobile from, object targeted, BaseCommand command, string[] args)
|
||||
{
|
||||
if (!BaseCommand.IsAccessible(from, targeted))
|
||||
{
|
||||
from.SendMessage("That is not accessible.");
|
||||
from.SendLocalizedMessage(500447); // That is not accessible.
|
||||
return;
|
||||
}
|
||||
|
||||
object[] states = (object[])state;
|
||||
BaseCommand command = (BaseCommand)states[0];
|
||||
string[] args = (string[])states[1];
|
||||
|
||||
if (command.ObjectTypes == ObjectTypes.Mobiles)
|
||||
return; // sanity check
|
||||
|
||||
|
|
@ -60,10 +54,15 @@ namespace Server.Commands.Generic
|
|||
return;
|
||||
}
|
||||
|
||||
List<Item> list = cont.FindItemsByType<Item>().Where(item => ext.IsValid(item)).ToList();
|
||||
List<object> list = new List<object>();
|
||||
|
||||
// TODO: Is there a way to avoid using ArrayList?
|
||||
ext.Filter(new ArrayList(list));
|
||||
foreach (Item item in cont.FindItemsByType<Item>())
|
||||
{
|
||||
if (ext.IsValid(item))
|
||||
list.Add(item);
|
||||
}
|
||||
|
||||
ext.Filter(list);
|
||||
|
||||
RunCommand(from, list, command, args);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,8 +25,7 @@ namespace Server.Commands.Generic
|
|||
if (map == null || map == Map.Internal)
|
||||
return;
|
||||
|
||||
impl.OnTarget(from, map, Point3D.Zero, new Point3D(map.Width - 1, map.Height - 1, 0),
|
||||
new object[] { command, args });
|
||||
impl.OnTarget(from, map, Point3D.Zero, new Point3D(map.Width - 1, map.Height - 1, 0), command, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Commands.Generic
|
||||
{
|
||||
|
|
@ -22,12 +22,10 @@ namespace Server.Commands.Generic
|
|||
{
|
||||
Extensions ext = Extensions.Parse(from, ref args);
|
||||
|
||||
bool items, mobiles;
|
||||
|
||||
if (!CheckObjectTypes(from, command, ext, out items, out mobiles))
|
||||
if (!CheckObjectTypes(from, command, ext, out bool items, out bool mobiles))
|
||||
return;
|
||||
|
||||
ArrayList list = new ArrayList();
|
||||
List<object> list = new List<object>();
|
||||
|
||||
if (items)
|
||||
foreach (Item item in World.Items.Values)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Commands.Generic
|
||||
|
|
@ -24,9 +24,7 @@ namespace Server.Commands.Generic
|
|||
{
|
||||
Extensions ext = Extensions.Parse(from, ref args);
|
||||
|
||||
bool items, mobiles;
|
||||
|
||||
if (!CheckObjectTypes(from, command, ext, out items, out mobiles))
|
||||
if (!CheckObjectTypes(from, command, ext, out bool _, out bool mobiles))
|
||||
return;
|
||||
|
||||
if (!mobiles) // sanity check
|
||||
|
|
@ -35,8 +33,8 @@ namespace Server.Commands.Generic
|
|||
return;
|
||||
}
|
||||
|
||||
ArrayList list = new ArrayList();
|
||||
ArrayList addresses = new ArrayList();
|
||||
List<object> list = new List<object>();
|
||||
List<IPAddress> addresses = new List<IPAddress>();
|
||||
|
||||
List<NetState> states = NetState.Instances;
|
||||
|
||||
|
|
|
|||
|
|
@ -17,20 +17,16 @@ namespace Server.Commands.Generic
|
|||
{
|
||||
if (command.ValidateArgs(this, new CommandEventArgs(from, command.Commands[0], GenerateArgString(args), args)))
|
||||
from.BeginTarget(-1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None,
|
||||
new TargetStateCallback(OnTarget), new object[] { command, args });
|
||||
(m, targeted) => OnTarget(m, targeted, command, args));
|
||||
}
|
||||
|
||||
public void OnTarget(Mobile from, object targeted, object state)
|
||||
public void OnTarget(Mobile from, object targeted, BaseCommand command, string[] args)
|
||||
{
|
||||
object[] states = (object[])state;
|
||||
BaseCommand command = (BaseCommand)states[0];
|
||||
string[] args = (string[])states[1];
|
||||
|
||||
if (!BaseCommand.IsAccessible(from, targeted))
|
||||
{
|
||||
from.SendMessage("That is not accessible.");
|
||||
from.SendLocalizedMessage(500447); // That is not accessible.
|
||||
from.BeginTarget(-1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None,
|
||||
new TargetStateCallback(OnTarget), new object[] { command, args });
|
||||
(m, t) => OnTarget(m, t, command, args));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -38,7 +34,7 @@ namespace Server.Commands.Generic
|
|||
{
|
||||
case ObjectTypes.Both:
|
||||
{
|
||||
if (!(targeted is Item) && !(targeted is Mobile))
|
||||
if (!(targeted is Item || targeted is Mobile))
|
||||
{
|
||||
from.SendMessage("This command does not work on that.");
|
||||
return;
|
||||
|
|
@ -70,8 +66,8 @@ namespace Server.Commands.Generic
|
|||
|
||||
RunCommand(from, targeted, command, args);
|
||||
|
||||
from.BeginTarget(-1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None, new TargetStateCallback(OnTarget),
|
||||
new object[] { command, args });
|
||||
from.BeginTarget(-1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None,
|
||||
(m, t) => OnTarget(m, t, command, args));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -81,7 +81,7 @@ namespace Server.Commands.Generic
|
|||
break;
|
||||
}
|
||||
|
||||
return ParseDirect(from, conditionArgs, 0, conditionArgs.Length);
|
||||
return ParseDirect(from, conditionArgs, 0, conditionArgs?.Length ?? 0);
|
||||
}
|
||||
|
||||
public static ObjectConditional ParseDirect(Mobile from, string[] args, int offset, int size)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server.Network;
|
||||
|
||||
|
|
@ -24,9 +23,7 @@ namespace Server.Commands.Generic
|
|||
{
|
||||
Extensions ext = Extensions.Parse(from, ref args);
|
||||
|
||||
bool items, mobiles;
|
||||
|
||||
if (!CheckObjectTypes(from, command, ext, out items, out mobiles))
|
||||
if (!CheckObjectTypes(from, command, ext, out bool _, out bool mobiles))
|
||||
return;
|
||||
|
||||
if (!mobiles) // sanity check
|
||||
|
|
@ -35,7 +32,7 @@ namespace Server.Commands.Generic
|
|||
return;
|
||||
}
|
||||
|
||||
ArrayList list = new ArrayList();
|
||||
List<object> list = new List<object>();
|
||||
|
||||
List<NetState> states = NetState.Instances;
|
||||
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ namespace Server.Commands.Generic
|
|||
Point3D start = new Point3D(from.X - range, from.Y - range, from.Z);
|
||||
Point3D end = new Point3D(from.X + range, from.Y + range, from.Z);
|
||||
|
||||
impl.OnTarget(from, map, start, end, new object[] { command, args });
|
||||
impl.OnTarget(from, map, start, end, command, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Commands.Generic
|
||||
{
|
||||
|
|
@ -22,14 +22,12 @@ namespace Server.Commands.Generic
|
|||
{
|
||||
Extensions ext = Extensions.Parse(from, ref args);
|
||||
|
||||
bool items, mobiles;
|
||||
|
||||
if (!CheckObjectTypes(from, command, ext, out items, out mobiles))
|
||||
if (!CheckObjectTypes(from, command, ext, out bool _, out bool mobiles))
|
||||
return;
|
||||
|
||||
Region reg = from.Region;
|
||||
|
||||
ArrayList list = new ArrayList();
|
||||
List<object> list = new List<object>();
|
||||
|
||||
if (mobiles)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ namespace Server.Commands.Generic
|
|||
{
|
||||
if (e.Length >= 2)
|
||||
{
|
||||
Serial serial = e.GetInt32(0);
|
||||
Serial serial = e.GetUInt32(0);
|
||||
|
||||
object obj = null;
|
||||
|
||||
|
|
|
|||
|
|
@ -38,21 +38,17 @@ namespace Server.Commands.Generic
|
|||
{
|
||||
if (command.ValidateArgs(this, new CommandEventArgs(from, command.Commands[0], GenerateArgString(args), args)))
|
||||
from.BeginTarget(-1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None,
|
||||
new TargetStateCallback(OnTarget), new object[] { command, args });
|
||||
(m, targeted) => OnTarget(m, targeted, command, args));
|
||||
}
|
||||
|
||||
public void OnTarget(Mobile from, object targeted, object state)
|
||||
public void OnTarget(Mobile from, object targeted, BaseCommand command, string[] args)
|
||||
{
|
||||
if (!BaseCommand.IsAccessible(from, targeted))
|
||||
{
|
||||
from.SendMessage("That is not accessible.");
|
||||
from.SendLocalizedMessage(500447); // That is not accessible.
|
||||
return;
|
||||
}
|
||||
|
||||
object[] states = (object[])state;
|
||||
BaseCommand command = (BaseCommand)states[0];
|
||||
string[] args = (string[])states[1];
|
||||
|
||||
switch (command.ObjectTypes)
|
||||
{
|
||||
case ObjectTypes.Both:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Server.Commands.Generic;
|
||||
|
|
@ -185,12 +184,10 @@ namespace Server.Commands
|
|||
}
|
||||
}
|
||||
|
||||
public static void DeleteList_Callback(Mobile from, bool okay, object state)
|
||||
public static void DeleteList_Callback(Mobile from, bool okay, List<IEntity> list)
|
||||
{
|
||||
if (okay)
|
||||
{
|
||||
List<IEntity> list = (List<IEntity>)state;
|
||||
|
||||
CommandLogging.WriteLine(from, "{0} {1} deleting {2} object{3}", from.AccessLevel,
|
||||
CommandLogging.Format(from), list.Count, list.Count == 1 ? "" : "s");
|
||||
|
||||
|
|
@ -213,11 +210,12 @@ namespace Server.Commands
|
|||
[Description("Deletes all items and mobiles in your facet. Players and their inventory will not be deleted.")]
|
||||
public static void ClearFacet_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
Map map = e.Mobile.Map;
|
||||
Mobile from = e.Mobile;
|
||||
Map map = from.Map;
|
||||
|
||||
if (map == null || map == Map.Internal)
|
||||
{
|
||||
e.Mobile.SendMessage("You may not run that command here.");
|
||||
from.SendMessage("You may not run that command here.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -233,17 +231,17 @@ namespace Server.Commands
|
|||
|
||||
if (list.Count > 0)
|
||||
{
|
||||
CommandLogging.WriteLine(e.Mobile, "{0} {1} starting facet clear of {2} ({3} object{4})",
|
||||
e.Mobile.AccessLevel, CommandLogging.Format(e.Mobile), map, list.Count, list.Count == 1 ? "" : "s");
|
||||
CommandLogging.WriteLine(from, "{0} {1} starting facet clear of {2} ({3} object{4})",
|
||||
from.AccessLevel, CommandLogging.Format(from), map, list.Count, list.Count == 1 ? "" : "s");
|
||||
|
||||
e.Mobile.SendGump(
|
||||
from.SendGump(
|
||||
new WarningGump(1060635, 30720,
|
||||
$"You are about to delete {list.Count} object{(list.Count == 1 ? "" : "s")} from this facet. Do you really wish to continue?",
|
||||
0xFFC000, 360, 260, DeleteList_Callback, list));
|
||||
0xFFC000, 360, 260, okay => DeleteList_Callback(from, okay, list)));
|
||||
}
|
||||
else
|
||||
{
|
||||
e.Mobile.SendMessage("There were no objects found to delete.");
|
||||
from.SendMessage("There were no objects found to delete.");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -285,7 +283,7 @@ namespace Server.Commands
|
|||
}
|
||||
else if (obj is Mobile master && master.Player)
|
||||
{
|
||||
ArrayList pets = new ArrayList();
|
||||
List<BaseCreature> pets = new List<BaseCreature>();
|
||||
|
||||
foreach (Mobile m in World.Mobiles.Values)
|
||||
if (m is BaseCreature bc)
|
||||
|
|
@ -443,7 +441,7 @@ namespace Server.Commands
|
|||
{
|
||||
try
|
||||
{
|
||||
int ser = e.GetInt32(0);
|
||||
uint ser = e.GetUInt32(0);
|
||||
|
||||
IEntity ent = World.FindEntity(ser);
|
||||
|
||||
|
|
@ -567,6 +565,7 @@ namespace Server.Commands
|
|||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
from.SendMessage("Region name not found");
|
||||
|
|
@ -760,7 +759,7 @@ namespace Server.Commands
|
|||
{
|
||||
if (!BaseCommand.IsAccessible(from, targeted))
|
||||
{
|
||||
from.SendMessage("That is not accessible.");
|
||||
from.SendLocalizedMessage(500447); // That is not accessible.
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -243,7 +243,6 @@ namespace Server.Commands
|
|||
m_List = list;
|
||||
}
|
||||
|
||||
|
||||
AddNewPage();
|
||||
|
||||
if (m_Page > 0)
|
||||
|
|
@ -269,7 +268,6 @@ namespace Server.Commands
|
|||
if ((int)c.AccessLevel != last)
|
||||
{
|
||||
AddNewLine();
|
||||
|
||||
AddEntryHtml(20 + OffsetSize + 160, Color(c.AccessLevel.ToString(), 0xFF0000));
|
||||
AddEntryHeader(20);
|
||||
line++;
|
||||
|
|
@ -278,9 +276,7 @@ namespace Server.Commands
|
|||
last = (int)c.AccessLevel;
|
||||
|
||||
AddNewLine();
|
||||
|
||||
AddEntryHtml(20 + OffsetSize + 160, c.Name);
|
||||
|
||||
AddEntryButton(20, ArrowRightID1, ArrowRightID2, 3 + i, ArrowRightWidth, ArrowRightHeight);
|
||||
}
|
||||
}
|
||||
|
|
@ -295,7 +291,7 @@ namespace Server.Commands
|
|||
{
|
||||
case 0:
|
||||
{
|
||||
m.CloseGump(typeof(CommandInfoGump));
|
||||
m.CloseGump<CommandInfoGump>();
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ namespace Server.Commands
|
|||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -87,6 +88,7 @@ namespace Server.Commands
|
|||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Server.Diagnostics;
|
||||
|
||||
namespace Server.Commands
|
||||
|
|
@ -52,6 +54,7 @@ namespace Server.Commands
|
|||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -80,6 +83,7 @@ namespace Server.Commands
|
|||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -89,37 +93,32 @@ namespace Server.Commands
|
|||
{
|
||||
using (StreamWriter op = new StreamWriter("objects.log"))
|
||||
{
|
||||
Hashtable table = new Hashtable();
|
||||
Dictionary<Type, int> table = new Dictionary<Type, int>();
|
||||
|
||||
foreach (Item item in World.Items.Values)
|
||||
{
|
||||
Type type = item.GetType();
|
||||
|
||||
object o = table[type];
|
||||
|
||||
if (o == null)
|
||||
table[type] = 1;
|
||||
if (table.ContainsKey(type))
|
||||
table[type] = 1 + table[type];
|
||||
else
|
||||
table[type] = 1 + (int)o;
|
||||
table[type] = 1;
|
||||
}
|
||||
|
||||
ArrayList items = new ArrayList(table);
|
||||
|
||||
List<KeyValuePair<Type, int>> items = table.ToList();
|
||||
table.Clear();
|
||||
|
||||
foreach (Mobile m in World.Mobiles.Values)
|
||||
{
|
||||
Type type = m.GetType();
|
||||
|
||||
object o = table[type];
|
||||
|
||||
if (o == null)
|
||||
table[type] = 1;
|
||||
if (table.ContainsKey(type))
|
||||
table[type] = 1 + table[type];
|
||||
else
|
||||
table[type] = 1 + (int)o;
|
||||
table[type] = 1;
|
||||
}
|
||||
|
||||
ArrayList mobiles = new ArrayList(table);
|
||||
List<KeyValuePair<Type, int>> mobiles = table.ToList();
|
||||
|
||||
items.Sort(new CountSorter());
|
||||
mobiles.Sort(new CountSorter());
|
||||
|
|
@ -130,16 +129,16 @@ namespace Server.Commands
|
|||
|
||||
op.WriteLine("# Items:");
|
||||
|
||||
foreach (DictionaryEntry de in items)
|
||||
op.WriteLine("{0}\t{1:F2}%\t{2}", de.Value, 100 * (int)de.Value / (double)World.Items.Count, de.Key);
|
||||
items.ForEach(kvp =>
|
||||
op.WriteLine("{0}\t{1:F2}%\t{2}", kvp.Value, 100.0 * kvp.Value / World.Items.Count, kvp.Key));
|
||||
|
||||
op.WriteLine();
|
||||
op.WriteLine();
|
||||
|
||||
op.WriteLine("#Mobiles:");
|
||||
|
||||
foreach (DictionaryEntry de in mobiles)
|
||||
op.WriteLine("{0}\t{1:F2}%\t{2}", de.Value, 100 * (int)de.Value / (double)World.Mobiles.Count, de.Key);
|
||||
mobiles.ForEach(kvp =>
|
||||
op.WriteLine("{0}\t{1:F2}%\t{2}", kvp.Value, 100.0 * kvp.Value / World.Mobiles.Count, kvp.Key));
|
||||
}
|
||||
|
||||
e.Mobile.SendMessage("Object table has been generated. See the file : <runuo root>/objects.log");
|
||||
|
|
@ -149,7 +148,7 @@ namespace Server.Commands
|
|||
[Description("Generates a log file describing all items using expanded memory.")]
|
||||
public static void TraceExpanded_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
Hashtable typeTable = new Hashtable();
|
||||
Dictionary<Type, int[]> typeTable = new Dictionary<Type, int[]>();
|
||||
|
||||
foreach (Item item in World.Items.Values)
|
||||
{
|
||||
|
|
@ -162,8 +161,10 @@ namespace Server.Commands
|
|||
|
||||
do
|
||||
{
|
||||
if (!(typeTable[itemType] is int[] countTable))
|
||||
typeTable[itemType] = countTable = new int[9];
|
||||
typeTable.TryGetValue(itemType, out int[] countTable);
|
||||
|
||||
if (countTable == null)
|
||||
countTable = new int[9];
|
||||
|
||||
if ((flags & ExpandFlag.Name) != 0)
|
||||
++countTable[0];
|
||||
|
|
@ -213,16 +214,15 @@ namespace Server.Commands
|
|||
"Spawner"
|
||||
};
|
||||
|
||||
ArrayList list = new ArrayList(typeTable);
|
||||
List<KeyValuePair<Type, int[]>> list = typeTable.ToList();
|
||||
|
||||
list.Sort(new CountSorter());
|
||||
list.Sort(new CountsSorter());
|
||||
|
||||
foreach (DictionaryEntry de in list)
|
||||
foreach (KeyValuePair<Type, int[]> kvp in list)
|
||||
{
|
||||
Type itemType = de.Key as Type;
|
||||
int[] countTable = de.Value as int[];
|
||||
int[] countTable = kvp.Value;
|
||||
|
||||
op.WriteLine("# {0}", itemType.FullName);
|
||||
op.WriteLine("# {0}", kvp.Key.FullName);
|
||||
|
||||
for (int i = 0; i < countTable.Length; ++i)
|
||||
if (countTable[i] > 0)
|
||||
|
|
@ -234,6 +234,7 @@ namespace Server.Commands
|
|||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -242,7 +243,7 @@ namespace Server.Commands
|
|||
public static void TraceInternal_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
int totalCount = 0;
|
||||
Hashtable table = new Hashtable();
|
||||
Dictionary<Type, int[]> table = new Dictionary<Type, int[]>();
|
||||
|
||||
foreach (Item item in World.Items.Values)
|
||||
{
|
||||
|
|
@ -252,7 +253,7 @@ namespace Server.Commands
|
|||
++totalCount;
|
||||
|
||||
Type type = item.GetType();
|
||||
int[] parms = (int[])table[type];
|
||||
int[] parms = table[type];
|
||||
|
||||
if (parms == null)
|
||||
table[type] = parms = new[] { 0, 0 };
|
||||
|
|
@ -269,12 +270,11 @@ namespace Server.Commands
|
|||
op.WriteLine();
|
||||
op.WriteLine("Type\t\tCount\t\tAmount\t\tAvg. Amount");
|
||||
|
||||
foreach (DictionaryEntry de in table)
|
||||
foreach (KeyValuePair<Type, int[]> de in table)
|
||||
{
|
||||
Type type = (Type)de.Key;
|
||||
int[] parms = (int[])de.Value;
|
||||
int[] parms = de.Value;
|
||||
|
||||
op.WriteLine("{0}\t\t{1}\t\t{2}\t\t{3:F2}", type.Name, parms[0], parms[1], (double)parms[1] / parms[0]);
|
||||
op.WriteLine("{0}\t\t{1}\t\t{2}\t\t{3:F2}", de.Key.Name, parms[0], parms[1], (double)parms[1] / parms[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -291,7 +291,7 @@ namespace Server.Commands
|
|||
{
|
||||
try
|
||||
{
|
||||
ArrayList types = new ArrayList();
|
||||
List<Type> types = new List<Type>();
|
||||
|
||||
using (BinaryReader bin = new BinaryReader(new FileStream(string.Format("Saves/{0}/{0}.tdb", type),
|
||||
FileMode.Open, FileAccess.Read, FileShare.Read)))
|
||||
|
|
@ -304,7 +304,7 @@ namespace Server.Commands
|
|||
|
||||
long total = 0;
|
||||
|
||||
Hashtable table = new Hashtable();
|
||||
Dictionary<Type, int> table = new Dictionary<Type, int>();
|
||||
|
||||
using (BinaryReader bin = new BinaryReader(new FileStream(string.Format("Saves/{0}/{0}.idx", type),
|
||||
FileMode.Open, FileAccess.Read, FileShare.Read)))
|
||||
|
|
@ -317,16 +317,14 @@ namespace Server.Commands
|
|||
int serial = bin.ReadInt32();
|
||||
long pos = bin.ReadInt64();
|
||||
int length = bin.ReadInt32();
|
||||
Type objType = (Type)types[typeID];
|
||||
Type objType = types[typeID];
|
||||
|
||||
while (objType != null && objType != typeof(object))
|
||||
while (objType != typeof(object))
|
||||
{
|
||||
object obj = table[objType];
|
||||
|
||||
if (obj == null)
|
||||
table[objType] = length;
|
||||
if (table.ContainsKey(objType))
|
||||
table[objType] = length + table[objType];
|
||||
else
|
||||
table[objType] = length + (int)obj;
|
||||
table[objType] = length;
|
||||
|
||||
objType = objType.BaseType;
|
||||
total += length;
|
||||
|
|
@ -334,7 +332,7 @@ namespace Server.Commands
|
|||
}
|
||||
}
|
||||
|
||||
ArrayList list = new ArrayList(table);
|
||||
List<KeyValuePair<Type, int>> list = table.ToList();
|
||||
|
||||
list.Sort(new CountSorter());
|
||||
|
||||
|
|
@ -345,55 +343,46 @@ namespace Server.Commands
|
|||
op.WriteLine();
|
||||
op.WriteLine();
|
||||
|
||||
foreach (DictionaryEntry de in list)
|
||||
op.WriteLine("{0}\t{1:F2}%\t{2}", de.Value, 100 * (int)de.Value / (double)total, de.Key);
|
||||
list.ForEach(kvp =>
|
||||
op.WriteLine("{0}\t{1:F2}%\t{2}", kvp.Value, 100.0 * kvp.Value / total, kvp.Key));
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
private class CountSorter : IComparer
|
||||
private class CountSorter : IComparer<KeyValuePair<Type, int>>
|
||||
{
|
||||
public int Compare(object x, object y)
|
||||
public int Compare(KeyValuePair<Type, int> x, KeyValuePair<Type, int> y)
|
||||
{
|
||||
DictionaryEntry a = (DictionaryEntry)x;
|
||||
DictionaryEntry b = (DictionaryEntry)y;
|
||||
|
||||
int aCount = GetCount(a.Value);
|
||||
int bCount = GetCount(b.Value);
|
||||
int aCount = x.Value;
|
||||
int bCount = y.Value;
|
||||
|
||||
int v = -aCount.CompareTo(bCount);
|
||||
|
||||
if (v == 0)
|
||||
{
|
||||
Type aType = (Type)a.Key;
|
||||
Type bType = (Type)b.Key;
|
||||
if (v != 0)
|
||||
return v;
|
||||
|
||||
v = aType.FullName.CompareTo(bType.FullName);
|
||||
}
|
||||
|
||||
return v;
|
||||
return x.Key.FullName.CompareTo(y.Key.FullName);
|
||||
}
|
||||
}
|
||||
|
||||
private int GetCount(object obj)
|
||||
private class CountsSorter : IComparer<KeyValuePair<Type, int[]>>
|
||||
{
|
||||
public int Compare(KeyValuePair<Type, int[]> x, KeyValuePair<Type, int[]> y)
|
||||
{
|
||||
if (obj is int intObj)
|
||||
return intObj;
|
||||
int aCount = x.Value.Aggregate(0, (t, val) => t + val);
|
||||
int bCount = y.Value.Aggregate(0, (t, val) => t + val);
|
||||
|
||||
if (obj is int[] list)
|
||||
{
|
||||
int total = 0;
|
||||
int v = -aCount.CompareTo(bCount);
|
||||
|
||||
for (int i = 0; i < list.Length; ++i)
|
||||
total += list[i];
|
||||
if (v != 0)
|
||||
return v;
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return x.Key.FullName.CompareTo(y.Key.FullName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ using CPA = Server.CommandPropertyAttribute;
|
|||
|
||||
namespace Server.Commands
|
||||
{
|
||||
[Flags]
|
||||
public enum PropertyAccess
|
||||
{
|
||||
Read = 0x01,
|
||||
|
|
@ -54,12 +55,12 @@ namespace Server.Commands
|
|||
{
|
||||
if (e.Length == 1)
|
||||
{
|
||||
IEntity ent = World.FindEntity(e.GetInt32(0));
|
||||
IEntity ent = World.FindEntity(e.GetUInt32(0));
|
||||
|
||||
if (ent == null)
|
||||
e.Mobile.SendMessage("No object with that serial was found.");
|
||||
else if (!BaseCommand.IsAccessible(e.Mobile, ent))
|
||||
e.Mobile.SendMessage("That is not accessible.");
|
||||
e.Mobile.SendLocalizedMessage(500447); // That is not accessible.
|
||||
else
|
||||
e.Mobile.SendGump(new PropertiesGump(e.Mobile, ent));
|
||||
}
|
||||
|
|
@ -394,7 +395,7 @@ namespace Server.Commands
|
|||
|
||||
m_ParseParams[0] = value;
|
||||
|
||||
return method.Invoke(o, m_ParseParams);
|
||||
return method?.Invoke(o, m_ParseParams);
|
||||
}
|
||||
|
||||
private static bool IsNumeric(Type t)
|
||||
|
|
@ -465,7 +466,7 @@ namespace Server.Commands
|
|||
}
|
||||
|
||||
if (isSerial) // mutate back
|
||||
toSet = (Serial)(int)toSet;
|
||||
toSet = (Serial)(toSet ?? Serial.MinusOne);
|
||||
|
||||
constructed = toSet;
|
||||
return null;
|
||||
|
|
@ -549,7 +550,7 @@ namespace Server.Commands
|
|||
protected override void OnTarget(Mobile from, object o)
|
||||
{
|
||||
if (!BaseCommand.IsAccessible(from, o))
|
||||
from.SendMessage("That is not accessible.");
|
||||
from.SendLocalizedMessage(500447); // That is not accessible.
|
||||
else
|
||||
from.SendGump(new PropertiesGump(from, o));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,8 +22,7 @@ namespace Server.Commands
|
|||
}
|
||||
else
|
||||
{
|
||||
SkillName skill;
|
||||
if (Enum.TryParse(arg.GetString(0), true, out skill))
|
||||
if (Enum.TryParse(arg.GetString(0), true, out SkillName skill))
|
||||
arg.Mobile.Target = new SkillTarget(skill, arg.GetDouble(1));
|
||||
else
|
||||
arg.Mobile.SendLocalizedMessage(1005631); // You have specified an invalid skill to set.
|
||||
|
|
@ -50,8 +49,7 @@ namespace Server.Commands
|
|||
}
|
||||
else
|
||||
{
|
||||
SkillName skill;
|
||||
if (Enum.TryParse(arg.GetString(0), true, out skill))
|
||||
if (Enum.TryParse(arg.GetString(0), true, out SkillName skill))
|
||||
arg.Mobile.Target = new SkillTarget(skill);
|
||||
else
|
||||
arg.Mobile.SendMessage("You have specified an invalid skill to get.");
|
||||
|
|
|
|||
|
|
@ -46,21 +46,25 @@ namespace Server
|
|||
CommandSystem.Register("UnfreezeWorld", AccessLevel.Administrator, UnfreezeWorld_OnCommand);
|
||||
}
|
||||
|
||||
public delegate void FreezeCallback( Mobile from, bool okay, StateInfo si );
|
||||
|
||||
[Usage("Freeze")]
|
||||
[Description("Makes a targeted area of dynamic items static.")]
|
||||
public static void Freeze_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
BoundingBoxPicker.Begin(e.Mobile, FreezeBox_Callback, null);
|
||||
Mobile from = e.Mobile;
|
||||
BoundingBoxPicker.Begin(from, (map, start, end) => FreezeBox_Callback(from, map, start, end));
|
||||
}
|
||||
|
||||
[Usage("FreezeMap")]
|
||||
[Description("Makes every dynamic item in your map static.")]
|
||||
public static void FreezeMap_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
Map map = e.Mobile.Map;
|
||||
Mobile from = e.Mobile;
|
||||
Map map = from.Map;
|
||||
|
||||
if (map != null && map != Map.Internal)
|
||||
SendWarning(e.Mobile, "You are about to freeze <u>all items in {0}</u>.", BaseFreezeWarning, map, NullP3D,
|
||||
SendWarning(from, "You are about to freeze <u>all items in {0}</u>.", BaseFreezeWarning, map, NullP3D,
|
||||
NullP3D, FreezeWarning_Callback);
|
||||
}
|
||||
|
||||
|
|
@ -73,31 +77,29 @@ namespace Server
|
|||
}
|
||||
|
||||
public static void SendWarning(Mobile m, string header, string baseWarning, Map map, Point3D start, Point3D end,
|
||||
WarningGumpCallback callback)
|
||||
FreezeCallback callback)
|
||||
{
|
||||
m.SendGump(new WarningGump(1060635, 30720, string.Format(baseWarning, string.Format(header, map)), 0xFFC000, 420,
|
||||
400, callback, new StateInfo(map, start, end)));
|
||||
400, okay => callback(m, okay, new StateInfo(map, start, end))));
|
||||
}
|
||||
|
||||
private static void FreezeBox_Callback(Mobile from, Map map, Point3D start, Point3D end, object state)
|
||||
private static void FreezeBox_Callback(Mobile from, Map map, Point3D start, Point3D end)
|
||||
{
|
||||
SendWarning(from, "You are about to freeze a section of items.", BaseFreezeWarning, map, start, end,
|
||||
FreezeWarning_Callback);
|
||||
}
|
||||
|
||||
private static void FreezeWarning_Callback(Mobile from, bool okay, object state)
|
||||
private static void FreezeWarning_Callback(Mobile from, bool okay, StateInfo si)
|
||||
{
|
||||
if (!okay)
|
||||
return;
|
||||
|
||||
StateInfo si = (StateInfo)state;
|
||||
|
||||
Freeze(from, si.m_Map, si.m_Start, si.m_End);
|
||||
}
|
||||
|
||||
public static void Freeze(Mobile from, Map targetMap, Point3D start3d, Point3D end3d)
|
||||
{
|
||||
Hashtable mapTable = new Hashtable();
|
||||
Dictionary<Map, Dictionary<Point2D, DeltaState>> mapTable = new Dictionary<Map, Dictionary<Point2D, DeltaState>>();
|
||||
|
||||
if (start3d == NullP3D && end3d == NullP3D)
|
||||
{
|
||||
|
|
@ -123,14 +125,14 @@ namespace Server
|
|||
if (itemMap == null || itemMap == Map.Internal)
|
||||
continue;
|
||||
|
||||
Hashtable table = (Hashtable)mapTable[itemMap];
|
||||
Dictionary<Point2D, DeltaState> table = mapTable[itemMap];
|
||||
|
||||
if (table == null)
|
||||
mapTable[itemMap] = table = new Hashtable();
|
||||
mapTable[itemMap] = table = new Dictionary<Point2D, DeltaState>();
|
||||
|
||||
Point2D p = new Point2D(item.X >> 3, item.Y >> 3);
|
||||
|
||||
DeltaState state = (DeltaState)table[p];
|
||||
DeltaState state = table[p];
|
||||
|
||||
if (state == null)
|
||||
table[p] = state = new DeltaState(p);
|
||||
|
|
@ -157,14 +159,14 @@ namespace Server
|
|||
if (itemMap == null || itemMap == Map.Internal)
|
||||
continue;
|
||||
|
||||
Hashtable table = (Hashtable)mapTable[itemMap];
|
||||
Dictionary<Point2D, DeltaState> table = mapTable[itemMap];
|
||||
|
||||
if (table == null)
|
||||
mapTable[itemMap] = table = new Hashtable();
|
||||
mapTable[itemMap] = table = new Dictionary<Point2D, DeltaState>();
|
||||
|
||||
Point2D p = new Point2D(item.X >> 3, item.Y >> 3);
|
||||
|
||||
DeltaState state = (DeltaState)table[p];
|
||||
DeltaState state = table[p];
|
||||
|
||||
if (state == null)
|
||||
table[p] = state = new DeltaState(p);
|
||||
|
|
@ -179,7 +181,7 @@ namespace Server
|
|||
{
|
||||
from.SendGump(new NoticeGump(1060637, 30720,
|
||||
"No freezable items were found. Only the following item types are frozen:<br> - Static<br> - BaseFloor<br> - BaseWall",
|
||||
0xFFC000, 320, 240, null, null));
|
||||
0xFFC000, 320, 240));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -187,10 +189,10 @@ namespace Server
|
|||
|
||||
int totalFrozen = 0;
|
||||
|
||||
foreach (DictionaryEntry de in mapTable)
|
||||
foreach (KeyValuePair<Map, Dictionary<Point2D, DeltaState>> de in mapTable)
|
||||
{
|
||||
Map map = (Map)de.Key;
|
||||
Hashtable table = (Hashtable)de.Value;
|
||||
Map map = de.Key;
|
||||
Dictionary<Point2D, DeltaState> table = de.Value;
|
||||
|
||||
TileMatrix matrix = map.Tiles;
|
||||
|
||||
|
|
@ -211,9 +213,8 @@ namespace Server
|
|||
|
||||
foreach (DeltaState state in table.Values)
|
||||
{
|
||||
int oldTileCount;
|
||||
StaticTile[] oldTiles = ReadStaticBlock(idxReader, mulStream, state.m_X, state.m_Y,
|
||||
matrix.BlockWidth, matrix.BlockHeight, out oldTileCount);
|
||||
matrix.BlockWidth, matrix.BlockHeight, out int oldTileCount);
|
||||
|
||||
if (oldTileCount < 0)
|
||||
continue;
|
||||
|
|
@ -296,18 +297,19 @@ namespace Server
|
|||
if (totalFrozen == 0 && badDataFile)
|
||||
from.SendGump(new NoticeGump(1060637, 30720,
|
||||
"Output data files could not be opened and the freeze operation has been aborted.<br><br>This probably means your server and client are using the same data files. Instructions on how to resolve this can be found in the first warning window.",
|
||||
0xFFC000, 320, 240, null, null));
|
||||
0xFFC000, 320, 240));
|
||||
else
|
||||
from.SendGump(new NoticeGump(1060637, 30720,
|
||||
$"Freeze operation completed successfully.<br><br>{totalFrozen} item{(totalFrozen != 1 ? "s were" : " was")} frozen.<br><br>You must restart your client and update it's data files to see the changes.",
|
||||
0xFFC000, 320, 240, null, null));
|
||||
0xFFC000, 320, 240));
|
||||
}
|
||||
|
||||
[Usage("Unfreeze")]
|
||||
[Description("Makes a targeted area of static items dynamic.")]
|
||||
public static void Unfreeze_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
BoundingBoxPicker.Begin(e.Mobile, UnfreezeBox_Callback, null);
|
||||
Mobile from = e.Mobile;
|
||||
BoundingBoxPicker.Begin(from, (map, start, end) => UnfreezeBox_Callback(from, map, start, end));
|
||||
}
|
||||
|
||||
[Usage("UnfreezeMap")]
|
||||
|
|
@ -329,19 +331,17 @@ namespace Server
|
|||
NullP3D, NullP3D, UnfreezeWarning_Callback);
|
||||
}
|
||||
|
||||
private static void UnfreezeBox_Callback(Mobile from, Map map, Point3D start, Point3D end, object state)
|
||||
private static void UnfreezeBox_Callback(Mobile from, Map map, Point3D start, Point3D end)
|
||||
{
|
||||
SendWarning(from, "You are about to unfreeze a section of items.", BaseUnfreezeWarning, map, start, end,
|
||||
UnfreezeWarning_Callback);
|
||||
}
|
||||
|
||||
private static void UnfreezeWarning_Callback(Mobile from, bool okay, object state)
|
||||
private static void UnfreezeWarning_Callback(Mobile from, bool okay, StateInfo si)
|
||||
{
|
||||
if (!okay)
|
||||
return;
|
||||
|
||||
StateInfo si = (StateInfo)state;
|
||||
|
||||
Unfreeze(from, si.m_Map, si.m_Start, si.m_End);
|
||||
}
|
||||
|
||||
|
|
@ -378,9 +378,8 @@ namespace Server
|
|||
for (int x = xStartBlock; x <= xEndBlock; ++x)
|
||||
for (int y = yStartBlock; y <= yEndBlock; ++y)
|
||||
{
|
||||
int oldTileCount;
|
||||
StaticTile[] oldTiles = ReadStaticBlock(idxReader, mulStream, x, y, matrix.BlockWidth,
|
||||
matrix.BlockHeight, out oldTileCount);
|
||||
matrix.BlockHeight, out int oldTileCount);
|
||||
|
||||
if (oldTileCount < 0)
|
||||
continue;
|
||||
|
|
@ -493,11 +492,11 @@ namespace Server
|
|||
if (totalUnfrozen == 0 && badDataFile)
|
||||
from.SendGump(new NoticeGump(1060637, 30720,
|
||||
"Output data files could not be opened and the unfreeze operation has been aborted.<br><br>This probably means your server and client are using the same data files. Instructions on how to resolve this can be found in the first warning window.",
|
||||
0xFFC000, 320, 240, null, null));
|
||||
0xFFC000, 320, 240));
|
||||
else
|
||||
from.SendGump(new NoticeGump(1060637, 30720,
|
||||
$"Unfreeze operation completed successfully.<br><br>{totalUnfrozen} item{(totalUnfrozen != 1 ? "s were" : " was")} unfrozen.<br><br>You must restart your client and update it's data files to see the changes.",
|
||||
0xFFC000, 320, 240, null, null));
|
||||
0xFFC000, 320, 240));
|
||||
}
|
||||
|
||||
private static FileStream OpenWrite(FileStream orig)
|
||||
|
|
@ -580,7 +579,7 @@ namespace Server
|
|||
}
|
||||
}
|
||||
|
||||
private class StateInfo
|
||||
public class StateInfo
|
||||
{
|
||||
public Map m_Map;
|
||||
public Point3D m_Start, m_End;
|
||||
|
|
@ -593,4 +592,4 @@ namespace Server
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,12 +54,7 @@ namespace Server.Commands
|
|||
|
||||
public static void BeginWipe(Mobile from, WipeType type)
|
||||
{
|
||||
BoundingBoxPicker.Begin(from, WipeBox_Callback, type);
|
||||
}
|
||||
|
||||
private static void WipeBox_Callback(Mobile from, Map map, Point3D start, Point3D end, object state)
|
||||
{
|
||||
DoWipe(from, map, start, end, (WipeType)state);
|
||||
BoundingBoxPicker.Begin(from, (map, start, end) => DoWipe(from, map, start, end, type));
|
||||
}
|
||||
|
||||
public static void DoWipe(Mobile from, Map map, Point3D start, Point3D end, WipeType type)
|
||||
|
|
@ -80,7 +75,7 @@ namespace Server.Commands
|
|||
if (!items && !multis || !mobiles)
|
||||
return;
|
||||
|
||||
eable = map.GetObjectsInBounds(rect, true, true);
|
||||
eable = map.GetObjectsInBounds(rect);
|
||||
|
||||
foreach (IEntity obj in eable)
|
||||
if (items && obj is Item && !(obj is BaseMulti || obj is HouseSign))
|
||||
|
|
|
|||
|
|
@ -74,8 +74,8 @@ namespace Server.Engines.BulkOrders
|
|||
|
||||
public BOBFilterGump(PlayerMobile from, BulkOrderBook book) : base(12, 24)
|
||||
{
|
||||
from.CloseGump(typeof(BOBGump));
|
||||
from.CloseGump(typeof(BOBFilterGump));
|
||||
from.CloseGump<BOBGump>();
|
||||
from.CloseGump<BOBFilterGump>();
|
||||
|
||||
m_From = from;
|
||||
m_Book = book;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
|
@ -13,18 +13,14 @@ namespace Server.Engines.BulkOrders
|
|||
private const int LabelColor = 0x7FFF;
|
||||
private BulkOrderBook m_Book;
|
||||
private PlayerMobile m_From;
|
||||
private ArrayList m_List;
|
||||
private List<IBOBEntry> m_List;
|
||||
|
||||
private int m_Page;
|
||||
|
||||
public BOBGump(PlayerMobile from, BulkOrderBook book) : this(from, book, 0, null)
|
||||
public BOBGump(PlayerMobile from, BulkOrderBook book, int page = 0, List<IBOBEntry> list = null) : base(12, 24)
|
||||
{
|
||||
}
|
||||
|
||||
public BOBGump(PlayerMobile from, BulkOrderBook book, int page, ArrayList list) : base(12, 24)
|
||||
{
|
||||
from.CloseGump(typeof(BOBGump));
|
||||
from.CloseGump(typeof(BOBFilterGump));
|
||||
from.CloseGump<BOBGump>();
|
||||
from.CloseGump<BOBFilterGump>();
|
||||
|
||||
m_From = from;
|
||||
m_Book = book;
|
||||
|
|
@ -32,14 +28,14 @@ namespace Server.Engines.BulkOrders
|
|||
|
||||
if (list == null)
|
||||
{
|
||||
list = new ArrayList(book.Entries.Count);
|
||||
list = new List<IBOBEntry>(book.Entries.Count);
|
||||
|
||||
for (int i = 0; i < book.Entries.Count; ++i)
|
||||
{
|
||||
object obj = book.Entries[i];
|
||||
IBOBEntry entry = book.Entries[i];
|
||||
|
||||
if (CheckFilter(obj))
|
||||
list.Add(obj);
|
||||
if (CheckFilter(entry))
|
||||
list.Add(entry);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -92,17 +88,13 @@ namespace Server.Engines.BulkOrders
|
|||
|
||||
for (int i = index; i < index + count && i >= 0 && i < list.Count; ++i)
|
||||
{
|
||||
object obj = list[i];
|
||||
IBOBEntry entry = list[i];
|
||||
|
||||
if (!CheckFilter(obj))
|
||||
if (!CheckFilter(entry))
|
||||
continue;
|
||||
|
||||
AddImageTiled(24, 94 + tableIndex * 32, canPrice ? 573 : 489, 2, 2624);
|
||||
|
||||
if (obj is BOBLargeEntry entry)
|
||||
tableIndex += entry.Entries.Length;
|
||||
else
|
||||
++tableIndex;
|
||||
tableIndex += entry is BOBLargeEntry largeEntry ? largeEntry.Entries.Length : 1;
|
||||
}
|
||||
|
||||
AddAlphaRegion(18, 20, width - 17, 420);
|
||||
|
|
@ -169,12 +161,12 @@ namespace Server.Engines.BulkOrders
|
|||
|
||||
for (int i = index; i < index + count && i >= 0 && i < list.Count; ++i)
|
||||
{
|
||||
object obj = list[i];
|
||||
IBOBEntry entry = list[i];
|
||||
|
||||
if (!CheckFilter(obj))
|
||||
if (!CheckFilter(entry))
|
||||
continue;
|
||||
|
||||
if (obj is BOBLargeEntry entry)
|
||||
if (entry is BOBLargeEntry largeEntry)
|
||||
{
|
||||
int y = 96 + tableIndex * 32;
|
||||
|
||||
|
|
@ -189,9 +181,9 @@ namespace Server.Engines.BulkOrders
|
|||
|
||||
AddHtmlLocalized(61, y, 50, 32, 1062225, LabelColor, false, false); // Large
|
||||
|
||||
for (int j = 0; j < entry.Entries.Length; ++j)
|
||||
for (int j = 0; j < largeEntry.Entries.Length; ++j)
|
||||
{
|
||||
BOBLargeSubEntry sub = entry.Entries[j];
|
||||
BOBLargeSubEntry sub = largeEntry.Entries[j];
|
||||
|
||||
AddHtmlLocalized(103, y, 130, 32, sub.Number, LabelColor, false, false);
|
||||
|
||||
|
|
@ -215,7 +207,7 @@ namespace Server.Engines.BulkOrders
|
|||
}
|
||||
else
|
||||
{
|
||||
BOBSmallEntry smallEntry = (BOBSmallEntry)obj;
|
||||
BOBSmallEntry smallEntry = (BOBSmallEntry)entry;
|
||||
|
||||
int y = 96 + tableIndex++ * 32;
|
||||
|
||||
|
|
@ -249,26 +241,15 @@ namespace Server.Engines.BulkOrders
|
|||
}
|
||||
}
|
||||
|
||||
public Item Reconstruct(object obj)
|
||||
{
|
||||
Item item = null;
|
||||
|
||||
if (obj is BOBLargeEntry entry)
|
||||
item = entry.Reconstruct();
|
||||
else
|
||||
item = ((BOBSmallEntry)obj).Reconstruct();
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public bool CheckFilter(object obj)
|
||||
{
|
||||
if (obj is BOBLargeEntry entry)
|
||||
public bool CheckFilter(IBOBEntry entry)
|
||||
{
|
||||
if (entry is BOBLargeEntry largeEntry)
|
||||
return CheckFilter(entry.Material, entry.AmountMax, true, entry.RequireExceptional, entry.DeedType,
|
||||
entry.Entries.Length > 0 ? entry.Entries[0].ItemType : null);
|
||||
if (obj is BOBSmallEntry smallEntry)
|
||||
return CheckFilter(smallEntry.Material, smallEntry.AmountMax, false, smallEntry.RequireExceptional,
|
||||
smallEntry.DeedType, smallEntry.ItemType);
|
||||
largeEntry.Entries.Length > 0 ? largeEntry.Entries[0].ItemType : null);
|
||||
|
||||
if (entry is BOBSmallEntry smallEntry)
|
||||
return CheckFilter(entry.Material, entry.AmountMax, false, entry.RequireExceptional,
|
||||
entry.DeedType, smallEntry.ItemType);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -344,20 +325,15 @@ namespace Server.Engines.BulkOrders
|
|||
int slots = 0;
|
||||
int count = 0;
|
||||
|
||||
ArrayList list = m_List;
|
||||
List<IBOBEntry> list = m_List;
|
||||
|
||||
for (int i = index; i >= 0 && i < list.Count; ++i)
|
||||
{
|
||||
object obj = list[i];
|
||||
IBOBEntry entry = list[i];
|
||||
|
||||
if (CheckFilter(obj))
|
||||
if (CheckFilter(entry))
|
||||
{
|
||||
int add;
|
||||
|
||||
if (obj is BOBLargeEntry entry)
|
||||
add = entry.Entries.Length;
|
||||
else
|
||||
add = 1;
|
||||
int add = entry is BOBLargeEntry largeEntry ? largeEntry.Entries.Length : 1;
|
||||
|
||||
if (slots + add > 10)
|
||||
break;
|
||||
|
|
@ -377,52 +353,42 @@ namespace Server.Engines.BulkOrders
|
|||
return 0;
|
||||
|
||||
int count = 0;
|
||||
int add = 0;
|
||||
int page = 0;
|
||||
ArrayList list = m_List;
|
||||
int i;
|
||||
object obj;
|
||||
|
||||
|
||||
List<IBOBEntry> list = m_List;
|
||||
for (i = 0; i < index && i < list.Count; i++)
|
||||
{
|
||||
obj = list[i];
|
||||
if (CheckFilter(obj))
|
||||
IBOBEntry entry = list[i];
|
||||
if (!CheckFilter(entry))
|
||||
continue;
|
||||
|
||||
int add = entry is BOBLargeEntry largeEntry ? largeEntry.Entries.Length : 1;
|
||||
count += add;
|
||||
if (count > 10)
|
||||
{
|
||||
if (obj is BOBLargeEntry entry)
|
||||
add = entry.Entries.Length;
|
||||
else
|
||||
add = 1;
|
||||
count += add;
|
||||
if (count > 10)
|
||||
{
|
||||
page++;
|
||||
count = add;
|
||||
}
|
||||
page++;
|
||||
count = add;
|
||||
}
|
||||
}
|
||||
|
||||
/* now we are on the page of the bod preceeding the dropped one.
|
||||
/* now we are on the page of the bod preceding the dropped one.
|
||||
* next step: checking whether we have to remain where we are.
|
||||
* The counter i needs to be incremented as the bod to this very moment
|
||||
* has not yet been removed from m_List */
|
||||
i++;
|
||||
|
||||
/* if, for instance, a big bod of size 6 has been removed, smaller bods
|
||||
* might fall back into this page. Depending on their sizes, the page eeds
|
||||
* might fall back into this page. Depending on their sizes, the page needs
|
||||
* to be adjusted accordingly. This is done now.
|
||||
*/
|
||||
if (count + sizeDropped > 10)
|
||||
{
|
||||
while (i < list.Count && count <= 10)
|
||||
{
|
||||
obj = list[i];
|
||||
if (CheckFilter(obj))
|
||||
{
|
||||
if (obj is BOBLargeEntry entry)
|
||||
count += entry.Entries.Length;
|
||||
else
|
||||
count += 1;
|
||||
}
|
||||
IBOBEntry entry = list[i];
|
||||
if (CheckFilter(entry))
|
||||
count += entry is BOBLargeEntry largeEntry ? largeEntry.Entries.Length : 1;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
|
@ -521,9 +487,6 @@ namespace Server.Engines.BulkOrders
|
|||
}
|
||||
default:
|
||||
{
|
||||
bool canDrop = m_Book.IsChildOf(m_From.Backpack);
|
||||
bool canPrice = canDrop || m_Book.RootParent is PlayerVendor;
|
||||
|
||||
index -= 5;
|
||||
|
||||
int type = index % 2;
|
||||
|
|
@ -532,9 +495,9 @@ namespace Server.Engines.BulkOrders
|
|||
if (index < 0 || index >= m_List.Count)
|
||||
break;
|
||||
|
||||
object obj = m_List[index];
|
||||
IBOBEntry bobEntry = m_List[index];
|
||||
|
||||
if (!m_Book.Entries.Contains(obj))
|
||||
if (!m_Book.Entries.Contains(bobEntry))
|
||||
{
|
||||
m_From.SendLocalizedMessage(1062382); // The deed selected is not available.
|
||||
break;
|
||||
|
|
@ -544,54 +507,43 @@ namespace Server.Engines.BulkOrders
|
|||
{
|
||||
if (m_Book.IsChildOf(m_From.Backpack))
|
||||
{
|
||||
Item item = Reconstruct(obj);
|
||||
Item item = bobEntry.Reconstruct();
|
||||
|
||||
if (item != null)
|
||||
Container pack = m_From.Backpack;
|
||||
if (pack == null || !pack.CheckHold(m_From, item, true, true, 0,
|
||||
item.PileWeight + item.TotalWeight))
|
||||
{
|
||||
Container pack = m_From.Backpack;
|
||||
if (pack == null || !pack.CheckHold(m_From, item, true, true, 0,
|
||||
item.PileWeight + item.TotalWeight))
|
||||
{
|
||||
m_From.SendLocalizedMessage(503204); // You do not have room in your backpack for this
|
||||
m_From.SendGump(new BOBGump(m_From, m_Book, m_Page, null));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_Book.IsChildOf(m_From.Backpack))
|
||||
{
|
||||
int sizeOfDroppedBod;
|
||||
if (obj is BOBLargeEntry entry)
|
||||
sizeOfDroppedBod = entry.Entries.Length;
|
||||
else
|
||||
sizeOfDroppedBod = 1;
|
||||
|
||||
m_From.AddToBackpack(item);
|
||||
m_From.SendLocalizedMessage(
|
||||
1045152); // The bulk order deed has been placed in your backpack.
|
||||
m_Book.Entries.Remove(obj);
|
||||
m_Book.InvalidateProperties();
|
||||
|
||||
if (m_Book.Entries.Count / 5 < m_Book.ItemCount)
|
||||
{
|
||||
m_Book.ItemCount--;
|
||||
m_Book.InvalidateItems();
|
||||
}
|
||||
|
||||
if (m_Book.Entries.Count > 0)
|
||||
{
|
||||
m_Page = GetPageForIndex(index, sizeOfDroppedBod);
|
||||
m_From.SendGump(new BOBGump(m_From, m_Book, m_Page, null));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_From.SendLocalizedMessage(1062381); // The book is empty.
|
||||
}
|
||||
}
|
||||
}
|
||||
m_From.SendLocalizedMessage(503204); // You do not have room in your backpack for this
|
||||
m_From.SendGump(new BOBGump(m_From, m_Book, m_Page));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_From.SendMessage("Internal error. The bulk order deed could not be reconstructed.");
|
||||
if (m_Book.IsChildOf(m_From.Backpack))
|
||||
{
|
||||
int sizeOfDroppedBod = bobEntry is BOBLargeEntry entry ? entry.Entries.Length : 1;
|
||||
|
||||
m_From.AddToBackpack(item);
|
||||
m_From.SendLocalizedMessage(
|
||||
1045152); // The bulk order deed has been placed in your backpack.
|
||||
m_Book.Entries.Remove(bobEntry);
|
||||
m_Book.InvalidateProperties();
|
||||
|
||||
if (m_Book.Entries.Count / 5 < m_Book.ItemCount)
|
||||
{
|
||||
m_Book.ItemCount--;
|
||||
m_Book.InvalidateItems();
|
||||
}
|
||||
|
||||
if (m_Book.Entries.Count > 0)
|
||||
{
|
||||
m_Page = GetPageForIndex(index, sizeOfDroppedBod);
|
||||
m_From.SendGump(new BOBGump(m_From, m_Book, m_Page));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_From.SendLocalizedMessage(1062381); // The book is empty.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -599,7 +551,7 @@ namespace Server.Engines.BulkOrders
|
|||
{
|
||||
if (m_Book.IsChildOf(m_From.Backpack))
|
||||
{
|
||||
m_From.Prompt = new SetPricePrompt(m_Book, obj, m_Page, m_List);
|
||||
m_From.Prompt = new SetPricePrompt(m_Book, bobEntry, m_Page, m_List);
|
||||
m_From.SendLocalizedMessage(1062383); // Type in a price for the deed:
|
||||
}
|
||||
else if (m_Book.RootParent is PlayerVendor pv)
|
||||
|
|
@ -608,18 +560,8 @@ namespace Server.Engines.BulkOrders
|
|||
|
||||
if (vi != null && !vi.IsForSale)
|
||||
{
|
||||
int sizeOfDroppedBod;
|
||||
int price = 0;
|
||||
if (obj is BOBLargeEntry entry)
|
||||
{
|
||||
price = entry.Price;
|
||||
sizeOfDroppedBod = entry.Entries.Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
price = ((BOBSmallEntry)obj).Price;
|
||||
sizeOfDroppedBod = 1;
|
||||
}
|
||||
int sizeOfDroppedBod = bobEntry is BOBLargeEntry largeEntry ? largeEntry.Entries.Length : 1;
|
||||
int price = bobEntry.Price;
|
||||
|
||||
if (price == 0)
|
||||
{
|
||||
|
|
@ -630,7 +572,7 @@ namespace Server.Engines.BulkOrders
|
|||
if (m_Book.Entries.Count > 0)
|
||||
{
|
||||
m_Page = GetPageForIndex(index, sizeOfDroppedBod);
|
||||
m_From.SendGump(new BODBuyGump(m_From, m_Book, obj, m_Page, price));
|
||||
m_From.SendGump(new BODBuyGump(m_From, m_Book, bobEntry, m_Page, price));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -649,21 +591,21 @@ namespace Server.Engines.BulkOrders
|
|||
private class SetPricePrompt : Prompt
|
||||
{
|
||||
private BulkOrderBook m_Book;
|
||||
private ArrayList m_List;
|
||||
private object m_Object;
|
||||
private List<IBOBEntry> m_List;
|
||||
private IBOBEntry m_Entry;
|
||||
private int m_Page;
|
||||
|
||||
public SetPricePrompt(BulkOrderBook book, object obj, int page, ArrayList list)
|
||||
public SetPricePrompt(BulkOrderBook book, IBOBEntry entry, int page, List<IBOBEntry> list)
|
||||
{
|
||||
m_Book = book;
|
||||
m_Object = obj;
|
||||
m_Entry = entry;
|
||||
m_Page = page;
|
||||
m_List = list;
|
||||
}
|
||||
|
||||
public override void OnResponse(Mobile from, string text)
|
||||
{
|
||||
if (m_Object != null && !m_Book.Entries.Contains(m_Object))
|
||||
if (m_Entry != null && !m_Book.Entries.Contains(m_Entry))
|
||||
{
|
||||
from.SendLocalizedMessage(1062382); // The deed selected is not available.
|
||||
return;
|
||||
|
|
@ -675,19 +617,16 @@ namespace Server.Engines.BulkOrders
|
|||
{
|
||||
from.SendLocalizedMessage(1062390); // The price you requested is outrageous!
|
||||
}
|
||||
else if (m_Object == null)
|
||||
else if (m_Entry == null)
|
||||
{
|
||||
for (int i = 0; i < m_List.Count; ++i)
|
||||
{
|
||||
object obj = m_List[i];
|
||||
IBOBEntry entry = m_List[i];
|
||||
|
||||
if (!m_Book.Entries.Contains(obj))
|
||||
if (!m_Book.Entries.Contains(entry))
|
||||
continue;
|
||||
|
||||
if (obj is BOBLargeEntry entry)
|
||||
entry.Price = price;
|
||||
else
|
||||
((BOBSmallEntry)obj).Price = price;
|
||||
|
||||
entry.Price = price;
|
||||
}
|
||||
|
||||
from.SendMessage("Deed prices set.");
|
||||
|
|
@ -695,21 +634,10 @@ namespace Server.Engines.BulkOrders
|
|||
if (from is PlayerMobile mobile)
|
||||
mobile.SendGump(new BOBGump(mobile, m_Book, m_Page, m_List));
|
||||
}
|
||||
else if (m_Object is BOBLargeEntry entry)
|
||||
{
|
||||
entry.Price = price;
|
||||
|
||||
from.SendLocalizedMessage(1062384); // Deed price set.
|
||||
|
||||
if (from is PlayerMobile mobile)
|
||||
mobile.SendGump(new BOBGump(mobile, m_Book, m_Page, m_List));
|
||||
}
|
||||
else
|
||||
{
|
||||
((BOBSmallEntry)m_Object).Price = price;
|
||||
|
||||
m_Entry.Price = price;
|
||||
from.SendLocalizedMessage(1062384); // Deed price set.
|
||||
|
||||
if (from is PlayerMobile mobile)
|
||||
mobile.SendGump(new BOBGump(mobile, m_Book, m_Page, m_List));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
namespace Server.Engines.BulkOrders
|
||||
{
|
||||
public class BOBLargeEntry
|
||||
public class BOBLargeEntry: IBOBEntry
|
||||
{
|
||||
public BOBLargeEntry(LargeBOD bod)
|
||||
{
|
||||
|
|
@ -80,8 +80,7 @@ namespace Server.Engines.BulkOrders
|
|||
for (int i = 0; i < Entries.Length; ++i)
|
||||
{
|
||||
entries[i] = new LargeBulkEntry(null,
|
||||
new SmallBulkEntry(Entries[i].ItemType, Entries[i].Number, Entries[i].Graphic));
|
||||
entries[i].Amount = Entries[i].AmountCur;
|
||||
new SmallBulkEntry(Entries[i].ItemType, Entries[i].Number, Entries[i].Graphic)) { Amount = Entries[i].AmountCur };
|
||||
}
|
||||
|
||||
return entries;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ using System;
|
|||
|
||||
namespace Server.Engines.BulkOrders
|
||||
{
|
||||
public class BOBSmallEntry
|
||||
public class BOBSmallEntry : IBOBEntry
|
||||
{
|
||||
public BOBSmallEntry(SmallBOD bod)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -9,15 +9,15 @@ namespace Server.Engines.BulkOrders
|
|||
{
|
||||
private BulkOrderBook m_Book;
|
||||
private PlayerMobile m_From;
|
||||
private object m_Object;
|
||||
private IBOBEntry m_Entry;
|
||||
private int m_Page;
|
||||
private int m_Price;
|
||||
|
||||
public BODBuyGump(PlayerMobile from, BulkOrderBook book, object obj, int page, int price) : base(100, 200)
|
||||
public BODBuyGump(PlayerMobile from, BulkOrderBook book, IBOBEntry entry, int page, int price) : base(100, 200)
|
||||
{
|
||||
m_From = from;
|
||||
m_Book = book;
|
||||
m_Object = obj;
|
||||
m_Entry = entry;
|
||||
m_Price = price;
|
||||
m_Page = page;
|
||||
|
||||
|
|
@ -40,100 +40,83 @@ namespace Server.Engines.BulkOrders
|
|||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (info.ButtonID == 2)
|
||||
if (info.ButtonID != 2)
|
||||
{
|
||||
PlayerVendor pv = m_Book.RootParent as PlayerVendor;
|
||||
m_From.SendLocalizedMessage(503207); // Cancelled purchase.
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_Book.Entries.Contains(m_Object) && pv != null)
|
||||
{
|
||||
int price = 0;
|
||||
if (!(m_Book.RootParent is PlayerVendor pv))
|
||||
{
|
||||
m_From.SendLocalizedMessage(1062382); // The deed selected is not available.
|
||||
return;
|
||||
}
|
||||
|
||||
VendorItem vi = pv.GetVendorItem(m_Book);
|
||||
if (!m_Book.Entries.Contains(m_Entry))
|
||||
{
|
||||
pv.SayTo(m_From, 1062382); // The deed selected is not available.
|
||||
return;
|
||||
}
|
||||
|
||||
int price = 0;
|
||||
|
||||
if (vi != null && !vi.IsForSale)
|
||||
{
|
||||
if (m_Object is BOBLargeEntry entry)
|
||||
price = entry.Price;
|
||||
else
|
||||
price = ((BOBSmallEntry)m_Object).Price;
|
||||
}
|
||||
VendorItem vi = pv.GetVendorItem(m_Book);
|
||||
|
||||
if (price != m_Price)
|
||||
{
|
||||
pv.SayTo(m_From,
|
||||
"The price has been been changed. If you like, you may offer to purchase the item again.");
|
||||
}
|
||||
else if (price == 0)
|
||||
{
|
||||
pv.SayTo(m_From, 1062382); // The deed selected is not available.
|
||||
}
|
||||
else
|
||||
{
|
||||
Item item = null;
|
||||
if (vi != null && !vi.IsForSale)
|
||||
price = m_Entry.Price;
|
||||
|
||||
if (m_Object is BOBLargeEntry entry)
|
||||
item = entry.Reconstruct();
|
||||
else
|
||||
item = ((BOBSmallEntry)m_Object).Reconstruct();
|
||||
if (price != m_Price)
|
||||
{
|
||||
pv.SayTo(m_From,
|
||||
"The price has been been changed. If you like, you may offer to purchase the item again.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
m_From.SendMessage("Internal error. The bulk order deed could not be reconstructed.");
|
||||
}
|
||||
else
|
||||
{
|
||||
pv.Say(m_From.Name);
|
||||
if (price == 0)
|
||||
{
|
||||
pv.SayTo(m_From, 1062382); // The deed selected is not available.
|
||||
return;
|
||||
}
|
||||
|
||||
Container pack = m_From.Backpack;
|
||||
Item item = m_Entry.Reconstruct();
|
||||
|
||||
pv.Say(m_From.Name);
|
||||
|
||||
if (pack == null || !pack.CheckHold(m_From, item, true, true, 0,
|
||||
item.PileWeight + item.TotalWeight))
|
||||
{
|
||||
pv.SayTo(m_From, 503204); // You do not have room in your backpack for this
|
||||
m_From.SendGump(new BOBGump(m_From, m_Book, m_Page, null));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pack.ConsumeTotal(typeof(Gold), price) || Banker.Withdraw(m_From, price))
|
||||
{
|
||||
m_Book.Entries.Remove(m_Object);
|
||||
m_Book.InvalidateProperties();
|
||||
pv.HoldGold += price;
|
||||
m_From.AddToBackpack(item);
|
||||
m_From.SendLocalizedMessage(
|
||||
1045152); // The bulk order deed has been placed in your backpack.
|
||||
Container pack = m_From.Backpack;
|
||||
|
||||
if (m_Book.Entries.Count / 5 < m_Book.ItemCount)
|
||||
{
|
||||
m_Book.ItemCount--;
|
||||
m_Book.InvalidateItems();
|
||||
}
|
||||
|
||||
if (m_Book.Entries.Count > 0)
|
||||
m_From.SendGump(new BOBGump(m_From, m_Book, m_Page, null));
|
||||
else
|
||||
m_From.SendLocalizedMessage(1062381); // The book is empty.
|
||||
}
|
||||
else
|
||||
{
|
||||
pv.SayTo(m_From, 503205); // You cannot afford this item.
|
||||
item.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pv == null)
|
||||
m_From.SendLocalizedMessage(1062382); // The deed selected is not available.
|
||||
else
|
||||
pv.SayTo(m_From, 1062382); // The deed selected is not available.
|
||||
}
|
||||
if (pack == null || !pack.CheckHold(m_From, item, true, true, 0,
|
||||
item.PileWeight + item.TotalWeight))
|
||||
{
|
||||
pv.SayTo(m_From, 503204); // You do not have room in your backpack for this
|
||||
m_From.SendGump(new BOBGump(m_From, m_Book, m_Page));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_From.SendLocalizedMessage(503207); // Cancelled purchase.
|
||||
if (pack.ConsumeTotal(typeof(Gold), price) || Banker.Withdraw(m_From, price))
|
||||
{
|
||||
m_Book.Entries.Remove(m_Entry);
|
||||
m_Book.InvalidateProperties();
|
||||
pv.HoldGold += price;
|
||||
m_From.AddToBackpack(item);
|
||||
m_From.SendLocalizedMessage(
|
||||
1045152); // The bulk order deed has been placed in your backpack.
|
||||
|
||||
if (m_Book.Entries.Count / 5 < m_Book.ItemCount)
|
||||
{
|
||||
m_Book.ItemCount--;
|
||||
m_Book.InvalidateItems();
|
||||
}
|
||||
|
||||
if (m_Book.Entries.Count > 0)
|
||||
m_From.SendGump(new BOBGump(m_From, m_Book, m_Page));
|
||||
else
|
||||
m_From.SendLocalizedMessage(1062381); // The book is empty.
|
||||
}
|
||||
else
|
||||
{
|
||||
pv.SayTo(m_From, 503205); // You cannot afford this item.
|
||||
item.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server.Gumps;
|
||||
using Server.Multis;
|
||||
|
|
@ -24,7 +22,7 @@ namespace Server.Engines.BulkOrders
|
|||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public SecureLevel Level { get; set; }
|
||||
|
||||
public ArrayList Entries { get; private set; }
|
||||
public List<IBOBEntry> Entries { get; private set; }
|
||||
|
||||
public BOBFilter Filter { get; private set; }
|
||||
|
||||
|
|
@ -36,7 +34,7 @@ namespace Server.Engines.BulkOrders
|
|||
Weight = 1.0;
|
||||
LootType = LootType.Blessed;
|
||||
|
||||
Entries = new ArrayList();
|
||||
Entries = new List<IBOBEntry>();
|
||||
Filter = new BOBFilter();
|
||||
|
||||
Level = SecureLevel.CoOwners;
|
||||
|
|
@ -73,9 +71,9 @@ namespace Server.Engines.BulkOrders
|
|||
SecureTrade trade = cont.Trade;
|
||||
|
||||
if ( trade != null && trade.From.Mobile == from )
|
||||
trade.To.Mobile.SendGump( new BOBGump( (PlayerMobile)(trade.To.Mobile), this ) );
|
||||
trade.To.Mobile.SendGump( new BOBGump( (PlayerMobile)trade.To.Mobile, this ) );
|
||||
else if ( trade != null && trade.To.Mobile == from )
|
||||
trade.From.Mobile.SendGump( new BOBGump( (PlayerMobile)(trade.From.Mobile), this ) );
|
||||
trade.From.Mobile.SendGump( new BOBGump( (PlayerMobile)trade.From.Mobile, this ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -216,7 +214,7 @@ namespace Server.Engines.BulkOrders
|
|||
|
||||
int count = reader.ReadEncodedInt();
|
||||
|
||||
Entries = new ArrayList( count );
|
||||
Entries = new List<IBOBEntry>( count );
|
||||
|
||||
for ( int i = 0; i < count; ++i )
|
||||
{
|
||||
|
|
@ -240,7 +238,7 @@ namespace Server.Engines.BulkOrders
|
|||
|
||||
list.Add( 1062344, Entries.Count.ToString() ); // Deeds in book: ~1_val~
|
||||
|
||||
if ( m_BookName != null && m_BookName.Length > 0 )
|
||||
if ( !string.IsNullOrEmpty(m_BookName) )
|
||||
list.Add( 1062481, m_BookName ); // Book Name: ~1_val~
|
||||
}
|
||||
|
||||
|
|
|
|||
12
Scripts/Engines/BulkOrders/Books/IBOBEntry.cs
Normal file
12
Scripts/Engines/BulkOrders/Books/IBOBEntry.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
namespace Server.Engines.BulkOrders
|
||||
{
|
||||
public interface IBOBEntry
|
||||
{
|
||||
bool RequireExceptional{ get; }
|
||||
BODType DeedType{ get; }
|
||||
BulkMaterialType Material{ get; }
|
||||
int AmountMax{ get; }
|
||||
int Price{ get; set; }
|
||||
Item Reconstruct();
|
||||
}
|
||||
}
|
||||
|
|
@ -13,8 +13,8 @@ namespace Server.Engines.BulkOrders
|
|||
m_From = from;
|
||||
m_Deed = deed;
|
||||
|
||||
m_From.CloseGump(typeof(LargeBODAcceptGump));
|
||||
m_From.CloseGump(typeof(SmallBODAcceptGump));
|
||||
m_From.CloseGump<LargeBODAcceptGump>();
|
||||
m_From.CloseGump<SmallBODAcceptGump>();
|
||||
|
||||
LargeBulkEntry[] entries = deed.Entries;
|
||||
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ namespace Server.Engines.BulkOrders
|
|||
m_From = from;
|
||||
m_Deed = deed;
|
||||
|
||||
m_From.CloseGump(typeof(LargeBODGump));
|
||||
m_From.CloseGump(typeof(SmallBODGump));
|
||||
m_From.CloseGump<LargeBODGump>();
|
||||
m_From.CloseGump<SmallBODGump>();
|
||||
|
||||
LargeBulkEntry[] entries = deed.Entries;
|
||||
|
||||
|
|
|
|||
|
|
@ -691,7 +691,7 @@ namespace Server.Engines.BulkOrders
|
|||
switch (Utility.Random(4))
|
||||
{
|
||||
default:
|
||||
case 0: return new SmallStretchedHideEastDeed();
|
||||
return new SmallStretchedHideEastDeed();
|
||||
case 1: return new SmallStretchedHideSouthDeed();
|
||||
case 2: return new MediumStretchedHideEastDeed();
|
||||
case 3: return new MediumStretchedHideSouthDeed();
|
||||
|
|
@ -703,7 +703,7 @@ namespace Server.Engines.BulkOrders
|
|||
switch (Utility.Random(4))
|
||||
{
|
||||
default:
|
||||
case 0: return new LightFlowerTapestryEastDeed();
|
||||
return new LightFlowerTapestryEastDeed();
|
||||
case 1: return new LightFlowerTapestrySouthDeed();
|
||||
case 2: return new DarkFlowerTapestryEastDeed();
|
||||
case 3: return new DarkFlowerTapestrySouthDeed();
|
||||
|
|
@ -715,7 +715,7 @@ namespace Server.Engines.BulkOrders
|
|||
switch (Utility.Random(4))
|
||||
{
|
||||
default:
|
||||
case 0: return new BrownBearRugEastDeed();
|
||||
return new BrownBearRugEastDeed();
|
||||
case 1: return new BrownBearRugSouthDeed();
|
||||
case 2: return new PolarBearRugEastDeed();
|
||||
case 3: return new PolarBearRugSouthDeed();
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ namespace Server.Engines.BulkOrders
|
|||
m_From = from;
|
||||
m_Deed = deed;
|
||||
|
||||
m_From.CloseGump(typeof(LargeBODAcceptGump));
|
||||
m_From.CloseGump(typeof(SmallBODAcceptGump));
|
||||
m_From.CloseGump<LargeBODAcceptGump>();
|
||||
m_From.CloseGump<SmallBODAcceptGump>();
|
||||
|
||||
AddPage(0);
|
||||
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ namespace Server.Engines.BulkOrders
|
|||
m_From = from;
|
||||
m_Deed = deed;
|
||||
|
||||
m_From.CloseGump(typeof(LargeBODGump));
|
||||
m_From.CloseGump(typeof(SmallBODGump));
|
||||
m_From.CloseGump<LargeBODGump>();
|
||||
m_From.CloseGump<SmallBODGump>();
|
||||
|
||||
AddPage(0);
|
||||
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ namespace Server.Engines.BulkOrders
|
|||
|
||||
if (entries.Length > 0)
|
||||
{
|
||||
double theirSkill = m.Skills[SkillName.Blacksmith].Base;
|
||||
double theirSkill = m.Skills.Blacksmith.Base;
|
||||
int amountMax;
|
||||
|
||||
if (theirSkill >= 70.1)
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ namespace Server.Engines.BulkOrders
|
|||
SmallBulkEntry[] entries;
|
||||
bool useMaterials = Utility.RandomBool();
|
||||
|
||||
double theirSkill = m.Skills[SkillName.Tailoring].Base;
|
||||
double theirSkill = m.Skills.Tailoring.Base;
|
||||
if (useMaterials && theirSkill >= 6.2
|
||||
) // Ugly, but the easiest leather BOD is Leather Cap which requires at least 6.2 skill.
|
||||
entries = SmallBulkEntry.TailorLeather;
|
||||
|
|
|
|||
|
|
@ -393,6 +393,7 @@ namespace Server.Engines.CannedEvil
|
|||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -769,7 +770,6 @@ namespace Server.Engines.CannedEvil
|
|||
switch (index)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
x = -1;
|
||||
y = -1;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
|
@ -11,7 +11,7 @@ namespace Server.Engines.ConPVP
|
|||
private const int LabelColor32 = 0xFFFFFF;
|
||||
private const int BlackColor32 = 0x000008;
|
||||
|
||||
private static Hashtable m_IgnoreLists = new Hashtable();
|
||||
private static Dictionary<Mobile, List<IgnoreEntry>> m_IgnoreLists = new Dictionary<Mobile, List<IgnoreEntry>>();
|
||||
|
||||
private bool m_Active = true;
|
||||
private Mobile m_Challenger, m_Challenged;
|
||||
|
|
@ -28,7 +28,7 @@ namespace Server.Engines.ConPVP
|
|||
m_Participant = p;
|
||||
m_Slot = slot;
|
||||
|
||||
challenged.CloseGump(typeof(AcceptDuelGump));
|
||||
challenged.CloseGump<AcceptDuelGump>();
|
||||
|
||||
Closable = false;
|
||||
|
||||
|
|
@ -109,7 +109,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
m_Active = false;
|
||||
|
||||
m_Challenged.CloseGump(typeof(AcceptDuelGump));
|
||||
m_Challenged.CloseGump<AcceptDuelGump>();
|
||||
|
||||
m_Challenger.SendMessage("{0} seems unresponsive.", m_Challenged.Name);
|
||||
m_Challenged.SendMessage("You decline the challenge.");
|
||||
|
|
@ -117,14 +117,14 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
public static void BeginIgnore(Mobile source, Mobile toIgnore)
|
||||
{
|
||||
ArrayList list = (ArrayList)m_IgnoreLists[source];
|
||||
List<IgnoreEntry> list = m_IgnoreLists[source];
|
||||
|
||||
if (list == null)
|
||||
m_IgnoreLists[source] = list = new ArrayList();
|
||||
m_IgnoreLists[source] = list = new List<IgnoreEntry>();
|
||||
|
||||
for (int i = 0; i < list.Count; ++i)
|
||||
{
|
||||
IgnoreEntry ie = (IgnoreEntry)list[i];
|
||||
IgnoreEntry ie = list[i];
|
||||
|
||||
if (ie.Ignored == toIgnore)
|
||||
{
|
||||
|
|
@ -132,7 +132,8 @@ namespace Server.Engines.ConPVP
|
|||
return;
|
||||
}
|
||||
|
||||
if (ie.Expired) list.RemoveAt(i--);
|
||||
if (ie.Expired)
|
||||
list.RemoveAt(i--);
|
||||
}
|
||||
|
||||
list.Add(new IgnoreEntry(toIgnore));
|
||||
|
|
@ -140,14 +141,14 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
public static bool IsIgnored(Mobile source, Mobile check)
|
||||
{
|
||||
ArrayList list = (ArrayList)m_IgnoreLists[source];
|
||||
List<IgnoreEntry> list = m_IgnoreLists[source];
|
||||
|
||||
if (list == null)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < list.Count; ++i)
|
||||
{
|
||||
IgnoreEntry ie = (IgnoreEntry)list[i];
|
||||
IgnoreEntry ie = list[i];
|
||||
|
||||
if (ie.Expired)
|
||||
list.RemoveAt(i--);
|
||||
|
|
|
|||
|
|
@ -8,15 +8,13 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
public class ArenaController : Item
|
||||
{
|
||||
private Arena m_Arena;
|
||||
|
||||
[Constructible]
|
||||
public ArenaController() : base(0x1B7A)
|
||||
{
|
||||
Visible = false;
|
||||
Movable = false;
|
||||
|
||||
m_Arena = new Arena();
|
||||
Arena = new Arena();
|
||||
|
||||
Instances.Add(this);
|
||||
}
|
||||
|
|
@ -26,11 +24,7 @@ namespace Server.Engines.ConPVP
|
|||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Arena Arena
|
||||
{
|
||||
get => m_Arena;
|
||||
set { }
|
||||
}
|
||||
public Arena Arena{ get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool IsPrivate{ get; set; }
|
||||
|
|
@ -44,13 +38,13 @@ namespace Server.Engines.ConPVP
|
|||
base.OnDelete();
|
||||
|
||||
Instances.Remove(this);
|
||||
m_Arena.Delete();
|
||||
Arena.Delete();
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (from.AccessLevel >= AccessLevel.GameMaster)
|
||||
from.SendGump(new PropertiesGump(from, m_Arena));
|
||||
from.SendGump(new PropertiesGump(from, Arena));
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
|
|
@ -61,7 +55,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
writer.Write(IsPrivate);
|
||||
|
||||
m_Arena.Serialize(writer);
|
||||
Arena.Serialize(writer);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
|
|
@ -80,7 +74,7 @@ namespace Server.Engines.ConPVP
|
|||
}
|
||||
case 0:
|
||||
{
|
||||
m_Arena = new Arena(reader);
|
||||
Arena = new Arena(reader);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -191,7 +185,6 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
private bool m_IsGuarded;
|
||||
private string m_Name;
|
||||
private ArenaStartPoints m_Points;
|
||||
|
||||
private SafeZone m_Region;
|
||||
|
||||
|
|
@ -200,7 +193,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
public Arena()
|
||||
{
|
||||
m_Points = new ArenaStartPoints();
|
||||
Points = new ArenaStartPoints();
|
||||
Players = new List<Mobile>();
|
||||
}
|
||||
|
||||
|
|
@ -269,7 +262,7 @@ namespace Server.Engines.ConPVP
|
|||
}
|
||||
|
||||
m_Active = reader.ReadBool();
|
||||
m_Points = new ArenaStartPoints(reader);
|
||||
Points = new ArenaStartPoints(reader);
|
||||
|
||||
if (m_Active)
|
||||
{
|
||||
|
|
@ -425,11 +418,7 @@ namespace Server.Engines.ConPVP
|
|||
public bool IsOccupied => Players.Count > 0;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public ArenaStartPoints Points
|
||||
{
|
||||
get => m_Points;
|
||||
set { }
|
||||
}
|
||||
public ArenaStartPoints Points{ get; private set; }
|
||||
|
||||
public Item Teleporter{ get; set; }
|
||||
|
||||
|
|
@ -514,7 +503,7 @@ namespace Server.Engines.ConPVP
|
|||
if (index < 0)
|
||||
index = 0;
|
||||
|
||||
return m_Points.Points[index % m_Points.Points.Length];
|
||||
return Points.Points[index % Points.Points.Length];
|
||||
}
|
||||
|
||||
public void MoveInside(DuelPlayer[] players, int index)
|
||||
|
|
@ -522,7 +511,7 @@ namespace Server.Engines.ConPVP
|
|||
if (index < 0)
|
||||
index = 0;
|
||||
else
|
||||
index %= m_Points.Points.Length;
|
||||
index %= Points.Points.Length;
|
||||
|
||||
Point3D start = GetBaseStartPoint(index);
|
||||
|
||||
|
|
@ -652,7 +641,7 @@ namespace Server.Engines.ConPVP
|
|||
writer.Write(Wall);
|
||||
writer.Write(m_Active);
|
||||
|
||||
m_Points.Serialize(writer);
|
||||
Points.Serialize(writer);
|
||||
}
|
||||
|
||||
public static Arena FindArena(List<Mobile> players)
|
||||
|
|
|
|||
|
|
@ -33,19 +33,18 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
private Timer m_Countdown;
|
||||
|
||||
private ArrayList m_Entered = new ArrayList();
|
||||
public EventGame m_EventGame;
|
||||
private Map m_GateFacet;
|
||||
|
||||
private Point3D m_GatePoint;
|
||||
public TournyMatch m_Match;
|
||||
public TourneyMatch m_Match;
|
||||
|
||||
public Arena m_OverrideArena;
|
||||
|
||||
private Timer m_SDWarnTimer, m_SDActivateTimer;
|
||||
public Tournament m_Tournament;
|
||||
|
||||
private ArrayList m_Walls = new ArrayList();
|
||||
private List<Item> m_Walls = new List<Item>();
|
||||
|
||||
private bool m_Yielding;
|
||||
|
||||
|
|
@ -56,7 +55,7 @@ namespace Server.Engines.ConPVP
|
|||
public DuelContext(Mobile initiator, RulesetLayout layout, bool addNew)
|
||||
{
|
||||
Initiator = initiator;
|
||||
Participants = new ArrayList();
|
||||
Participants = new List<Participant>();
|
||||
Ruleset = new Ruleset(layout);
|
||||
Ruleset.ApplyDefault(layout.Defaults[0]);
|
||||
|
||||
|
|
@ -64,8 +63,7 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
Participants.Add(new Participant(this, 1));
|
||||
Participants.Add(new Participant(this, 1));
|
||||
|
||||
((Participant)Participants[0]).Add(initiator);
|
||||
Participants[0].Add(initiator);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -83,7 +81,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
public Mobile Initiator{ get; }
|
||||
|
||||
public ArrayList Participants{ get; }
|
||||
public List<Participant> Participants{ get; }
|
||||
|
||||
public Ruleset Ruleset{ get; private set; }
|
||||
|
||||
|
|
@ -93,22 +91,8 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
public bool IsSuddenDeath{ get; set; }
|
||||
|
||||
public bool IsOneVsOne
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Participants.Count != 2)
|
||||
return false;
|
||||
|
||||
if (((Participant)Participants[0]).Players.Length != 1)
|
||||
return false;
|
||||
|
||||
if (((Participant)Participants[1]).Players.Length != 1)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public bool IsOneVsOne => Participants.Count == 2 && Participants[0].Players.Length == 1 &&
|
||||
Participants[1].Players.Length == 1;
|
||||
|
||||
public bool StartedBeginCountdown{ get; private set; }
|
||||
|
||||
|
|
@ -134,7 +118,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
public void DelayBounce(TimeSpan ts, Mobile mob, Container corpse)
|
||||
{
|
||||
Timer.DelayCall(ts, new TimerStateCallback(DelayBounce_Callback), new object[] { mob, corpse });
|
||||
Timer.DelayCall(ts, () => DelayBounce_Callback(mob, corpse));
|
||||
}
|
||||
|
||||
public static bool AllowSpecialMove(Mobile from, string name, SpecialMove move)
|
||||
|
|
@ -183,7 +167,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
DuelPlayer pl = Find(from);
|
||||
|
||||
if (pl == null || pl.Eliminated)
|
||||
if (pl?.Eliminated != false)
|
||||
return true;
|
||||
|
||||
if (CantDoAnything(from))
|
||||
|
|
@ -192,7 +176,8 @@ namespace Server.Engines.ConPVP
|
|||
if (spell is RecallSpell)
|
||||
from.SendMessage("You may not cast this spell.");
|
||||
|
||||
string title = null, option = null;
|
||||
string title = null;
|
||||
string option;
|
||||
|
||||
if (spell is ArcanistSpell)
|
||||
{
|
||||
|
|
@ -492,12 +477,8 @@ namespace Server.Engines.ConPVP
|
|||
return false;
|
||||
}
|
||||
|
||||
private void DelayBounce_Callback(object state)
|
||||
private void DelayBounce_Callback(Mobile mob, Container corpse)
|
||||
{
|
||||
object[] states = (object[])state;
|
||||
Mobile mob = (Mobile)states[0];
|
||||
Container corpse = (Container)states[1];
|
||||
|
||||
RemoveAggressions(mob);
|
||||
SendOutside(mob);
|
||||
Refresh(mob, corpse);
|
||||
|
|
@ -698,11 +679,11 @@ namespace Server.Engines.ConPVP
|
|||
winner.Players.Length == 1 ? "{0} has won the duel." : "{0} and {1} team have won the duel.",
|
||||
winner.Players.Length == 1 ? "You have won the duel." : "Your team has won the duel.");
|
||||
|
||||
if (m_Tournament != null && winner.TournyPart != null)
|
||||
if (m_Tournament != null && winner.TourneyPart != null)
|
||||
{
|
||||
m_Match.Winner = winner.TournyPart;
|
||||
winner.TournyPart.WonMatch(m_Match);
|
||||
m_Tournament.HandleWon(Arena, m_Match, winner.TournyPart);
|
||||
m_Match.Winner = winner.TourneyPart;
|
||||
winner.TourneyPart.WonMatch(m_Match);
|
||||
m_Tournament.HandleWon(Arena, m_Match, winner.TourneyPart);
|
||||
}
|
||||
|
||||
for (int i = 0; i < Participants.Count; ++i)
|
||||
|
|
@ -716,7 +697,7 @@ namespace Server.Engines.ConPVP
|
|||
loser.Players.Length == 1 ? "You have lost the duel." : "Your team has lost the duel.");
|
||||
|
||||
if (m_Tournament != null)
|
||||
loser.TournyPart?.LostMatch(m_Match);
|
||||
loser.TourneyPart?.LostMatch(m_Match);
|
||||
}
|
||||
|
||||
for (int j = 0; j < loser.Players.Length; ++j)
|
||||
|
|
@ -724,7 +705,7 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
RemoveAggressions(loser.Players[j].Mobile);
|
||||
loser.Players[j].Mobile.Delta(MobileDelta.Noto);
|
||||
loser.Players[j].Mobile.CloseGump(typeof(BeginGump));
|
||||
loser.Players[j].Mobile.CloseGump<BeginGump>();
|
||||
|
||||
if (m_Tournament != null)
|
||||
loser.Players[j].Mobile.SendEverything();
|
||||
|
|
@ -814,12 +795,6 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
StopSDTimers();
|
||||
|
||||
Type[] types =
|
||||
{
|
||||
typeof(BeginGump), typeof(DuelContextGump), typeof(ParticipantGump), typeof(PickRulesetGump),
|
||||
typeof(ReadyGump), typeof(ReadyUpGump), typeof(RulesetGump)
|
||||
};
|
||||
|
||||
for (int i = 0; i < Participants.Count; ++i)
|
||||
{
|
||||
Participant p = (Participant)Participants[i];
|
||||
|
|
@ -834,8 +809,7 @@ namespace Server.Engines.ConPVP
|
|||
if (pl.Mobile is PlayerMobile mobile)
|
||||
mobile.DuelPlayer = null;
|
||||
|
||||
for (int k = 0; k < types.Length; ++k)
|
||||
pl.Mobile.CloseGump(types[k]);
|
||||
CloseAllGumps(pl);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -936,33 +910,21 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
cb(count);
|
||||
m_Countdown = Timer.DelayCall(TimeSpan.FromSeconds(1.0), TimeSpan.FromSeconds(1.0), count,
|
||||
new TimerStateCallback(Countdown_Callback), new object[] { count - 1, cb });
|
||||
() => Countdown_Callback(--count, cb));
|
||||
}
|
||||
|
||||
public void StopCountdown()
|
||||
{
|
||||
m_Countdown?.Stop();
|
||||
|
||||
m_Countdown = null;
|
||||
}
|
||||
|
||||
private void Countdown_Callback(object state)
|
||||
private void Countdown_Callback(int count, CountdownCallback cb)
|
||||
{
|
||||
object[] states = (object[])state;
|
||||
|
||||
int count = (int)states[0];
|
||||
CountdownCallback cb = (CountdownCallback)states[1];
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
m_Countdown?.Stop();
|
||||
|
||||
m_Countdown = null;
|
||||
}
|
||||
StopCountdown();
|
||||
|
||||
cb(count);
|
||||
|
||||
states[0] = count - 1;
|
||||
}
|
||||
|
||||
public void StopSDTimers()
|
||||
|
|
@ -1051,7 +1013,7 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
m_AutoTieTimer?.Stop();
|
||||
|
||||
TimeSpan ts = m_Tournament == null || m_Tournament.TournyType == TournyType.Standard
|
||||
TimeSpan ts = m_Tournament == null || m_Tournament.TourneyType == TourneyType.Standard
|
||||
? AutoTieDelay
|
||||
: TimeSpan.FromMinutes(90.0);
|
||||
|
||||
|
|
@ -1077,11 +1039,11 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
StopSDTimers();
|
||||
|
||||
ArrayList remaining = new ArrayList();
|
||||
List<TourneyParticipant> remaining = new List<TourneyParticipant>();
|
||||
|
||||
for (int i = 0; i < Participants.Count; ++i)
|
||||
{
|
||||
Participant p = (Participant)Participants[i];
|
||||
Participant p = Participants[i];
|
||||
|
||||
if (p.Eliminated)
|
||||
{
|
||||
|
|
@ -1107,8 +1069,8 @@ namespace Server.Engines.ConPVP
|
|||
DelayBounce(TimeSpan.FromSeconds(8.0), pl.Mobile, null);
|
||||
}
|
||||
|
||||
if (p.TournyPart != null)
|
||||
remaining.Add(p.TournyPart);
|
||||
if (p.TourneyPart != null)
|
||||
remaining.Add(p.TourneyPart);
|
||||
}
|
||||
|
||||
for (int j = 0; j < p.Players.Length; ++j)
|
||||
|
|
@ -1204,12 +1166,10 @@ namespace Server.Engines.ConPVP
|
|||
}
|
||||
}
|
||||
|
||||
private static void ViewLadder_OnTarget(Mobile from, object obj, object state)
|
||||
private static void ViewLadder_OnTarget(Mobile from, object obj, Ladder ladder)
|
||||
{
|
||||
if (obj is PlayerMobile pm)
|
||||
{
|
||||
Ladder ladder = (Ladder)state;
|
||||
|
||||
LadderEntry entry = ladder.Find(pm);
|
||||
|
||||
if (entry == null)
|
||||
|
|
@ -1249,7 +1209,7 @@ namespace Server.Engines.ConPVP
|
|||
if (!pm.CheckAlive())
|
||||
{
|
||||
}
|
||||
else if (pm.Region.IsPartOf(typeof(Jail)))
|
||||
else if (pm.Region.IsPartOf<Jail>())
|
||||
{
|
||||
}
|
||||
else if (CheckCombat(pm))
|
||||
|
|
@ -1285,7 +1245,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
if (prefs != null)
|
||||
{
|
||||
e.Mobile.CloseGump(typeof(PreferencesGump));
|
||||
e.Mobile.CloseGump<PreferencesGump>();
|
||||
e.Mobile.SendGump(new PreferencesGump(e.Mobile, prefs));
|
||||
}
|
||||
}
|
||||
|
|
@ -1341,7 +1301,7 @@ namespace Server.Engines.ConPVP
|
|||
else
|
||||
{
|
||||
pm.SendMessage("Target a player to view their ranking and level.");
|
||||
pm.BeginTarget(16, false, TargetFlags.None, new TargetStateCallback(ViewLadder_OnTarget), instance);
|
||||
pm.BeginTarget(16, false, TargetFlags.None, ViewLadder_OnTarget, instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1551,12 +1511,20 @@ namespace Server.Engines.ConPVP
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void CloseAllGumps(DuelPlayer pl)
|
||||
{
|
||||
pl.Mobile.CloseGump<BeginGump>();
|
||||
pl.Mobile.CloseGump<DuelContextGump>();
|
||||
pl.Mobile.CloseGump<ParticipantGump>();
|
||||
pl.Mobile.CloseGump<PickRulesetGump>();
|
||||
pl.Mobile.CloseGump<ReadyGump>();
|
||||
pl.Mobile.CloseGump<ReadyUpGump>();
|
||||
pl.Mobile.CloseGump<RulesetGump>();
|
||||
}
|
||||
|
||||
public void CloseAllGumps()
|
||||
{
|
||||
Type[] types = { typeof(DuelContextGump), typeof(ParticipantGump), typeof(RulesetGump) };
|
||||
int[] defs = { -1, -1, -1 };
|
||||
|
||||
for (int i = 0; i < Participants.Count; ++i)
|
||||
{
|
||||
Participant p = (Participant)Participants[i];
|
||||
|
|
@ -1565,14 +1533,8 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
DuelPlayer pl = p.Players[j];
|
||||
|
||||
if (pl == null)
|
||||
continue;
|
||||
|
||||
Mobile mob = pl.Mobile;
|
||||
|
||||
for (int k = 0; k < types.Length; ++k)
|
||||
mob.CloseGump(types[k]);
|
||||
//mob.CloseGump( types[k], defs[k] );
|
||||
if (pl != null)
|
||||
CloseAllGumps(pl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1582,9 +1544,6 @@ namespace Server.Engines.ConPVP
|
|||
if (StartedReadyCountdown)
|
||||
return; // sanity
|
||||
|
||||
Type[] types = { typeof(DuelContextGump), typeof(ReadyUpGump), typeof(ReadyGump) };
|
||||
int[] defs = { -1, -1, -1 };
|
||||
|
||||
for (int i = 0; i < Participants.Count; ++i)
|
||||
{
|
||||
Participant p = (Participant)Participants[i];
|
||||
|
|
@ -1612,10 +1571,11 @@ namespace Server.Engines.ConPVP
|
|||
else
|
||||
mob.SendMessage(0x22, "{0} has rejected the {1}.", rejector.Name, Rematch ? "rematch" : page);
|
||||
}
|
||||
|
||||
for (int k = 0; k < types.Length; ++k)
|
||||
mob.CloseGump(types[k]);
|
||||
//mob.CloseGump( types[k], defs[k] );
|
||||
|
||||
// Close all of them?
|
||||
mob.CloseGump<DuelContextGump>();
|
||||
mob.CloseGump<ReadyUpGump>();
|
||||
mob.CloseGump<ReadyGump>();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1655,7 +1615,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
ArchProtectionSpell.RemoveEntry(mob);
|
||||
|
||||
mob.EndAction(typeof(DefensiveSpell));
|
||||
mob.EndAction<DefensiveSpell>();
|
||||
}
|
||||
|
||||
TransformationSpellHelper.RemoveContext(mob, true);
|
||||
|
|
@ -1664,11 +1624,11 @@ namespace Server.Engines.ConPVP
|
|||
if (DisguiseTimers.IsDisguised(mob))
|
||||
DisguiseTimers.StopTimer(mob);
|
||||
|
||||
if (!mob.CanBeginAction(typeof(PolymorphSpell)))
|
||||
if (!mob.CanBeginAction<PolymorphSpell>())
|
||||
{
|
||||
mob.BodyMod = 0;
|
||||
mob.HueMod = -1;
|
||||
mob.EndAction(typeof(PolymorphSpell));
|
||||
mob.EndAction<PolymorphSpell>();
|
||||
}
|
||||
|
||||
BaseArmor.ValidateMobile(mob);
|
||||
|
|
@ -1692,7 +1652,7 @@ namespace Server.Engines.ConPVP
|
|||
public void DestroyWall()
|
||||
{
|
||||
for (int i = 0; i < m_Walls.Count; ++i)
|
||||
((Item)m_Walls[i]).Delete();
|
||||
m_Walls[i].Delete();
|
||||
|
||||
m_Walls.Clear();
|
||||
}
|
||||
|
|
@ -1739,11 +1699,11 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
for (int i = 0; i < Participants.Count; ++i)
|
||||
{
|
||||
Participant p = (Participant)Participants[i];
|
||||
Participant p = Participants[i];
|
||||
|
||||
if (p.Players.Length > 1)
|
||||
{
|
||||
ArrayList players = new ArrayList();
|
||||
List<Mobile> players = new List<Mobile>();
|
||||
|
||||
for (int j = 0; j < p.Players.Length; ++j)
|
||||
{
|
||||
|
|
@ -1758,7 +1718,7 @@ namespace Server.Engines.ConPVP
|
|||
if (players.Count > 1)
|
||||
for (int leaderIndex = 0; leaderIndex + 1 < players.Count; leaderIndex += Party.Capacity)
|
||||
{
|
||||
Mobile leader = (Mobile)players[leaderIndex];
|
||||
Mobile leader = players[leaderIndex];
|
||||
Party party = Party.Get(leader);
|
||||
|
||||
if (party == null)
|
||||
|
|
@ -1774,7 +1734,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
for (int j = leaderIndex + 1; j < players.Count && j < leaderIndex + Party.Capacity; ++j)
|
||||
{
|
||||
Mobile player = (Mobile)players[j];
|
||||
Mobile player = players[j];
|
||||
Party existing = Party.Get(player);
|
||||
|
||||
if (existing == party)
|
||||
|
|
@ -1807,7 +1767,7 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
for (int i = 0; i < Participants.Count; ++i)
|
||||
{
|
||||
Participant p = (Participant)Participants[i];
|
||||
Participant p = Participants[i];
|
||||
|
||||
for (int j = 0; j < p.Players.Length; ++j)
|
||||
{
|
||||
|
|
@ -1945,11 +1905,9 @@ namespace Server.Engines.ConPVP
|
|||
BeginAutoTie();
|
||||
}
|
||||
|
||||
Type[] types = { typeof(ReadyGump), typeof(ReadyUpGump), typeof(BeginGump) };
|
||||
|
||||
for (int i = 0; i < Participants.Count; ++i)
|
||||
{
|
||||
Participant p = (Participant)Participants[i];
|
||||
Participant p = Participants[i];
|
||||
|
||||
for (int j = 0; j < p.Players.Length; ++j)
|
||||
{
|
||||
|
|
@ -1963,13 +1921,18 @@ namespace Server.Engines.ConPVP
|
|||
if (count > 0)
|
||||
{
|
||||
if (count == 10)
|
||||
CloseAndSendGump(mob, new BeginGump(count), types);
|
||||
{
|
||||
mob.CloseGump<ReadyGump>();
|
||||
mob.CloseGump<ReadyUpGump>();
|
||||
mob.CloseGump<BeginGump>();
|
||||
mob.SendGump(new BeginGump(count));
|
||||
}
|
||||
|
||||
mob.Frozen = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mob.CloseGump(typeof(BeginGump));
|
||||
mob.CloseGump<BeginGump>();
|
||||
mob.Frozen = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1980,7 +1943,7 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
for (int i = 0; i < Participants.Count; ++i)
|
||||
{
|
||||
Participant p = (Participant)Participants[i];
|
||||
Participant p = Participants[i];
|
||||
|
||||
for (int j = 0; j < p.Players.Length; ++j)
|
||||
{
|
||||
|
|
@ -2005,11 +1968,9 @@ namespace Server.Engines.ConPVP
|
|||
ReadyWait = true;
|
||||
ReadyCount = -1;
|
||||
|
||||
Type[] types = { typeof(ReadyUpGump) };
|
||||
|
||||
for (int i = 0; i < Participants.Count; ++i)
|
||||
{
|
||||
Participant p = (Participant)Participants[i];
|
||||
Participant p = Participants[i];
|
||||
|
||||
for (int j = 0; j < p.Players.Length; ++j)
|
||||
{
|
||||
|
|
@ -2017,9 +1978,11 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
Mobile mob = pl?.Mobile;
|
||||
|
||||
if (mob != null)
|
||||
if (m_Tournament == null)
|
||||
CloseAndSendGump(mob, new ReadyUpGump(mob, this), types);
|
||||
if (mob != null && m_Tournament == null)
|
||||
{
|
||||
mob.CloseGump<ReadyUpGump>();
|
||||
mob.SendGump(new ReadyUpGump(mob, this));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2031,7 +1994,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
for (int i = 0; i < Participants.Count; ++i)
|
||||
{
|
||||
Participant p = (Participant)Participants[i];
|
||||
Participant p = Participants[i];
|
||||
|
||||
for (int j = 0; j < p.Players.Length; ++j)
|
||||
{
|
||||
|
|
@ -2040,7 +2003,7 @@ namespace Server.Engines.ConPVP
|
|||
if (dp == null)
|
||||
return "a slot is empty";
|
||||
|
||||
if (dp.Mobile.Region.IsPartOf(typeof(Jail)))
|
||||
if (dp.Mobile.Region.IsPartOf<Jail>())
|
||||
return $"{dp.Mobile.Name} is in jail";
|
||||
|
||||
if (Sigil.ExistsOn(dp.Mobile))
|
||||
|
|
@ -2089,7 +2052,7 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
for (int i = 0; i < Participants.Count; ++i)
|
||||
{
|
||||
Participant p = (Participant)Participants[i];
|
||||
Participant p = Participants[i];
|
||||
|
||||
for (int j = 0; j < p.Players.Length; ++j)
|
||||
{
|
||||
|
|
@ -2110,7 +2073,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
for (int i = 0; i < Participants.Count; ++i)
|
||||
{
|
||||
Participant p = (Participant)Participants[i];
|
||||
Participant p = Participants[i];
|
||||
|
||||
for (int j = 0; j < p.Players.Length; ++j)
|
||||
{
|
||||
|
|
@ -2130,7 +2093,7 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
for (int i = 0; i < Participants.Count; ++i)
|
||||
{
|
||||
Participant p = (Participant)Participants[i];
|
||||
Participant p = Participants[i];
|
||||
|
||||
for (int j = 0; j < p.Players.Length; ++j)
|
||||
{
|
||||
|
|
@ -2173,7 +2136,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
for (int i = 0; i < Participants.Count; ++i)
|
||||
{
|
||||
Participant p = (Participant)Participants[i];
|
||||
Participant p = Participants[i];
|
||||
|
||||
for (int j = 0; j < p.Players.Length; ++j)
|
||||
{
|
||||
|
|
@ -2206,7 +2169,7 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
for (int i = 0; i < Participants.Count; ++i)
|
||||
{
|
||||
Participant p = (Participant)Participants[i];
|
||||
Participant p = Participants[i];
|
||||
|
||||
for (int j = 0; j < p.Players.Length; ++j)
|
||||
{
|
||||
|
|
@ -2227,11 +2190,9 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
bool isAllReady = true;
|
||||
|
||||
Type[] types = { typeof(ReadyGump) };
|
||||
|
||||
for (int i = 0; i < Participants.Count; ++i)
|
||||
{
|
||||
Participant p = (Participant)Participants[i];
|
||||
Participant p = Participants[i];
|
||||
|
||||
for (int j = 0; j < p.Players.Length; ++j)
|
||||
{
|
||||
|
|
@ -2245,7 +2206,10 @@ namespace Server.Engines.ConPVP
|
|||
if (pl.Ready)
|
||||
{
|
||||
if (m_Tournament == null)
|
||||
CloseAndSendGump(mob, new ReadyGump(mob, this, count), types);
|
||||
{
|
||||
mob.CloseGump<ReadyGump>();
|
||||
mob.SendGump(new ReadyGump(mob, this, count));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2258,45 +2222,6 @@ namespace Server.Engines.ConPVP
|
|||
StartCountdown(3, SendReadyGump);
|
||||
}
|
||||
|
||||
public static void CloseAndSendGump(Mobile mob, Gump g, params Type[] types)
|
||||
{
|
||||
CloseAndSendGump(mob.NetState, g, types);
|
||||
}
|
||||
|
||||
public static void CloseAndSendGump(NetState ns, Gump g, params Type[] types)
|
||||
{
|
||||
Mobile mob = ns?.Mobile;
|
||||
|
||||
if (mob != null)
|
||||
{
|
||||
foreach (Type type in types) mob.CloseGump(type);
|
||||
|
||||
mob.SendGump(g);
|
||||
}
|
||||
|
||||
/*if ( ns == null )
|
||||
return;
|
||||
|
||||
for ( int i = 0; i < types.Length; ++i )
|
||||
ns.Send( new CloseGump( Gump.GetTypeID( types[i] ), 0 ) );
|
||||
|
||||
g.SendTo( ns );
|
||||
|
||||
ns.AddGump( g );
|
||||
|
||||
Packet[] packets = new Packet[types.Length + 1];
|
||||
|
||||
for ( int i = 0; i < types.Length; ++i )
|
||||
packets[i] = new CloseGump( Gump.GetTypeID( types[i] ), 0 );
|
||||
|
||||
packets[types.Length] = (Packet) typeof( Gump ).InvokeMember( "Compile", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, g, null, null );
|
||||
|
||||
bool compress = ns.CompressionEnabled;
|
||||
ns.CompressionEnabled = false;
|
||||
ns.Send( BindPackets( compress, packets ) );
|
||||
ns.CompressionEnabled = compress;*/
|
||||
}
|
||||
|
||||
private class InternalWall : Item
|
||||
{
|
||||
public InternalWall() : base(0x80)
|
||||
|
|
@ -2395,11 +2320,11 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
private class ExitTeleporter : Item
|
||||
{
|
||||
private ArrayList m_Entries;
|
||||
private List<ReturnEntry> m_Entries;
|
||||
|
||||
public ExitTeleporter() : base(0x1822)
|
||||
{
|
||||
m_Entries = new ArrayList();
|
||||
m_Entries = new List<ReturnEntry>();
|
||||
|
||||
Hue = 0x482;
|
||||
Movable = false;
|
||||
|
|
@ -2428,7 +2353,7 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
for (int i = 0; i < m_Entries.Count; ++i)
|
||||
{
|
||||
ReturnEntry entry = (ReturnEntry)m_Entries[i];
|
||||
ReturnEntry entry = m_Entries[i];
|
||||
|
||||
if (entry.Mobile == mob)
|
||||
return entry;
|
||||
|
|
@ -2472,7 +2397,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
for (int i = 0; i < m_Entries.Count; ++i)
|
||||
{
|
||||
ReturnEntry entry = (ReturnEntry)m_Entries[i];
|
||||
ReturnEntry entry = m_Entries[i];
|
||||
|
||||
writer.Write(entry.Mobile);
|
||||
writer.Write(entry.Location);
|
||||
|
|
@ -2495,7 +2420,7 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
int count = reader.ReadEncodedInt();
|
||||
|
||||
m_Entries = new ArrayList(count);
|
||||
m_Entries = new List<ReturnEntry>(count);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
|
|
@ -2586,35 +2511,5 @@ namespace Server.Engines.ConPVP
|
|||
Delete();
|
||||
}
|
||||
}
|
||||
|
||||
/*public static Packet BindPackets( bool compress, params Packet[] packets )
|
||||
{
|
||||
if ( packets.Length == 0 )
|
||||
throw new ArgumentException( "No packets to bind", "packets" );
|
||||
|
||||
byte[][] compiled = new byte[packets.Length][];
|
||||
int[] lengths = new int[packets.Length];
|
||||
|
||||
int length = 0;
|
||||
|
||||
for ( int i = 0; i < packets.Length; ++i )
|
||||
{
|
||||
compiled[i] = packets[i].Compile( compress, out lengths[i] );
|
||||
length += lengths[i];
|
||||
}
|
||||
|
||||
return new BoundPackets( length, compiled, lengths );
|
||||
}
|
||||
|
||||
private class BoundPackets : Packet
|
||||
{
|
||||
public BoundPackets( int length, byte[][] compiled, int[] lengths ) : base( 0, length )
|
||||
{
|
||||
m_Stream.Seek( 0, System.IO.SeekOrigin.Begin );
|
||||
|
||||
for ( int i = 0; i < compiled.Length; ++i )
|
||||
m_Stream.Write( compiled[i], 0, lengths[i] );
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
|
|
@ -15,7 +16,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
private BRGame m_Game;
|
||||
|
||||
private ArrayList m_Helpers;
|
||||
private List<Mobile> m_Helpers;
|
||||
|
||||
private Point3DList m_Path = new Point3DList();
|
||||
private int m_PathIdx;
|
||||
|
|
@ -29,7 +30,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
m_Game = game;
|
||||
|
||||
m_Helpers = new ArrayList();
|
||||
m_Helpers = new List<Mobile>();
|
||||
|
||||
m_Timer = new EffectTimer(this);
|
||||
m_Timer.Start();
|
||||
|
|
@ -230,7 +231,7 @@ namespace Server.Engines.ConPVP
|
|||
private void DoAnim(Point3D start, Point3D end, Map map)
|
||||
{
|
||||
Effects.SendMovingEffect(new Entity(Serial.Zero, start, map), new Entity(Serial.Zero, end, map),
|
||||
ItemID, 15, 0, false, false, Hue, 0);
|
||||
ItemID, 15, 0, false, false, Hue);
|
||||
}
|
||||
|
||||
private void DoCatch(Mobile m)
|
||||
|
|
@ -270,29 +271,21 @@ namespace Server.Engines.ConPVP
|
|||
dest = swap;
|
||||
}*/
|
||||
|
||||
ArrayList list = new ArrayList();
|
||||
double rise, run, zslp;
|
||||
double dist3d, dist2d;
|
||||
double x, y, z;
|
||||
int xd, yd, zd;
|
||||
Point3D p;
|
||||
List<Point3D> list = new List<Point3D>();
|
||||
|
||||
xd = dest.X - org.X;
|
||||
yd = dest.Y - org.Y;
|
||||
zd = dest.Z - org.Z;
|
||||
dist2d = Math.Sqrt(xd * xd + yd * yd);
|
||||
if (zd != 0)
|
||||
dist3d = Math.Sqrt(dist2d * dist2d + zd * zd);
|
||||
else
|
||||
dist3d = dist2d;
|
||||
int xd = dest.X - org.X;
|
||||
int yd = dest.Y - org.Y;
|
||||
int zd = dest.Z - org.Z;
|
||||
double dist2d = Math.Sqrt(xd * xd + yd * yd);
|
||||
double dist3d = zd == 0 ? dist2d : Math.Sqrt(dist2d * dist2d + zd * zd);
|
||||
|
||||
rise = yd / dist3d;
|
||||
run = xd / dist3d;
|
||||
zslp = zd / dist3d;
|
||||
double rise = yd / dist3d;
|
||||
double run = xd / dist3d;
|
||||
double zslp = zd / dist3d;
|
||||
|
||||
x = org.X;
|
||||
y = org.Y;
|
||||
z = org.Z;
|
||||
double x = org.X;
|
||||
double y = org.Y;
|
||||
double z = org.Z;
|
||||
while (Utility.NumberBetween(x, dest.X, org.X, 0.5) && Utility.NumberBetween(y, dest.Y, org.Y, 0.5) &&
|
||||
Utility.NumberBetween(z, dest.Z, org.Z, 0.5))
|
||||
{
|
||||
|
|
@ -302,7 +295,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
if (list.Count > 0)
|
||||
{
|
||||
p = (Point3D)list[list.Count - 1];
|
||||
Point3D p = list[list.Count - 1];
|
||||
|
||||
if (p.X != ix || p.Y != iy || p.Z != iz)
|
||||
list.Add(new Point3D(ix, iy, iz));
|
||||
|
|
@ -317,9 +310,8 @@ namespace Server.Engines.ConPVP
|
|||
z += zslp;
|
||||
}
|
||||
|
||||
if (list.Count > 0)
|
||||
if ((Point3D)list[list.Count - 1] != dest)
|
||||
list.Add(dest);
|
||||
if (list.Count > 0 && list[list.Count - 1] != dest)
|
||||
list.Add(dest);
|
||||
|
||||
/*if ( dist3d > 4 && ( dest.X != org.X || dest.Y != org.Y ) )
|
||||
{
|
||||
|
|
@ -359,7 +351,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
p = (Point3D)list[i];
|
||||
Point3D p = list[i];
|
||||
|
||||
int xp = i - count / 2;
|
||||
|
||||
|
|
@ -371,7 +363,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
m_Path.Clear();
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
m_Path.Add((Point3D)list[i]);
|
||||
m_Path.Add(list[i]);
|
||||
|
||||
m_PathIdx = 0;
|
||||
|
||||
|
|
@ -616,7 +608,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
for (int i = m_Helpers.Count - 1; i >= 0; i--)
|
||||
{
|
||||
Mobile mob = (Mobile)m_Helpers[i];
|
||||
Mobile mob = m_Helpers[i];
|
||||
|
||||
BRPlayerInfo pi = team[mob];
|
||||
if (pi != null)
|
||||
|
|
@ -661,7 +653,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
if (m_Helpers.Count > 0)
|
||||
{
|
||||
Mobile last = (Mobile)m_Helpers[0];
|
||||
Mobile last = m_Helpers[0];
|
||||
|
||||
if (m_Game.GetTeamInfo(last) != team)
|
||||
m_Helpers.Clear();
|
||||
|
|
@ -951,7 +943,7 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
if (m_TeamInfo?.Game != null)
|
||||
{
|
||||
from.CloseGump(typeof(BRBoardGump));
|
||||
from.CloseGump<BRBoardGump>();
|
||||
from.SendGump(new BRBoardGump(from, m_TeamInfo.Game));
|
||||
}
|
||||
}
|
||||
|
|
@ -983,16 +975,17 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
}
|
||||
|
||||
public BRBoardGump(Mobile mob, BRGame game, BRTeamInfo section)
|
||||
: base(60, 60)
|
||||
public BRBoardGump(Mobile mob, BRGame game, BRTeamInfo section) : base(60, 60)
|
||||
{
|
||||
m_Game = game;
|
||||
|
||||
BRTeamInfo ourTeam = game.GetTeamInfo(mob);
|
||||
|
||||
ArrayList entries = new ArrayList();
|
||||
List<BRTeamInfo> entries = new List<BRTeamInfo>();
|
||||
int total = 0;
|
||||
|
||||
if (section == null)
|
||||
{
|
||||
for (int i = 0; i < game.Context.Participants.Count; ++i)
|
||||
{
|
||||
BRTeamInfo teamInfo = game.Controller.TeamInfo[i % game.Controller.TeamInfo.Length];
|
||||
|
|
@ -1002,17 +995,15 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
entries.Add(teamInfo);
|
||||
}
|
||||
|
||||
total = entries.Count;
|
||||
}
|
||||
else
|
||||
foreach (BRPlayerInfo player in section.Players.Values)
|
||||
if (player.Score > 0)
|
||||
entries.Add(player);
|
||||
total++;
|
||||
|
||||
entries.Sort();
|
||||
/*
|
||||
delegate( IRankedCTF a, IRankedCTF b )
|
||||
{
|
||||
return b.Score - a.Score;
|
||||
} );*/
|
||||
|
||||
int height = 0;
|
||||
|
||||
|
|
@ -1027,7 +1018,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
AddImageTiled(16, 15, 369, height - 29, 3604);
|
||||
|
||||
for (int i = 0; i < entries.Count; i += 1)
|
||||
for (int i = 0; i < total; i += 1)
|
||||
AddImageTiled(22, 58 + i * 75, 357, 70, 0x2430);
|
||||
|
||||
AddAlphaRegion(16, 15, 369, height - 29);
|
||||
|
|
@ -1043,7 +1034,7 @@ namespace Server.Engines.ConPVP
|
|||
if (section == null)
|
||||
for (int i = 0; i < entries.Count; ++i)
|
||||
{
|
||||
BRTeamInfo teamInfo = entries[i] as BRTeamInfo;
|
||||
BRTeamInfo teamInfo = entries[i];
|
||||
|
||||
AddImage(30, 70 + i * 75, 10152);
|
||||
AddImage(30, 85 + i * 75, 10151);
|
||||
|
|
@ -1208,20 +1199,20 @@ namespace Server.Engines.ConPVP
|
|||
}
|
||||
|
||||
[PropertyObject]
|
||||
public sealed class BRTeamInfo : IRankedCTF, IComparable
|
||||
public sealed class BRTeamInfo : IRankedCTF, IComparable<BRTeamInfo>
|
||||
{
|
||||
private BRGoal m_Goal;
|
||||
|
||||
public BRTeamInfo(int teamID)
|
||||
{
|
||||
TeamID = teamID;
|
||||
Players = new Hashtable();
|
||||
Players = new Dictionary<Mobile, BRPlayerInfo>();
|
||||
}
|
||||
|
||||
public BRTeamInfo(int teamID, GenericReader ip)
|
||||
{
|
||||
TeamID = teamID;
|
||||
Players = new Hashtable();
|
||||
Players = new Dictionary<Mobile, BRPlayerInfo>();
|
||||
|
||||
int version = ip.ReadEncodedInt();
|
||||
|
||||
|
|
@ -1247,7 +1238,7 @@ namespace Server.Engines.ConPVP
|
|||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public BRBoard Board{ get; set; }
|
||||
|
||||
public Hashtable Players{ get; }
|
||||
public Dictionary<Mobile, BRPlayerInfo> Players{ get; }
|
||||
|
||||
public BRPlayerInfo this[Mobile mob]
|
||||
{
|
||||
|
|
@ -1281,9 +1272,8 @@ namespace Server.Engines.ConPVP
|
|||
}
|
||||
}
|
||||
|
||||
public int CompareTo(object obj)
|
||||
public int CompareTo(BRTeamInfo ti)
|
||||
{
|
||||
BRTeamInfo ti = (BRTeamInfo)obj;
|
||||
int res = ti.Captures.CompareTo(Captures);
|
||||
if (res == 0)
|
||||
{
|
||||
|
|
@ -1367,32 +1357,16 @@ namespace Server.Engines.ConPVP
|
|||
public BRTeamInfo[] TeamInfo{ get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public BRTeamInfo Team1
|
||||
{
|
||||
get => TeamInfo[0];
|
||||
set { }
|
||||
}
|
||||
public BRTeamInfo Team1 => TeamInfo[0];
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public BRTeamInfo Team2
|
||||
{
|
||||
get => TeamInfo[1];
|
||||
set { }
|
||||
}
|
||||
public BRTeamInfo Team2 => TeamInfo[1];
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public BRTeamInfo Team3
|
||||
{
|
||||
get => TeamInfo[2];
|
||||
set { }
|
||||
}
|
||||
public BRTeamInfo Team3 => TeamInfo[2];
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public BRTeamInfo Team4
|
||||
{
|
||||
get => TeamInfo[3];
|
||||
set { }
|
||||
}
|
||||
public BRTeamInfo Team4 => TeamInfo[3];
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TimeSpan Duration{ get; set; }
|
||||
|
|
@ -1515,7 +1489,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
for (int i = 0; i < m_Context.Participants.Count; ++i)
|
||||
{
|
||||
Participant p = m_Context.Participants[i] as Participant;
|
||||
Participant p = m_Context.Participants[i];
|
||||
|
||||
for (int j = 0; j < p.Players.Length; ++j)
|
||||
if (p.Players[j] != null)
|
||||
|
|
@ -1566,19 +1540,12 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
public void DelayBounce(TimeSpan ts, Mobile mob, Container corpse)
|
||||
{
|
||||
Timer.DelayCall(ts, new TimerStateCallback(DelayBounce_Callback), new object[] { mob, corpse });
|
||||
Timer.DelayCall(ts, () => DelayBounce_Callback(mob, corpse));
|
||||
}
|
||||
|
||||
private void DelayBounce_Callback(object state)
|
||||
private void DelayBounce_Callback(Mobile mob, Container corpse)
|
||||
{
|
||||
object[] states = (object[])state;
|
||||
Mobile mob = (Mobile)states[0];
|
||||
Container corpse = (Container)states[1];
|
||||
|
||||
DuelPlayer dp = null;
|
||||
|
||||
if (mob is PlayerMobile mobile)
|
||||
dp = mobile.DuelPlayer;
|
||||
DuelPlayer dp = mob is PlayerMobile mobile ? mobile.DuelPlayer : null;
|
||||
|
||||
m_Context.RemoveAggressions(mob);
|
||||
|
||||
|
|
@ -1631,7 +1598,7 @@ namespace Server.Engines.ConPVP
|
|||
}
|
||||
}
|
||||
|
||||
mob.CloseGump(typeof(BRBoardGump));
|
||||
mob.CloseGump<BRBoardGump>();
|
||||
mob.SendGump(new BRBoardGump(mob, this));
|
||||
|
||||
m_Context.Requip(mob, corpse);
|
||||
|
|
@ -1651,7 +1618,7 @@ namespace Server.Engines.ConPVP
|
|||
}
|
||||
|
||||
for (int i = 0; i < m_Context.Participants.Count; ++i)
|
||||
ApplyHues(m_Context.Participants[i] as Participant,
|
||||
ApplyHues(m_Context.Participants[i],
|
||||
Controller.TeamInfo[i % Controller.TeamInfo.Length].Color);
|
||||
|
||||
m_FinishTimer?.Stop();
|
||||
|
|
@ -1664,51 +1631,49 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
private void Finish_Callback()
|
||||
{
|
||||
ArrayList teams = new ArrayList();
|
||||
List<BRTeamInfo> teams = new List<BRTeamInfo>();
|
||||
|
||||
for (int i = 0; i < m_Context.Participants.Count; ++i)
|
||||
{
|
||||
BRTeamInfo teamInfo = Controller.TeamInfo[i % Controller.TeamInfo.Length];
|
||||
|
||||
if (teamInfo == null)
|
||||
continue;
|
||||
|
||||
teams.Add(teamInfo);
|
||||
if (teamInfo != null)
|
||||
teams.Add(teamInfo);
|
||||
}
|
||||
|
||||
teams.Sort();
|
||||
|
||||
Tournament tourny = m_Context.m_Tournament;
|
||||
Tournament tourney = m_Context.m_Tournament;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
if (tourny != null && tourny.TournyType == TournyType.FreeForAll)
|
||||
if (tourney != null && tourney.TourneyType == TourneyType.FreeForAll)
|
||||
{
|
||||
sb.Append(m_Context.Participants.Count * tourny.PlayersPerParticipant);
|
||||
sb.Append(m_Context.Participants.Count * tourney.PlayersPerParticipant);
|
||||
sb.Append("-man FFA");
|
||||
}
|
||||
else if (tourny != null && tourny.TournyType == TournyType.RandomTeam)
|
||||
else if (tourney != null && tourney.TourneyType == TourneyType.RandomTeam)
|
||||
{
|
||||
sb.Append(tourny.ParticipantsPerMatch);
|
||||
sb.Append(tourney.ParticipantsPerMatch);
|
||||
sb.Append("-team");
|
||||
}
|
||||
else if (tourny != null && tourny.TournyType == TournyType.RedVsBlue)
|
||||
else if (tourney != null && tourney.TourneyType == TourneyType.RedVsBlue)
|
||||
{
|
||||
sb.Append("Red v Blue");
|
||||
}
|
||||
else if (tourny != null && tourny.TournyType == TournyType.Faction)
|
||||
else if (tourney != null && tourney.TourneyType == TourneyType.Faction)
|
||||
{
|
||||
sb.Append(tourny.ParticipantsPerMatch);
|
||||
sb.Append(tourney.ParticipantsPerMatch);
|
||||
sb.Append("-team Faction");
|
||||
}
|
||||
else if (tourny != null)
|
||||
else if (tourney != null)
|
||||
{
|
||||
for (int i = 0; i < tourny.ParticipantsPerMatch; ++i)
|
||||
for (int i = 0; i < tourney.ParticipantsPerMatch; ++i)
|
||||
{
|
||||
if (sb.Length > 0)
|
||||
sb.Append('v');
|
||||
|
||||
sb.Append(tourny.PlayersPerParticipant);
|
||||
sb.Append(tourney.PlayersPerParticipant);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1717,7 +1682,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
string title = sb.ToString();
|
||||
|
||||
BRTeamInfo winner = (BRTeamInfo)(teams.Count > 0 ? teams[0] : null);
|
||||
BRTeamInfo winner = teams.Count > 0 ? teams[0] : null;
|
||||
|
||||
for (int i = 0; i < teams.Count; ++i)
|
||||
{
|
||||
|
|
@ -1728,9 +1693,9 @@ namespace Server.Engines.ConPVP
|
|||
else if (i == 1)
|
||||
rank = TrophyRank.Silver;
|
||||
|
||||
BRPlayerInfo leader = ((BRTeamInfo)teams[i]).Leader;
|
||||
BRPlayerInfo leader = teams[i].Leader;
|
||||
|
||||
foreach (BRPlayerInfo pl in ((BRTeamInfo)teams[i]).Players.Values)
|
||||
foreach (BRPlayerInfo pl in teams[i].Players.Values)
|
||||
{
|
||||
Mobile mob = pl.Player;
|
||||
|
||||
|
|
@ -1767,7 +1732,7 @@ namespace Server.Engines.ConPVP
|
|||
if (pl == leader)
|
||||
item.ItemID = 4810;
|
||||
|
||||
item.Name = $"{item.Name}, {((BRTeamInfo)teams[i]).Name.ToLower()} team";
|
||||
item.Name = $"{item.Name}, {teams[i].Name.ToLower()} team";
|
||||
|
||||
if (!mob.PlaceInBackpack(item))
|
||||
mob.BankBox.DropItem(item);
|
||||
|
|
@ -1804,7 +1769,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
if (dp?.Mobile != null)
|
||||
{
|
||||
dp.Mobile.CloseGump(typeof(BRBoardGump));
|
||||
dp.Mobile.CloseGump<BRBoardGump>();
|
||||
dp.Mobile.SendGump(new BRBoardGump(dp.Mobile, this));
|
||||
}
|
||||
}
|
||||
|
|
@ -1818,7 +1783,7 @@ namespace Server.Engines.ConPVP
|
|||
p.Players[j].Eliminated = true;
|
||||
}
|
||||
|
||||
m_Context.Finish(m_Context.Participants[winner.TeamID] as Participant);
|
||||
m_Context.Finish(m_Context.Participants[winner.TeamID]);
|
||||
}
|
||||
|
||||
public override void OnStop()
|
||||
|
|
@ -1838,10 +1803,10 @@ namespace Server.Engines.ConPVP
|
|||
m_Bomb?.Delete();
|
||||
|
||||
for (int i = 0; i < m_Context.Participants.Count; ++i)
|
||||
ApplyHues(m_Context.Participants[i] as Participant, -1);
|
||||
ApplyHues(m_Context.Participants[i], -1);
|
||||
|
||||
m_FinishTimer?.Stop();
|
||||
m_FinishTimer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
if (m_TeamInfo?.Game != null)
|
||||
{
|
||||
from.CloseGump(typeof(CTFBoardGump));
|
||||
from.CloseGump<CTFBoardGump>();
|
||||
from.SendGump(new CTFBoardGump(from, m_TeamInfo.Game));
|
||||
}
|
||||
}
|
||||
|
|
@ -58,12 +58,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
private CTFGame m_Game;
|
||||
|
||||
public CTFBoardGump(Mobile mob, CTFGame game)
|
||||
: this(mob, game, null)
|
||||
{
|
||||
}
|
||||
|
||||
public CTFBoardGump(Mobile mob, CTFGame game, CTFTeamInfo section)
|
||||
public CTFBoardGump(Mobile mob, CTFGame game, CTFTeamInfo section = null)
|
||||
: base(60, 60)
|
||||
{
|
||||
m_Game = game;
|
||||
|
|
@ -719,60 +714,28 @@ namespace Server.Engines.ConPVP
|
|||
public CTFTeamInfo[] TeamInfo{ get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public CTFTeamInfo Team1
|
||||
{
|
||||
get => TeamInfo[0];
|
||||
set { }
|
||||
}
|
||||
public CTFTeamInfo Team1 => TeamInfo[0];
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public CTFTeamInfo Team2
|
||||
{
|
||||
get => TeamInfo[1];
|
||||
set { }
|
||||
}
|
||||
public CTFTeamInfo Team2 => TeamInfo[1];
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public CTFTeamInfo Team3
|
||||
{
|
||||
get => TeamInfo[2];
|
||||
set { }
|
||||
}
|
||||
public CTFTeamInfo Team3 => TeamInfo[2];
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public CTFTeamInfo Team4
|
||||
{
|
||||
get => TeamInfo[3];
|
||||
set { }
|
||||
}
|
||||
public CTFTeamInfo Team4 => TeamInfo[3];
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public CTFTeamInfo Team5
|
||||
{
|
||||
get => TeamInfo[4];
|
||||
set { }
|
||||
}
|
||||
public CTFTeamInfo Team5 => TeamInfo[4];
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public CTFTeamInfo Team6
|
||||
{
|
||||
get => TeamInfo[5];
|
||||
set { }
|
||||
}
|
||||
public CTFTeamInfo Team6 => TeamInfo[5];
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public CTFTeamInfo Team7
|
||||
{
|
||||
get => TeamInfo[6];
|
||||
set { }
|
||||
}
|
||||
public CTFTeamInfo Team7 => TeamInfo[6];
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public CTFTeamInfo Team8
|
||||
{
|
||||
get => TeamInfo[7];
|
||||
set { }
|
||||
}
|
||||
public CTFTeamInfo Team8 => TeamInfo[7];
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TimeSpan Duration{ get; set; }
|
||||
|
|
@ -876,7 +839,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
for (int i = 0; i < m_Context.Participants.Count; ++i)
|
||||
{
|
||||
Participant p = m_Context.Participants[i] as Participant;
|
||||
Participant p = m_Context.Participants[i];
|
||||
|
||||
for (int j = 0; j < p.Players.Length; ++j)
|
||||
if (p.Players[j] != null)
|
||||
|
|
@ -932,19 +895,12 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
public void DelayBounce(TimeSpan ts, Mobile mob, Container corpse)
|
||||
{
|
||||
Timer.DelayCall(ts, new TimerStateCallback(DelayBounce_Callback), new object[] { mob, corpse });
|
||||
Timer.DelayCall(ts, () => DelayBounce_Callback(mob, corpse));
|
||||
}
|
||||
|
||||
private void DelayBounce_Callback(object state)
|
||||
private void DelayBounce_Callback(Mobile mob, Container corpse)
|
||||
{
|
||||
object[] states = (object[])state;
|
||||
Mobile mob = (Mobile)states[0];
|
||||
Container corpse = (Container)states[1];
|
||||
|
||||
DuelPlayer dp = null;
|
||||
|
||||
if (mob is PlayerMobile mobile)
|
||||
dp = mobile.DuelPlayer;
|
||||
DuelPlayer dp = mob is PlayerMobile mobile ? mobile.DuelPlayer : null;
|
||||
|
||||
m_Context.RemoveAggressions(mob);
|
||||
|
||||
|
|
@ -1027,7 +983,7 @@ namespace Server.Engines.ConPVP
|
|||
}
|
||||
}
|
||||
|
||||
mob.CloseGump(typeof(CTFBoardGump));
|
||||
mob.CloseGump<CTFBoardGump>();
|
||||
mob.SendGump(new CTFBoardGump(mob, this));
|
||||
|
||||
m_Context.Requip(mob, corpse);
|
||||
|
|
@ -1047,7 +1003,7 @@ namespace Server.Engines.ConPVP
|
|||
}
|
||||
|
||||
for (int i = 0; i < m_Context.Participants.Count; ++i)
|
||||
ApplyHues(m_Context.Participants[i] as Participant, Controller.TeamInfo[i % 8].Color);
|
||||
ApplyHues(m_Context.Participants[i], Controller.TeamInfo[i % 8].Color);
|
||||
|
||||
m_FinishTimer?.Stop();
|
||||
|
||||
|
|
@ -1070,37 +1026,37 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
teams.Sort(delegate(CTFTeamInfo a, CTFTeamInfo b) { return b.Score - a.Score; });
|
||||
|
||||
Tournament tourny = m_Context.m_Tournament;
|
||||
Tournament tourney = m_Context.m_Tournament;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
if (tourny != null && tourny.TournyType == TournyType.FreeForAll)
|
||||
if (tourney != null && tourney.TourneyType == TourneyType.FreeForAll)
|
||||
{
|
||||
sb.Append(m_Context.Participants.Count * tourny.PlayersPerParticipant);
|
||||
sb.Append(m_Context.Participants.Count * tourney.PlayersPerParticipant);
|
||||
sb.Append("-man FFA");
|
||||
}
|
||||
else if (tourny != null && tourny.TournyType == TournyType.RandomTeam)
|
||||
else if (tourney != null && tourney.TourneyType == TourneyType.RandomTeam)
|
||||
{
|
||||
sb.Append(tourny.ParticipantsPerMatch);
|
||||
sb.Append(tourney.ParticipantsPerMatch);
|
||||
sb.Append("-team");
|
||||
}
|
||||
else if (tourny != null && tourny.TournyType == TournyType.RedVsBlue)
|
||||
else if (tourney != null && tourney.TourneyType == TourneyType.RedVsBlue)
|
||||
{
|
||||
sb.Append("Red v Blue");
|
||||
}
|
||||
else if (tourny != null && tourny.TournyType == TournyType.Faction)
|
||||
else if (tourney != null && tourney.TourneyType == TourneyType.Faction)
|
||||
{
|
||||
sb.Append(tourny.ParticipantsPerMatch);
|
||||
sb.Append(tourney.ParticipantsPerMatch);
|
||||
sb.Append("-team Faction");
|
||||
}
|
||||
else if (tourny != null)
|
||||
else if (tourney != null)
|
||||
{
|
||||
for (int i = 0; i < tourny.ParticipantsPerMatch; ++i)
|
||||
for (int i = 0; i < tourney.ParticipantsPerMatch; ++i)
|
||||
{
|
||||
if (sb.Length > 0)
|
||||
sb.Append('v');
|
||||
|
||||
sb.Append(tourny.PlayersPerParticipant);
|
||||
sb.Append(tourney.PlayersPerParticipant);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1193,7 +1149,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
for (int i = 0; i < m_Context.Participants.Count; ++i)
|
||||
{
|
||||
Participant p = m_Context.Participants[i] as Participant;
|
||||
Participant p = m_Context.Participants[i];
|
||||
|
||||
for (int j = 0; j < p.Players.Length; ++j)
|
||||
{
|
||||
|
|
@ -1201,7 +1157,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
if (dp?.Mobile != null)
|
||||
{
|
||||
dp.Mobile.CloseGump(typeof(CTFBoardGump));
|
||||
dp.Mobile.CloseGump<CTFBoardGump>();
|
||||
dp.Mobile.SendGump(new CTFBoardGump(dp.Mobile, this));
|
||||
}
|
||||
}
|
||||
|
|
@ -1214,7 +1170,7 @@ namespace Server.Engines.ConPVP
|
|||
p.Players[j].Eliminated = true;
|
||||
}
|
||||
|
||||
m_Context.Finish(m_Context.Participants[winner.TeamID] as Participant);
|
||||
m_Context.Finish(m_Context.Participants[winner.TeamID]);
|
||||
}
|
||||
|
||||
public override void OnStop()
|
||||
|
|
@ -1236,7 +1192,7 @@ namespace Server.Engines.ConPVP
|
|||
}
|
||||
|
||||
for (int i = 0; i < m_Context.Participants.Count; ++i)
|
||||
ApplyHues(m_Context.Participants[i] as Participant, -1);
|
||||
ApplyHues(m_Context.Participants[i], -1);
|
||||
|
||||
m_FinishTimer?.Stop();
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
if (m_TeamInfo?.Game != null)
|
||||
{
|
||||
from.CloseGump(typeof(DDBoardGump));
|
||||
from.CloseGump<DDBoardGump>();
|
||||
from.SendGump(new DDBoardGump(from, m_TeamInfo.Game));
|
||||
}
|
||||
}
|
||||
|
|
@ -389,18 +389,10 @@ namespace Server.Engines.ConPVP
|
|||
public DDTeamInfo[] TeamInfo{ get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DDTeamInfo Team1
|
||||
{
|
||||
get => TeamInfo[0];
|
||||
set { }
|
||||
}
|
||||
public DDTeamInfo Team1 => TeamInfo[0];
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DDTeamInfo Team2
|
||||
{
|
||||
get => TeamInfo[1];
|
||||
set { }
|
||||
}
|
||||
public DDTeamInfo Team2 => TeamInfo[1];
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DDWayPoint PointA{ get; set; }
|
||||
|
|
@ -501,7 +493,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
for (int i = 0; i < m_Context.Participants.Count; ++i)
|
||||
{
|
||||
Participant p = m_Context.Participants[i] as Participant;
|
||||
Participant p = m_Context.Participants[i];
|
||||
|
||||
for (int j = 0; j < p.Players.Length; ++j)
|
||||
if (p.Players[j] != null)
|
||||
|
|
@ -552,19 +544,12 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
public void DelayBounce(TimeSpan ts, Mobile mob, Container corpse)
|
||||
{
|
||||
Timer.DelayCall(ts, new TimerStateCallback(DelayBounce_Callback), new object[] { mob, corpse });
|
||||
Timer.DelayCall(ts, () => DelayBounce_Callback(mob, corpse));
|
||||
}
|
||||
|
||||
private void DelayBounce_Callback(object state)
|
||||
private void DelayBounce_Callback(Mobile mob, Container corpse)
|
||||
{
|
||||
object[] states = (object[])state;
|
||||
Mobile mob = (Mobile)states[0];
|
||||
Container corpse = (Container)states[1];
|
||||
|
||||
DuelPlayer dp = null;
|
||||
|
||||
if (mob is PlayerMobile mobile)
|
||||
dp = mobile.DuelPlayer;
|
||||
DuelPlayer dp = mob is PlayerMobile mobile ? mobile.DuelPlayer : null;
|
||||
|
||||
m_Context.RemoveAggressions(mob);
|
||||
|
||||
|
|
@ -613,7 +598,7 @@ namespace Server.Engines.ConPVP
|
|||
}
|
||||
}
|
||||
|
||||
mob.CloseGump(typeof(DDBoardGump));
|
||||
mob.CloseGump<DDBoardGump>();
|
||||
mob.SendGump(new DDBoardGump(mob, this));
|
||||
|
||||
m_Context.Requip(mob, corpse);
|
||||
|
|
@ -653,7 +638,7 @@ namespace Server.Engines.ConPVP
|
|||
Controller.PointB.Game = this;
|
||||
|
||||
for (int i = 0; i < m_Context.Participants.Count; ++i)
|
||||
ApplyHues(m_Context.Participants[i] as Participant,
|
||||
ApplyHues(m_Context.Participants[i],
|
||||
Controller.TeamInfo[i % Controller.TeamInfo.Length].Color);
|
||||
|
||||
m_FinishTimer?.Stop();
|
||||
|
|
@ -674,37 +659,37 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
teams.Sort((a, b) => b.Score - a.Score);
|
||||
|
||||
Tournament tourny = m_Context.m_Tournament;
|
||||
Tournament tourney = m_Context.m_Tournament;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
if (tourny != null && tourny.TournyType == TournyType.FreeForAll)
|
||||
if (tourney != null && tourney.TourneyType == TourneyType.FreeForAll)
|
||||
{
|
||||
sb.Append(m_Context.Participants.Count * tourny.PlayersPerParticipant);
|
||||
sb.Append(m_Context.Participants.Count * tourney.PlayersPerParticipant);
|
||||
sb.Append("-man FFA");
|
||||
}
|
||||
else if (tourny != null && tourny.TournyType == TournyType.RandomTeam)
|
||||
else if (tourney != null && tourney.TourneyType == TourneyType.RandomTeam)
|
||||
{
|
||||
sb.Append(tourny.ParticipantsPerMatch);
|
||||
sb.Append(tourney.ParticipantsPerMatch);
|
||||
sb.Append("-team");
|
||||
}
|
||||
else if (tourny != null && tourny.TournyType == TournyType.RedVsBlue)
|
||||
else if (tourney != null && tourney.TourneyType == TourneyType.RedVsBlue)
|
||||
{
|
||||
sb.Append("Red v Blue");
|
||||
}
|
||||
else if (tourny != null && tourny.TournyType == TournyType.Faction)
|
||||
else if (tourney != null && tourney.TourneyType == TourneyType.Faction)
|
||||
{
|
||||
sb.Append(tourny.ParticipantsPerMatch);
|
||||
sb.Append(tourney.ParticipantsPerMatch);
|
||||
sb.Append("-team Faction");
|
||||
}
|
||||
else if (tourny != null)
|
||||
else if (tourney != null)
|
||||
{
|
||||
for (int i = 0; i < tourny.ParticipantsPerMatch; ++i)
|
||||
for (int i = 0; i < tourney.ParticipantsPerMatch; ++i)
|
||||
{
|
||||
if (sb.Length > 0)
|
||||
sb.Append('v');
|
||||
|
||||
sb.Append(tourny.PlayersPerParticipant);
|
||||
sb.Append(tourney.PlayersPerParticipant);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -797,7 +782,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
for (int i = 0; i < m_Context.Participants.Count; ++i)
|
||||
{
|
||||
Participant p = m_Context.Participants[i] as Participant;
|
||||
Participant p = m_Context.Participants[i];
|
||||
|
||||
for (int j = 0; j < p.Players.Length; ++j)
|
||||
{
|
||||
|
|
@ -805,7 +790,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
if (dp?.Mobile != null)
|
||||
{
|
||||
dp.Mobile.CloseGump(typeof(DDBoardGump));
|
||||
dp.Mobile.CloseGump<DDBoardGump>();
|
||||
dp.Mobile.SendGump(new DDBoardGump(dp.Mobile, this));
|
||||
}
|
||||
}
|
||||
|
|
@ -818,7 +803,7 @@ namespace Server.Engines.ConPVP
|
|||
p.Players[j].Eliminated = true;
|
||||
}
|
||||
|
||||
m_Context.Finish(m_Context.Participants[winner.TeamID] as Participant);
|
||||
m_Context.Finish(m_Context.Participants[winner.TeamID]);
|
||||
}
|
||||
|
||||
public override void OnStop()
|
||||
|
|
@ -854,7 +839,7 @@ namespace Server.Engines.ConPVP
|
|||
}
|
||||
|
||||
for (int i = 0; i < m_Context.Participants.Count; ++i)
|
||||
ApplyHues(m_Context.Participants[i] as Participant, -1);
|
||||
ApplyHues(m_Context.Participants[i], -1);
|
||||
|
||||
m_FinishTimer?.Stop();
|
||||
m_FinishTimer = null;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
|
|
@ -170,12 +171,10 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
private void ReKingify(Mobile m)
|
||||
{
|
||||
KHTeamInfo ti = null;
|
||||
if (m_Game == null || m == null)
|
||||
return;
|
||||
|
||||
ti = m_Game.GetTeamInfo(m);
|
||||
if (ti == null)
|
||||
if (m_Game.GetTeamInfo(m) == null)
|
||||
return;
|
||||
|
||||
King = m;
|
||||
|
|
@ -216,7 +215,6 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
protected override void OnTick()
|
||||
{
|
||||
KHTeamInfo ti = null;
|
||||
KHPlayerInfo pi = null;
|
||||
|
||||
if (m_Hill == null || m_Hill.Deleted || m_Hill.Game == null)
|
||||
|
|
@ -232,7 +230,7 @@ namespace Server.Engines.ConPVP
|
|||
return;
|
||||
}
|
||||
|
||||
ti = m_Hill.Game.GetTeamInfo(m_Hill.King);
|
||||
KHTeamInfo ti = m_Hill.Game.GetTeamInfo(m_Hill.King);
|
||||
if (ti != null)
|
||||
pi = ti[m_Hill.King];
|
||||
|
||||
|
|
@ -251,11 +249,9 @@ namespace Server.Engines.ConPVP
|
|||
if (m_Counter >= m_Hill.ScoreInterval)
|
||||
{
|
||||
string hill = m_Hill.Name;
|
||||
string king = m_Hill.King.Name;
|
||||
if (king == null)
|
||||
king = "";
|
||||
string king = m_Hill.King.Name ?? "";
|
||||
|
||||
if (hill == null || hill == "")
|
||||
if (string.IsNullOrEmpty(hill))
|
||||
hill = "the hill";
|
||||
|
||||
m_Hill.Game.Alert("{0} ({1}) is king of {2}!", king, ti.Name, hill);
|
||||
|
|
@ -315,7 +311,7 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
if (m_Game != null)
|
||||
{
|
||||
from.CloseGump(typeof(KHBoardGump));
|
||||
from.CloseGump<KHBoardGump>();
|
||||
from.SendGump(new KHBoardGump(from, m_Game));
|
||||
}
|
||||
else
|
||||
|
|
@ -364,16 +360,14 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
KHTeamInfo ourTeam = game.GetTeamInfo(mob);
|
||||
|
||||
ArrayList entries = new ArrayList();
|
||||
List<KHTeamInfo> entries = new List<KHTeamInfo>();
|
||||
|
||||
for (int i = 0; i < game.Context.Participants.Count; ++i)
|
||||
{
|
||||
KHTeamInfo teamInfo = game.Controller.TeamInfo[i % game.Controller.TeamInfo.Length];
|
||||
|
||||
if (teamInfo == null)
|
||||
continue;
|
||||
|
||||
entries.Add(teamInfo);
|
||||
if (teamInfo != null)
|
||||
entries.Add(teamInfo);
|
||||
}
|
||||
|
||||
entries.Sort();
|
||||
|
|
@ -408,7 +402,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
for (int i = 0; i < entries.Count; ++i)
|
||||
{
|
||||
KHTeamInfo teamInfo = entries[i] as KHTeamInfo;
|
||||
KHTeamInfo teamInfo = entries[i];
|
||||
|
||||
AddImage(30, 70 + i * 75, 10152);
|
||||
AddImage(30, 85 + i * 75, 10151);
|
||||
|
|
@ -505,7 +499,7 @@ namespace Server.Engines.ConPVP
|
|||
}
|
||||
}
|
||||
|
||||
public sealed class KHPlayerInfo : IRankedCTF, IComparable
|
||||
public sealed class KHPlayerInfo : IRankedCTF, IComparable<KHPlayerInfo>
|
||||
{
|
||||
private int m_Captures;
|
||||
|
||||
|
|
@ -521,30 +515,18 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
public Mobile Player{ get; }
|
||||
|
||||
public int CompareTo(object obj)
|
||||
public int CompareTo(KHPlayerInfo pi)
|
||||
{
|
||||
KHPlayerInfo pi = (KHPlayerInfo)obj;
|
||||
int res = pi.Score.CompareTo(Score);
|
||||
if (res == 0)
|
||||
{
|
||||
res = pi.Captures.CompareTo(Captures);
|
||||
if (res != 0)
|
||||
return res;
|
||||
|
||||
if (res == 0)
|
||||
res = pi.Kills.CompareTo(Kills);
|
||||
}
|
||||
res = pi.Captures.CompareTo(Captures);
|
||||
|
||||
return res;
|
||||
return res != 0 ? res : pi.Kills.CompareTo(Kills);
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Player?.Name == null)
|
||||
return "";
|
||||
return Player.Name;
|
||||
}
|
||||
}
|
||||
public string Name => Player.Name ?? "";
|
||||
|
||||
public int Kills
|
||||
{
|
||||
|
|
@ -586,13 +568,13 @@ namespace Server.Engines.ConPVP
|
|||
public KHTeamInfo(int teamID)
|
||||
{
|
||||
TeamID = teamID;
|
||||
Players = new Hashtable();
|
||||
Players = new Dictionary<Mobile, KHPlayerInfo>();
|
||||
}
|
||||
|
||||
public KHTeamInfo(int teamID, GenericReader ip)
|
||||
{
|
||||
TeamID = teamID;
|
||||
Players = new Hashtable();
|
||||
Players = new Dictionary<Mobile, KHPlayerInfo>();
|
||||
|
||||
int version = ip.ReadEncodedInt();
|
||||
|
||||
|
|
@ -613,7 +595,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
public KHPlayerInfo Leader{ get; set; }
|
||||
|
||||
public Hashtable Players{ get; }
|
||||
public Dictionary<Mobile, KHPlayerInfo> Players{ get; }
|
||||
|
||||
public KHPlayerInfo this[Mobile mob]
|
||||
{
|
||||
|
|
@ -706,7 +688,7 @@ namespace Server.Engines.ConPVP
|
|||
Name = "King of the Hill Controller";
|
||||
|
||||
Duration = TimeSpan.FromMinutes(30.0);
|
||||
Boards = new ArrayList();
|
||||
Boards = new List<KHBoard>();
|
||||
Hills = new HillOfTheKing[4];
|
||||
TeamInfo = new KHTeamInfo[8];
|
||||
|
||||
|
|
@ -722,60 +704,28 @@ namespace Server.Engines.ConPVP
|
|||
public KHTeamInfo[] TeamInfo{ get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public KHTeamInfo Team1_W
|
||||
{
|
||||
get => TeamInfo[0];
|
||||
set { }
|
||||
}
|
||||
public KHTeamInfo Team1_W => TeamInfo[0];
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public KHTeamInfo Team2_E
|
||||
{
|
||||
get => TeamInfo[1];
|
||||
set { }
|
||||
}
|
||||
public KHTeamInfo Team2_E => TeamInfo[1];
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public KHTeamInfo Team3_N
|
||||
{
|
||||
get => TeamInfo[2];
|
||||
set { }
|
||||
}
|
||||
public KHTeamInfo Team3_N => TeamInfo[2];
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public KHTeamInfo Team4_S
|
||||
{
|
||||
get => TeamInfo[3];
|
||||
set { }
|
||||
}
|
||||
public KHTeamInfo Team4_S => TeamInfo[3];
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public KHTeamInfo Team5_NW
|
||||
{
|
||||
get => TeamInfo[4];
|
||||
set { }
|
||||
}
|
||||
public KHTeamInfo Team5_NW => TeamInfo[4];
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public KHTeamInfo Team6_SE
|
||||
{
|
||||
get => TeamInfo[5];
|
||||
set { }
|
||||
}
|
||||
public KHTeamInfo Team6_SE => TeamInfo[5];
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public KHTeamInfo Team7_SW
|
||||
{
|
||||
get => TeamInfo[6];
|
||||
set { }
|
||||
}
|
||||
public KHTeamInfo Team7_SW => TeamInfo[6];
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public KHTeamInfo Team8_NE
|
||||
{
|
||||
get => TeamInfo[7];
|
||||
set { }
|
||||
}
|
||||
public KHTeamInfo Team8_NE => TeamInfo[7];
|
||||
|
||||
public HillOfTheKing[] Hills{ get; private set; }
|
||||
|
||||
|
|
@ -807,7 +757,7 @@ namespace Server.Engines.ConPVP
|
|||
set => Hills[3] = value;
|
||||
}
|
||||
|
||||
public ArrayList Boards{ get; private set; }
|
||||
public List<KHBoard> Boards{ get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TimeSpan Duration{ get; set; }
|
||||
|
|
@ -873,7 +823,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
Duration = reader.ReadTimeSpan();
|
||||
|
||||
Boards = reader.ReadItemList();
|
||||
Boards = reader.ReadStrongItemList<KHBoard>();
|
||||
|
||||
Hills = new HillOfTheKing[reader.ReadEncodedInt()];
|
||||
for (int i = 0; i < Hills.Length; ++i)
|
||||
|
|
@ -893,8 +843,7 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
private Timer m_FinishTimer;
|
||||
|
||||
public KHGame(KHController controller, DuelContext context)
|
||||
: base(context)
|
||||
public KHGame(KHController controller, DuelContext context) : base(context)
|
||||
{
|
||||
Controller = controller;
|
||||
}
|
||||
|
|
@ -928,7 +877,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
for (int i = 0; i < m_Context.Participants.Count; ++i)
|
||||
{
|
||||
Participant p = m_Context.Participants[i] as Participant;
|
||||
Participant p = m_Context.Participants[i];
|
||||
|
||||
for (int j = 0; j < p.Players.Length; ++j)
|
||||
if (p.Players[j] != null)
|
||||
|
|
@ -979,19 +928,12 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
public void DelayBounce(TimeSpan ts, Mobile mob, Container corpse)
|
||||
{
|
||||
Timer.DelayCall(ts, new TimerStateCallback(DelayBounce_Callback), new object[] { mob, corpse });
|
||||
Timer.DelayCall(ts, () => DelayBounce_Callback(mob, corpse));
|
||||
}
|
||||
|
||||
private void DelayBounce_Callback(object state)
|
||||
private void DelayBounce_Callback(Mobile mob, Container corpse)
|
||||
{
|
||||
object[] states = (object[])state;
|
||||
Mobile mob = (Mobile)states[0];
|
||||
Container corpse = (Container)states[1];
|
||||
|
||||
DuelPlayer dp = null;
|
||||
|
||||
if (mob is PlayerMobile mobile)
|
||||
dp = mobile.DuelPlayer;
|
||||
DuelPlayer dp = mob is PlayerMobile mobile ? mobile.DuelPlayer : null;
|
||||
|
||||
m_Context.RemoveAggressions(mob);
|
||||
|
||||
|
|
@ -1045,7 +987,7 @@ namespace Server.Engines.ConPVP
|
|||
}
|
||||
}
|
||||
|
||||
mob.CloseGump(typeof(KHBoardGump));
|
||||
mob.CloseGump<KHBoardGump>();
|
||||
mob.SendGump(new KHBoardGump(mob, this));
|
||||
|
||||
m_Context.Requip(mob, corpse);
|
||||
|
|
@ -1065,7 +1007,7 @@ namespace Server.Engines.ConPVP
|
|||
}
|
||||
|
||||
for (int i = 0; i < m_Context.Participants.Count; ++i)
|
||||
ApplyHues(m_Context.Participants[i] as Participant,
|
||||
ApplyHues(m_Context.Participants[i],
|
||||
Controller.TeamInfo[i % Controller.TeamInfo.Length].Color);
|
||||
|
||||
m_FinishTimer?.Stop();
|
||||
|
|
@ -1083,46 +1025,44 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
private void Finish_Callback()
|
||||
{
|
||||
ArrayList teams = new ArrayList();
|
||||
List<KHTeamInfo> teams = new List<KHTeamInfo>();
|
||||
|
||||
for (int i = 0; i < m_Context.Participants.Count; ++i)
|
||||
{
|
||||
KHTeamInfo teamInfo = Controller.TeamInfo[i % Controller.TeamInfo.Length];
|
||||
|
||||
if (teamInfo == null)
|
||||
continue;
|
||||
|
||||
teams.Add(teamInfo);
|
||||
if (teamInfo != null)
|
||||
teams.Add(teamInfo);
|
||||
}
|
||||
|
||||
teams.Sort();
|
||||
|
||||
Tournament tourny = m_Context.m_Tournament;
|
||||
Tournament tourney = m_Context.m_Tournament;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
if (tourny != null && tourny.TournyType == TournyType.FreeForAll)
|
||||
if (tourney != null && tourney.TourneyType == TourneyType.FreeForAll)
|
||||
{
|
||||
sb.Append(m_Context.Participants.Count * tourny.PlayersPerParticipant);
|
||||
sb.Append(m_Context.Participants.Count * tourney.PlayersPerParticipant);
|
||||
sb.Append("-man FFA");
|
||||
}
|
||||
else if (tourny != null && tourny.TournyType == TournyType.RandomTeam)
|
||||
else if (tourney != null && tourney.TourneyType == TourneyType.RandomTeam)
|
||||
{
|
||||
sb.Append(tourny.ParticipantsPerMatch);
|
||||
sb.Append(tourney.ParticipantsPerMatch);
|
||||
sb.Append("-team");
|
||||
}
|
||||
else if (tourny != null && tourny.TournyType == TournyType.RedVsBlue)
|
||||
else if (tourney != null && tourney.TourneyType == TourneyType.RedVsBlue)
|
||||
{
|
||||
sb.Append("Red v Blue");
|
||||
}
|
||||
else if (tourny != null)
|
||||
else if (tourney != null)
|
||||
{
|
||||
for (int i = 0; i < tourny.ParticipantsPerMatch; ++i)
|
||||
for (int i = 0; i < tourney.ParticipantsPerMatch; ++i)
|
||||
{
|
||||
if (sb.Length > 0)
|
||||
sb.Append('v');
|
||||
|
||||
sb.Append(tourny.PlayersPerParticipant);
|
||||
sb.Append(tourney.PlayersPerParticipant);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1131,7 +1071,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
string title = sb.ToString();
|
||||
|
||||
KHTeamInfo winner = (KHTeamInfo)(teams.Count > 0 ? teams[0] : null);
|
||||
KHTeamInfo winner = teams.Count > 0 ? teams[0] : null;
|
||||
|
||||
for (int i = 0; i < teams.Count; ++i)
|
||||
{
|
||||
|
|
@ -1142,9 +1082,9 @@ namespace Server.Engines.ConPVP
|
|||
else if (i == 1)
|
||||
rank = TrophyRank.Silver;
|
||||
|
||||
KHPlayerInfo leader = ((KHTeamInfo)teams[i]).Leader;
|
||||
KHPlayerInfo leader = teams[i].Leader;
|
||||
|
||||
foreach (KHPlayerInfo pl in ((KHTeamInfo)teams[i]).Players.Values)
|
||||
foreach (KHPlayerInfo pl in teams[i].Players.Values)
|
||||
{
|
||||
Mobile mob = pl.Player;
|
||||
|
||||
|
|
@ -1182,7 +1122,7 @@ namespace Server.Engines.ConPVP
|
|||
if (pl == leader)
|
||||
item.ItemID = 4810;
|
||||
|
||||
item.Name = $"{item.Name}, {((KHTeamInfo)teams[i]).Name.ToLower()}";
|
||||
item.Name = $"{item.Name}, {teams[i].Name.ToLower()}";
|
||||
|
||||
if (!mob.PlaceInBackpack(item))
|
||||
mob.BankBox.DropItem(item);
|
||||
|
|
@ -1219,21 +1159,22 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
if (dp?.Mobile != null)
|
||||
{
|
||||
dp.Mobile.CloseGump(typeof(KHBoardGump));
|
||||
dp.Mobile.CloseGump<KHBoardGump>();
|
||||
dp.Mobile.SendGump(new KHBoardGump(dp.Mobile, this));
|
||||
}
|
||||
}
|
||||
|
||||
if (i == winner.TeamID)
|
||||
if (i == winner?.TeamID)
|
||||
continue;
|
||||
|
||||
if (p?.Players != null)
|
||||
if (p.Players != null)
|
||||
for (int j = 0; j < p.Players.Length; ++j)
|
||||
if (p.Players[j] != null)
|
||||
p.Players[j].Eliminated = true;
|
||||
}
|
||||
|
||||
m_Context.Finish(m_Context.Participants[winner.TeamID] as Participant);
|
||||
if (winner != null)
|
||||
m_Context.Finish(m_Context.Participants[winner.TeamID]);
|
||||
}
|
||||
|
||||
public override void OnStop()
|
||||
|
|
@ -1250,10 +1191,10 @@ namespace Server.Engines.ConPVP
|
|||
board.m_Game = null;
|
||||
|
||||
for (int i = 0; i < m_Context.Participants.Count; ++i)
|
||||
ApplyHues(m_Context.Participants[i] as Participant, -1);
|
||||
ApplyHues(m_Context.Participants[i], -1);
|
||||
|
||||
m_FinishTimer?.Stop();
|
||||
m_FinishTimer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
123
Scripts/Engines/ConPVP/Games/TourneyMatch.cs
Normal file
123
Scripts/Engines/ConPVP/Games/TourneyMatch.cs
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
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 != null && Context.Registered;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
382
Scripts/Engines/ConPVP/Gumps/AcceptTeamGump.cs
Normal file
382
Scripts/Engines/ConPVP/Gumps/AcceptTeamGump.cs
Normal file
|
|
@ -0,0 +1,382 @@
|
|||
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 Mobile m_From;
|
||||
private List<Mobile> m_Players;
|
||||
private Mobile m_Registrar;
|
||||
private Mobile m_Requested;
|
||||
private 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;
|
||||
|
||||
#region Rules
|
||||
|
||||
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)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;
|
||||
|
||||
#endregion
|
||||
|
||||
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);
|
||||
|
||||
#region Rules
|
||||
|
||||
int y = 100;
|
||||
|
||||
string groupText = null;
|
||||
|
||||
switch (tourney.GroupType)
|
||||
{
|
||||
case GroupingType.HighVsLow:
|
||||
groupText = "High vs Low";
|
||||
break;
|
||||
case GroupingType.Nearest:
|
||||
groupText = "Closest opponent";
|
||||
break;
|
||||
case GroupingType.Random:
|
||||
groupText = "Random";
|
||||
break;
|
||||
}
|
||||
|
||||
AddBorderedText(35, y, 190, 20, $"Grouping: {groupText}", LabelColor32, BlackColor32);
|
||||
y += 20;
|
||||
|
||||
string tieText = null;
|
||||
|
||||
switch (tourney.TieType)
|
||||
{
|
||||
case TieType.Random:
|
||||
tieText = "Random";
|
||||
break;
|
||||
case TieType.Highest:
|
||||
tieText = "Highest advances";
|
||||
break;
|
||||
case TieType.Lowest:
|
||||
tieText = "Lowest advances";
|
||||
break;
|
||||
case TieType.FullAdvancement:
|
||||
tieText = tourney.ParticipantsPerMatch == 2 ? "Both advance" : "Everyone advances";
|
||||
break;
|
||||
case TieType.FullElimination:
|
||||
tieText = tourney.ParticipantsPerMatch == 2 ? "Both eliminated" : "Everyone eliminated";
|
||||
break;
|
||||
}
|
||||
|
||||
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)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;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
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, GumpButtonType.Reply, 0);
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(15.0), AutoReject);
|
||||
}
|
||||
|
||||
public string Center(string text)
|
||||
{
|
||||
return $"<CENTER>{text}</CENTER>";
|
||||
}
|
||||
|
||||
public string Color(string text, int color)
|
||||
{
|
||||
return $"<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, false, false);
|
||||
else
|
||||
AddHtml(x, y, width, height, Color(text, color), false, false);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -50,7 +50,7 @@ namespace Server.Engines.ConPVP
|
|||
return false;
|
||||
}
|
||||
|
||||
from.CloseGump(typeof(ArenaGump));
|
||||
from.CloseGump<ArenaGump>();
|
||||
from.SendGump(new ArenaGump(from, this));
|
||||
|
||||
if (!from.Hidden || from.AccessLevel == AccessLevel.Player)
|
||||
566
Scripts/Engines/ConPVP/Gumps/ConfirmSignupGump.cs
Normal file
566
Scripts/Engines/ConPVP/Gumps/ConfirmSignupGump.cs
Normal file
|
|
@ -0,0 +1,566 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Server.Factions;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class ConfirmSignupGump : Gump
|
||||
{
|
||||
private const int BlackColor32 = 0x000008;
|
||||
private const int LabelColor32 = 0xFFFFFF;
|
||||
private Mobile m_From;
|
||||
private List<Mobile> m_Players;
|
||||
private Mobile m_Registrar;
|
||||
private Tournament m_Tournament;
|
||||
|
||||
public ConfirmSignupGump(Mobile from, Mobile registrar, Tournament tourney, List<Mobile> players) : base(50, 50)
|
||||
{
|
||||
m_From = from;
|
||||
m_Registrar = registrar;
|
||||
m_Tournament = tourney;
|
||||
m_Players = players;
|
||||
|
||||
m_From.CloseGump<AcceptTeamGump>();
|
||||
m_From.CloseGump<AcceptDuelGump>();
|
||||
m_From.CloseGump<DuelContextGump>();
|
||||
m_From.CloseGump<ConfirmSignupGump>();
|
||||
|
||||
#region Rules
|
||||
|
||||
Ruleset ruleset = tourney.Ruleset;
|
||||
Ruleset basedef = ruleset.Base;
|
||||
|
||||
int height = 185 + 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)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;
|
||||
|
||||
if (tourney.PlayersPerParticipant > 1)
|
||||
height += 36 + tourney.PlayersPerParticipant * 20;
|
||||
|
||||
#endregion
|
||||
|
||||
Closable = false;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
//AddBackground( 0, 0, 400, 220, 9150 );
|
||||
AddBackground(1, 1, 398, height, 3600);
|
||||
//AddBackground( 16, 15, 369, 189, 9100 );
|
||||
|
||||
AddImageTiled(16, 15, 369, height - 29, 3604);
|
||||
AddAlphaRegion(16, 15, 369, height - 29);
|
||||
|
||||
AddImage(215, -43, 0xEE40);
|
||||
//AddImage( 330, 141, 0x8BA );
|
||||
|
||||
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 Signup");
|
||||
|
||||
AddBorderedText(22, 22, 294, 20, Center(sb.ToString()), LabelColor32, BlackColor32);
|
||||
AddBorderedText(22, 50, 294, 40, "You have requested to join the tournament. Do you accept the rules?", 0xB0C868,
|
||||
BlackColor32);
|
||||
|
||||
AddImageTiled(32, 88, 264, 1, 9107);
|
||||
AddImageTiled(42, 90, 264, 1, 9157);
|
||||
|
||||
#region Rules
|
||||
|
||||
int y = 100;
|
||||
|
||||
string groupText = null;
|
||||
|
||||
switch (tourney.GroupType)
|
||||
{
|
||||
case GroupingType.HighVsLow:
|
||||
groupText = "High vs Low";
|
||||
break;
|
||||
case GroupingType.Nearest:
|
||||
groupText = "Closest opponent";
|
||||
break;
|
||||
case GroupingType.Random:
|
||||
groupText = "Random";
|
||||
break;
|
||||
}
|
||||
|
||||
AddBorderedText(35, y, 190, 20, $"Grouping: {groupText}", LabelColor32, BlackColor32);
|
||||
y += 20;
|
||||
|
||||
string tieText = null;
|
||||
|
||||
switch (tourney.TieType)
|
||||
{
|
||||
case TieType.Random:
|
||||
tieText = "Random";
|
||||
break;
|
||||
case TieType.Highest:
|
||||
tieText = "Highest advances";
|
||||
break;
|
||||
case TieType.Lowest:
|
||||
tieText = "Lowest advances";
|
||||
break;
|
||||
case TieType.FullAdvancement:
|
||||
tieText = tourney.ParticipantsPerMatch == 2 ? "Both advance" : "Everyone advances";
|
||||
break;
|
||||
case TieType.FullElimination:
|
||||
tieText = tourney.ParticipantsPerMatch == 2 ? "Both eliminated" : "Everyone eliminated";
|
||||
break;
|
||||
}
|
||||
|
||||
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)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;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Team
|
||||
|
||||
if (tourney.PlayersPerParticipant > 1)
|
||||
{
|
||||
y += 8;
|
||||
AddImageTiled(32, y - 1, 264, 1, 9107);
|
||||
AddImageTiled(42, y + 1, 264, 1, 9157);
|
||||
y += 8;
|
||||
|
||||
AddBorderedText(35, y, 190, 20, "Your Team", LabelColor32, BlackColor32);
|
||||
y += 20;
|
||||
|
||||
for (int i = 0; i < players.Count; ++i, y += 20)
|
||||
{
|
||||
if (i == 0)
|
||||
AddImage(35, y, 0xD2);
|
||||
else
|
||||
AddGoldenButton(35, y, 1 + i);
|
||||
|
||||
AddBorderedText(60, y, 200, 20, players[i].Name, LabelColor32, BlackColor32);
|
||||
}
|
||||
|
||||
for (int i = players.Count; i < tourney.PlayersPerParticipant; ++i, y += 20)
|
||||
{
|
||||
if (i == 0)
|
||||
AddImage(35, y, 0xD2);
|
||||
else
|
||||
AddGoldenButton(35, y, 1 + i);
|
||||
|
||||
AddBorderedText(60, y, 200, 20, "(Empty)", LabelColor32, BlackColor32);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
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 wish to join the tournament.", LabelColor32, BlackColor32);
|
||||
y += 35;
|
||||
|
||||
AddRadio(24, y, 9727, 9730, false, 2);
|
||||
AddBorderedText(60, y + 5, 250, 20, "No, I do not wish to join.", LabelColor32, BlackColor32);
|
||||
y += 35;
|
||||
|
||||
y -= 3;
|
||||
AddButton(314, y, 247, 248, 1, GumpButtonType.Reply, 0);
|
||||
}
|
||||
|
||||
public string Center(string text)
|
||||
{
|
||||
return $"<CENTER>{text}</CENTER>";
|
||||
}
|
||||
|
||||
public string Color(string text, int color)
|
||||
{
|
||||
return $"<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, false, false);
|
||||
else
|
||||
AddHtml(x, y, width, height, Color(text, color), false, false);
|
||||
}
|
||||
|
||||
public void AddGoldenButton(int x, int y, int bid)
|
||||
{
|
||||
AddButton(x, y, 0xD2, 0xD2, bid, GumpButtonType.Reply, 0);
|
||||
AddButton(x + 3, y + 3, 0xD8, 0xD8, bid, GumpButtonType.Reply, 0);
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (info.ButtonID == 1 && info.IsSwitched(1))
|
||||
{
|
||||
Tournament tourney = m_Tournament;
|
||||
Mobile from = m_From;
|
||||
|
||||
switch (tourney.Stage)
|
||||
{
|
||||
case TournamentStage.Fighting:
|
||||
{
|
||||
if (m_Registrar != null)
|
||||
{
|
||||
if (m_Tournament.HasParticipant(from))
|
||||
m_Registrar.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x35, false, "Excuse me? You are already signed up.", from.NetState);
|
||||
else
|
||||
m_Registrar.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x22, false, "The tournament has already begun. You are too late to signup now.",
|
||||
from.NetState);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case TournamentStage.Inactive:
|
||||
{
|
||||
m_Registrar?.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x35, false, "The tournament is closed.", from.NetState);
|
||||
|
||||
break;
|
||||
}
|
||||
case TournamentStage.Signup:
|
||||
{
|
||||
if (m_Players.Count != tourney.PlayersPerParticipant)
|
||||
{
|
||||
m_Registrar?.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x35, false, "You have not yet chosen your team.", from.NetState);
|
||||
|
||||
m_From.SendGump(new ConfirmSignupGump(m_From, m_Registrar, m_Tournament, m_Players));
|
||||
break;
|
||||
}
|
||||
|
||||
Ladder ladder = Ladder.Instance;
|
||||
|
||||
for (int i = 0; i < m_Players.Count; ++i)
|
||||
{
|
||||
Mobile mob = m_Players[i];
|
||||
|
||||
LadderEntry entry = ladder?.Find(mob);
|
||||
|
||||
if (entry != null && Ladder.GetLevel(entry.Experience) < tourney.LevelRequirement)
|
||||
{
|
||||
if (m_Registrar != null)
|
||||
{
|
||||
if (mob == from)
|
||||
m_Registrar.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x35, false, "You have not yet proven yourself a worthy dueler.", from.NetState);
|
||||
else
|
||||
m_Registrar.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x35, false, $"{mob.Name} has not yet proven themselves a worthy dueler.",
|
||||
from.NetState);
|
||||
}
|
||||
|
||||
m_From.SendGump(new ConfirmSignupGump(m_From, m_Registrar, m_Tournament, m_Players));
|
||||
return;
|
||||
}
|
||||
|
||||
if (tourney.IsFactionRestricted && Faction.Find(mob) == null)
|
||||
{
|
||||
m_Registrar?.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x35, false, "Only those who have declared their faction allegiance may participate.",
|
||||
from.NetState);
|
||||
|
||||
m_From.SendGump(new ConfirmSignupGump(m_From, m_Registrar, m_Tournament, m_Players));
|
||||
return;
|
||||
}
|
||||
|
||||
if (tourney.HasParticipant(mob))
|
||||
{
|
||||
if (m_Registrar != null)
|
||||
{
|
||||
if (mob == from)
|
||||
m_Registrar.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x35, false, "You have already entered this tournament.", from.NetState);
|
||||
else
|
||||
m_Registrar.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x35, false, $"{mob.Name} has already entered this tournament.", from.NetState);
|
||||
}
|
||||
|
||||
m_From.SendGump(new ConfirmSignupGump(m_From, m_Registrar, m_Tournament, m_Players));
|
||||
return;
|
||||
}
|
||||
|
||||
if (mob is PlayerMobile mobile && mobile.DuelContext != null)
|
||||
{
|
||||
if (mob == from)
|
||||
m_Registrar?.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x35, false,
|
||||
"You are already assigned to a duel. You must yield it before joining this tournament.",
|
||||
from.NetState);
|
||||
else
|
||||
m_Registrar?.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x35, false,
|
||||
$"{mobile.Name} is already assigned to a duel. They must yield it before joining this tournament.",
|
||||
from.NetState);
|
||||
|
||||
m_From.SendGump(new ConfirmSignupGump(m_From, m_Registrar, m_Tournament, m_Players));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_Registrar != null)
|
||||
{
|
||||
string fmt;
|
||||
|
||||
if (tourney.PlayersPerParticipant == 1)
|
||||
fmt =
|
||||
"As you say m'{0}. I've written your name to the bracket. The tournament will begin {1}.";
|
||||
else if (tourney.PlayersPerParticipant == 2)
|
||||
fmt =
|
||||
"As you wish m'{0}. The tournament will begin {1}, but first you must name your partner.";
|
||||
else
|
||||
fmt = "As you wish m'{0}. The tournament will begin {1}, but first you must name your team.";
|
||||
|
||||
string timeUntil;
|
||||
int minutesUntil = (int)Math.Round((tourney.SignupStart + tourney.SignupPeriod - DateTime.UtcNow)
|
||||
.TotalMinutes);
|
||||
|
||||
if (minutesUntil == 0)
|
||||
timeUntil = "momentarily";
|
||||
else
|
||||
timeUntil = $"in {minutesUntil} minute{(minutesUntil == 1 ? "" : "s")}";
|
||||
|
||||
m_Registrar.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x35, false, string.Format(fmt, from.Female ? "Lady" : "Lord", timeUntil), from.NetState);
|
||||
}
|
||||
|
||||
TourneyParticipant part = new TourneyParticipant(from);
|
||||
part.Players.Clear();
|
||||
part.Players.AddRange(m_Players);
|
||||
|
||||
tourney.Participants.Add(part);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (info.ButtonID > 1)
|
||||
{
|
||||
int index = info.ButtonID - 1;
|
||||
|
||||
if (index > 0 && index < m_Players.Count)
|
||||
{
|
||||
m_Players.RemoveAt(index);
|
||||
m_From.SendGump(new ConfirmSignupGump(m_From, m_Registrar, m_Tournament, m_Players));
|
||||
}
|
||||
else if (m_Players.Count < m_Tournament.PlayersPerParticipant)
|
||||
{
|
||||
m_From.BeginTarget(12, false, TargetFlags.None, AddPlayer_OnTarget);
|
||||
m_From.SendGump(new ConfirmSignupGump(m_From, m_Registrar, m_Tournament, m_Players));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AddPlayer_OnTarget(Mobile from, object obj)
|
||||
{
|
||||
if (!(obj is Mobile mob) || mob == from)
|
||||
{
|
||||
m_From.SendGump(new ConfirmSignupGump(m_From, m_Registrar, m_Tournament, m_Players));
|
||||
|
||||
m_Registrar?.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x22, false, "Excuse me?", from.NetState);
|
||||
}
|
||||
else if (!mob.Player)
|
||||
{
|
||||
m_From.SendGump(new ConfirmSignupGump(m_From, m_Registrar, m_Tournament, m_Players));
|
||||
|
||||
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)
|
||||
{
|
||||
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 (!(mob is PlayerMobile pm))
|
||||
return;
|
||||
|
||||
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 (mob.HasGump<AcceptTeamGump>())
|
||||
{
|
||||
m_From.SendGump(new ConfirmSignupGump(m_From, m_Registrar, m_Tournament, m_Players));
|
||||
|
||||
m_Registrar?.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x22, false, "They have already been offered a partnership.", from.NetState);
|
||||
}
|
||||
else if (mob.HasGump<ConfirmSignupGump>())
|
||||
{
|
||||
m_From.SendGump(new ConfirmSignupGump(m_From, m_Registrar, m_Tournament, m_Players));
|
||||
|
||||
m_Registrar?.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x22, false, "They are already trying to join this tournament.", 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_From.SendGump(new ConfirmSignupGump(m_From, m_Registrar, m_Tournament, m_Players));
|
||||
mob.SendGump(new AcceptTeamGump(from, mob, m_Tournament, m_Registrar, m_Players));
|
||||
|
||||
m_Registrar?.PrivateOverheadMessage(MessageType.Regular,
|
||||
0x59, false,
|
||||
$"As you command m'{(from.Female ? "Lady" : "Lord")}. I've given your offer to {mob.Name}.",
|
||||
from.NetState);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -10,9 +10,9 @@ namespace Server.Engines.ConPVP
|
|||
From = from;
|
||||
Context = context;
|
||||
|
||||
from.CloseGump(typeof(RulesetGump));
|
||||
from.CloseGump(typeof(DuelContextGump));
|
||||
from.CloseGump(typeof(ParticipantGump));
|
||||
from.CloseGump<RulesetGump>();
|
||||
from.CloseGump<DuelContextGump>();
|
||||
from.CloseGump<ParticipantGump>();
|
||||
|
||||
int count = context.Participants.Count;
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
|
|
@ -41,7 +41,7 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
case 1:
|
||||
{
|
||||
Ladder = reader.ReadItem() as LadderController;
|
||||
Ladder = reader.ReadItem<LadderController>();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -51,15 +51,12 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
if (from.InRange(GetWorldLocation(), 2))
|
||||
{
|
||||
Ladder ladder = ConPVP.Ladder.Instance;
|
||||
|
||||
if (Ladder != null)
|
||||
ladder = Ladder.Ladder;
|
||||
Ladder ladder = ConPVP.Ladder.Instance ?? Ladder.Ladder;
|
||||
|
||||
if (ladder != null)
|
||||
{
|
||||
from.CloseGump(typeof(LadderGump));
|
||||
from.SendGump(new LadderGump(ladder, 0));
|
||||
from.CloseGump<LadderGump>();
|
||||
from.SendGump(new LadderGump(ladder));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -74,24 +71,19 @@ namespace Server.Engines.ConPVP
|
|||
private int m_ColumnX = 12;
|
||||
private Ladder m_Ladder;
|
||||
|
||||
private ArrayList m_List;
|
||||
private List<LadderEntry> m_List;
|
||||
private int m_Page;
|
||||
|
||||
public LadderGump(Ladder ladder) : this(ladder, 0)
|
||||
{
|
||||
}
|
||||
|
||||
public LadderGump(Ladder ladder, int page) : base(50, 50)
|
||||
public LadderGump(Ladder ladder, int page = 0) : base(50, 50)
|
||||
{
|
||||
m_Ladder = ladder;
|
||||
m_Page = page;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
ArrayList list = ladder.ToArrayList();
|
||||
m_List = list;
|
||||
m_List = new List<LadderEntry>(ladder.Entries);
|
||||
|
||||
int lc = Math.Min(list.Count, 150);
|
||||
int lc = Math.Min(m_List.Count, 150);
|
||||
|
||||
int start = page * 15;
|
||||
int end = start + 15;
|
||||
|
|
@ -121,7 +113,7 @@ namespace Server.Engines.ConPVP
|
|||
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}", list.Count, page + 1, (lc + 14) / 15, lc),
|
||||
Color(string.Format("Top {3} of {0:N0} duelists, page {1} of {2}", m_List.Count, page + 1, (lc + 14) / 15, lc),
|
||||
0xFFC000), false, false);
|
||||
|
||||
AddColumnHeader(75, "Rank");
|
||||
|
|
@ -133,7 +125,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
for (int i = start; i < end && i < lc; ++i)
|
||||
{
|
||||
LadderEntry entry = (LadderEntry)list[i];
|
||||
LadderEntry entry = m_List[i];
|
||||
|
||||
int y = 32 + (i - start) * 20;
|
||||
int x = 12;
|
||||
|
|
@ -153,8 +145,7 @@ namespace Server.Engines.ConPVP
|
|||
int xp = entry.Experience;
|
||||
int level = Ladder.GetLevel(xp);
|
||||
|
||||
int xpBase, xpAdvance;
|
||||
Ladder.GetLevelInfo(level, out xpBase, out xpAdvance);
|
||||
Ladder.GetLevelInfo(level, out int xpBase, out int xpAdvance);
|
||||
|
||||
int width;
|
||||
|
||||
|
|
@ -13,9 +13,9 @@ namespace Server.Engines.ConPVP
|
|||
Context = context;
|
||||
Participant = p;
|
||||
|
||||
from.CloseGump(typeof(RulesetGump));
|
||||
from.CloseGump(typeof(DuelContextGump));
|
||||
from.CloseGump(typeof(ParticipantGump));
|
||||
from.CloseGump<RulesetGump>();
|
||||
from.CloseGump<DuelContextGump>();
|
||||
from.CloseGump<ParticipantGump>();
|
||||
|
||||
int count = p.Players.Length;
|
||||
|
||||
|
|
@ -231,7 +231,7 @@ namespace Server.Engines.ConPVP
|
|||
from.SendMessage("{0} cannot fight because they have recently been in combat with another player.",
|
||||
pm.Name);
|
||||
}
|
||||
else if (mob.HasGump(typeof(AcceptDuelGump)))
|
||||
else if (mob.HasGump<AcceptDuelGump>())
|
||||
{
|
||||
from.SendMessage("{0} has already been offered a duel.");
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
|
|
@ -16,7 +16,7 @@ namespace Server.Engines.ConPVP
|
|||
m_Context = context;
|
||||
m_Count = count;
|
||||
|
||||
ArrayList parts = context.Participants;
|
||||
List<Participant> parts = context.Participants;
|
||||
|
||||
int height = 25 + 20;
|
||||
|
||||
|
|
@ -35,7 +35,7 @@ namespace Server.Engines.ConPVP
|
|||
height += 25;
|
||||
|
||||
Closable = false;
|
||||
Dragable = false;
|
||||
Draggable = false;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
|
@ -36,13 +37,13 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
AddPage(1);
|
||||
|
||||
ArrayList parts = context.Participants;
|
||||
List<Participant> parts = context.Participants;
|
||||
|
||||
int height = 25 + 20;
|
||||
|
||||
for (int i = 0; i < parts.Count; ++i)
|
||||
{
|
||||
Participant p = (Participant)parts[i];
|
||||
Participant p = parts[i];
|
||||
|
||||
height += 4;
|
||||
|
||||
|
|
@ -63,7 +64,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
for (int i = 0; i < parts.Count; ++i)
|
||||
{
|
||||
Participant p = (Participant)parts[i];
|
||||
Participant p = parts[i];
|
||||
|
||||
y += 4;
|
||||
|
||||
|
|
@ -12,13 +12,8 @@ namespace Server.Engines.ConPVP
|
|||
private bool m_ReadOnly;
|
||||
private Ruleset m_Ruleset;
|
||||
|
||||
public RulesetGump(Mobile from, Ruleset ruleset, RulesetLayout page, DuelContext duelContext) : this(from, ruleset,
|
||||
page, duelContext, false)
|
||||
{
|
||||
}
|
||||
|
||||
public RulesetGump(Mobile from, Ruleset ruleset, RulesetLayout page, DuelContext duelContext, bool readOnly) : base(
|
||||
readOnly ? 310 : 50, 50)
|
||||
public RulesetGump(Mobile from, Ruleset ruleset, RulesetLayout page, DuelContext duelContext, bool readOnly = false)
|
||||
: base(readOnly ? 310 : 50, 50)
|
||||
{
|
||||
m_From = from;
|
||||
m_Ruleset = ruleset;
|
||||
|
|
@ -26,11 +21,11 @@ namespace Server.Engines.ConPVP
|
|||
m_DuelContext = duelContext;
|
||||
m_ReadOnly = readOnly;
|
||||
|
||||
Dragable = !readOnly;
|
||||
Draggable = !readOnly;
|
||||
|
||||
from.CloseGump(typeof(RulesetGump));
|
||||
from.CloseGump(typeof(DuelContextGump));
|
||||
from.CloseGump(typeof(ParticipantGump));
|
||||
from.CloseGump<RulesetGump>();
|
||||
from.CloseGump<DuelContextGump>();
|
||||
from.CloseGump<ParticipantGump>();
|
||||
|
||||
RulesetLayout depthCounter = page;
|
||||
int depth = 0;
|
||||
862
Scripts/Engines/ConPVP/Gumps/TournamentBracketGump.cs
Normal file
862
Scripts/Engines/ConPVP/Gumps/TournamentBracketGump.cs
Normal file
|
|
@ -0,0 +1,862 @@
|
|||
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 enum TourneyBracketGumpType
|
||||
{
|
||||
Index,
|
||||
Rules_Info,
|
||||
Participant_List,
|
||||
Participant_Info,
|
||||
Round_List,
|
||||
Round_Info,
|
||||
Match_Info,
|
||||
Player_Info
|
||||
}
|
||||
|
||||
public class TournamentBracketGump : Gump
|
||||
{
|
||||
private const int BlackColor32 = 0x000008;
|
||||
private const int LabelColor32 = 0xFFFFFF;
|
||||
private Mobile m_From;
|
||||
private List<object> m_List;
|
||||
private object m_Object;
|
||||
private int m_Page;
|
||||
private int m_PerPage;
|
||||
private Tournament m_Tournament;
|
||||
private TourneyBracketGumpType m_Type;
|
||||
|
||||
public TournamentBracketGump(Mobile from, Tournament tourney, TourneyBracketGumpType type,
|
||||
List<object> list = null, int page = 0, object obj = null) : base(50, 50)
|
||||
{
|
||||
m_From = from;
|
||||
m_Tournament = tourney;
|
||||
m_Type = type;
|
||||
m_List = list;
|
||||
m_Page = page;
|
||||
m_Object = obj;
|
||||
m_PerPage = 12;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case TourneyBracketGumpType.Index:
|
||||
{
|
||||
AddPage(0);
|
||||
AddBackground(0, 0, 300, 300, 9380);
|
||||
|
||||
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.RedVsBlue)
|
||||
{
|
||||
sb.Append("Red v Blue");
|
||||
}
|
||||
else if (tourney.TourneyType == TourneyType.Faction)
|
||||
{
|
||||
sb.Append(tourney.ParticipantsPerMatch);
|
||||
sb.Append("-Team Faction");
|
||||
}
|
||||
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 Bracket");
|
||||
|
||||
AddHtml(25, 35, 250, 20, Center(sb.ToString()), false, false);
|
||||
|
||||
AddRightArrow(25, 53, ToButtonID(0, 4), "Rules");
|
||||
AddRightArrow(25, 71, ToButtonID(0, 1), "Participants");
|
||||
|
||||
if (m_Tournament.Stage == TournamentStage.Signup)
|
||||
{
|
||||
TimeSpan until = m_Tournament.SignupStart + m_Tournament.SignupPeriod - DateTime.UtcNow;
|
||||
string text;
|
||||
int secs = (int)until.TotalSeconds;
|
||||
|
||||
if (secs > 0)
|
||||
{
|
||||
int mins = secs / 60;
|
||||
secs %= 60;
|
||||
|
||||
if (mins > 0 && secs > 0)
|
||||
text =
|
||||
$"The tournament will begin in {mins} minute{(mins == 1 ? "" : "s")} and {secs} second{(secs == 1 ? "" : "s")}.";
|
||||
else if (mins > 0)
|
||||
text = $"The tournament will begin in {mins} minute{(mins == 1 ? "" : "s")}.";
|
||||
else if (secs > 0)
|
||||
text = $"The tournament will begin in {secs} second{(secs == 1 ? "" : "s")}.";
|
||||
else
|
||||
text = "The tournament will begin shortly.";
|
||||
}
|
||||
else
|
||||
{
|
||||
text = "The tournament will begin shortly.";
|
||||
}
|
||||
|
||||
AddHtml(25, 92, 250, 40, text, false, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddRightArrow(25, 89, ToButtonID(0, 2), "Rounds");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case TourneyBracketGumpType.Rules_Info:
|
||||
{
|
||||
Ruleset ruleset = tourney.Ruleset;
|
||||
Ruleset basedef = ruleset.Base;
|
||||
|
||||
BitArray defs;
|
||||
|
||||
if (ruleset.Flavors.Count > 0)
|
||||
{
|
||||
defs = new BitArray(basedef.Options);
|
||||
|
||||
for (int i = 0; i < ruleset.Flavors.Count; ++i)
|
||||
defs.Or(((Ruleset)ruleset.Flavors[i]).Options);
|
||||
}
|
||||
else
|
||||
{
|
||||
defs = basedef.Options;
|
||||
}
|
||||
|
||||
int changes = 0;
|
||||
|
||||
BitArray opts = ruleset.Options;
|
||||
|
||||
for (int i = 0; i < opts.Length; ++i)
|
||||
if (defs[i] != opts[i])
|
||||
++changes;
|
||||
|
||||
AddPage(0);
|
||||
AddBackground(0, 0, 300,
|
||||
60 + 18 + 20 + 20 + 20 + 8 + 20 + ruleset.Flavors.Count * 18 + 4 + 20 + changes * 22 + 6, 9380);
|
||||
|
||||
AddLeftArrow(25, 11, ToButtonID(0, 0));
|
||||
AddHtml(25, 35, 250, 20, Center("Rules"), false, false);
|
||||
|
||||
int y = 53;
|
||||
|
||||
string groupText = null;
|
||||
|
||||
switch (tourney.GroupType)
|
||||
{
|
||||
case GroupingType.HighVsLow:
|
||||
groupText = "High vs Low";
|
||||
break;
|
||||
case GroupingType.Nearest:
|
||||
groupText = "Closest opponent";
|
||||
break;
|
||||
case GroupingType.Random:
|
||||
groupText = "Random";
|
||||
break;
|
||||
}
|
||||
|
||||
AddHtml(35, y, 190, 20, $"Grouping: {groupText}", false, false);
|
||||
y += 20;
|
||||
|
||||
string tieText = null;
|
||||
|
||||
switch (tourney.TieType)
|
||||
{
|
||||
case TieType.Random:
|
||||
tieText = "Random";
|
||||
break;
|
||||
case TieType.Highest:
|
||||
tieText = "Highest advances";
|
||||
break;
|
||||
case TieType.Lowest:
|
||||
tieText = "Lowest advances";
|
||||
break;
|
||||
case TieType.FullAdvancement:
|
||||
tieText = tourney.ParticipantsPerMatch == 2 ? "Both advance" : "Everyone advances";
|
||||
break;
|
||||
case TieType.FullElimination:
|
||||
tieText = tourney.ParticipantsPerMatch == 2 ? "Both eliminated" : "Everyone eliminated";
|
||||
break;
|
||||
}
|
||||
|
||||
AddHtml(35, y, 190, 20, $"Tiebreaker: {tieText}", false, false);
|
||||
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)";
|
||||
}
|
||||
|
||||
AddHtml(35, y, 240, 20, $"Sudden Death: {sdText}", false, false);
|
||||
y += 20;
|
||||
|
||||
y += 8;
|
||||
|
||||
AddHtml(35, y, 190, 20, $"Ruleset: {basedef.Title}", false, false);
|
||||
y += 20;
|
||||
|
||||
for (int i = 0; i < ruleset.Flavors.Count; ++i, y += 18)
|
||||
AddHtml(35, y, 190, 20, $" + {((Ruleset)ruleset.Flavors[i]).Title}", false, false);
|
||||
|
||||
y += 4;
|
||||
|
||||
if (changes > 0)
|
||||
{
|
||||
AddHtml(35, y, 190, 20, "Modifications:", false, false);
|
||||
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, false, false);
|
||||
}
|
||||
|
||||
y += 22;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddHtml(35, y, 190, 20, "Modifications: None", false, false);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case TourneyBracketGumpType.Participant_List:
|
||||
{
|
||||
AddPage(0);
|
||||
AddBackground(0, 0, 300, 300, 9380);
|
||||
|
||||
List<TourneyParticipant> pList = m_List != null
|
||||
? Utility.CastListCovariant<object, TourneyParticipant>(m_List)
|
||||
: new List<TourneyParticipant>(tourney.Participants);
|
||||
|
||||
AddLeftArrow(25, 11, ToButtonID(0, 0));
|
||||
AddHtml(25, 35, 250, 20, Center($"{pList.Count} Participant{(pList.Count == 1 ? "" : "s")}"), false,
|
||||
false);
|
||||
|
||||
StartPage(out int index, out int count, out int y, 12);
|
||||
|
||||
for (int i = 0; i < count; ++i, y += 18)
|
||||
{
|
||||
TourneyParticipant part = pList[index + i];
|
||||
string name = part.NameList;
|
||||
|
||||
if (m_Tournament.TourneyType != TourneyType.Standard && part.Players.Count == 1)
|
||||
if (part.Players[0] is PlayerMobile pm && pm.DuelPlayer != null)
|
||||
name = Color(name, pm.DuelPlayer.Eliminated ? 0x6633333 : 0x336666);
|
||||
|
||||
AddRightArrow(25, y, ToButtonID(2, index + i), name);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case TourneyBracketGumpType.Participant_Info:
|
||||
{
|
||||
if (!(obj is TourneyParticipant part))
|
||||
break;
|
||||
|
||||
AddPage(0);
|
||||
AddBackground(0, 0, 300, 60 + 18 + 20 + part.Players.Count * 18 + 20 + 20 + 160, 9380);
|
||||
|
||||
AddLeftArrow(25, 11, ToButtonID(0, 1));
|
||||
AddHtml(25, 35, 250, 20, Center("Participants"), false, false);
|
||||
|
||||
int y = 53;
|
||||
|
||||
AddHtml(25, y, 200, 20, part.Players.Count == 1 ? "Players" : "Team", false, false);
|
||||
y += 20;
|
||||
|
||||
for (int i = 0; i < part.Players.Count; ++i)
|
||||
{
|
||||
Mobile mob = part.Players[i];
|
||||
string name = mob.Name;
|
||||
|
||||
if (m_Tournament.TourneyType != TourneyType.Standard)
|
||||
if (mob is PlayerMobile pm && pm.DuelPlayer != null)
|
||||
name = Color(name, pm.DuelPlayer.Eliminated ? 0x6633333 : 0x336666);
|
||||
|
||||
AddRightArrow(35, y, ToButtonID(4, i), name);
|
||||
y += 18;
|
||||
}
|
||||
|
||||
AddHtml(25, y, 200, 20,
|
||||
$"Free Advances: {(part.FreeAdvances == 0 ? "None" : part.FreeAdvances.ToString())}", false, false);
|
||||
y += 20;
|
||||
|
||||
AddHtml(25, y, 200, 20, "Log:", false, false);
|
||||
y += 20;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < part.Log.Count; ++i)
|
||||
{
|
||||
if (sb.Length > 0)
|
||||
sb.Append("<br>");
|
||||
|
||||
sb.Append(part.Log[i]);
|
||||
}
|
||||
|
||||
if (sb.Length == 0)
|
||||
sb.Append("Nothing logged yet.");
|
||||
|
||||
AddHtml(25, y, 250, 150, Color(sb.ToString(), BlackColor32), false, true);
|
||||
|
||||
break;
|
||||
}
|
||||
case TourneyBracketGumpType.Player_Info:
|
||||
{
|
||||
AddPage(0);
|
||||
AddBackground(0, 0, 300, 300, 9380);
|
||||
|
||||
AddLeftArrow(25, 11, ToButtonID(0, 3));
|
||||
AddHtml(25, 35, 250, 20, Center("Participants"), false, false);
|
||||
|
||||
if (!(obj is Mobile mob))
|
||||
break;
|
||||
|
||||
Ladder ladder = Ladder.Instance;
|
||||
LadderEntry entry = ladder?.Find(mob);
|
||||
|
||||
AddHtml(25, 53, 250, 20, $"Name: {mob.Name}", false, false);
|
||||
AddHtml(25, 73, 250, 20,
|
||||
$"Guild: {(mob.Guild == null ? "None" : mob.Guild.Name + " [" + mob.Guild.Abbreviation + "]")}",
|
||||
false, false);
|
||||
AddHtml(25, 93, 250, 20, $"Rank: {(entry == null ? "N/A" : LadderGump.Rank(entry.Index + 1))}", false,
|
||||
false);
|
||||
AddHtml(25, 113, 250, 20, $"Level: {(entry == null ? 0 : Ladder.GetLevel(entry.Experience))}", false,
|
||||
false);
|
||||
AddHtml(25, 133, 250, 20, $"Wins: {entry?.Wins ?? 0:N0}", false, false);
|
||||
AddHtml(25, 153, 250, 20, $"Losses: {entry?.Losses ?? 0:N0}", false, false);
|
||||
|
||||
break;
|
||||
}
|
||||
case TourneyBracketGumpType.Round_List:
|
||||
{
|
||||
AddPage(0);
|
||||
AddBackground(0, 0, 300, 300, 9380);
|
||||
|
||||
AddLeftArrow(25, 11, ToButtonID(0, 0));
|
||||
AddHtml(25, 35, 250, 20, Center("Rounds"), false, false);
|
||||
|
||||
// List<PyramidLevel> levelsList = m_List != null
|
||||
// ? Utility.CastListCovariant<object, PyramidLevel>(m_List)
|
||||
// : new List<PyramidLevel>(tourney.Pyramid.Levels);
|
||||
|
||||
StartPage(out int index, out int count, out int y, 12);
|
||||
|
||||
for (int i = 0; i < count; ++i, y += 18)
|
||||
AddRightArrow(25, y, ToButtonID(3, index + i), "Round #" + (index + i + 1));
|
||||
|
||||
break;
|
||||
}
|
||||
case TourneyBracketGumpType.Round_Info:
|
||||
{
|
||||
AddPage(0);
|
||||
AddBackground(0, 0, 300, 300, 9380);
|
||||
|
||||
AddLeftArrow(25, 11, ToButtonID(0, 2));
|
||||
AddHtml(25, 35, 250, 20, Center("Rounds"), false, false);
|
||||
|
||||
if (!(m_Object is PyramidLevel level))
|
||||
break;
|
||||
|
||||
List<TourneyMatch> matchesList = m_List != null
|
||||
? Utility.CastListCovariant<object, TourneyMatch>(m_List)
|
||||
: new List<TourneyMatch>(level.Matches);
|
||||
|
||||
AddRightArrow(25, 53, ToButtonID(5, 0),
|
||||
$"Free Advance: {(level.FreeAdvance == null ? "None" : level.FreeAdvance.NameList)}");
|
||||
|
||||
AddHtml(25, 73, 200, 20, $"{matchesList.Count} Match{(matchesList.Count == 1 ? "" : "es")}", false, false);
|
||||
|
||||
StartPage(out int index, out int count, out int y, 10);
|
||||
|
||||
for (int i = 0; i < count; ++i, y += 18)
|
||||
{
|
||||
TourneyMatch match = matchesList[index + i];
|
||||
|
||||
int color = -1;
|
||||
|
||||
if (match.InProgress)
|
||||
color = 0x336666;
|
||||
else if (match.Context != null && match.Winner == null)
|
||||
color = 0x666666;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
if (m_Tournament.TourneyType == TourneyType.Standard)
|
||||
for (int j = 0; j < match.Participants.Count; ++j)
|
||||
{
|
||||
if (sb.Length > 0)
|
||||
sb.Append(" vs ");
|
||||
|
||||
TourneyParticipant part = match.Participants[j];
|
||||
string txt = part.NameList;
|
||||
|
||||
if (color == -1 && match.Context != null && match.Winner == part)
|
||||
txt = Color(txt, 0x336633);
|
||||
else if (color == -1 && match.Context != null)
|
||||
txt = Color(txt, 0x663333);
|
||||
|
||||
sb.Append(txt);
|
||||
}
|
||||
else if (m_Tournament.EventController != null || m_Tournament.TourneyType == TourneyType.RandomTeam ||
|
||||
m_Tournament.TourneyType == TourneyType.RedVsBlue ||
|
||||
m_Tournament.TourneyType == TourneyType.Faction)
|
||||
for (int j = 0; j < match.Participants.Count; ++j)
|
||||
{
|
||||
if (sb.Length > 0)
|
||||
sb.Append(" vs ");
|
||||
|
||||
TourneyParticipant part = match.Participants[j];
|
||||
string txt;
|
||||
|
||||
if (m_Tournament.EventController != null)
|
||||
{
|
||||
txt = $"Team {m_Tournament.EventController.GetTeamName(j)} ({part.Players.Count})";
|
||||
}
|
||||
else if (m_Tournament.TourneyType == TourneyType.RandomTeam)
|
||||
{
|
||||
txt = $"Team {j + 1} ({part.Players.Count})";
|
||||
}
|
||||
else if (m_Tournament.TourneyType == TourneyType.Faction)
|
||||
{
|
||||
if (m_Tournament.ParticipantsPerMatch == 4)
|
||||
{
|
||||
string name = "(null)";
|
||||
|
||||
switch (j)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
name = "Minax";
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
name = "Council of Mages";
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
name = "True Britannians";
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
name = "Shadowlords";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
txt = $"{name} ({part.Players.Count})";
|
||||
}
|
||||
else if (m_Tournament.ParticipantsPerMatch == 2)
|
||||
{
|
||||
txt = $"{(j == 0 ? "Evil" : "Hero")} Team ({part.Players.Count})";
|
||||
}
|
||||
else
|
||||
{
|
||||
txt = $"Team {j + 1} ({part.Players.Count})";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
txt = $"Team {(j == 0 ? "Red" : "Blue")} ({part.Players.Count})";
|
||||
}
|
||||
|
||||
if (color == -1 && match.Context != null && match.Winner == part)
|
||||
txt = Color(txt, 0x336633);
|
||||
else if (color == -1 && match.Context != null)
|
||||
txt = Color(txt, 0x663333);
|
||||
|
||||
sb.Append(txt);
|
||||
}
|
||||
else if (m_Tournament.TourneyType == TourneyType.FreeForAll) sb.Append("Free For All");
|
||||
|
||||
string str = sb.ToString();
|
||||
|
||||
if (color >= 0)
|
||||
str = Color(str, color);
|
||||
|
||||
AddRightArrow(25, y, ToButtonID(5, index + i + 1), str);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case TourneyBracketGumpType.Match_Info:
|
||||
{
|
||||
if (!(obj is TourneyMatch match))
|
||||
break;
|
||||
|
||||
int ct = m_Tournament.TourneyType == TourneyType.FreeForAll ? 2 : match.Participants.Count;
|
||||
|
||||
AddPage(0);
|
||||
AddBackground(0, 0, 300, 60 + 18 + 20 + 20 + 20 + ct * 18 + 6, 9380);
|
||||
|
||||
AddLeftArrow(25, 11, ToButtonID(0, 5));
|
||||
AddHtml(25, 35, 250, 20, Center("Rounds"), false, false);
|
||||
|
||||
AddHtml(25, 53, 250, 20, $"Winner: {(match.Winner == null ? "N/A" : match.Winner.NameList)}", false,
|
||||
false);
|
||||
AddHtml(25, 73, 250, 20,
|
||||
$"State: {(match.InProgress ? "In progress" : match.Context != null ? "Complete" : "Waiting")}",
|
||||
false, false);
|
||||
AddHtml(25, 93, 250, 20, "Participants:", false, false);
|
||||
|
||||
if (m_Tournament.TourneyType == TourneyType.Standard)
|
||||
for (int i = 0; i < match.Participants.Count; ++i)
|
||||
{
|
||||
TourneyParticipant part = match.Participants[i];
|
||||
|
||||
AddRightArrow(25, 113 + i * 18, ToButtonID(6, i), part.NameList);
|
||||
}
|
||||
else if (m_Tournament.EventController != null || m_Tournament.TourneyType == TourneyType.RandomTeam ||
|
||||
m_Tournament.TourneyType == TourneyType.RedVsBlue ||
|
||||
m_Tournament.TourneyType == TourneyType.Faction)
|
||||
for (int i = 0; i < match.Participants.Count; ++i)
|
||||
{
|
||||
TourneyParticipant part = match.Participants[i];
|
||||
|
||||
if (m_Tournament.EventController != null)
|
||||
{
|
||||
AddRightArrow(25, 113 + i * 18, ToButtonID(6, i),
|
||||
$"Team {m_Tournament.EventController.GetTeamName(i)} ({part.Players.Count})");
|
||||
}
|
||||
else if (m_Tournament.TourneyType == TourneyType.RandomTeam)
|
||||
{
|
||||
AddRightArrow(25, 113 + i * 18, ToButtonID(6, i),
|
||||
$"Team {i + 1} ({part.Players.Count})");
|
||||
}
|
||||
else if (m_Tournament.TourneyType == TourneyType.Faction)
|
||||
{
|
||||
if (m_Tournament.ParticipantsPerMatch == 4)
|
||||
{
|
||||
string name = "(null)";
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
name = "Minax";
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
name = "Council of Mages";
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
name = "True Britannians";
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
name = "Shadowlords";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
AddRightArrow(25, 113 + i * 18, ToButtonID(6, i),
|
||||
$"{name} ({part.Players.Count})");
|
||||
}
|
||||
else if (m_Tournament.ParticipantsPerMatch == 2)
|
||||
{
|
||||
AddRightArrow(25, 113 + i * 18, ToButtonID(6, i),
|
||||
$"{(i == 0 ? "Evil" : "Hero")} Team ({part.Players.Count})");
|
||||
}
|
||||
else
|
||||
{
|
||||
AddRightArrow(25, 113 + i * 18, ToButtonID(6, i),
|
||||
$"Team {i + 1} ({part.Players.Count})");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddRightArrow(25, 113 + i * 18, ToButtonID(6, i),
|
||||
$"Team {(i == 0 ? "Red" : "Blue")} ({part.Players.Count})");
|
||||
}
|
||||
}
|
||||
else if (m_Tournament.TourneyType == TourneyType.FreeForAll)
|
||||
AddHtml(25, 113, 250, 20, "Free For All", false, false);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string Center(string text)
|
||||
{
|
||||
return $"<CENTER>{text}</CENTER>";
|
||||
}
|
||||
|
||||
public string Color(string text, int color)
|
||||
{
|
||||
return $"<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, false, false);
|
||||
else
|
||||
AddHtml(x, y, width, height, Color(text, color), false, false);
|
||||
}
|
||||
|
||||
public void AddRightArrow(int x, int y, int bid, string text)
|
||||
{
|
||||
AddButton(x, y, 0x15E1, 0x15E5, bid, GumpButtonType.Reply, 0);
|
||||
|
||||
if (text != null)
|
||||
AddHtml(x + 20, y - 1, 230, 20, text, false, false);
|
||||
}
|
||||
|
||||
public void AddRightArrow(int x, int y, int bid)
|
||||
{
|
||||
AddRightArrow(x, y, bid, null);
|
||||
}
|
||||
|
||||
public void AddLeftArrow(int x, int y, int bid, string text)
|
||||
{
|
||||
AddButton(x, y, 0x15E3, 0x15E7, bid, GumpButtonType.Reply, 0);
|
||||
|
||||
if (text != null)
|
||||
AddHtml(x + 20, y - 1, 230, 20, text, false, false);
|
||||
}
|
||||
|
||||
public void AddLeftArrow(int x, int y, int bid)
|
||||
{
|
||||
AddLeftArrow(x, y, bid, null);
|
||||
}
|
||||
|
||||
public int ToButtonID(int type, int index)
|
||||
{
|
||||
return 1 + index * 7 + type;
|
||||
}
|
||||
|
||||
public bool FromButtonID(int bid, out int type, out int index)
|
||||
{
|
||||
type = (bid - 1) % 7;
|
||||
index = (bid - 1) / 7;
|
||||
return bid >= 1;
|
||||
}
|
||||
|
||||
public void StartPage(out int index, out int count, out int y, int perPage)
|
||||
{
|
||||
m_PerPage = perPage;
|
||||
|
||||
index = Math.Max(m_Page * perPage, 0);
|
||||
count = Math.Max(Math.Min(m_List.Count - index, perPage), 0);
|
||||
|
||||
y = 53 + (12 - perPage) * 18;
|
||||
|
||||
if (m_Page > 0)
|
||||
AddLeftArrow(242, 35, ToButtonID(1, 0));
|
||||
|
||||
if ((m_Page + 1) * perPage < m_List.Count)
|
||||
AddRightArrow(260, 35, ToButtonID(1, 1));
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (!FromButtonID(info.ButtonID, out int type, out int index))
|
||||
return;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
m_From.SendGump(new TournamentBracketGump(m_From, m_Tournament, TourneyBracketGumpType.Index));
|
||||
break;
|
||||
case 1:
|
||||
m_From.SendGump(new TournamentBracketGump(m_From, m_Tournament,
|
||||
TourneyBracketGumpType.Participant_List));
|
||||
break;
|
||||
case 2:
|
||||
m_From.SendGump(new TournamentBracketGump(m_From, m_Tournament, TourneyBracketGumpType.Round_List));
|
||||
break;
|
||||
case 4:
|
||||
m_From.SendGump(new TournamentBracketGump(m_From, m_Tournament, TourneyBracketGumpType.Rules_Info));
|
||||
break;
|
||||
case 3:
|
||||
{
|
||||
Mobile mob = m_Object as Mobile;
|
||||
|
||||
for (int i = 0; i < m_Tournament.Participants.Count; ++i)
|
||||
{
|
||||
TourneyParticipant part = m_Tournament.Participants[i];
|
||||
|
||||
if (part.Players.Contains(mob))
|
||||
{
|
||||
m_From.SendGump(new TournamentBracketGump(m_From, m_Tournament,
|
||||
TourneyBracketGumpType.Participant_Info, null, 0, part));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
if (!(m_Object is TourneyMatch match))
|
||||
break;
|
||||
|
||||
for (int i = 0; i < m_Tournament.Pyramid.Levels.Count; ++i)
|
||||
{
|
||||
PyramidLevel level = m_Tournament.Pyramid.Levels[i];
|
||||
|
||||
if (level.Matches.Contains(match))
|
||||
m_From.SendGump(new TournamentBracketGump(m_From, m_Tournament,
|
||||
TourneyBracketGumpType.Round_Info, null, 0, level));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
if (m_List != null && m_Page > 0)
|
||||
m_From.SendGump(new TournamentBracketGump(m_From, m_Tournament, m_Type, m_List, m_Page - 1,
|
||||
m_Object));
|
||||
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
if (m_List != null && (m_Page + 1) * m_PerPage < m_List.Count)
|
||||
m_From.SendGump(new TournamentBracketGump(m_From, m_Tournament, m_Type, m_List, m_Page + 1,
|
||||
m_Object));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
if (m_Type != TourneyBracketGumpType.Participant_List)
|
||||
break;
|
||||
|
||||
if (index >= 0 && index < m_List.Count)
|
||||
m_From.SendGump(new TournamentBracketGump(m_From, m_Tournament,
|
||||
TourneyBracketGumpType.Participant_Info, null, 0, m_List[index]));
|
||||
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
if (m_Type != TourneyBracketGumpType.Round_List)
|
||||
break;
|
||||
|
||||
if (index >= 0 && index < m_List.Count)
|
||||
m_From.SendGump(new TournamentBracketGump(m_From, m_Tournament, TourneyBracketGumpType.Round_Info,
|
||||
null, 0, m_List[index]));
|
||||
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
if (m_Type != TourneyBracketGumpType.Participant_Info)
|
||||
break;
|
||||
|
||||
if (m_Object is TourneyParticipant part && index >= 0 && index < part.Players.Count)
|
||||
m_From.SendGump(new TournamentBracketGump(m_From, m_Tournament, TourneyBracketGumpType.Player_Info,
|
||||
null, 0, part.Players[index]));
|
||||
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
if (m_Type != TourneyBracketGumpType.Round_Info)
|
||||
break;
|
||||
|
||||
if (!(m_Object is PyramidLevel level))
|
||||
break;
|
||||
|
||||
if (index == 0)
|
||||
{
|
||||
if (level.FreeAdvance != null)
|
||||
m_From.SendGump(new TournamentBracketGump(m_From, m_Tournament,
|
||||
TourneyBracketGumpType.Participant_Info, null, 0, level.FreeAdvance));
|
||||
else
|
||||
m_From.SendGump(
|
||||
new TournamentBracketGump(m_From, m_Tournament, m_Type, m_List, m_Page, m_Object));
|
||||
}
|
||||
else if (index >= 1 && index <= level.Matches.Count)
|
||||
{
|
||||
m_From.SendGump(new TournamentBracketGump(m_From, m_Tournament, TourneyBracketGumpType.Match_Info,
|
||||
null, 0, level.Matches[index - 1]));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
if (m_Type != TourneyBracketGumpType.Match_Info)
|
||||
break;
|
||||
|
||||
if (m_Object is TourneyMatch match && index >= 0 && index < match.Participants.Count)
|
||||
m_From.SendGump(new TournamentBracketGump(m_From, m_Tournament,
|
||||
TourneyBracketGumpType.Participant_Info, null, 0, match.Participants[index]));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,40 +1,34 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class LadderController : Item
|
||||
{
|
||||
private Ladder m_Ladder;
|
||||
|
||||
[Constructible]
|
||||
public LadderController() : base(0x1B7A)
|
||||
{
|
||||
Visible = false;
|
||||
Movable = false;
|
||||
|
||||
m_Ladder = new Ladder();
|
||||
Ladder = new Ladder();
|
||||
|
||||
if (Ladder.Instance == null)
|
||||
Ladder.Instance = m_Ladder;
|
||||
Ladder.Instance = Ladder;
|
||||
}
|
||||
|
||||
public LadderController(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
//[CommandProperty( AccessLevel.GameMaster )]
|
||||
public Ladder Ladder
|
||||
{
|
||||
get => m_Ladder;
|
||||
set { }
|
||||
}
|
||||
[CommandProperty( AccessLevel.Administrator )]
|
||||
public Ladder Ladder{ get; private set; }
|
||||
|
||||
public override string DefaultName => "ladder controller";
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
if (Ladder.Instance == m_Ladder)
|
||||
if (Ladder.Instance == Ladder)
|
||||
Ladder.Instance = null;
|
||||
|
||||
base.Delete();
|
||||
|
|
@ -46,9 +40,9 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
writer.Write(1);
|
||||
|
||||
m_Ladder.Serialize(writer);
|
||||
Ladder.Serialize(writer);
|
||||
|
||||
writer.Write(Ladder.Instance == m_Ladder);
|
||||
writer.Write(Ladder.Instance == Ladder);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
|
|
@ -62,10 +56,10 @@ namespace Server.Engines.ConPVP
|
|||
case 1:
|
||||
case 0:
|
||||
{
|
||||
m_Ladder = new Ladder(reader);
|
||||
Ladder = new Ladder(reader);
|
||||
|
||||
if (version < 1 || reader.ReadBool())
|
||||
Ladder.Instance = m_Ladder;
|
||||
Ladder.Instance = Ladder;
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
@ -120,14 +114,13 @@ namespace Server.Engines.ConPVP
|
|||
/* +6 */ { 40, 160 }
|
||||
};
|
||||
|
||||
private ArrayList m_Entries;
|
||||
public List<LadderEntry> Entries{ get; } = new List<LadderEntry>();
|
||||
|
||||
private Hashtable m_Table;
|
||||
private Dictionary<Mobile, LadderEntry> m_Table;
|
||||
|
||||
public Ladder()
|
||||
{
|
||||
m_Table = new Hashtable();
|
||||
m_Entries = new ArrayList();
|
||||
m_Table = new Dictionary<Mobile, LadderEntry>();
|
||||
}
|
||||
|
||||
public Ladder(GenericReader reader)
|
||||
|
|
@ -141,8 +134,8 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
int count = reader.ReadEncodedInt();
|
||||
|
||||
m_Table = new Hashtable(count);
|
||||
m_Entries = new ArrayList(count);
|
||||
m_Table = new Dictionary<Mobile, LadderEntry>(count);
|
||||
Entries = new List<LadderEntry>(count);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
|
|
@ -151,18 +144,18 @@ namespace Server.Engines.ConPVP
|
|||
if (entry.Mobile != null)
|
||||
{
|
||||
m_Table[entry.Mobile] = entry;
|
||||
entry.Index = m_Entries.Count;
|
||||
m_Entries.Add(entry);
|
||||
entry.Index = Entries.Count;
|
||||
Entries.Add(entry);
|
||||
}
|
||||
}
|
||||
|
||||
if (version == 0)
|
||||
{
|
||||
m_Entries.Sort();
|
||||
Entries.Sort();
|
||||
|
||||
for (int i = 0; i < m_Entries.Count; ++i)
|
||||
for (int i = 0; i < Entries.Count; ++i)
|
||||
{
|
||||
LadderEntry entry = (LadderEntry)m_Entries[i];
|
||||
LadderEntry entry = Entries[i];
|
||||
|
||||
entry.Index = i;
|
||||
}
|
||||
|
|
@ -247,20 +240,15 @@ namespace Server.Engines.ConPVP
|
|||
return xp * (weWon ? 1 : -1);
|
||||
}
|
||||
|
||||
public ArrayList ToArrayList()
|
||||
{
|
||||
return m_Entries;
|
||||
}
|
||||
|
||||
private int Swap(int idx, int newIdx)
|
||||
{
|
||||
object hold = m_Entries[idx];
|
||||
LadderEntry hold = Entries[idx];
|
||||
|
||||
m_Entries[idx] = m_Entries[newIdx];
|
||||
m_Entries[newIdx] = hold;
|
||||
Entries[idx] = Entries[newIdx];
|
||||
Entries[newIdx] = hold;
|
||||
|
||||
((LadderEntry)m_Entries[idx]).Index = idx;
|
||||
((LadderEntry)m_Entries[newIdx]).Index = newIdx;
|
||||
Entries[idx].Index = idx;
|
||||
Entries[newIdx].Index = newIdx;
|
||||
|
||||
return newIdx;
|
||||
}
|
||||
|
|
@ -269,29 +257,25 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
int index = entry.Index;
|
||||
|
||||
if (index >= 0 && index < m_Entries.Count)
|
||||
if (index >= 0 && index < Entries.Count)
|
||||
{
|
||||
// sanity
|
||||
|
||||
int c;
|
||||
|
||||
while (index - 1 >= 0 && (c = entry.CompareTo(m_Entries[index - 1])) < 0)
|
||||
while (index - 1 >= 0 && (entry.CompareTo(Entries[index - 1])) < 0)
|
||||
index = Swap(index, index - 1);
|
||||
|
||||
while (index + 1 < m_Entries.Count && (c = entry.CompareTo(m_Entries[index + 1])) > 0)
|
||||
while (index + 1 < Entries.Count && (entry.CompareTo(Entries[index + 1])) > 0)
|
||||
index = Swap(index, index + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public LadderEntry Find(Mobile mob)
|
||||
{
|
||||
LadderEntry entry = (LadderEntry)m_Table[mob];
|
||||
LadderEntry entry = m_Table[mob];
|
||||
|
||||
if (entry == null)
|
||||
{
|
||||
m_Table[mob] = entry = new LadderEntry(mob, this);
|
||||
entry.Index = m_Entries.Count;
|
||||
m_Entries.Add(entry);
|
||||
entry.Index = Entries.Count;
|
||||
Entries.Add(entry);
|
||||
}
|
||||
|
||||
return entry;
|
||||
|
|
@ -299,17 +283,17 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
public LadderEntry FindNoCreate(Mobile mob)
|
||||
{
|
||||
return m_Table[mob] as LadderEntry;
|
||||
return m_Table[mob];
|
||||
}
|
||||
|
||||
public void Serialize(GenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(1); // version;
|
||||
|
||||
writer.WriteEncodedInt(m_Entries.Count);
|
||||
writer.WriteEncodedInt(Entries.Count);
|
||||
|
||||
for (int i = 0; i < m_Entries.Count; ++i)
|
||||
((LadderEntry)m_Entries[i]).Serialize(writer);
|
||||
for (int i = 0; i < Entries.Count; ++i)
|
||||
Entries[i].Serialize(writer);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
public DuelContext Context{ get; }
|
||||
|
||||
public TournyParticipant TournyPart{ get; set; }
|
||||
public TourneyParticipant TourneyPart{ get; set; }
|
||||
|
||||
public int FilledSlots
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
|
@ -7,18 +6,16 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
public class PreferencesController : Item
|
||||
{
|
||||
private Preferences m_Preferences;
|
||||
|
||||
[Constructible]
|
||||
public PreferencesController() : base(0x1B7A)
|
||||
{
|
||||
Visible = false;
|
||||
Movable = false;
|
||||
|
||||
m_Preferences = new Preferences();
|
||||
Preferences = new Preferences();
|
||||
|
||||
if (Preferences.Instance == null)
|
||||
Preferences.Instance = m_Preferences;
|
||||
Preferences.Instance = Preferences;
|
||||
else
|
||||
Delete();
|
||||
}
|
||||
|
|
@ -27,18 +24,14 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
}
|
||||
|
||||
//[CommandProperty( AccessLevel.GameMaster )]
|
||||
public Preferences Preferences
|
||||
{
|
||||
get => m_Preferences;
|
||||
set { }
|
||||
}
|
||||
[CommandProperty( AccessLevel.Administrator )]
|
||||
public Preferences Preferences{ get; private set; }
|
||||
|
||||
public override string DefaultName => "preferences controller";
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
if (Preferences.Instance != m_Preferences)
|
||||
if (Preferences.Instance != Preferences)
|
||||
base.Delete();
|
||||
}
|
||||
|
||||
|
|
@ -48,7 +41,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
writer.Write(0);
|
||||
|
||||
m_Preferences.Serialize(writer);
|
||||
Preferences.Serialize(writer);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
|
|
@ -61,8 +54,8 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
case 0:
|
||||
{
|
||||
m_Preferences = new Preferences(reader);
|
||||
Preferences.Instance = m_Preferences;
|
||||
Preferences = new Preferences(reader);
|
||||
Preferences.Instance = Preferences;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -71,12 +64,12 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
public class Preferences
|
||||
{
|
||||
private Hashtable m_Table;
|
||||
private Dictionary<Mobile, PreferencesEntry> m_Table;
|
||||
|
||||
public Preferences()
|
||||
{
|
||||
m_Table = new Hashtable();
|
||||
Entries = new ArrayList();
|
||||
m_Table = new Dictionary<Mobile, PreferencesEntry>();
|
||||
Entries = new List<PreferencesEntry>();
|
||||
}
|
||||
|
||||
public Preferences(GenericReader reader)
|
||||
|
|
@ -89,12 +82,12 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
int count = reader.ReadEncodedInt();
|
||||
|
||||
m_Table = new Hashtable(count);
|
||||
Entries = new ArrayList(count);
|
||||
m_Table = new Dictionary<Mobile, PreferencesEntry>(count);
|
||||
Entries = new List<PreferencesEntry>(count);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
PreferencesEntry entry = new PreferencesEntry(reader, this, version);
|
||||
PreferencesEntry entry = new PreferencesEntry(reader, version);
|
||||
|
||||
if (entry.Mobile != null)
|
||||
{
|
||||
|
|
@ -108,17 +101,17 @@ namespace Server.Engines.ConPVP
|
|||
}
|
||||
}
|
||||
|
||||
public ArrayList Entries{ get; }
|
||||
public List<PreferencesEntry> Entries{ get; }
|
||||
|
||||
public static Preferences Instance{ get; set; }
|
||||
|
||||
public PreferencesEntry Find(Mobile mob)
|
||||
{
|
||||
PreferencesEntry entry = (PreferencesEntry)m_Table[mob];
|
||||
PreferencesEntry entry = m_Table[mob];
|
||||
|
||||
if (entry == null)
|
||||
{
|
||||
m_Table[mob] = entry = new PreferencesEntry(mob, this);
|
||||
m_Table[mob] = entry = new PreferencesEntry(mob);
|
||||
Entries.Add(entry);
|
||||
}
|
||||
|
||||
|
|
@ -132,25 +125,20 @@ namespace Server.Engines.ConPVP
|
|||
writer.WriteEncodedInt(Entries.Count);
|
||||
|
||||
for (int i = 0; i < Entries.Count; ++i)
|
||||
((PreferencesEntry)Entries[i]).Serialize(writer);
|
||||
Entries[i].Serialize(writer);
|
||||
}
|
||||
}
|
||||
|
||||
public class PreferencesEntry
|
||||
{
|
||||
private Preferences m_Preferences;
|
||||
|
||||
public PreferencesEntry(Mobile mob, Preferences prefs)
|
||||
public PreferencesEntry(Mobile mob)
|
||||
{
|
||||
m_Preferences = prefs;
|
||||
Mobile = mob;
|
||||
Disliked = new ArrayList();
|
||||
Disliked = new List<string>();
|
||||
}
|
||||
|
||||
public PreferencesEntry(GenericReader reader, Preferences prefs, int version)
|
||||
public PreferencesEntry(GenericReader reader, int version)
|
||||
{
|
||||
m_Preferences = prefs;
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
|
|
@ -159,7 +147,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
int count = reader.ReadEncodedInt();
|
||||
|
||||
Disliked = new ArrayList(count);
|
||||
Disliked = new List<string>(count);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
Disliked.Add(reader.ReadString());
|
||||
|
|
@ -171,7 +159,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
public Mobile Mobile{ get; }
|
||||
|
||||
public ArrayList Disliked{ get; }
|
||||
public List<string> Disliked{ get; }
|
||||
|
||||
public void Serialize(GenericWriter writer)
|
||||
{
|
||||
|
|
@ -180,7 +168,7 @@ namespace Server.Engines.ConPVP
|
|||
writer.WriteEncodedInt(Disliked.Count);
|
||||
|
||||
for (int i = 0; i < Disliked.Count; ++i)
|
||||
writer.Write((string)Disliked[i]);
|
||||
writer.Write(Disliked[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -188,11 +176,9 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
private int m_ColumnX = 12;
|
||||
private PreferencesEntry m_Entry;
|
||||
private Mobile m_From;
|
||||
|
||||
public PreferencesGump(Mobile from, Preferences prefs) : base(50, 50)
|
||||
{
|
||||
m_From = from;
|
||||
m_Entry = prefs.Find(from);
|
||||
|
||||
if (m_Entry == null)
|
||||
|
|
@ -221,10 +207,7 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
Arena ar = arenas[i];
|
||||
|
||||
string name = ar.Name;
|
||||
|
||||
if (name == null)
|
||||
name = "(no name)";
|
||||
string name = ar.Name ?? "(no name)";
|
||||
|
||||
int x = 12;
|
||||
int y = 32 + i * 31;
|
||||
|
|
@ -235,7 +218,6 @@ namespace Server.Engines.ConPVP
|
|||
x += 35;
|
||||
|
||||
AddBorderedText(x + 5, y + 5, 115 - 5, name, color, 0);
|
||||
x += 115;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -272,12 +254,6 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
|
|
@ -18,7 +19,7 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
public Ruleset Base{ get; private set; }
|
||||
|
||||
public ArrayList Flavors{ get; } = new ArrayList();
|
||||
public List<Ruleset> Flavors{ get; } = new List<Ruleset>();
|
||||
|
||||
public bool Changed{ get; set; }
|
||||
|
||||
|
|
@ -36,7 +37,7 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
for (int i = 0; i < Flavors.Count; ++i)
|
||||
{
|
||||
Ruleset flavor = (Ruleset)Flavors[i];
|
||||
Ruleset flavor = Flavors[i];
|
||||
|
||||
Options.Or(flavor.Options);
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,121 +0,0 @@
|
|||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
#if false
|
||||
[Flippable( 0x9A8, 0xE80 )]
|
||||
public class StakesContainer : LockableContainer
|
||||
{
|
||||
private Mobile m_Initiator;
|
||||
private Participant m_Participant;
|
||||
private Hashtable m_Owners;
|
||||
|
||||
public override bool CheckItemUse( Mobile from, Item item )
|
||||
{
|
||||
Mobile owner = (Mobile)m_Owners[item];
|
||||
|
||||
if ( owner != null && owner != from )
|
||||
return false;
|
||||
|
||||
return base.CheckItemUse( from, item );
|
||||
}
|
||||
|
||||
public override bool CheckTarget( Mobile from, Server.Targeting.Target targ, object targeted )
|
||||
{
|
||||
Mobile owner = (Mobile)m_Owners[targeted];
|
||||
|
||||
if ( owner != null && owner != from )
|
||||
return false;
|
||||
|
||||
return base.CheckTarget( from, targ, targeted );
|
||||
}
|
||||
|
||||
public override bool CheckLift(Mobile from, Item item)
|
||||
{
|
||||
Mobile owner = (Mobile)m_Owners[item];
|
||||
|
||||
if ( owner != null && owner != from )
|
||||
return false;
|
||||
|
||||
return base.CheckLift( from, item );
|
||||
}
|
||||
|
||||
public void ReturnItems()
|
||||
{
|
||||
ArrayList items = new ArrayList( this.Items );
|
||||
|
||||
for ( int i = 0; i < items.Count; ++i )
|
||||
{
|
||||
Item item = (Item)items[i];
|
||||
Mobile owner = (Mobile)m_Owners[item];
|
||||
|
||||
if ( owner == null || owner.Deleted )
|
||||
owner = m_Initiator;
|
||||
|
||||
if ( owner == null || owner.Deleted )
|
||||
return;
|
||||
|
||||
if ( item.LootType != LootType.Blessed || !owner.PlaceInBackpack( item ) )
|
||||
owner.BankBox.DropItem( item );
|
||||
}
|
||||
}
|
||||
|
||||
public override bool TryDropItem( Mobile from, Item dropped, bool sendFullMessage )
|
||||
{
|
||||
if ( m_Participant == null || !m_Participant.Contains( from ) )
|
||||
{
|
||||
if ( sendFullMessage )
|
||||
from.SendMessage( "You are not allowed to place items here." );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( dropped is Container || dropped.Stackable )
|
||||
{
|
||||
if ( sendFullMessage )
|
||||
from.SendMessage( "That item cannot be used as stakes." );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !base.TryDropItem( from, dropped, sendFullMessage ) )
|
||||
return false;
|
||||
|
||||
if ( from != null )
|
||||
m_Owners[dropped] = from;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void RemoveItem( Item item )
|
||||
{
|
||||
base.RemoveItem( item );
|
||||
m_Owners.Remove( item );
|
||||
}
|
||||
|
||||
public StakesContainer( DuelContext context, Participant participant ) : base( 0x9A8 )
|
||||
{
|
||||
Movable = false;
|
||||
m_Initiator = context.Initiator;
|
||||
m_Participant = participant;
|
||||
m_Owners = new Hashtable();
|
||||
}
|
||||
|
||||
public StakesContainer( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
65
Scripts/Engines/ConPVP/TournamentBracketItem.cs
Normal file
65
Scripts/Engines/ConPVP/TournamentBracketItem.cs
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(Tournament);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
Tournament = reader.ReadItem() as TournamentController;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
143
Scripts/Engines/ConPVP/TournamentController.cs
Normal file
143
Scripts/Engines/ConPVP/TournamentController.cs
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.ContextMenus;
|
||||
using Server.Gumps;
|
||||
|
||||
namespace Server.Engines.ConPVP
|
||||
{
|
||||
public class TournamentController : Item
|
||||
{
|
||||
private static 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 != null && !controller.Deleted && 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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
|
||||
Tournament.Serialize(writer);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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 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 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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
189
Scripts/Engines/ConPVP/TournamentPyramid.cs
Normal file
189
Scripts/Engines/ConPVP/TournamentPyramid.cs
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
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
|
||||
|
||||
int idx = Utility.Random(toAdvance.Count);
|
||||
|
||||
toAdvance[idx].AddLog(
|
||||
"Advanced automatically due to an odd number of challengers.");
|
||||
level.FreeAdvance = toAdvance[idx];
|
||||
++level.FreeAdvance.FreeAdvances;
|
||||
copy.Remove(toAdvance[idx]);
|
||||
}
|
||||
|
||||
while (copy.Count >= partsPerMatch)
|
||||
{
|
||||
List<TourneyParticipant> thisMatch = new List<TourneyParticipant>();
|
||||
|
||||
for (int i = 0; i < partsPerMatch; ++i)
|
||||
{
|
||||
int idx = 0;
|
||||
|
||||
switch (groupType)
|
||||
{
|
||||
case GroupingType.HighVsLow:
|
||||
idx = i * (copy.Count - 1) / (partsPerMatch - 1);
|
||||
break;
|
||||
case GroupingType.Nearest:
|
||||
idx = 0;
|
||||
break;
|
||||
case GroupingType.Random:
|
||||
idx = Utility.Random(copy.Count);
|
||||
break;
|
||||
}
|
||||
|
||||
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; }
|
||||
}
|
||||
}
|
||||
93
Scripts/Engines/ConPVP/TournamentRegistrar.cs
Normal file
93
Scripts/Engines/ConPVP/TournamentRegistrar.cs
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(Tournament);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
149
Scripts/Engines/ConPVP/TournamentSignupItem.cs
Normal file
149
Scripts/Engines/ConPVP/TournamentSignupItem.cs
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
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(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(Tournament);
|
||||
writer.Write(Registrar);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
Tournament = reader.ReadItem() as TournamentController;
|
||||
Registrar = reader.ReadMobile();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
109
Scripts/Engines/ConPVP/TourneyParticipant.cs
Normal file
109
Scripts/Engines/ConPVP/TourneyParticipant.cs
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
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);
|
||||
}
|
||||
|
||||
if (sb.Length == 0)
|
||||
return "Empty";
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public int CompareTo(TourneyParticipant p)
|
||||
{
|
||||
return 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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -35,8 +35,8 @@ namespace Server.Engines.Craft
|
|||
|
||||
CraftContext context = craftSystem.GetContext(from);
|
||||
|
||||
from.CloseGump(typeof(CraftGump));
|
||||
from.CloseGump(typeof(CraftGumpItem));
|
||||
from.CloseGump<CraftGump>();
|
||||
from.CloseGump<CraftGumpItem>();
|
||||
|
||||
AddPage(0);
|
||||
|
||||
|
|
@ -125,7 +125,7 @@ namespace Server.Engines.Craft
|
|||
|
||||
if (from.Backpack != null)
|
||||
{
|
||||
Item[] items = from.Backpack.FindItemsByType(resourceType, true);
|
||||
Item[] items = from.Backpack.FindItemsByType(resourceType);
|
||||
|
||||
for (int i = 0; i < items.Length; ++i)
|
||||
resourceCount += items[i].Amount;
|
||||
|
|
@ -163,7 +163,7 @@ namespace Server.Engines.Craft
|
|||
|
||||
if (from.Backpack != null)
|
||||
{
|
||||
Item[] items = from.Backpack.FindItemsByType(resourceType, true);
|
||||
Item[] items = from.Backpack.FindItemsByType(resourceType);
|
||||
|
||||
for (int i = 0; i < items.Length; ++i)
|
||||
resourceCount += items[i].Amount;
|
||||
|
|
@ -219,7 +219,7 @@ namespace Server.Engines.Craft
|
|||
|
||||
if (from.Backpack != null)
|
||||
{
|
||||
Item[] items = from.Backpack.FindItemsByType(subResource.ItemType, true);
|
||||
Item[] items = from.Backpack.FindItemsByType(subResource.ItemType);
|
||||
|
||||
for (int j = 0; j < items.Length; ++j)
|
||||
resourceCount += items[j].Amount;
|
||||
|
|
@ -471,8 +471,6 @@ namespace Server.Engines.Craft
|
|||
{
|
||||
if (m_Page == CraftPage.PickResource && index >= 0 && index < system.CraftSubRes.Count)
|
||||
{
|
||||
int groupIndex = context?.LastGroupIndex ?? -1;
|
||||
|
||||
CraftSubRes res = system.CraftSubRes.GetAt(index);
|
||||
|
||||
if (m_From.Skills[system.MainSkill].Base < res.RequiredSkill)
|
||||
|
|
@ -489,8 +487,6 @@ namespace Server.Engines.Craft
|
|||
}
|
||||
else if (m_Page == CraftPage.PickResource2 && index >= 0 && index < system.CraftSubRes2.Count)
|
||||
{
|
||||
int groupIndex = context?.LastGroupIndex ?? -1;
|
||||
|
||||
CraftSubRes res = system.CraftSubRes2.GetAt(index);
|
||||
|
||||
if (m_From.Skills[system.MainSkill].Base < res.RequiredSkill)
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@ namespace Server.Engines.Craft
|
|||
m_CraftItem = craftItem;
|
||||
m_Tool = tool;
|
||||
|
||||
from.CloseGump(typeof(CraftGump));
|
||||
from.CloseGump(typeof(CraftGumpItem));
|
||||
from.CloseGump<CraftGump>();
|
||||
from.CloseGump<CraftGumpItem>();
|
||||
|
||||
AddPage(0);
|
||||
AddBackground(0, 0, 530, 417, 5054);
|
||||
|
|
@ -143,7 +143,7 @@ namespace Server.Engines.Craft
|
|||
for (int i = 0; i < m_CraftItem.Skills.Count; i++)
|
||||
{
|
||||
CraftSkill skill = m_CraftItem.Skills.GetAt(i);
|
||||
double minSkill = skill.MinSkill, maxSkill = skill.MaxSkill;
|
||||
double minSkill = skill.MinSkill;
|
||||
|
||||
if (minSkill < 0)
|
||||
minSkill = 0;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Server.Commands;
|
||||
using Server.Factions;
|
||||
using Server.Items;
|
||||
|
|
@ -142,6 +141,7 @@ namespace Server.Engines.Craft
|
|||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
if (item != null)
|
||||
|
|
@ -177,9 +177,9 @@ namespace Server.Engines.Craft
|
|||
|
||||
public bool ConsumeAttributes(Mobile from, ref object message, bool consume)
|
||||
{
|
||||
bool consumMana = false;
|
||||
bool consumHits = false;
|
||||
bool consumStam = false;
|
||||
bool consumMana;
|
||||
bool consumHits;
|
||||
bool consumStam;
|
||||
|
||||
if (Hits > 0 && from.Hits < Hits)
|
||||
{
|
||||
|
|
@ -755,7 +755,7 @@ namespace Server.Engines.Craft
|
|||
|
||||
public void Craft(Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool)
|
||||
{
|
||||
if (from.BeginAction(typeof(CraftSystem)))
|
||||
if (from.BeginAction<CraftSystem>())
|
||||
{
|
||||
if (RequiredExpansion == Expansion.None ||
|
||||
from.NetState != null && from.NetState.SupportsExpansion(RequiredExpansion))
|
||||
|
|
@ -794,39 +794,39 @@ namespace Server.Engines.Craft
|
|||
}
|
||||
else
|
||||
{
|
||||
from.EndAction(typeof(CraftSystem));
|
||||
from.EndAction<CraftSystem>();
|
||||
from.SendGump(new CraftGump(from, craftSystem, tool, message));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.EndAction(typeof(CraftSystem));
|
||||
from.EndAction<CraftSystem>();
|
||||
from.SendGump(new CraftGump(from, craftSystem, tool, message));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.EndAction(typeof(CraftSystem));
|
||||
from.EndAction<CraftSystem>();
|
||||
from.SendGump(new CraftGump(from, craftSystem, tool, badCraft));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.EndAction(typeof(CraftSystem));
|
||||
from.EndAction<CraftSystem>();
|
||||
from.SendGump(new CraftGump(from, craftSystem, tool,
|
||||
1072847)); // You must learn that recipe from a scroll.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.EndAction(typeof(CraftSystem));
|
||||
from.EndAction<CraftSystem>();
|
||||
from.SendGump(new CraftGump(from, craftSystem, tool,
|
||||
1044153)); // You don't have the required skills to attempt this item.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.EndAction(typeof(CraftSystem));
|
||||
from.EndAction<CraftSystem>();
|
||||
from.SendGump(new CraftGump(from, craftSystem, tool,
|
||||
RequiredExpansionMessage(RequiredExpansion))); //The {0} expansion is required to attempt this item.
|
||||
}
|
||||
|
|
@ -1098,7 +1098,7 @@ namespace Server.Engines.Craft
|
|||
}
|
||||
else
|
||||
{
|
||||
m_From.EndAction(typeof(CraftSystem));
|
||||
m_From.EndAction<CraftSystem>();
|
||||
|
||||
int badCraft = m_CraftSystem.CanCraft(m_From, m_Tool, m_CraftItem.ItemType);
|
||||
|
||||
|
|
|
|||
|
|
@ -80,18 +80,18 @@ namespace Server.Engines.Craft
|
|||
}
|
||||
|
||||
int phys = 0, fire = 0, cold = 0, pois = 0, nrgy = 0;
|
||||
int dura = 0, luck = 0, lreq = 0, dinc = 0;
|
||||
int baseChance = 0;
|
||||
int dura, luck, lreq, dinc = 0;
|
||||
int baseChance;
|
||||
|
||||
bool physBonus = false;
|
||||
bool fireBonus = false;
|
||||
bool coldBonus = false;
|
||||
bool nrgyBonus = false;
|
||||
bool poisBonus = false;
|
||||
bool duraBonus = false;
|
||||
bool luckBonus = false;
|
||||
bool lreqBonus = false;
|
||||
bool dincBonus = false;
|
||||
bool fireBonus;
|
||||
bool coldBonus;
|
||||
bool nrgyBonus;
|
||||
bool poisBonus;
|
||||
bool duraBonus;
|
||||
bool luckBonus;
|
||||
bool lreqBonus;
|
||||
bool dincBonus;
|
||||
|
||||
if (item is BaseWeapon weapon)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace Server.Engines.Craft
|
|||
public QueryMakersMarkGump(int quality, Mobile from, CraftItem craftItem, CraftSystem craftSystem, Type typeRes,
|
||||
BaseTool tool) : base(100, 200)
|
||||
{
|
||||
from.CloseGump(typeof(QueryMakersMarkGump));
|
||||
from.CloseGump<QueryMakersMarkGump>();
|
||||
|
||||
m_Quality = quality;
|
||||
m_From = from;
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ namespace Server.Engines.Craft
|
|||
private static void LearnAllRecipes_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
Mobile m = e.Mobile;
|
||||
m.SendMessage("Target a player to teach them all of the recipies.");
|
||||
m.SendMessage("Target a player to teach them all of the recipes.");
|
||||
|
||||
m.BeginTarget(-1, false, TargetFlags.None, delegate(Mobile from, object targeted)
|
||||
{
|
||||
|
|
@ -65,7 +65,7 @@ namespace Server.Engines.Craft
|
|||
foreach (KeyValuePair<int, Recipe> kvp in Recipes)
|
||||
mobile.AcquireRecipe(kvp.Key);
|
||||
|
||||
m.SendMessage("You teach them all of the recipies.");
|
||||
m.SendMessage("You teach them all of the recipes.");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -75,11 +75,11 @@ namespace Server.Engines.Craft
|
|||
}
|
||||
|
||||
[Usage("ForgetAllRecipes")]
|
||||
[Description("Makes a player forget all the recipies they've learned.")]
|
||||
[Description("Makes a player forget all the recipes they've learned.")]
|
||||
private static void ForgetAllRecipes_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
Mobile m = e.Mobile;
|
||||
m.SendMessage("Target a player to have them forget all of the recipies they've learned.");
|
||||
m.SendMessage("Target a player to have them forget all of the recipes they've learned.");
|
||||
|
||||
m.BeginTarget(-1, false, TargetFlags.None, delegate(Mobile from, object targeted)
|
||||
{
|
||||
|
|
@ -87,7 +87,7 @@ namespace Server.Engines.Craft
|
|||
{
|
||||
mobile.ResetRecipes();
|
||||
|
||||
m.SendMessage("They forget all their recipies.");
|
||||
m.SendMessage("They forget all their recipes.");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue