using System;
using System.Collections;
using Server;
using Server.Items;
namespace Arya.Chess
{
///
/// Defines the two colors used in the chess game
///
public enum ChessColor
{
Black,
White
}
///
/// This abstract class defines the basic features of a chess piece
///
public abstract class BaseChessPiece
{
#region Variables
///
/// This represents the NPC that corresponds to this chess piece
///
protected ChessMobile m_Piece;
///
/// The BChessboard object parent of this chess piece
///
protected BChessboard m_BChessboard;
///
/// The color of this piece
///
protected ChessColor m_Color;
///
/// The position of the chess piece on the board
///
protected Point2D m_Position;
///
/// Specifies if this piece has been killed
///
protected bool m_Dead = false;
///
/// Specifies if the piece has already been moved or not
///
protected bool m_HasMoved = false;
///
/// The move this piece is performing
///
protected Move m_Move;
///
/// The sound made when the piece moves
///
protected int m_MoveSound;
///
/// The sound made when the piece captures
///
protected int m_CaptureSound;
///
/// The sound made when the piece is captured
///
protected int m_DeathSound;
#endregion
#region Properties
///
/// Gets the NPC corresponding to this chess piece
///
public ChessMobile Piece
{
get { return m_Piece; }
}
///
/// Gets the color of this piece
///
public ChessColor Color
{
get { return m_Color; }
}
///
/// Gets the color of the enemy
///
public ChessColor EnemyColor
{
get
{
if ( m_Color == ChessColor.Black )
return ChessColor.White;
else
return ChessColor.Black;
}
}
///
/// Gets or sets the position of this chess piece.
/// This does NOT move the chess piece on the chess board
///
public Point2D Position
{
get { return m_Position; }
set { m_Position = value; }
}
///
/// Gets the facing for the NPC when it's standing
///
public virtual Direction Facing
{
get
{
if ( m_BChessboard.Orientation == BoardOrientation.NorthSouth )
{
if ( m_Color == ChessColor.Black )
return Direction.South;
else
return Direction.North;
}
else
{
if ( m_Color == ChessColor.Black )
return Direction.East;
else
return Direction.West;
}
}
}
///
/// Gets the hue used to color items for this piece
///
public virtual int Hue
{
get
{
if ( m_Color == ChessColor.Black )
return m_BChessboard.BlackHue;
else
return m_BChessboard.WhiteHue;
}
}
///
/// Gets the opposite hue for this piece
///
public virtual int SecondaryHue
{
get
{
if ( m_Color == ChessColor.Black )
return m_BChessboard.WhiteHue;
else
return m_BChessboard.BlackHue;
}
}
public virtual int MinorHue
{
get
{
if ( m_Color == ChessColor.Black )
return m_BChessboard.BlackMinorHue;
else
return m_BChessboard.WhiteMinorHue;
}
}
///
/// Gets the power value of this piece
///
public abstract int Power
{
get;
}
///
/// States whether this piece has already moved
///
public virtual bool HasMoved
{
get { return m_HasMoved; }
}
///
/// Specifies if this piece can be captured by a pawn en passant
///
public virtual bool AllowEnPassantCapture
{
get { return false; }
set {}
}
#endregion
///
/// Creates a new chess piece object
///
/// The BChessboard object hosting this piece
/// The color of this piece
/// The initial position on the board
public BaseChessPiece( BChessboard board, ChessColor color, Point2D position )
{
m_BChessboard = board;
m_Color = color;
m_Position = position;
CreatePiece();
}
#region NPC Creation
///
/// Creates the NPC that will represent this piece and places it in the correct world location
///
protected virtual void CreatePiece()
{
InitializePiece();
Point3D loc = new Point3D( m_BChessboard.BoardToWorld( m_Position ), m_BChessboard.Z );
if ( m_BChessboard.OverrideMinorHue )
m_Piece.SolidHueOverride = Hue;
m_Piece.MoveToWorld( loc, m_BChessboard.Map );
m_Piece.FixedParticles( 14089, 1, 15, 5012, Hue, 2, EffectLayer.Waist );
}
///
/// Creates and initializes the chess piece NPC
///
///
public abstract void InitializePiece();
///
/// Rebuilds the NPC applying any changes made to the appearance
///
public virtual void Rebuild()
{
Die( false );
CreatePiece();
m_Dead = false;
}
#endregion
#region Piece Movement
///
/// Verifies if this piece can move to a specified location.
///
/// The new location
/// Will hold the eventual error message
/// True if the move is allowed, false otherwise.
public virtual bool CanMoveTo( Point2D newLocation, ref string err )
{
if ( newLocation == m_Position )
{
err = "Can't move to the same spot";
return false; // Same spot isn't a valid move
}
// Base version, check only for out of bounds
if ( newLocation.X >= 0 && newLocation.Y >= 0 && newLocation.X < 8 && newLocation.Y < 8 )
{
return true;
}
else
{
err = "Can't move out of chessboard";
return false;
}
}
///
/// Moves the chess piece to the specified position. This function assumes that a previous call
/// to CanMoveTo() has been made and the move has been authorized.
///
/// The move performed
public virtual void MoveTo( Move move )
{
m_HasMoved = true;
m_Move = move;
Point2D worldLocation = m_BChessboard.BoardToWorld( move.To );
if ( move.Capture )
{
m_BChessboard.PlaySound( m_Piece, m_CaptureSound );
// It's a capture, do an effect
m_Piece.MovingParticles( move.CapturedPiece.m_Piece, m_BChessboard.AttackEffect, 5, 0, false, true, Hue, 2, 0, 1, 4006, EffectLayer.Waist, 0 );
move.CapturedPiece.Die(true);
}
else
{
m_BChessboard.PlaySound( m_Piece, m_MoveSound );
}
m_Piece.GoTo( worldLocation );
}
///
/// This function is called by the NPC when its move is over
///
public virtual void OnMoveOver()
{
m_BChessboard.OnMoveOver( m_Move );
m_Move = null;
m_Piece.Direction = Facing;
}
///
/// Gets the list of possible moves this piece can perform
///
/// Specifies whether the moves should include squares where a piece would be captured
/// An ArrayList objects of Point2D values
public abstract ArrayList GetMoves( bool capture );
///
/// Gets the piece that this piece would capture when moving to a specific location.
/// This function assumes that the square can be reached.
///
/// The target location with the potential capture
/// Will hold a value stating whether this move is made en passant
/// A BaseChessPiece if a capture is possible, null otherwise
public virtual BaseChessPiece GetCaptured( Point2D at, ref bool enpassant )
{
enpassant = false;
BaseChessPiece piece = m_BChessboard[ at ];
if ( piece != null && piece.Color != m_Color )
return piece;
else
return null;
}
///
/// Verifies if a given move would be a castle
///
/// The target location
/// True if the move is a castle
public virtual bool IsCastle( Point2D loc )
{
return false;
}
#endregion
#region Deletion and killing
///
/// This function is invoked whenever a piece NPC is deleted
///
public virtual void OnPieceDeleted()
{
if ( ! m_Dead )
{
m_BChessboard.OnStaffDelete();
}
}
///
/// This function is invoked when the piece is captured and the NPC should be removed from the board
///
/// Specifies if to play the death sound
public virtual void Die( bool sound )
{
if ( sound ) // Use sound for bolt too - sound is used in normal gameplay
{
if ( m_BChessboard.BoltOnDeath )
m_Piece.BoltEffect( SecondaryHue );
m_BChessboard.PlaySound( m_Piece, m_DeathSound );
}
m_Dead = true;
m_Piece.Delete();
}
///
/// Forces the deletion of this piece
///
public virtual void ForceDelete()
{
if ( m_Piece != null && ! m_Piece.Deleted )
{
m_Dead = true;
m_Piece.Delete();
}
}
#endregion
}
}