rendered paste bodyusing System;
using System.IO;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Commands;
using Server.Network;
using Server.Gumps;
using Server.Items;
using Server.Mobiles;
using Server.Regions;
namespace Server.DuelSystem
{
public class DuelingPit : Item
{
private static ArrayList m_Pits = new ArrayList();
public static ArrayList Pits{ get{ return m_Pits; } }
#region Properties
private Arena m_Arena;
private Announcer m_Announcer;
private Wall m_Wall;
private DuelRegion m_DuelRegion;
private BufferRegion m_BufferRegion;
private ContenderInfo m_Challenger, m_Defender;
private ArrayList m_Contenders;
private bool m_InUse, m_InProgress, m_Disposing;
private Timer m_Timer;
private Hashtable m_Damage;
public Arena Arena{ get{ return m_Arena; } }
public bool Disposing{ get{ return m_Disposing; } }
public bool InUse{ get{ return m_InUse; } set{ m_InUse = value; } }
public BufferRegion BufferRegion{ get{ return m_BufferRegion; } }
public ArrayList Contenders
{
get
{
if ( m_Contenders == null )
m_Contenders = new ArrayList( 2 );
return m_Contenders;
}
}
public bool InProgress
{
get{ return m_InProgress; }
set
{
m_InProgress = value;
foreach ( Mobile m in Contenders )
m.Delta( MobileDelta.Noto );
}
}
[CommandProperty(AccessLevel.GameMaster)]
public bool ForceDispose
{
get{ return false; }
set
{
if ( m_InUse && value )
Dispose();
}
}
#endregion
#region Constructors
[Constructable]
public DuelingPit() : base( 0x1BC3 )
{
Name = "pit control";
Movable = false;
Visible = false;
m_Contenders = new ArrayList( 2 );
m_Damage = new Hashtable( 2 );
m_Arena = new Arena( this );
m_Announcer = new Announcer( this );
m_DuelRegion = new DuelRegion( this );
m_BufferRegion = new BufferRegion( this );
UpdateRegions();
m_Pits.Add( this );
}
public DuelingPit( Serial serial ) : base( serial )
{
}
#endregion
#region Serialization
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int)1 );
writer.Write( m_Challenger != null );
if ( m_Challenger != null )
m_Challenger.Serialize( writer );
writer.Write( m_Defender != null );
if ( m_Defender != null )
m_Defender.Serialize( writer );
writer.Write( m_Arena );
writer.Write( m_Announcer );
writer.Write( m_Wall );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch( version )
{
case 1:
{
if ( reader.ReadBool() )
m_Challenger = new ContenderInfo( reader );
if ( reader.ReadBool() )
m_Defender = new ContenderInfo( reader );
goto case 0;
}
case 0:
{
m_Arena = reader.ReadItem() as Arena;
m_Announcer = reader.ReadMobile() as Announcer;
m_Wall = reader.ReadItem() as Wall;
break;
}
}
if ( m_Wall != null )
m_Wall.Delete();
m_DuelRegion = new DuelRegion( this );
Region.AddRegion( m_DuelRegion );
m_BufferRegion = new BufferRegion( this );
Region.AddRegion( m_BufferRegion );
UpdateRegions();
m_Contenders = new ArrayList( 2 );
m_Damage = new Hashtable( 2 );
m_Pits.Add( this );
}
#endregion
#region Methods
public static DuelingPit FindOpenPit()
{
for ( int i = 0; i < Pits.Count; ++i )
{
if ( i >= m_Pits.Count )
break;
DuelingPit pit = (DuelingPit)Pits[i];
if ( pit != null )
{
if ( pit.Map == null || pit.Map == Map.Internal )
pit.Delete();
else if ( !pit.InUse )
return pit;
}
}
return null;
}
private void OnTick_Callback( object state )
{
((ConfirmationMoongate)state).Delete();
}
public void Begin( ChallengeRequest request )
{
if ( request == null || request.Challenger == null || request.Defender == null )
return;
m_InUse = true;
Contenders.Add( request.Challenger );
Contenders.Add( request.Defender );
m_Wall = new Wall();
m_Wall.MoveToWorld( Location, Map );
m_Challenger = new ContenderInfo( request.Challenger, new Point3D( X-3, Y, Z ), Map );
m_Defender = new ContenderInfo( request.Defender, new Point3D( X+3, Y, Z ), Map );
ConfirmationMoongate gate = new ConfirmationMoongate( m_DuelRegion.GoLocation, Map );
gate.ItemID = 0x1FD4;
gate.GumpWidth = 300;
gate.GumpHeight = 100;
gate.TitleNumber = 1062051;
gate.TitleColor = 30720;
gate.MessageString = "Do you wish to spectate this duel?";
gate.MessageColor = 0xFFC000;
gate.MoveToWorld( m_Challenger.ReturnPos, m_Challenger.ReturnMap );
Timer.DelayCall( TimeSpan.FromSeconds( 10.0 ), new TimerStateCallback( OnTick_Callback ), gate );
Announce( "The duel will start in six seconds!" );
m_Timer = Timer.DelayCall( TimeSpan.FromSeconds( 6.5 ), new TimerCallback( Fight ) );
}
public void Fight()
{
if ( m_Disposing )
return;
Announce( "GO! GO! GO!" );
if ( m_Wall != null )
m_Wall.Delete();
foreach ( Mobile m in Contenders )
m.Frozen = false;
InProgress = true;
if ( Config.UseEndTimer )
m_Timer = Timer.DelayCall( TimeSpan.FromMinutes( 5.0 ), new TimerCallback( End ) );
}
public void End()
{
if ( m_Disposing || !m_InProgress )
return;
InProgress = false;
if ( m_Timer != null )
m_Timer.Stop();
RealmPlayer champion = GetChampion();
int num = -3;
foreach ( Mobile m in Contenders )
{
m.Frozen = true;
DuelHelper.RemoveSpellEffects( m );
m.MoveToWorld( new Point3D( X+num, Y, Z ), Map );
num += 6;
}
foreach ( RealmPlayer m in Contenders )
{
if ( champion != null )
{
Timer.DelayCall( TimeSpan.FromSeconds( 2.0 ), new TimerStateCallback( Message_Callback ), new object[] {m, (champion == m)} );
if ( champion != m )
DuelHelper.CalculatePoints( champion, m );
}
}
if ( champion == null )
Announce( "The match has ended in a draw!" );
else
Announce( "{0} has won the match!", champion.Name );
m_Timer = Timer.DelayCall( TimeSpan.FromSeconds( 5.0 ), new TimerCallback( Dispose ) );
}
public void Dispose()
{
if ( m_Disposing )
return;
m_Disposing = true;
if ( m_Wall != null )
m_Wall.Delete();
if ( m_Timer != null )
m_Timer.Stop();
if ( m_Challenger != null )
m_Challenger.ReturnHome();
if ( m_Defender != null )
m_Defender.ReturnHome();
m_Challenger = null;
m_Defender = null;
InProgress = false;
foreach ( RealmPlayer m in Contenders )
m.SetCanRegenHits( true );
Contenders.Clear();
m_Damage.Clear();
m_InUse = m_Disposing = false;
}
private void Message_Callback( object state )
{
object[] objects = (object[])state;
Mobile from = (Mobile)objects[0];
bool isChampion = (bool)objects[1];
if ( isChampion )
from.PublicOverheadMessage( Network.MessageType.Regular, 0x44 , false, "You are the winner!" );
else
from.PublicOverheadMessage( Network.MessageType.Regular, 0x20, false, "You have lost the duel." );
}
private RealmPlayer GetChampion()
{
RealmPlayer mob = null;
foreach ( RealmPlayer m in Contenders )
{
if ( mob == null )
{
mob = m;
continue;
}
if ( Config.UseEndTimer && mob.Hits > 0 && m.Hits > 0 )
{
if ( GetDamage( m ) == GetDamage( mob ) )
mob = null;
else if ( GetDamage( m ) > GetDamage( mob ) )
mob = m;
}
else if ( m.Hits == mob.Hits )
mob = null;
else if ( m.Hits > mob.Hits )
mob = m;
}
return mob;
}
private int GetDamage( Mobile from )
{
object o = m_Damage[from];
if ( o == null )
return 0;
return (int)o;
}
public void AddDamage( Mobile from, int damage )
{
if ( Config.UseEndTimer )
return;
int num = 0;
object o = m_Damage[from];
if ( o != null )
num = (int)o;
num += damage;
m_Damage[from] = num;
}
public bool IsContender( Mobile m )
{
if ( m_Contenders.Contains( m ) )
return true;
return false;
}
public void UpdateRegions()
{
ArrayList coords = new ArrayList();
coords.Add( new Rectangle2D( X-5, Y-5, 11, 11 ) );
m_DuelRegion.Coords = coords;
m_DuelRegion.GoLocation = new Point3D( X+6, Y-6, Z+5 );
m_DuelRegion.MinZ = Z;
coords = new ArrayList();
coords.Add( new Rectangle2D( X-20, Y-20, 40, 40 ) );
m_BufferRegion.Coords = coords;
}
public void Announce( string format, params object[] args )
{
Announce( String.Format( format, args ) );
}
public void Announce( string message )
{
if ( m_Announcer == null )
return;
m_Announcer.Yell( message );
}
#endregion
public override void OnDoubleClick( Mobile from )
{
if ( m_InUse && from.AccessLevel > AccessLevel.Counselor )
{
Dispose();
from.SendMessage( "You have terminated the match!" );
}
}
public override void OnLocationChange( Point3D oldLocation )
{
if ( Deleted )
return;
if ( m_InUse )
Dispose();
if ( m_Arena != null )
m_Arena.MoveToWorld( Location, Map );
if ( m_Announcer != null )
m_Announcer.MoveToWorld( new Point3D( X, Y-6, Z+5) , Map );
UpdateRegions();
}
public override void OnMapChange()
{
if ( Deleted )
return;
if ( m_InUse )
Dispose();
if ( m_Arena != null )
m_Arena.Map = Map;
if ( m_Announcer != null )
m_Announcer.Map = Map;
if ( m_DuelRegion != null )
m_DuelRegion.Map = Map;
if ( m_BufferRegion != null )
m_BufferRegion.Map = Map;
UpdateRegions();
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
if ( m_InUse )
Dispose();
if ( m_Arena != null )
m_Arena.Delete();
if ( m_Announcer != null )
m_Announcer.Delete();
if ( m_DuelRegion != null )
Region.RemoveRegion( m_DuelRegion );
if ( m_BufferRegion != null )
Region.RemoveRegion( m_BufferRegion );
if ( m_Pits.Contains( this ) )
m_Pits.Remove( this );
}
}
}