Convert movement, actions (lift/use), combat, and spells to use Core.TickCount and avoid DateTime caveats (performance, system time dependency, etc) Refactor DateTime.Now to DateTime.UtcNow Add LOS check for Iron Maiden addon
3377 lines
No EOL
94 KiB
C#
3377 lines
No EOL
94 KiB
C#
using System;
|
|
using System.Text;
|
|
using System.Collections;
|
|
using Server;
|
|
using Server.Items;
|
|
using Server.Gumps;
|
|
using Server.Network;
|
|
using Server.ContextMenus;
|
|
using Server.Mobiles;
|
|
using Server.Targeting;
|
|
using System.Collections.Generic;
|
|
|
|
namespace Server.Engines.ConPVP
|
|
{
|
|
public enum TournamentStage
|
|
{
|
|
Inactive,
|
|
Signup,
|
|
Fighting
|
|
}
|
|
|
|
public enum GroupingType
|
|
{
|
|
HighVsLow,
|
|
Nearest,
|
|
Random
|
|
}
|
|
|
|
public enum TieType
|
|
{
|
|
Random,
|
|
Highest,
|
|
Lowest,
|
|
FullElimination,
|
|
FullAdvancement
|
|
}
|
|
|
|
public class TournamentRegistrar : Banker
|
|
{
|
|
private TournamentController m_Tournament;
|
|
|
|
[CommandProperty( AccessLevel.GameMaster )]
|
|
public TournamentController Tournament{ get{ return m_Tournament; } set{ m_Tournament = value; } }
|
|
|
|
[Constructable]
|
|
public TournamentRegistrar()
|
|
{
|
|
Timer.DelayCall( TimeSpan.FromSeconds( 30.0 ), TimeSpan.FromSeconds( 30.0 ), new TimerCallback( Announce_Callback ) );
|
|
}
|
|
|
|
private void Announce_Callback()
|
|
{
|
|
Tournament tourny = null;
|
|
|
|
if ( m_Tournament != null )
|
|
tourny = m_Tournament.Tournament;
|
|
|
|
if ( tourny != null && tourny.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 tourny = null;
|
|
|
|
if ( m_Tournament != null )
|
|
tourny = m_Tournament.Tournament;
|
|
|
|
if ( InRange( m, 4 ) && !InRange( oldLocation, 4 ) && tourny != null && tourny.Stage == TournamentStage.Signup && m.CanBeginAction( this ) )
|
|
{
|
|
Ladder ladder = Ladder.Instance;
|
|
|
|
if ( ladder != null )
|
|
{
|
|
LadderEntry entry = ladder.Find( m );
|
|
|
|
if ( entry != null && Ladder.GetLevel( entry.Experience ) < tourny.LevelRequirement )
|
|
return;
|
|
}
|
|
|
|
if ( tourny.HasParticipant( m ) )
|
|
return;
|
|
|
|
PrivateOverheadMessage( MessageType.Regular, 0x35, false, String.Format( "Hello m'{0}. Dost thou wish to enter this tournament? You need only to write your name in this book.", m.Female ? "Lady" : "Lord" ), m.NetState );
|
|
m.BeginAction( this );
|
|
Timer.DelayCall( TimeSpan.FromSeconds( 10.0 ), new TimerStateCallback( ReleaseLock_Callback ), m );
|
|
}
|
|
}
|
|
|
|
private void ReleaseLock_Callback( object obj )
|
|
{
|
|
((Mobile)obj).EndAction( this );
|
|
}
|
|
|
|
public TournamentRegistrar( Serial serial ) : base( serial )
|
|
{
|
|
}
|
|
|
|
public override void Serialize( GenericWriter writer )
|
|
{
|
|
base.Serialize( writer );
|
|
|
|
writer.Write( (int) 0 );
|
|
|
|
writer.Write( (Item) m_Tournament );
|
|
}
|
|
|
|
public override void Deserialize( GenericReader reader )
|
|
{
|
|
base.Deserialize( reader );
|
|
|
|
int version = reader.ReadInt();
|
|
|
|
switch ( version )
|
|
{
|
|
case 0:
|
|
{
|
|
m_Tournament = reader.ReadItem() as TournamentController;
|
|
break;
|
|
}
|
|
}
|
|
|
|
Timer.DelayCall( TimeSpan.FromSeconds( 30.0 ), TimeSpan.FromSeconds( 30.0 ), new TimerCallback( Announce_Callback ) );
|
|
}
|
|
}
|
|
|
|
public class TournamentSignupItem : Item
|
|
{
|
|
private TournamentController m_Tournament;
|
|
private Mobile m_Registrar;
|
|
|
|
[CommandProperty( AccessLevel.GameMaster )]
|
|
public TournamentController Tournament{ get{ return m_Tournament; } set{ m_Tournament = value; } }
|
|
|
|
[CommandProperty( AccessLevel.GameMaster )]
|
|
public Mobile Registrar{ get{ return m_Registrar; } set{ m_Registrar = value; } }
|
|
|
|
public override string DefaultName
|
|
{
|
|
get { return "tournament signup book"; }
|
|
}
|
|
|
|
[Constructable]
|
|
public TournamentSignupItem() : base( 4029 )
|
|
{
|
|
Movable = false;
|
|
}
|
|
|
|
public override void OnDoubleClick( Mobile from )
|
|
{
|
|
if ( !from.InRange( GetWorldLocation(), 2 ) )
|
|
{
|
|
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that
|
|
}
|
|
else if ( m_Tournament != null )
|
|
{
|
|
Tournament tourny = m_Tournament.Tournament;
|
|
|
|
if ( tourny != null )
|
|
{
|
|
if ( m_Registrar != null )
|
|
m_Registrar.Direction = m_Registrar.GetDirectionTo( this );
|
|
|
|
switch ( tourny.Stage )
|
|
{
|
|
case TournamentStage.Fighting:
|
|
{
|
|
if ( m_Registrar != null )
|
|
{
|
|
if ( tourny.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:
|
|
{
|
|
if ( m_Registrar != null )
|
|
m_Registrar.PrivateOverheadMessage( MessageType.Regular,
|
|
0x35, false, "The tournament is closed.", from.NetState );
|
|
|
|
break;
|
|
}
|
|
case TournamentStage.Signup:
|
|
{
|
|
Ladder ladder = Ladder.Instance;
|
|
|
|
if ( ladder != null )
|
|
{
|
|
LadderEntry entry = ladder.Find( from );
|
|
|
|
if ( entry != null && Ladder.GetLevel( entry.Experience ) < tourny.LevelRequirement )
|
|
{
|
|
if ( m_Registrar != null )
|
|
{
|
|
m_Registrar.PrivateOverheadMessage( MessageType.Regular,
|
|
0x35, false, "You have not yet proven yourself a worthy dueler.", from.NetState );
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( from.HasGump( typeof( AcceptTeamGump ) ) )
|
|
{
|
|
if ( m_Registrar != null )
|
|
m_Registrar.PrivateOverheadMessage( MessageType.Regular,
|
|
0x22, false, "You must first respond to the offer I've given you.", from.NetState );
|
|
}
|
|
else if ( from.HasGump( typeof( AcceptDuelGump ) ) )
|
|
{
|
|
if ( m_Registrar != null )
|
|
m_Registrar.PrivateOverheadMessage( MessageType.Regular,
|
|
0x22, false, "You must first cancel your duel offer.", from.NetState );
|
|
}
|
|
else if ( from is PlayerMobile && ((PlayerMobile)from).DuelContext != null )
|
|
{
|
|
if ( m_Registrar != null )
|
|
m_Registrar.PrivateOverheadMessage( MessageType.Regular,
|
|
0x22, false, "You are already participating in a duel.", from.NetState );
|
|
}
|
|
else if ( !tourny.HasParticipant( from ) )
|
|
{
|
|
ArrayList players = new ArrayList();
|
|
players.Add(from);
|
|
from.CloseGump( typeof( ConfirmSignupGump ) );
|
|
from.SendGump( new ConfirmSignupGump( from, m_Registrar, tourny, players ) );
|
|
}
|
|
else if ( m_Registrar != null )
|
|
{
|
|
m_Registrar.PrivateOverheadMessage( MessageType.Regular,
|
|
0x35, false, "You have already entered this tournament.", from.NetState );
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public TournamentSignupItem( Serial serial ) : base( serial )
|
|
{
|
|
}
|
|
|
|
public override void Serialize( GenericWriter writer )
|
|
{
|
|
base.Serialize( writer );
|
|
|
|
writer.Write( (int) 0 );
|
|
|
|
writer.Write( (Item) m_Tournament );
|
|
writer.Write( (Mobile) m_Registrar );
|
|
}
|
|
|
|
public override void Deserialize( GenericReader reader )
|
|
{
|
|
base.Deserialize( reader );
|
|
|
|
int version = reader.ReadInt();
|
|
|
|
switch ( version )
|
|
{
|
|
case 0:
|
|
{
|
|
m_Tournament = reader.ReadItem() as TournamentController;
|
|
m_Registrar = reader.ReadMobile();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public class ConfirmSignupGump : Gump
|
|
{
|
|
private Mobile m_From;
|
|
private Tournament m_Tournament;
|
|
private ArrayList m_Players;
|
|
private Mobile m_Registrar;
|
|
|
|
private const int BlackColor32 = 0x000008;
|
|
private const int LabelColor32 = 0xFFFFFF;
|
|
|
|
public string Center( string text )
|
|
{
|
|
return String.Format( "<CENTER>{0}</CENTER>", text );
|
|
}
|
|
|
|
public string Color( string text, int color )
|
|
{
|
|
return String.Format( "<BASEFONT COLOR=#{0:X6}>{1}</BASEFONT>", color, text );
|
|
}
|
|
|
|
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 ConfirmSignupGump( Mobile from, Mobile registrar, Tournament tourny, ArrayList players ) : base( 50, 50 )
|
|
{
|
|
m_From = from;
|
|
m_Registrar = registrar;
|
|
m_Tournament = tourny;
|
|
m_Players = players;
|
|
|
|
m_From.CloseGump( typeof( AcceptTeamGump ) );
|
|
m_From.CloseGump( typeof( AcceptDuelGump ) );
|
|
m_From.CloseGump( typeof( DuelContextGump ) );
|
|
m_From.CloseGump( typeof( ConfirmSignupGump ) );
|
|
|
|
#region Rules
|
|
Ruleset ruleset = tourny.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 ( tourny.PlayersPerParticipant > 1 )
|
|
height += 36 + (tourny.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 ( tourny.TournyType == TournyType.FreeForAll )
|
|
{
|
|
sb.Append( "FFA" );
|
|
}
|
|
else if ( tourny.TournyType == TournyType.RandomTeam )
|
|
{
|
|
sb.Append( "Team" );
|
|
}
|
|
else if ( tourny.TournyType == TournyType.RedVsBlue )
|
|
{
|
|
sb.Append( "Red v Blue" );
|
|
}
|
|
else
|
|
{
|
|
for ( int i = 0; i < tourny.ParticipantsPerMatch; ++i )
|
|
{
|
|
if ( sb.Length > 0 )
|
|
sb.Append( 'v' );
|
|
|
|
sb.Append( tourny.PlayersPerParticipant );
|
|
}
|
|
}
|
|
|
|
if ( tourny.EventController != null )
|
|
sb.Append( ' ' ).Append( tourny.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 ( tourny.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, String.Format( "Grouping: {0}", groupText ), LabelColor32, BlackColor32 );
|
|
y += 20;
|
|
|
|
string tieText = null;
|
|
|
|
switch ( tourny.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 = ( tourny.ParticipantsPerMatch == 2 ? "Both advance" : "Everyone advances" ); break;
|
|
case TieType.FullElimination: tieText = ( tourny.ParticipantsPerMatch == 2 ? "Both eliminated" : "Everyone eliminated" ); break;
|
|
}
|
|
|
|
AddBorderedText( 35, y, 190, 20, String.Format( "Tiebreaker: {0}", tieText ), LabelColor32, BlackColor32 );
|
|
y += 20;
|
|
|
|
string sdText = "Off";
|
|
|
|
if ( tourny.SuddenDeath > TimeSpan.Zero )
|
|
{
|
|
sdText = String.Format( "{0}:{1:D2}", (int) tourny.SuddenDeath.TotalMinutes, tourny.SuddenDeath.Seconds );
|
|
|
|
if ( tourny.SuddenDeathRounds > 0 )
|
|
sdText = String.Format( "{0} (first {1} rounds)", sdText, tourny.SuddenDeathRounds );
|
|
else
|
|
sdText = String.Format( "{0} (all rounds)", sdText );
|
|
}
|
|
|
|
AddBorderedText( 35, y, 240, 20, String.Format( "Sudden Death: {0}", 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, String.Format( "Ruleset: {0}", basedef.Title ), LabelColor32, BlackColor32 );
|
|
y += 20;
|
|
|
|
for ( int i = 0; i < ruleset.Flavors.Count; ++i, y += 18 )
|
|
AddBorderedText( 35, y, 190, 20, String.Format( " + {0}", ((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 ( tourny.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, ((Mobile)players[i]).Name, LabelColor32, BlackColor32 );
|
|
}
|
|
|
|
for ( int i = players.Count; i < tourny.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 override void OnResponse( NetState sender, RelayInfo info )
|
|
{
|
|
if ( info.ButtonID == 1 && info.IsSwitched( 1 ) )
|
|
{
|
|
Tournament tourny = m_Tournament;
|
|
Mobile from = m_From;
|
|
|
|
switch ( tourny.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:
|
|
{
|
|
if ( m_Registrar != null )
|
|
m_Registrar.PrivateOverheadMessage( MessageType.Regular,
|
|
0x35, false, "The tournament is closed.", from.NetState );
|
|
|
|
break;
|
|
}
|
|
case TournamentStage.Signup:
|
|
{
|
|
if ( m_Players.Count != tourny.PlayersPerParticipant )
|
|
{
|
|
if ( m_Registrar != null )
|
|
{
|
|
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 = (Mobile)m_Players[i];
|
|
|
|
LadderEntry entry = ( ladder == null ? null : ladder.Find( mob ) );
|
|
|
|
if ( entry != null && Ladder.GetLevel( entry.Experience ) < tourny.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, String.Format( "{0} has not yet proven themselves a worthy dueler.", mob.Name ), from.NetState );
|
|
}
|
|
}
|
|
|
|
m_From.SendGump( new ConfirmSignupGump( m_From, m_Registrar, m_Tournament, m_Players ) );
|
|
return;
|
|
}
|
|
else if ( tourny.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, String.Format( "{0} has already entered this tournament.", mob.Name ), from.NetState );
|
|
}
|
|
}
|
|
|
|
m_From.SendGump( new ConfirmSignupGump( m_From, m_Registrar, m_Tournament, m_Players ) );
|
|
return;
|
|
}
|
|
else if ( mob is PlayerMobile && ((PlayerMobile)mob).DuelContext != null )
|
|
{
|
|
if ( m_Registrar != 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, String.Format( "{0} is already assigned to a duel. They must yield it before joining this tournament.", mob.Name ), from.NetState );
|
|
}
|
|
}
|
|
|
|
m_From.SendGump( new ConfirmSignupGump( m_From, m_Registrar, m_Tournament, m_Players ) );
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ( m_Registrar != null )
|
|
{
|
|
string fmt;
|
|
|
|
if ( tourny.PlayersPerParticipant == 1 )
|
|
fmt = "As you say m'{0}. I've written your name to the bracket. The tournament will begin {1}.";
|
|
else if ( tourny.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( ( (tourny.SignupStart + tourny.SignupPeriod) - DateTime.UtcNow ).TotalMinutes );
|
|
|
|
if ( minutesUntil == 0 )
|
|
timeUntil = "momentarily";
|
|
else
|
|
timeUntil = String.Format( "in {0} minute{1}", minutesUntil, minutesUntil == 1 ? "" : "s" );
|
|
|
|
m_Registrar.PrivateOverheadMessage( MessageType.Regular,
|
|
0x35, false, String.Format( fmt, from.Female ? "Lady" : "Lord", timeUntil ), from.NetState );
|
|
}
|
|
|
|
TournyParticipant part = new TournyParticipant( from );
|
|
part.Players.Clear();
|
|
part.Players.AddRange( m_Players );
|
|
|
|
tourny.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, new TargetCallback( AddPlayer_OnTarget ) );
|
|
m_From.SendGump( new ConfirmSignupGump( m_From, m_Registrar, m_Tournament, m_Players ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
private void AddPlayer_OnTarget( Mobile from, object obj )
|
|
{
|
|
Mobile mob = obj as Mobile;
|
|
|
|
if ( mob == null || mob == 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, "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 ) );
|
|
|
|
if ( m_Registrar != null )
|
|
m_Registrar.PrivateOverheadMessage( MessageType.Regular,
|
|
0x22, false, "They ignore your invitation.", from.NetState );
|
|
}
|
|
else
|
|
{
|
|
PlayerMobile pm = mob as PlayerMobile;
|
|
|
|
if ( pm == null )
|
|
return;
|
|
|
|
if ( pm.DuelContext != null )
|
|
{
|
|
m_From.SendGump( new ConfirmSignupGump( m_From, m_Registrar, m_Tournament, m_Players ) );
|
|
|
|
if ( m_Registrar != null )
|
|
m_Registrar.PrivateOverheadMessage( MessageType.Regular,
|
|
0x22, false, "They are already assigned to another duel.", from.NetState );
|
|
}
|
|
else if ( mob.HasGump( typeof( 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, "They have already been offered a partnership.", from.NetState );
|
|
}
|
|
else if ( mob.HasGump( typeof( ConfirmSignupGump ) ) )
|
|
{
|
|
m_From.SendGump( new ConfirmSignupGump( m_From, m_Registrar, m_Tournament, m_Players ) );
|
|
|
|
if ( m_Registrar != null )
|
|
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 ) );
|
|
|
|
if ( m_Registrar != null )
|
|
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 ) );
|
|
|
|
if ( m_Registrar != null )
|
|
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 ) );
|
|
|
|
if ( m_Registrar != null )
|
|
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 ) );
|
|
|
|
if ( m_Registrar != null )
|
|
m_Registrar.PrivateOverheadMessage( MessageType.Regular,
|
|
0x59, false, String.Format( "As you command m'{0}. I've given your offer to {1}.", from.Female ? "Lady" : "Lord", mob.Name ), from.NetState );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public class AcceptTeamGump : Gump
|
|
{
|
|
private bool m_Active;
|
|
|
|
private Mobile m_From;
|
|
private Mobile m_Requested;
|
|
private Tournament m_Tournament;
|
|
private Mobile m_Registrar;
|
|
private ArrayList m_Players;
|
|
|
|
private const int BlackColor32 = 0x000008;
|
|
private const int LabelColor32 = 0xFFFFFF;
|
|
|
|
public string Center( string text )
|
|
{
|
|
return String.Format( "<CENTER>{0}</CENTER>", text );
|
|
}
|
|
|
|
public string Color( string text, int color )
|
|
{
|
|
return String.Format( "<BASEFONT COLOR=#{0:X6}>{1}</BASEFONT>", color, text );
|
|
}
|
|
|
|
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 AcceptTeamGump( Mobile from, Mobile requested, Tournament tourny, Mobile registrar, ArrayList players ) : base( 50, 50 )
|
|
{
|
|
m_From = from;
|
|
m_Requested = requested;
|
|
m_Tournament = tourny;
|
|
m_Registrar = registrar;
|
|
m_Players = players;
|
|
|
|
m_Active = true;
|
|
|
|
#region Rules
|
|
Ruleset ruleset = tourny.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 ( tourny.TournyType == TournyType.FreeForAll )
|
|
{
|
|
sb.Append( "FFA" );
|
|
}
|
|
else if ( tourny.TournyType == TournyType.RandomTeam )
|
|
{
|
|
sb.Append( tourny.ParticipantsPerMatch );
|
|
sb.Append( "-Team" );
|
|
}
|
|
else if ( tourny.TournyType == TournyType.RedVsBlue )
|
|
{
|
|
sb.Append( "Red v Blue" );
|
|
}
|
|
else
|
|
{
|
|
for ( int i = 0; i < tourny.ParticipantsPerMatch; ++i )
|
|
{
|
|
if ( sb.Length > 0 )
|
|
sb.Append( 'v' );
|
|
|
|
sb.Append( tourny.PlayersPerParticipant );
|
|
}
|
|
}
|
|
|
|
if ( tourny.EventController != null )
|
|
sb.Append( ' ' ).Append( tourny.EventController.Title );
|
|
|
|
sb.Append( " Tournament Invitation" );
|
|
|
|
AddBorderedText( 22, 22, 294, 20, Center( sb.ToString() ), LabelColor32, BlackColor32 );
|
|
|
|
AddBorderedText( 22, 50, 294, 40,
|
|
String.Format( "You have been asked to partner with {0} in a tournament. Do you accept?", from.Name ),
|
|
0xB0C868, BlackColor32 );
|
|
|
|
AddImageTiled( 32, 88, 264, 1, 9107 );
|
|
AddImageTiled( 42, 90, 264, 1, 9157 );
|
|
|
|
#region Rules
|
|
int y = 100;
|
|
|
|
string groupText = null;
|
|
|
|
switch ( tourny.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, String.Format( "Grouping: {0}", groupText ), LabelColor32, BlackColor32 );
|
|
y += 20;
|
|
|
|
string tieText = null;
|
|
|
|
switch ( tourny.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 = ( tourny.ParticipantsPerMatch == 2 ? "Both advance" : "Everyone advances" ); break;
|
|
case TieType.FullElimination: tieText = ( tourny.ParticipantsPerMatch == 2 ? "Both eliminated" : "Everyone eliminated" ); break;
|
|
}
|
|
|
|
AddBorderedText( 35, y, 190, 20, String.Format( "Tiebreaker: {0}", tieText ), LabelColor32, BlackColor32 );
|
|
y += 20;
|
|
|
|
string sdText = "Off";
|
|
|
|
if ( tourny.SuddenDeath > TimeSpan.Zero )
|
|
{
|
|
sdText = String.Format( "{0}:{1:D2}", (int) tourny.SuddenDeath.TotalMinutes, tourny.SuddenDeath.Seconds );
|
|
|
|
if ( tourny.SuddenDeathRounds > 0 )
|
|
sdText = String.Format( "{0} (first {1} rounds)", sdText, tourny.SuddenDeathRounds );
|
|
else
|
|
sdText = String.Format( "{0} (all rounds)", sdText );
|
|
}
|
|
|
|
AddBorderedText( 35, y, 240, 20, String.Format( "Sudden Death: {0}", 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, String.Format( "Ruleset: {0}", basedef.Title ), LabelColor32, BlackColor32 );
|
|
y += 20;
|
|
|
|
for ( int i = 0; i < ruleset.Flavors.Count; ++i, y += 18 )
|
|
AddBorderedText( 35, y, 190, 20, String.Format( " + {0}", ((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 ), new TimerCallback( AutoReject ) );
|
|
}
|
|
|
|
public void AutoReject()
|
|
{
|
|
if ( !m_Active )
|
|
return;
|
|
|
|
m_Active = false;
|
|
|
|
m_Requested.CloseGump( typeof( 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, String.Format( "{0} seems unresponsive.", m_Requested.Name ), m_From.NetState );
|
|
|
|
m_Registrar.PrivateOverheadMessage( MessageType.Regular,
|
|
0x22, false, String.Format( "You have declined the partnership with {0}.", 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 ) )
|
|
{
|
|
PlayerMobile pm = mob as PlayerMobile;
|
|
|
|
if ( pm == null )
|
|
return;
|
|
|
|
if ( AcceptDuelGump.IsIgnored( mob, from ) || mob.Blessed )
|
|
{
|
|
m_From.SendGump( new ConfirmSignupGump( m_From, m_Registrar, m_Tournament, m_Players ) );
|
|
|
|
if ( m_Registrar != null )
|
|
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 ) );
|
|
|
|
if ( m_Registrar != null )
|
|
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 ) );
|
|
|
|
if ( m_Registrar != null )
|
|
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 ) );
|
|
|
|
if ( m_Registrar != null )
|
|
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 ) );
|
|
|
|
if ( m_Registrar != null )
|
|
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, String.Format( "{0} has accepted your offer of partnership.", mob.Name ), from.NetState );
|
|
|
|
m_Registrar.PrivateOverheadMessage( MessageType.Regular,
|
|
0x59, false, String.Format( "You have accepted the partnership with {0}.", 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, String.Format( "{0} has declined your offer of partnership.", mob.Name ), from.NetState );
|
|
|
|
m_Registrar.PrivateOverheadMessage( MessageType.Regular,
|
|
0x22, false, String.Format( "You have declined the partnership with {0}.", from.Name ), mob.NetState );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public class TournamentController : Item
|
|
{
|
|
private Tournament m_Tournament;
|
|
|
|
[CommandProperty( AccessLevel.GameMaster )]
|
|
public Tournament Tournament{ get{ return m_Tournament; } set{} }
|
|
|
|
private static ArrayList m_Instances = new ArrayList();
|
|
|
|
public static bool IsActive
|
|
{
|
|
get
|
|
{
|
|
for ( int i = 0; i < m_Instances.Count; ++i )
|
|
{
|
|
TournamentController controller = (TournamentController)m_Instances[i];
|
|
|
|
if ( controller != null && !controller.Deleted && controller.Tournament != null && controller.Tournament.Stage!=TournamentStage.Inactive )
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public override string DefaultName
|
|
{
|
|
get { return "tournament controller"; }
|
|
}
|
|
|
|
[Constructable]
|
|
public TournamentController() : base( 0x1B7A )
|
|
{
|
|
Visible = false;
|
|
Movable = false;
|
|
|
|
m_Tournament = new Tournament();
|
|
m_Instances.Add( this );
|
|
}
|
|
|
|
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
|
|
{
|
|
base.GetContextMenuEntries( from, list );
|
|
|
|
if ( from.AccessLevel >= AccessLevel.GameMaster && m_Tournament != null )
|
|
{
|
|
list.Add( new EditEntry( m_Tournament ) );
|
|
|
|
if ( m_Tournament.CurrentStage == TournamentStage.Inactive )
|
|
list.Add( new StartEntry( m_Tournament ) );
|
|
}
|
|
}
|
|
|
|
private class EditEntry : ContextMenuEntry
|
|
{
|
|
private Tournament m_Tournament;
|
|
|
|
public EditEntry( Tournament tourny ) : base( 5101 )
|
|
{
|
|
m_Tournament = tourny;
|
|
}
|
|
|
|
public override void OnClick()
|
|
{
|
|
Owner.From.SendGump( new PropertiesGump( Owner.From, m_Tournament ) );
|
|
}
|
|
}
|
|
|
|
private class StartEntry : ContextMenuEntry
|
|
{
|
|
private Tournament m_Tournament;
|
|
|
|
public StartEntry( Tournament tourny ) : base( 5113 )
|
|
{
|
|
m_Tournament = tourny;
|
|
}
|
|
|
|
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." );
|
|
}
|
|
}
|
|
}
|
|
|
|
public override void OnDoubleClick( Mobile from )
|
|
{
|
|
if ( from.AccessLevel >= AccessLevel.GameMaster && m_Tournament != null )
|
|
{
|
|
from.CloseGump( typeof( PickRulesetGump ) );
|
|
from.CloseGump( typeof( RulesetGump ) );
|
|
from.SendGump( new PickRulesetGump( from, null, m_Tournament.Ruleset ) );
|
|
}
|
|
}
|
|
|
|
public TournamentController( Serial serial ) : base( serial )
|
|
{
|
|
}
|
|
|
|
public override void Serialize( GenericWriter writer )
|
|
{
|
|
base.Serialize( writer );
|
|
|
|
writer.Write( (int) 0 );
|
|
|
|
m_Tournament.Serialize( writer );
|
|
}
|
|
|
|
public override void Deserialize( GenericReader reader )
|
|
{
|
|
base.Deserialize( reader );
|
|
|
|
int version = reader.ReadInt();
|
|
|
|
switch ( version )
|
|
{
|
|
case 0:
|
|
{
|
|
m_Tournament = new Tournament( reader );
|
|
break;
|
|
}
|
|
}
|
|
|
|
m_Instances.Add( this );
|
|
}
|
|
|
|
public override void OnDelete()
|
|
{
|
|
base.OnDelete();
|
|
|
|
m_Instances.Remove( this );
|
|
}
|
|
}
|
|
|
|
public enum TournyType
|
|
{
|
|
Standard,
|
|
FreeForAll,
|
|
RandomTeam,
|
|
RedVsBlue
|
|
}
|
|
|
|
[PropertyObject]
|
|
public class Tournament
|
|
{
|
|
private int m_ParticipantsPerMatch;
|
|
private int m_PlayersPerParticipant;
|
|
private int m_LevelRequirement;
|
|
private TournyPyramid m_Pyramid;
|
|
private Ruleset m_Ruleset;
|
|
|
|
private ArrayList m_Arenas;
|
|
private ArrayList m_Participants;
|
|
private ArrayList m_Undefeated;
|
|
|
|
private TimeSpan m_SignupPeriod;
|
|
private DateTime m_SignupStart;
|
|
|
|
private TournamentStage m_Stage;
|
|
|
|
private GroupingType m_GroupType;
|
|
private TieType m_TieType;
|
|
private TimeSpan m_SuddenDeath;
|
|
|
|
private TournyType m_TournyType;
|
|
|
|
private int m_SuddenDeathRounds;
|
|
|
|
private EventController m_EventController;
|
|
|
|
public bool IsNotoRestricted { get { return ( m_TournyType != TournyType.Standard ); } }
|
|
|
|
[CommandProperty( AccessLevel.GameMaster )]
|
|
public EventController EventController
|
|
{
|
|
get { return m_EventController; }
|
|
set { m_EventController = value; }
|
|
}
|
|
|
|
[CommandProperty( AccessLevel.GameMaster )]
|
|
public int SuddenDeathRounds
|
|
{
|
|
get{ return m_SuddenDeathRounds; }
|
|
set{ m_SuddenDeathRounds = value; }
|
|
}
|
|
|
|
[CommandProperty( AccessLevel.GameMaster )]
|
|
public TournyType TournyType
|
|
{
|
|
get{ return m_TournyType; }
|
|
set{ m_TournyType = value; }
|
|
}
|
|
|
|
[CommandProperty( AccessLevel.GameMaster )]
|
|
public GroupingType GroupType
|
|
{
|
|
get{ return m_GroupType; }
|
|
set{ m_GroupType = value; }
|
|
}
|
|
|
|
[CommandProperty( AccessLevel.GameMaster )]
|
|
public TieType TieType
|
|
{
|
|
get{ return m_TieType; }
|
|
set{ m_TieType = value; }
|
|
}
|
|
|
|
[CommandProperty( AccessLevel.GameMaster )]
|
|
public TimeSpan SuddenDeath
|
|
{
|
|
get{ return m_SuddenDeath; }
|
|
set{ m_SuddenDeath = value; }
|
|
}
|
|
|
|
public Ruleset Ruleset
|
|
{
|
|
get{ return m_Ruleset; }
|
|
set{ m_Ruleset = value; }
|
|
}
|
|
|
|
[CommandProperty( AccessLevel.GameMaster )]
|
|
public int ParticipantsPerMatch
|
|
{
|
|
get{ return m_ParticipantsPerMatch; }
|
|
set{ if ( value < 2 ) value = 2; else if ( value > 10 ) value = 10; m_ParticipantsPerMatch = value; }
|
|
}
|
|
|
|
[CommandProperty( AccessLevel.GameMaster )]
|
|
public int PlayersPerParticipant
|
|
{
|
|
get{ return m_PlayersPerParticipant; }
|
|
set{ if ( value < 1 ) value = 1; else if ( value > 10 ) value = 10; m_PlayersPerParticipant = value; }
|
|
}
|
|
|
|
[CommandProperty( AccessLevel.GameMaster )]
|
|
public int LevelRequirement
|
|
{
|
|
get{ return m_LevelRequirement; }
|
|
set{ m_LevelRequirement = value; }
|
|
}
|
|
|
|
[CommandProperty( AccessLevel.GameMaster )]
|
|
public TimeSpan SignupPeriod
|
|
{
|
|
get{ return m_SignupPeriod; }
|
|
set{ m_SignupPeriod = value; }
|
|
}
|
|
|
|
[CommandProperty( AccessLevel.GameMaster )]
|
|
public DateTime SignupStart
|
|
{
|
|
get{ return m_SignupStart; }
|
|
set{ m_SignupStart = value; }
|
|
}
|
|
|
|
[CommandProperty( AccessLevel.GameMaster )]
|
|
public TournamentStage CurrentStage
|
|
{
|
|
get{ return m_Stage; }
|
|
}
|
|
|
|
public TournamentStage Stage
|
|
{
|
|
get{ return m_Stage; }
|
|
set{ m_Stage = value; }
|
|
}
|
|
|
|
public TournyPyramid Pyramid
|
|
{
|
|
get{ return m_Pyramid; }
|
|
set{ m_Pyramid = value; }
|
|
}
|
|
|
|
public ArrayList Arenas
|
|
{
|
|
get{ return m_Arenas; }
|
|
set{ m_Arenas = value; }
|
|
}
|
|
|
|
public ArrayList Participants
|
|
{
|
|
get{ return m_Participants; }
|
|
set{ m_Participants = value; }
|
|
}
|
|
|
|
public ArrayList Undefeated
|
|
{
|
|
get{ return m_Undefeated; }
|
|
set{ m_Undefeated = value; }
|
|
}
|
|
|
|
public bool HasParticipant( Mobile mob )
|
|
{
|
|
for ( int i = 0; i < m_Participants.Count; ++i )
|
|
{
|
|
TournyParticipant part = (TournyParticipant)m_Participants[i];
|
|
|
|
if ( part.Players.Contains( mob ) )
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public void Serialize( GenericWriter writer )
|
|
{
|
|
writer.WriteEncodedInt( (int) 4 ); // version
|
|
|
|
writer.Write( (Item) m_EventController );
|
|
|
|
writer.WriteEncodedInt( (int) m_SuddenDeathRounds );
|
|
|
|
writer.WriteEncodedInt( (int) m_TournyType );
|
|
|
|
writer.WriteEncodedInt( (int) m_GroupType );
|
|
writer.WriteEncodedInt( (int) m_TieType );
|
|
writer.Write( (TimeSpan) m_SuddenDeath );
|
|
|
|
writer.WriteEncodedInt( (int) m_ParticipantsPerMatch );
|
|
writer.WriteEncodedInt( (int) m_PlayersPerParticipant );
|
|
writer.Write( (TimeSpan) m_SignupPeriod );
|
|
}
|
|
|
|
public Tournament( GenericReader reader )
|
|
{
|
|
int version = reader.ReadEncodedInt();
|
|
|
|
switch ( version )
|
|
{
|
|
case 4:
|
|
{
|
|
m_EventController = reader.ReadItem() as EventController;
|
|
|
|
goto case 3;
|
|
}
|
|
case 3:
|
|
{
|
|
m_SuddenDeathRounds = reader.ReadEncodedInt();
|
|
|
|
goto case 2;
|
|
}
|
|
case 2:
|
|
{
|
|
m_TournyType = (TournyType)reader.ReadEncodedInt();
|
|
|
|
goto case 1;
|
|
}
|
|
case 1:
|
|
{
|
|
m_GroupType = (GroupingType)reader.ReadEncodedInt();
|
|
m_TieType = (TieType)reader.ReadEncodedInt();
|
|
m_SignupPeriod = reader.ReadTimeSpan();
|
|
|
|
goto case 0;
|
|
}
|
|
case 0:
|
|
{
|
|
if ( version < 3 )
|
|
m_SuddenDeathRounds = 3;
|
|
|
|
m_ParticipantsPerMatch = reader.ReadEncodedInt();
|
|
m_PlayersPerParticipant = reader.ReadEncodedInt();
|
|
m_SignupPeriod = reader.ReadTimeSpan();
|
|
m_Stage = TournamentStage.Inactive;
|
|
m_Pyramid = new TournyPyramid();
|
|
m_Ruleset = new Ruleset( RulesetLayout.Root );
|
|
m_Ruleset.ApplyDefault( m_Ruleset.Layout.Defaults[0] );
|
|
m_Participants = new ArrayList();
|
|
m_Undefeated = new ArrayList();
|
|
m_Arenas = new ArrayList();
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
Timer.DelayCall( SliceInterval, SliceInterval, new TimerCallback( Slice ) );
|
|
}
|
|
|
|
public Tournament()
|
|
{
|
|
m_ParticipantsPerMatch = 2;
|
|
m_PlayersPerParticipant = 1;
|
|
m_Pyramid = new TournyPyramid();
|
|
m_Ruleset = new Ruleset( RulesetLayout.Root );
|
|
m_Ruleset.ApplyDefault( m_Ruleset.Layout.Defaults[0] );
|
|
m_Participants = new ArrayList();
|
|
m_Undefeated = new ArrayList();
|
|
m_Arenas = new ArrayList();
|
|
m_SignupPeriod = TimeSpan.FromMinutes( 10.0 );
|
|
|
|
Timer.DelayCall( SliceInterval, SliceInterval, new TimerCallback( Slice ) );
|
|
}
|
|
|
|
public void HandleTie( Arena arena, TournyMatch match, ArrayList remaining )
|
|
{
|
|
if ( remaining.Count == 1 )
|
|
HandleWon( arena, match, (TournyParticipant)remaining[0] );
|
|
|
|
if ( remaining.Count < 2 )
|
|
return;
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
sb.Append( "The match has ended in a tie " );
|
|
|
|
if ( remaining.Count == 2 )
|
|
sb.Append( "between " );
|
|
else
|
|
sb.Append( "among " );
|
|
|
|
sb.Append( remaining.Count );
|
|
|
|
if ( ((TournyParticipant)remaining[0]).Players.Count == 1 )
|
|
sb.Append( " players: " );
|
|
else
|
|
sb.Append( " teams: " );
|
|
|
|
bool hasAppended = false;
|
|
|
|
for ( int j = 0; j < match.Participants.Count; ++j )
|
|
{
|
|
TournyParticipant part = (TournyParticipant)match.Participants[j];
|
|
|
|
if ( remaining.Contains( part ) )
|
|
{
|
|
if ( hasAppended )
|
|
sb.Append( ", " );
|
|
|
|
sb.Append( part.NameList );
|
|
hasAppended = true;
|
|
}
|
|
else
|
|
{
|
|
m_Undefeated.Remove( part );
|
|
}
|
|
}
|
|
|
|
sb.Append( ". " );
|
|
|
|
string whole = ( remaining.Count == 2 ? "both" : "all" );
|
|
|
|
TieType tieType = m_TieType;
|
|
|
|
if ( tieType == TieType.FullElimination && remaining.Count >= m_Undefeated.Count )
|
|
tieType = TieType.FullAdvancement;
|
|
|
|
switch ( m_TieType )
|
|
{
|
|
case TieType.FullAdvancement:
|
|
{
|
|
sb.AppendFormat( "In accordance with the rules, {0} parties are advanced.", whole );
|
|
break;
|
|
}
|
|
case TieType.FullElimination:
|
|
{
|
|
for ( int j = 0; j < remaining.Count; ++j )
|
|
m_Undefeated.Remove( remaining[j] );
|
|
|
|
sb.AppendFormat( "In accordance with the rules, {0} parties are eliminated.", whole );
|
|
break;
|
|
}
|
|
case TieType.Random:
|
|
{
|
|
TournyParticipant advanced = (TournyParticipant)remaining[Utility.Random( remaining.Count )];
|
|
|
|
for ( int i = 0; i < remaining.Count; ++i )
|
|
{
|
|
if ( remaining[i] != advanced )
|
|
m_Undefeated.Remove( remaining[i] );
|
|
}
|
|
|
|
if ( advanced != null )
|
|
sb.AppendFormat( "In accordance with the rules, {0} {1} advanced.", advanced.NameList, advanced.Players.Count == 1 ? "is" : "are" );
|
|
|
|
break;
|
|
}
|
|
case TieType.Highest:
|
|
{
|
|
TournyParticipant advanced = null;
|
|
|
|
for ( int i = 0; i < remaining.Count; ++i )
|
|
{
|
|
TournyParticipant part = (TournyParticipant)remaining[i];
|
|
|
|
if ( advanced == null || part.TotalLadderXP > advanced.TotalLadderXP )
|
|
advanced = part;
|
|
}
|
|
|
|
for ( int i = 0; i < remaining.Count; ++i )
|
|
{
|
|
if ( remaining[i] != advanced )
|
|
m_Undefeated.Remove( remaining[i] );
|
|
}
|
|
|
|
if ( advanced != null )
|
|
sb.AppendFormat( "In accordance with the rules, {0} {1} advanced.", advanced.NameList, advanced.Players.Count == 1 ? "is" : "are" );
|
|
|
|
break;
|
|
}
|
|
case TieType.Lowest:
|
|
{
|
|
TournyParticipant advanced = null;
|
|
|
|
for ( int i = 0; i < remaining.Count; ++i )
|
|
{
|
|
TournyParticipant part = (TournyParticipant)remaining[i];
|
|
|
|
if ( advanced == null || part.TotalLadderXP < advanced.TotalLadderXP )
|
|
advanced = part;
|
|
}
|
|
|
|
for ( int i = 0; i < remaining.Count; ++i )
|
|
{
|
|
if ( remaining[i] != advanced )
|
|
m_Undefeated.Remove( remaining[i] );
|
|
}
|
|
|
|
if ( advanced != null )
|
|
sb.AppendFormat( "In accordance with the rules, {0} {1} advanced.", advanced.NameList, advanced.Players.Count == 1 ? "is" : "are" );
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
Alert( arena, sb.ToString() );
|
|
}
|
|
|
|
public void OnEliminated( DuelPlayer player )
|
|
{
|
|
Participant part = player.Participant;
|
|
|
|
if ( !part.Eliminated )
|
|
return;
|
|
|
|
if ( m_TournyType == TournyType.FreeForAll )
|
|
{
|
|
int rem = 0;
|
|
|
|
for ( int i = 0; i < part.Context.Participants.Count; ++i )
|
|
{
|
|
Participant check = (Participant)part.Context.Participants[i];
|
|
|
|
if ( check != null && !check.Eliminated )
|
|
++rem;
|
|
}
|
|
|
|
TournyParticipant tp = part.TournyPart;
|
|
|
|
if ( tp == null )
|
|
return;
|
|
|
|
if ( rem == 1 )
|
|
GiveAwards( tp.Players, TrophyRank.Silver, ComputeCashAward() / 2 );
|
|
else if ( rem == 2 )
|
|
GiveAwards( tp.Players, TrophyRank.Bronze, ComputeCashAward() / 4 );
|
|
}
|
|
}
|
|
|
|
public void HandleWon( Arena arena, TournyMatch match, TournyParticipant winner )
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
sb.Append( "The match is complete. " );
|
|
sb.Append( winner.NameList );
|
|
|
|
if ( winner.Players.Count > 1 )
|
|
sb.Append( " have bested " );
|
|
else
|
|
sb.Append( " has bested " );
|
|
|
|
if ( match.Participants.Count > 2 )
|
|
sb.AppendFormat( "{0} other {1}: ", match.Participants.Count - 1, winner.Players.Count == 1 ? "players" : "teams" );
|
|
|
|
bool hasAppended = false;
|
|
|
|
for ( int j = 0; j < match.Participants.Count; ++j )
|
|
{
|
|
TournyParticipant part = (TournyParticipant)match.Participants[j];
|
|
|
|
if ( part == winner )
|
|
continue;
|
|
|
|
m_Undefeated.Remove( part );
|
|
|
|
if ( hasAppended )
|
|
sb.Append( ", " );
|
|
|
|
sb.Append( part.NameList );
|
|
hasAppended = true;
|
|
}
|
|
|
|
sb.Append( "." );
|
|
|
|
if ( m_TournyType == TournyType.Standard )
|
|
Alert( arena, sb.ToString() );
|
|
}
|
|
|
|
private static readonly TimeSpan SliceInterval = TimeSpan.FromSeconds( 12.0 );
|
|
|
|
private int ComputeCashAward()
|
|
{
|
|
return m_Participants.Count * m_PlayersPerParticipant * 2500;
|
|
}
|
|
|
|
private void GiveAwards()
|
|
{
|
|
switch ( m_TournyType )
|
|
{
|
|
case TournyType.FreeForAll:
|
|
{
|
|
if ( m_Pyramid.Levels.Count < 1 )
|
|
break;
|
|
|
|
PyramidLevel top = m_Pyramid.Levels[m_Pyramid.Levels.Count - 1] as PyramidLevel;
|
|
|
|
if ( top.FreeAdvance != null || top.Matches.Count != 1 )
|
|
break;
|
|
|
|
TournyMatch match = top.Matches[0] as TournyMatch;
|
|
TournyParticipant winner = match.Winner;
|
|
|
|
if ( winner != null )
|
|
GiveAwards( winner.Players, TrophyRank.Gold, ComputeCashAward() );
|
|
|
|
break;
|
|
}
|
|
case TournyType.Standard:
|
|
{
|
|
if ( m_Pyramid.Levels.Count < 2 )
|
|
break;
|
|
|
|
PyramidLevel top = m_Pyramid.Levels[m_Pyramid.Levels.Count - 1] as PyramidLevel;
|
|
|
|
if ( top.FreeAdvance != null || top.Matches.Count != 1 )
|
|
break;
|
|
|
|
int cash = ComputeCashAward();
|
|
|
|
TournyMatch match = top.Matches[0] as TournyMatch;
|
|
TournyParticipant winner = match.Winner;
|
|
|
|
for ( int i = 0; i < match.Participants.Count; ++i )
|
|
{
|
|
TournyParticipant part = (TournyParticipant) match.Participants[i];
|
|
|
|
if ( part == winner )
|
|
GiveAwards( part.Players, TrophyRank.Gold, cash );
|
|
else
|
|
GiveAwards( part.Players, TrophyRank.Silver, cash / 2 );
|
|
}
|
|
|
|
PyramidLevel next = m_Pyramid.Levels[m_Pyramid.Levels.Count - 2] as PyramidLevel;
|
|
|
|
if ( next.Matches.Count > 2 )
|
|
break;
|
|
|
|
for ( int i = 0; i < next.Matches.Count; ++i )
|
|
{
|
|
match = (TournyMatch)next.Matches[i];
|
|
winner = match.Winner;
|
|
|
|
for ( int j = 0; j < match.Participants.Count; ++j )
|
|
{
|
|
TournyParticipant part = (TournyParticipant) match.Participants[j];
|
|
|
|
if ( part != winner )
|
|
GiveAwards( part.Players, TrophyRank.Bronze, cash / 4 );
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void GiveAwards( ArrayList players, TrophyRank rank, int cash )
|
|
{
|
|
if ( players.Count == 0 )
|
|
return;
|
|
|
|
if ( players.Count > 1 )
|
|
cash /= ( players.Count - 1 );
|
|
|
|
cash += 500;
|
|
cash /= 1000;
|
|
cash *= 1000;
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
if ( m_TournyType == TournyType.FreeForAll )
|
|
{
|
|
sb.Append( m_Participants.Count * m_PlayersPerParticipant );
|
|
sb.Append( "-man FFA" );
|
|
}
|
|
else if ( m_TournyType == TournyType.RandomTeam )
|
|
{
|
|
sb.Append( m_ParticipantsPerMatch );
|
|
sb.Append( "-team" );
|
|
}
|
|
else if ( m_TournyType == TournyType.RedVsBlue )
|
|
{
|
|
sb.Append( "Red v Blue" );
|
|
}
|
|
else
|
|
{
|
|
for ( int i = 0; i < m_ParticipantsPerMatch; ++i )
|
|
{
|
|
if ( sb.Length > 0 )
|
|
sb.Append( 'v' );
|
|
|
|
sb.Append( m_PlayersPerParticipant );
|
|
}
|
|
}
|
|
|
|
if ( m_EventController != null )
|
|
sb.Append( ' ' ).Append( m_EventController.Title );
|
|
|
|
sb.Append( " Champion" );
|
|
|
|
string title = sb.ToString();
|
|
|
|
for ( int i = 0; i < players.Count; ++i )
|
|
{
|
|
Mobile mob = (Mobile) players[i];
|
|
|
|
if ( mob == null || mob.Deleted )
|
|
continue;
|
|
|
|
Item item = new Trophy( title, rank );
|
|
|
|
if ( !mob.PlaceInBackpack( item ) )
|
|
mob.BankBox.DropItem( item );
|
|
|
|
if ( cash > 0 )
|
|
{
|
|
item = new BankCheck( cash );
|
|
|
|
if ( !mob.PlaceInBackpack( item ) )
|
|
mob.BankBox.DropItem( item );
|
|
|
|
mob.SendMessage( "You have been awarded a {0} trophy and {1:N0}gp for your participation in this tournament.", rank.ToString().ToLower(), cash );
|
|
}
|
|
else
|
|
{
|
|
mob.SendMessage( "You have been awarded a {0} trophy for your participation in this tournament.", rank.ToString().ToLower() );
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Slice()
|
|
{
|
|
if ( m_Stage == TournamentStage.Signup )
|
|
{
|
|
TimeSpan until = ( m_SignupStart + m_SignupPeriod ) - DateTime.UtcNow;
|
|
|
|
if ( until <= TimeSpan.Zero )
|
|
{
|
|
for ( int i = m_Participants.Count - 1; i >= 0; --i )
|
|
{
|
|
TournyParticipant part = (TournyParticipant)m_Participants[i];
|
|
bool bad = false;
|
|
|
|
for ( int j = 0; j < part.Players.Count; ++j )
|
|
{
|
|
Mobile check = (Mobile) part.Players[j];
|
|
|
|
if ( check.Deleted || check.Map == null || check.Map == Map.Internal || !check.Alive || Factions.Sigil.ExistsOn( check ) || check.Region.IsPartOf( typeof( Regions.Jail ) ) )
|
|
{
|
|
bad = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( bad )
|
|
{
|
|
for ( int j = 0; j < part.Players.Count; ++j )
|
|
((Mobile)part.Players[j]).SendMessage( "You have been disqualified from the tournament." );
|
|
|
|
m_Participants.RemoveAt( i );
|
|
}
|
|
}
|
|
|
|
if ( m_Participants.Count >= 2 )
|
|
{
|
|
m_Stage = TournamentStage.Fighting;
|
|
|
|
m_Undefeated.Clear();
|
|
|
|
m_Pyramid.Levels.Clear();
|
|
m_Pyramid.AddLevel( m_ParticipantsPerMatch, m_Participants, m_GroupType, m_TournyType );
|
|
|
|
PyramidLevel level = (PyramidLevel)m_Pyramid.Levels[0];
|
|
|
|
if ( level.FreeAdvance != null )
|
|
m_Undefeated.Add( level.FreeAdvance );
|
|
|
|
for ( int i = 0; i < level.Matches.Count; ++i )
|
|
{
|
|
TournyMatch match = (TournyMatch)level.Matches[i];
|
|
|
|
m_Undefeated.AddRange( match.Participants );
|
|
}
|
|
|
|
Alert( "Hear ye! Hear ye!", "The tournament will begin shortly." );
|
|
}
|
|
else
|
|
{
|
|
Alert( "Is this all?", "Pitiful. Signup extended." );
|
|
m_SignupStart = DateTime.UtcNow;
|
|
}
|
|
}
|
|
else if ( Math.Abs( until.TotalSeconds - TimeSpan.FromMinutes( 1.0 ).TotalSeconds ) < (SliceInterval.TotalSeconds/2) )
|
|
{
|
|
Alert( "Last call!", "If you wish to enter the tournament, sign up with the registrar now." );
|
|
}
|
|
else if ( Math.Abs( until.TotalSeconds - TimeSpan.FromMinutes( 5.0 ).TotalSeconds ) < (SliceInterval.TotalSeconds/2) )
|
|
{
|
|
Alert( "The tournament will begin in 5 minutes.", "Sign up now before it's too late." );
|
|
}
|
|
}
|
|
else if ( m_Stage == TournamentStage.Fighting )
|
|
{
|
|
if ( m_Undefeated.Count == 1 )
|
|
{
|
|
TournyParticipant winner = (TournyParticipant)m_Undefeated[0];
|
|
|
|
try
|
|
{
|
|
if ( m_EventController != null )
|
|
Alert( "The tournament has completed!", String.Format( "Team {0} has won!", m_EventController.GetTeamName( ((TournyMatch)((PyramidLevel)m_Pyramid.Levels[0]).Matches[0]).Participants.IndexOf( winner ) ) ) );
|
|
else if ( m_TournyType == TournyType.RandomTeam )
|
|
Alert( "The tournament has completed!", String.Format( "Team {0} has won!", ((TournyMatch)((PyramidLevel)m_Pyramid.Levels[0]).Matches[0]).Participants.IndexOf( winner ) + 1 ) );
|
|
else if ( m_TournyType == TournyType.RedVsBlue )
|
|
Alert( "The tournament has completed!", String.Format( "Team {0} has won!", ((TournyMatch)((PyramidLevel)m_Pyramid.Levels[0]).Matches[0]).Participants.IndexOf( winner ) == 0 ? "Red" : "Blue" ) );
|
|
else
|
|
Alert( "The tournament has completed!", String.Format( "{0} {1} the champion{2}.", winner.NameList, winner.Players.Count > 1 ? "are" : "is", winner.Players.Count == 1 ? "" : "s" ) );
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
|
|
GiveAwards();
|
|
|
|
m_Stage = TournamentStage.Inactive;
|
|
m_Undefeated.Clear();
|
|
}
|
|
else if ( m_Pyramid.Levels.Count > 0 )
|
|
{
|
|
PyramidLevel activeLevel = (PyramidLevel)m_Pyramid.Levels[m_Pyramid.Levels.Count - 1];
|
|
bool stillGoing = false;
|
|
|
|
for ( int i = 0; i < activeLevel.Matches.Count; ++i )
|
|
{
|
|
TournyMatch match = (TournyMatch)activeLevel.Matches[i];
|
|
|
|
if ( match.Winner == null )
|
|
{
|
|
stillGoing = true;
|
|
|
|
if ( !match.InProgress )
|
|
{
|
|
for ( int j = 0; j < m_Arenas.Count; ++j )
|
|
{
|
|
Arena arena = (Arena)m_Arenas[j];
|
|
|
|
if ( !arena.IsOccupied )
|
|
{
|
|
match.Start( arena, this );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( !stillGoing )
|
|
{
|
|
for ( int i = m_Undefeated.Count - 1; i >= 0; --i )
|
|
{
|
|
TournyParticipant part = (TournyParticipant)m_Undefeated[i];
|
|
bool bad = false;
|
|
|
|
for ( int j = 0; j < part.Players.Count; ++j )
|
|
{
|
|
Mobile check = (Mobile) part.Players[j];
|
|
|
|
if ( check.Deleted || check.Map == null || check.Map == Map.Internal || !check.Alive || Factions.Sigil.ExistsOn( check ) || check.Region.IsPartOf( typeof( Regions.Jail ) ) )
|
|
{
|
|
bad = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( bad )
|
|
{
|
|
for ( int j = 0; j < part.Players.Count; ++j )
|
|
((Mobile)part.Players[j]).SendMessage( "You have been disqualified from the tournament." );
|
|
|
|
m_Undefeated.RemoveAt( i );
|
|
|
|
if ( m_Undefeated.Count == 1 )
|
|
{
|
|
TournyParticipant winner = (TournyParticipant)m_Undefeated[0];
|
|
|
|
try
|
|
{
|
|
if ( m_EventController != null )
|
|
Alert( "The tournament has completed!", String.Format( "Team {0} has won", m_EventController.GetTeamName( ( (TournyMatch) ( (PyramidLevel) m_Pyramid.Levels[0] ).Matches[0] ).Participants.IndexOf( winner ) ) ) );
|
|
else if ( m_TournyType == TournyType.RandomTeam )
|
|
Alert( "The tournament has completed!", String.Format( "Team {0} has won!", ((TournyMatch)((PyramidLevel)m_Pyramid.Levels[0]).Matches[0]).Participants.IndexOf( winner ) + 1 ) );
|
|
else if ( m_TournyType == TournyType.RedVsBlue )
|
|
Alert( "The tournament has completed!", String.Format( "Team {0} has won!", ((TournyMatch)((PyramidLevel)m_Pyramid.Levels[0]).Matches[0]).Participants.IndexOf( winner ) == 0 ? "Red" : "Blue" ) );
|
|
else
|
|
Alert( "The tournament has completed!", String.Format( "{0} {1} the champion{2}.", winner.NameList, winner.Players.Count > 1 ? "are" : "is", winner.Players.Count == 1 ? "" : "s" ) );
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
|
|
GiveAwards();
|
|
|
|
m_Stage = TournamentStage.Inactive;
|
|
m_Undefeated.Clear();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( m_Undefeated.Count > 1 )
|
|
m_Pyramid.AddLevel( m_ParticipantsPerMatch, m_Undefeated, m_GroupType, m_TournyType );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Alert( params string[] alerts )
|
|
{
|
|
for ( int i = 0; i < m_Arenas.Count; ++i )
|
|
Alert( (Arena) m_Arenas[i], alerts );
|
|
}
|
|
|
|
public void Alert( Arena arena, params string[] alerts )
|
|
{
|
|
if ( arena != null && arena.Announcer != null )
|
|
{
|
|
for ( int j = 0; j < alerts.Length; ++j )
|
|
Timer.DelayCall( TimeSpan.FromSeconds( Math.Max( j-0.5, 0.0 ) ), new TimerStateCallback( Alert_Callback ), new object[]{ arena.Announcer, alerts[j] } );
|
|
}
|
|
}
|
|
|
|
private void Alert_Callback( object state )
|
|
{
|
|
object[] states = (object[])state;
|
|
|
|
if ( states[0] != null )
|
|
((Mobile)states[0]).PublicOverheadMessage( MessageType.Regular, 0x35, false, (string)states[1] );
|
|
}
|
|
}
|
|
|
|
public class TournyPyramid
|
|
{
|
|
private ArrayList m_Levels;
|
|
|
|
public ArrayList Levels
|
|
{
|
|
get{ return m_Levels; }
|
|
set{ m_Levels = value; }
|
|
}
|
|
|
|
public TournyPyramid()
|
|
{
|
|
m_Levels = new ArrayList();
|
|
}
|
|
|
|
public void AddLevel( int partsPerMatch, ArrayList participants, GroupingType groupType, TournyType tournyType )
|
|
{
|
|
ArrayList copy = new ArrayList( participants );
|
|
|
|
if ( groupType == GroupingType.Nearest || groupType == GroupingType.HighVsLow )
|
|
copy.Sort();
|
|
|
|
PyramidLevel level = new PyramidLevel();
|
|
|
|
switch ( tournyType )
|
|
{
|
|
case TournyType.RedVsBlue:
|
|
{
|
|
TournyParticipant[] parts = new TournyParticipant[2];
|
|
|
|
for ( int i = 0; i < parts.Length; ++i )
|
|
parts[i] = new TournyParticipant( new ArrayList() );
|
|
|
|
for ( int i = 0; i < copy.Count; ++i )
|
|
{
|
|
ArrayList players = ((TournyParticipant)copy[i]).Players;
|
|
|
|
for ( int j = 0; j < players.Count; ++j )
|
|
{
|
|
Mobile mob = (Mobile) players[j];
|
|
|
|
if ( mob.Kills >= 5 )
|
|
parts[0].Players.Add( mob );
|
|
else
|
|
parts[1].Players.Add( mob );
|
|
}
|
|
}
|
|
|
|
level.Matches.Add( new TournyMatch( new ArrayList( parts ) ) );
|
|
break;
|
|
}
|
|
case TournyType.RandomTeam:
|
|
{
|
|
TournyParticipant[] parts = new TournyParticipant[partsPerMatch];
|
|
|
|
for ( int i = 0; i < partsPerMatch; ++i )
|
|
parts[i] = new TournyParticipant( new ArrayList() );
|
|
|
|
for ( int i = 0; i < copy.Count; ++i )
|
|
parts[i % parts.Length].Players.AddRange( ((TournyParticipant)copy[i]).Players );
|
|
|
|
level.Matches.Add( new TournyMatch( new ArrayList( parts ) ) );
|
|
break;
|
|
}
|
|
case TournyType.FreeForAll:
|
|
{
|
|
level.Matches.Add( new TournyMatch( copy ) );
|
|
break;
|
|
}
|
|
case TournyType.Standard:
|
|
{
|
|
if ( partsPerMatch >= 2 && participants.Count % partsPerMatch == 1 )
|
|
{
|
|
int lowAdvances = int.MaxValue;
|
|
|
|
for ( int i = 0; i < participants.Count; ++i )
|
|
{
|
|
TournyParticipant p = (TournyParticipant)participants[i];
|
|
|
|
if ( p.FreeAdvances < lowAdvances )
|
|
lowAdvances = p.FreeAdvances;
|
|
}
|
|
|
|
ArrayList toAdvance = new ArrayList();
|
|
|
|
for ( int i = 0; i < participants.Count; ++i )
|
|
{
|
|
TournyParticipant p = (TournyParticipant)participants[i];
|
|
|
|
if ( p.FreeAdvances == lowAdvances )
|
|
toAdvance.Add( p );
|
|
}
|
|
|
|
if ( toAdvance.Count == 0 )
|
|
toAdvance = copy; // sanity
|
|
|
|
int idx = Utility.Random( toAdvance.Count );
|
|
|
|
((TournyParticipant)toAdvance[idx]).AddLog( "Advanced automatically due to an odd number of challengers." );
|
|
level.FreeAdvance = (TournyParticipant)toAdvance[idx];
|
|
++level.FreeAdvance.FreeAdvances;
|
|
copy.Remove( toAdvance[idx] );
|
|
}
|
|
|
|
while ( copy.Count >= partsPerMatch )
|
|
{
|
|
ArrayList thisMatch = new ArrayList();
|
|
|
|
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 TournyMatch( thisMatch ) );
|
|
}
|
|
|
|
if ( copy.Count > 1 )
|
|
level.Matches.Add( new TournyMatch( copy ) );
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
m_Levels.Add( level );
|
|
}
|
|
}
|
|
|
|
public class PyramidLevel
|
|
{
|
|
private ArrayList m_Matches;
|
|
private TournyParticipant m_FreeAdvance;
|
|
|
|
public ArrayList Matches
|
|
{
|
|
get{ return m_Matches; }
|
|
set{ m_Matches = value; }
|
|
}
|
|
|
|
public TournyParticipant FreeAdvance
|
|
{
|
|
get{ return m_FreeAdvance; }
|
|
set{ m_FreeAdvance = value; }
|
|
}
|
|
|
|
public PyramidLevel()
|
|
{
|
|
m_Matches = new ArrayList();
|
|
}
|
|
}
|
|
|
|
public class TournyMatch
|
|
{
|
|
private ArrayList m_Participants;
|
|
private TournyParticipant m_Winner;
|
|
private DuelContext m_Context;
|
|
|
|
public ArrayList Participants
|
|
{
|
|
get{ return m_Participants; }
|
|
set{ m_Participants = value; }
|
|
}
|
|
|
|
public TournyParticipant Winner
|
|
{
|
|
get{ return m_Winner; }
|
|
set{ m_Winner = value; }
|
|
}
|
|
|
|
public DuelContext Context
|
|
{
|
|
get{ return m_Context; }
|
|
set{ m_Context = value; }
|
|
}
|
|
|
|
public bool InProgress
|
|
{
|
|
get{ return ( m_Context != null && m_Context.Registered ); }
|
|
}
|
|
|
|
public void Start( Arena arena, Tournament tourny )
|
|
{
|
|
TournyParticipant first = (TournyParticipant)m_Participants[0];
|
|
|
|
DuelContext dc = new DuelContext( (Mobile)first.Players[0], tourny.Ruleset.Layout, false );
|
|
dc.Ruleset.Options.SetAll(false);
|
|
dc.Ruleset.Options.Or(tourny.Ruleset.Options);
|
|
|
|
for ( int i = 0; i < m_Participants.Count; ++i )
|
|
{
|
|
TournyParticipant tournyPart = (TournyParticipant)m_Participants[i];
|
|
Participant duelPart = new Participant( dc, tournyPart.Players.Count );
|
|
|
|
duelPart.TournyPart = tournyPart;
|
|
|
|
for ( int j = 0; j < tournyPart.Players.Count; ++j )
|
|
duelPart.Add( (Mobile) tournyPart.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 ( tourny.EventController != null )
|
|
dc.m_EventGame = tourny.EventController.Construct( dc );
|
|
|
|
dc.m_Tournament = tourny;
|
|
dc.m_Match = this;
|
|
|
|
dc.m_OverrideArena = arena;
|
|
|
|
if ( tourny.SuddenDeath > TimeSpan.Zero && (tourny.SuddenDeathRounds == 0 || tourny.Pyramid.Levels.Count <= tourny.SuddenDeathRounds) )
|
|
dc.StartSuddenDeath( tourny.SuddenDeath );
|
|
|
|
dc.SendReadyGump( 0 );
|
|
|
|
if ( dc.StartedBeginCountdown )
|
|
{
|
|
m_Context = dc;
|
|
|
|
for ( int i = 0; i < m_Participants.Count; ++i )
|
|
{
|
|
TournyParticipant p = (TournyParticipant)m_Participants[i];
|
|
|
|
for ( int j = 0; j < p.Players.Count; ++j )
|
|
{
|
|
Mobile mob = (Mobile)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();
|
|
}
|
|
}
|
|
|
|
public TournyMatch( ArrayList participants )
|
|
{
|
|
m_Participants = participants;
|
|
|
|
for ( int i = 0; i < participants.Count; ++i )
|
|
{
|
|
TournyParticipant part = (TournyParticipant)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( ((TournyParticipant)participants[j]).NameList );
|
|
hasAppended = true;
|
|
}
|
|
|
|
sb.Append( "." );
|
|
|
|
part.AddLog( sb.ToString() );
|
|
}
|
|
}
|
|
}
|
|
|
|
public class TournyParticipant : IComparable
|
|
{
|
|
private ArrayList m_Players;
|
|
private ArrayList m_Log;
|
|
private int m_FreeAdvances;
|
|
|
|
public ArrayList Players
|
|
{
|
|
get{ return m_Players; }
|
|
set{ m_Players = value; }
|
|
}
|
|
|
|
public ArrayList Log
|
|
{
|
|
get{ return m_Log; }
|
|
set{ m_Log = value; }
|
|
}
|
|
|
|
public int FreeAdvances
|
|
{
|
|
get{ return m_FreeAdvances; }
|
|
set{ m_FreeAdvances = value; }
|
|
}
|
|
|
|
public int TotalLadderXP
|
|
{
|
|
get
|
|
{
|
|
Ladder ladder = Ladder.Instance;
|
|
|
|
if ( ladder == null )
|
|
return 0;
|
|
|
|
int total = 0;
|
|
|
|
for ( int i = 0; i < m_Players.Count; ++i )
|
|
{
|
|
Mobile mob = (Mobile)m_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 < m_Players.Count; ++i )
|
|
{
|
|
if ( m_Players[i] == null )
|
|
continue;
|
|
|
|
Mobile mob = (Mobile) m_Players[i];
|
|
|
|
if ( sb.Length > 0 )
|
|
{
|
|
if ( m_Players.Count == 2 )
|
|
sb.Append( " and " );
|
|
else if ( (i+1) < m_Players.Count )
|
|
sb.Append( ", " );
|
|
else
|
|
sb.Append( ", and " );
|
|
}
|
|
|
|
sb.Append( mob.Name );
|
|
}
|
|
|
|
if ( sb.Length == 0 )
|
|
return "Empty";
|
|
|
|
return sb.ToString();
|
|
}
|
|
}
|
|
|
|
public void AddLog( string text )
|
|
{
|
|
m_Log.Add( text );
|
|
}
|
|
|
|
public void AddLog( string format, params object[] args )
|
|
{
|
|
AddLog( String.Format( format, args ) );
|
|
}
|
|
|
|
public void WonMatch( TournyMatch match )
|
|
{
|
|
AddLog( "Match won." );
|
|
}
|
|
|
|
public void LostMatch( TournyMatch match )
|
|
{
|
|
AddLog( "Match lost." );
|
|
}
|
|
|
|
public TournyParticipant( Mobile owner )
|
|
{
|
|
m_Log = new ArrayList();
|
|
m_Players = new ArrayList();
|
|
m_Players.Add( owner );
|
|
}
|
|
|
|
public TournyParticipant( ArrayList players )
|
|
{
|
|
m_Log = new ArrayList();
|
|
m_Players = players;
|
|
}
|
|
|
|
public int CompareTo( object obj )
|
|
{
|
|
TournyParticipant p = (TournyParticipant)obj;
|
|
|
|
return p.TotalLadderXP - this.TotalLadderXP;
|
|
}
|
|
}
|
|
|
|
public enum TournyBracketGumpType
|
|
{
|
|
Index,
|
|
Rules_Info,
|
|
Participant_List,
|
|
Participant_Info,
|
|
Round_List,
|
|
Round_Info,
|
|
Match_Info,
|
|
Player_Info
|
|
}
|
|
|
|
public class TournamentBracketGump : Gump
|
|
{
|
|
private Mobile m_From;
|
|
private Tournament m_Tournament;
|
|
private TournyBracketGumpType m_Type;
|
|
private ArrayList m_List;
|
|
private int m_Page;
|
|
private int m_PerPage;
|
|
private object m_Object;
|
|
|
|
private const int BlackColor32 = 0x000008;
|
|
private const int LabelColor32 = 0xFFFFFF;
|
|
|
|
public string Center( string text )
|
|
{
|
|
return String.Format( "<CENTER>{0}</CENTER>", text );
|
|
}
|
|
|
|
public string Color( string text, int color )
|
|
{
|
|
return String.Format( "<BASEFONT COLOR=#{0:X6}>{1}</BASEFONT>", color, text );
|
|
}
|
|
|
|
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 TournamentBracketGump( Mobile from, Tournament tourny, TournyBracketGumpType type, ArrayList list, int page, object obj ) : base( 50, 50 )
|
|
{
|
|
m_From = from;
|
|
m_Tournament = tourny;
|
|
m_Type = type;
|
|
m_List = list;
|
|
m_Page = page;
|
|
m_Object = obj;
|
|
m_PerPage = 12;
|
|
|
|
switch ( type )
|
|
{
|
|
case TournyBracketGumpType.Index:
|
|
{
|
|
AddPage( 0 );
|
|
AddBackground( 0, 0, 300, 300, 9380 );
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
if ( tourny.TournyType == TournyType.FreeForAll )
|
|
{
|
|
sb.Append( "FFA" );
|
|
}
|
|
else if ( tourny.TournyType == TournyType.RandomTeam )
|
|
{
|
|
sb.Append( "Team" );
|
|
}
|
|
else if ( tourny.TournyType == TournyType.RedVsBlue )
|
|
{
|
|
sb.Append( "Red v Blue" );
|
|
}
|
|
else
|
|
{
|
|
for ( int i = 0; i < tourny.ParticipantsPerMatch; ++i )
|
|
{
|
|
if ( sb.Length > 0 )
|
|
sb.Append( 'v' );
|
|
|
|
sb.Append( tourny.PlayersPerParticipant );
|
|
}
|
|
}
|
|
|
|
if ( tourny.EventController != null )
|
|
sb.Append( ' ' ).Append( tourny.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 = String.Format( "The tournament will begin in {0} minute{1} and {2} second{3}.", mins, mins==1?"":"s", secs, secs==1?"":"s" );
|
|
else if ( mins > 0 )
|
|
text = String.Format( "The tournament will begin in {0} minute{1}.", mins, mins==1?"":"s" );
|
|
else if ( secs > 0 )
|
|
text = String.Format( "The tournament will begin in {0} second{1}.", secs, 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 TournyBracketGumpType.Rules_Info:
|
|
{
|
|
Ruleset ruleset = tourny.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 ( tourny.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, String.Format( "Grouping: {0}", groupText ), false, false );
|
|
y += 20;
|
|
|
|
string tieText = null;
|
|
|
|
switch ( tourny.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 = ( tourny.ParticipantsPerMatch == 2 ? "Both advance" : "Everyone advances" ); break;
|
|
case TieType.FullElimination: tieText = ( tourny.ParticipantsPerMatch == 2 ? "Both eliminated" : "Everyone eliminated" ); break;
|
|
}
|
|
|
|
AddHtml( 35, y, 190, 20, String.Format( "Tiebreaker: {0}", tieText ), false, false );
|
|
y += 20;
|
|
|
|
string sdText = "Off";
|
|
|
|
if ( tourny.SuddenDeath > TimeSpan.Zero )
|
|
{
|
|
sdText = String.Format( "{0}:{1:D2}", (int) tourny.SuddenDeath.TotalMinutes, tourny.SuddenDeath.Seconds );
|
|
|
|
if ( tourny.SuddenDeathRounds > 0 )
|
|
sdText = String.Format( "{0} (first {1} rounds)", sdText, tourny.SuddenDeathRounds );
|
|
else
|
|
sdText = String.Format( "{0} (all rounds)", sdText );
|
|
}
|
|
|
|
AddHtml( 35, y, 240, 20, String.Format( "Sudden Death: {0}", sdText ), false, false );
|
|
y += 20;
|
|
|
|
y += 8;
|
|
|
|
AddHtml( 35, y, 190, 20, String.Format( "Ruleset: {0}", basedef.Title ), false, false );
|
|
y += 20;
|
|
|
|
for ( int i = 0; i < ruleset.Flavors.Count; ++i, y += 18 )
|
|
AddHtml( 35, y, 190, 20, String.Format( " + {0}", ((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 );
|
|
y += 20;
|
|
}
|
|
|
|
break;
|
|
}
|
|
case TournyBracketGumpType.Participant_List:
|
|
{
|
|
AddPage( 0 );
|
|
AddBackground( 0, 0, 300, 300, 9380 );
|
|
|
|
if ( m_List == null )
|
|
m_List = new ArrayList( tourny.Participants );
|
|
|
|
AddLeftArrow( 25, 11, ToButtonID( 0, 0 ) );
|
|
AddHtml( 25, 35, 250, 20, Center( String.Format( "{0} Participant{1}", m_List.Count, m_List.Count == 1 ? "" : "s" ) ), false, false );
|
|
|
|
int index, count, y;
|
|
StartPage( out index, out count, out y, 12 );
|
|
|
|
for ( int i = 0; i < count; ++i, y += 18 )
|
|
{
|
|
TournyParticipant part = (TournyParticipant)m_List[index + i];
|
|
string name = part.NameList;
|
|
|
|
if ( m_Tournament.TournyType != TournyType.Standard && part.Players.Count == 1 )
|
|
{
|
|
PlayerMobile pm = part.Players[0] as PlayerMobile;
|
|
|
|
if ( pm != null && pm.DuelPlayer != null )
|
|
name = Color( name, pm.DuelPlayer.Eliminated ? 0x6633333 : 0x336666 );
|
|
}
|
|
|
|
AddRightArrow( 25, y, ToButtonID( 2, index + i ), name );
|
|
}
|
|
|
|
break;
|
|
}
|
|
case TournyBracketGumpType.Participant_Info:
|
|
{
|
|
TournyParticipant part = obj as TournyParticipant;
|
|
|
|
if ( part == null )
|
|
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 = (Mobile)part.Players[i];
|
|
string name = mob.Name;
|
|
|
|
if ( m_Tournament.TournyType != TournyType.Standard )
|
|
{
|
|
PlayerMobile pm = mob as PlayerMobile;
|
|
|
|
if ( pm != null && 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, String.Format( "Free Advances: {0}", 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 TournyBracketGumpType.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 );
|
|
|
|
Mobile mob = obj as Mobile;
|
|
|
|
if ( mob == null )
|
|
break;
|
|
|
|
Ladder ladder = Ladder.Instance;
|
|
LadderEntry entry = ( ladder == null ? null : ladder.Find( mob ) );
|
|
|
|
AddHtml( 25, 53, 250, 20, String.Format( "Name: {0}", mob.Name ), false, false );
|
|
AddHtml( 25, 73, 250, 20, String.Format( "Guild: {0}", mob.Guild == null ? "None" : mob.Guild.Name + " [" + mob.Guild.Abbreviation + "]" ), false, false );
|
|
AddHtml( 25, 93, 250, 20, String.Format( "Rank: {0}", entry == null ? "N/A" : LadderGump.Rank( entry.Index + 1 ) ), false, false );
|
|
AddHtml( 25, 113, 250, 20, String.Format( "Level: {0}", entry == null ? 0 : Ladder.GetLevel( entry.Experience ) ), false, false );
|
|
AddHtml( 25, 133, 250, 20, String.Format( "Wins: {0:N0}", entry == null ? 0 : entry.Wins ), false, false );
|
|
AddHtml( 25, 153, 250, 20, String.Format( "Losses: {0:N0}", entry == null ? 0 : entry.Losses ), false, false );
|
|
|
|
break;
|
|
}
|
|
case TournyBracketGumpType.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 );
|
|
|
|
if ( m_List == null )
|
|
m_List = new ArrayList( tourny.Pyramid.Levels );
|
|
|
|
int index, count, y;
|
|
StartPage( out index, out count, out y, 12 );
|
|
|
|
for ( int i = 0; i < count; ++i, y += 18 )
|
|
{
|
|
PyramidLevel level = (PyramidLevel)m_List[index + i];
|
|
|
|
AddRightArrow( 25, y, ToButtonID( 3, index + i ), "Round #" + (index + i + 1) );
|
|
}
|
|
|
|
break;
|
|
}
|
|
case TournyBracketGumpType.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 );
|
|
|
|
PyramidLevel level = m_Object as PyramidLevel;
|
|
|
|
if ( level == null )
|
|
break;
|
|
|
|
if ( m_List == null )
|
|
m_List = new ArrayList( level.Matches );
|
|
|
|
AddRightArrow( 25, 53, ToButtonID( 5, 0 ), String.Format( "Free Advance: {0}", level.FreeAdvance == null ? "None" : level.FreeAdvance.NameList ) );
|
|
|
|
AddHtml( 25, 73, 200, 20, String.Format( "{0} Match{1}", m_List.Count, m_List.Count == 1 ? "" : "es" ), false, false );
|
|
|
|
int index, count, y;
|
|
StartPage( out index, out count, out y, 10 );
|
|
|
|
for ( int i = 0; i < count; ++i, y += 18 )
|
|
{
|
|
TournyMatch match = (TournyMatch)m_List[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.TournyType == TournyType.Standard )
|
|
{
|
|
for ( int j = 0; j < match.Participants.Count; ++j )
|
|
{
|
|
if ( sb.Length > 0 )
|
|
sb.Append( " vs " );
|
|
|
|
TournyParticipant part = (TournyParticipant)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.TournyType == TournyType.RandomTeam || m_Tournament.TournyType == TournyType.RedVsBlue )
|
|
{
|
|
for ( int j = 0; j < match.Participants.Count; ++j )
|
|
{
|
|
if ( sb.Length > 0 )
|
|
sb.Append( " vs " );
|
|
|
|
TournyParticipant part = (TournyParticipant)match.Participants[j];
|
|
string txt;
|
|
|
|
if ( m_Tournament.EventController != null )
|
|
txt = String.Format( "Team {0} ({1})", m_Tournament.EventController.GetTeamName( j ), part.Players.Count );
|
|
else if ( m_Tournament.TournyType == TournyType.RandomTeam )
|
|
txt = String.Format( "Team {0} ({1})", j + 1, part.Players.Count );
|
|
else
|
|
txt = String.Format( "Team {0} ({1})", 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.TournyType == TournyType.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 TournyBracketGumpType.Match_Info:
|
|
{
|
|
TournyMatch match = obj as TournyMatch;
|
|
|
|
if ( match == null )
|
|
break;
|
|
|
|
int ct = ( m_Tournament.TournyType == TournyType.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, String.Format( "Winner: {0}", match.Winner == null ? "N/A" : match.Winner.NameList ), false, false );
|
|
AddHtml( 25, 73, 250, 20, String.Format( "State: {0}", match.InProgress ? "In progress" : match.Context != null ? "Complete" : "Waiting" ), false, false );
|
|
AddHtml( 25, 93, 250, 20, String.Format( "Participants:" ), false, false );
|
|
|
|
if ( m_Tournament.TournyType == TournyType.Standard )
|
|
{
|
|
for ( int i = 0; i < match.Participants.Count; ++i )
|
|
{
|
|
TournyParticipant part = (TournyParticipant)match.Participants[i];
|
|
|
|
AddRightArrow( 25, 113 + (i * 18), ToButtonID( 6, i ), part.NameList );
|
|
}
|
|
}
|
|
else if ( m_Tournament.EventController != null || m_Tournament.TournyType == TournyType.RandomTeam || m_Tournament.TournyType == TournyType.RedVsBlue )
|
|
{
|
|
for ( int i = 0; i < match.Participants.Count; ++i )
|
|
{
|
|
TournyParticipant part = (TournyParticipant)match.Participants[i];
|
|
|
|
if ( m_Tournament.EventController != null )
|
|
AddRightArrow( 25, 113 + (i * 18), ToButtonID( 6, i ), String.Format( "Team {0} ({1})", m_Tournament.EventController.GetTeamName( i ), part.Players.Count ) );
|
|
else if ( m_Tournament.TournyType == TournyType.RandomTeam )
|
|
AddRightArrow( 25, 113 + (i * 18), ToButtonID( 6, i ), String.Format( "Team {0} ({1})", i+1, part.Players.Count ) );
|
|
else
|
|
AddRightArrow( 25, 113 + (i * 18), ToButtonID( 6, i ), String.Format( "Team {0} ({1})", i==0?"Red":"Blue", part.Players.Count ) );
|
|
}
|
|
}
|
|
else if ( m_Tournament.TournyType == TournyType.FreeForAll )
|
|
{
|
|
AddHtml( 25, 113, 250, 20, "Free For All", false, false );
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public override void OnResponse( NetState sender, RelayInfo info )
|
|
{
|
|
int type, index;
|
|
|
|
if ( !FromButtonID( info.ButtonID, out type, out index ) )
|
|
return;
|
|
|
|
switch ( type )
|
|
{
|
|
case 0:
|
|
{
|
|
switch ( index )
|
|
{
|
|
case 0: m_From.SendGump( new TournamentBracketGump( m_From, m_Tournament, TournyBracketGumpType.Index, null, 0, null ) ); break;
|
|
case 1: m_From.SendGump( new TournamentBracketGump( m_From, m_Tournament, TournyBracketGumpType.Participant_List, null, 0, null ) ); break;
|
|
case 2: m_From.SendGump( new TournamentBracketGump( m_From, m_Tournament, TournyBracketGumpType.Round_List, null, 0, null ) ); break;
|
|
case 4: m_From.SendGump( new TournamentBracketGump( m_From, m_Tournament, TournyBracketGumpType.Rules_Info, null, 0, null ) ); break;
|
|
case 3:
|
|
{
|
|
Mobile mob = m_Object as Mobile;
|
|
|
|
for ( int i = 0; i < m_Tournament.Participants.Count; ++i )
|
|
{
|
|
TournyParticipant part = (TournyParticipant)m_Tournament.Participants[i];
|
|
|
|
if ( part.Players.Contains( mob ) )
|
|
{
|
|
m_From.SendGump( new TournamentBracketGump( m_From, m_Tournament, TournyBracketGumpType.Participant_Info, null, 0, part ) );
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
case 5:
|
|
{
|
|
TournyMatch match = m_Object as TournyMatch;
|
|
|
|
if ( match == null )
|
|
break;
|
|
|
|
for ( int i = 0; i < m_Tournament.Pyramid.Levels.Count; ++i )
|
|
{
|
|
PyramidLevel level = (PyramidLevel)m_Tournament.Pyramid.Levels[i];
|
|
|
|
if ( level.Matches.Contains( match ) )
|
|
m_From.SendGump( new TournamentBracketGump( m_From, m_Tournament, TournyBracketGumpType.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 != TournyBracketGumpType.Participant_List )
|
|
break;
|
|
|
|
if ( index >= 0 && index < m_List.Count )
|
|
m_From.SendGump( new TournamentBracketGump( m_From, m_Tournament, TournyBracketGumpType.Participant_Info, null, 0, m_List[index] ) );
|
|
|
|
break;
|
|
}
|
|
case 3:
|
|
{
|
|
if ( m_Type != TournyBracketGumpType.Round_List )
|
|
break;
|
|
|
|
if ( index >= 0 && index < m_List.Count )
|
|
m_From.SendGump( new TournamentBracketGump( m_From, m_Tournament, TournyBracketGumpType.Round_Info, null, 0, m_List[index] ) );
|
|
|
|
break;
|
|
}
|
|
case 4:
|
|
{
|
|
if ( m_Type != TournyBracketGumpType.Participant_Info )
|
|
break;
|
|
|
|
TournyParticipant part = m_Object as TournyParticipant;
|
|
|
|
if ( part != null && index >= 0 && index < part.Players.Count )
|
|
m_From.SendGump( new TournamentBracketGump( m_From, m_Tournament, TournyBracketGumpType.Player_Info, null, 0, part.Players[index] ) );
|
|
|
|
break;
|
|
}
|
|
case 5:
|
|
{
|
|
if ( m_Type != TournyBracketGumpType.Round_Info )
|
|
break;
|
|
|
|
PyramidLevel level = m_Object as PyramidLevel;
|
|
|
|
if ( level == null )
|
|
break;
|
|
|
|
if ( index == 0 )
|
|
{
|
|
if ( level.FreeAdvance != null )
|
|
m_From.SendGump( new TournamentBracketGump( m_From, m_Tournament, TournyBracketGumpType.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, TournyBracketGumpType.Match_Info, null, 0, level.Matches[index-1] ) );
|
|
}
|
|
|
|
break;
|
|
}
|
|
case 6:
|
|
{
|
|
if ( m_Type != TournyBracketGumpType.Match_Info )
|
|
break;
|
|
|
|
TournyMatch match = m_Object as TournyMatch;
|
|
|
|
if ( match != null && index >= 0 && index < match.Participants.Count )
|
|
m_From.SendGump( new TournamentBracketGump( m_From, m_Tournament, TournyBracketGumpType.Participant_Info, null, 0, match.Participants[index] ) );
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public class TournamentBracketItem : Item
|
|
{
|
|
private TournamentController m_Tournament;
|
|
|
|
[CommandProperty( AccessLevel.GameMaster )]
|
|
public TournamentController Tournament{ get{ return m_Tournament; } set{ m_Tournament = value; } }
|
|
|
|
public override string DefaultName
|
|
{
|
|
get { return "tournament bracket"; }
|
|
}
|
|
|
|
[Constructable]
|
|
public TournamentBracketItem() : base( 3774 )
|
|
{
|
|
Movable = false;
|
|
}
|
|
|
|
public override void OnDoubleClick(Mobile from)
|
|
{
|
|
if ( !from.InRange( GetWorldLocation(), 2 ) )
|
|
{
|
|
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that
|
|
}
|
|
else if ( m_Tournament != null )
|
|
{
|
|
Tournament tourny = m_Tournament.Tournament;
|
|
|
|
if ( tourny != null )
|
|
{
|
|
from.CloseGump( typeof( TournamentBracketGump ) );
|
|
from.SendGump( new TournamentBracketGump( from, tourny, TournyBracketGumpType.Index, null, 0, null ) );
|
|
|
|
/*if ( tourny.Stage == TournamentStage.Fighting && tourny.Pyramid.Levels.Count > 0 )
|
|
from.SendGump( new TournamentBracketGump( tourny, (PyramidLevel)tourny.Pyramid.Levels[tourny.Pyramid.Levels.Count - 1] ) );
|
|
else
|
|
from.SendGump( new TournamentBracketGump( tourny, 0 ) );*/
|
|
}
|
|
}
|
|
}
|
|
|
|
public TournamentBracketItem( Serial serial ) : base( serial )
|
|
{
|
|
}
|
|
|
|
public override void Serialize( GenericWriter writer )
|
|
{
|
|
base.Serialize( writer );
|
|
|
|
writer.Write( (int) 0 );
|
|
|
|
writer.Write( (Item) m_Tournament );
|
|
}
|
|
|
|
public override void Deserialize( GenericReader reader )
|
|
{
|
|
base.Deserialize( reader );
|
|
|
|
int version = reader.ReadInt();
|
|
|
|
switch ( version )
|
|
{
|
|
case 0:
|
|
{
|
|
m_Tournament = reader.ReadItem() as TournamentController;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |