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 } }