Overwrite

Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
Unstable Kitsune
2023-11-28 23:20:26 -05:00
parent 3cd54811de
commit b918192e4e
11608 changed files with 2644205 additions and 47 deletions

View File

@@ -0,0 +1,11 @@
Version 1.3
- RunUO 2.0 RC1 compatible
Version 1.2.5
- Refactored the Chessboard class to BChessboard. This will prevent the crash occuring when using the [Decorate command.
- NPCs will be now ejected from the chessboard
- Fixed crash occuring when staff would delete a pawn in the middle of its promotion
- If the winner has no backpack they will not receive their winning certificate
- You can no longer check mate your enemy and win the game, while being checked yourself.

View File

@@ -0,0 +1,40 @@
using System;
namespace Arya.Chess
{
public class ChessConfig
{
/// <summary>
/// The time out for the game to start. If a second player hasn't accepted the game within this time
/// the game will be reset.
/// </summary>
public static TimeSpan GameStartTimeOut = TimeSpan.FromMinutes( 2 );
/// <summary>
/// The maximum time allowed for a player to make a move. If no move is made within this amount of time
/// the game will be reset.
/// </summary>
public static TimeSpan MoveTimeOut = TimeSpan.FromMinutes( 10 );
/// <summary>
/// When a player disconnects, the game will give them time to get back to their game (to handle
/// player system crashes, connections faults and so on). If one of the player doesn't log back in within
/// this time frame, the game is reset.
/// </summary>
public static TimeSpan DisconnectTimeOut = TimeSpan.FromMinutes( 10 );
/// <summary>
/// This is the amount of time given to players before the game ends after they have been notified of the
/// move time out. Also when the game ends regularly, both players get a gump asking to confirm the end
/// of the game. If they don't close it within this time frame, the game will reset.
/// </summary>
public static TimeSpan EndGameTimerOut = TimeSpan.FromMinutes( 3 );
/// <summary>
/// Specifies whether the winner should receive a reward scroll or not after the game is over.
/// No scroll is given for stalemate, or canceled games. This item has no function in the real world,
/// its properties only show the results of the game.
/// </summary>
public static bool GiveRewardScroll = true;
/// <summary>
/// This is the keyword that can be used to restore the gumps if anything goes wrong and the gump disappears
/// </summary>
public static string ResetKeyword = "game";
}
}

View File

@@ -0,0 +1,937 @@
using System;
using Server;
namespace Arya.Chess
{
/// <summary>
/// Describes the status of the current game
/// </summary>
public enum GameStatus
{
/// <summary>
/// The game is being setup
/// </summary>
Setup,
/// <summary>
/// White should make the next move
/// </summary>
WhiteToMove,
/// <summary>
/// Black should make the next move
/// </summary>
BlackToMove,
/// <summary>
/// A white piece is moving
/// </summary>
WhiteMoving,
/// <summary>
/// A black piece is moving
/// </summary>
BlackMoving,
/// <summary>
/// A white pawn has been promoted and the system is waiting for the user to make the decision
/// </summary>
WhitePromotion,
/// <summary>
/// A black pawn has been promoted and the system is waiting for the user to make the decision
/// </summary>
BlackPromotion,
/// <summary>
/// Game over
/// </summary>
Over
}
/// <summary>
/// Describes the logic for dealing with players, from creation to game end
/// </summary>
public class ChessGame
{
#region Variables
/// <summary>
/// The mobile playing black
/// </summary>
private Mobile m_Black;
/// <summary>
/// The mobile playing white
/// </summary>
private Mobile m_White;
/// <summary>
/// Flag stating that the black player is the game owner
/// </summary>
private bool m_BlackOwner;
/// <summary>
/// Moment when the game started
/// </summary>
private DateTime m_GameStart;
/// <summary>
/// The time used by black to make its moves
/// </summary>
private TimeSpan m_WhiteTime = TimeSpan.Zero;
/// <summary>
/// Time used by white to make its moves
/// </summary>
private TimeSpan m_BlackTime = TimeSpan.Zero;
/// <summary>
/// The BChessboard object providing game logic
/// </summary>
private BChessboard m_Board;
/// <summary>
/// The piece that is performing a move
/// </summary>
private BaseChessPiece m_MovingPiece;
/// <summary>
/// The status of the game
/// </summary>
private GameStatus m_Status = GameStatus.Setup;
/// <summary>
/// The moment when the last move was made
/// </summary>
private DateTime m_MoveTime;
/// <summary>
/// The bounds of the BChessboard
/// </summary>
private Rectangle2D m_Bounds;
/// <summary>
/// The height of the BChessboard
/// </summary>
private int m_Z;
/// <summary>
/// The pawn that is being promoted
/// </summary>
private Pawn m_PromotedPawn;
/// <summary>
/// The timer object providing time out support
/// </summary>
private ChessTimer m_Timer;
/// <summary>
/// States whether the game is idle because a player has been disconnected
/// </summary>
private bool m_Pending;
/// <summary>
/// The ChessControl object owner of this game
/// </summary>
private ChessControl m_Parent;
/// <summary>
/// The region for the BChessboard
/// </summary>
private ChessRegion m_Region;
/// <summary>
/// Specifies if other players can get on the board or not
/// </summary>
private bool m_AllowSpectators;
#endregion
#region Properties
/// <summary>
/// Gets the mobile who started this game
/// </summary>
public Mobile Owner
{
get
{
return m_BlackOwner ? m_Black : m_White;
}
}
/// <summary>
/// Gets or sets the player who has been invited to join the game
/// </summary>
public Mobile Guest
{
get
{
return m_BlackOwner ? m_White : m_Black;
}
set
{
if ( m_BlackOwner )
m_White = value;
else
m_Black = value;
}
}
/// <summary>
/// States whether the game is able to accept targets
/// </summary>
public bool AllowTarget
{
get
{
if ( m_Pending ) // Pending status
return false;
if ( m_Status == GameStatus.Setup && Owner == null ) // Ownerless setup - is this even needed?
return false;
if ( m_Status != GameStatus.Setup )
{
if ( m_White == null || m_Black == null || m_White.NetState == null || m_Black.NetState == null )
return false;
}
if ( m_Status == GameStatus.Over )
return false;
return true;
}
}
/// <summary>
/// Verifies if the game is in a consistent state and can send the game gumps to players
/// </summary>
public bool AllowGame
{
get
{
if ( m_Pending )
return false;
if ( m_Status == GameStatus.Setup || m_Status == GameStatus.Over )
return false;
if ( m_White == null || m_Black == null || m_White.NetState == null || m_Black.NetState == null )
return false;
return false;
}
}
/// <summary>
/// Sets the attack effect on the BChessboard
/// </summary>
public int AttackEffect
{
get
{
if ( m_Parent != null )
return m_Parent.AttackEffect;
else
return 0;
}
}
/// <summary>
/// Sets the capture effect on the BChessboard
/// </summary>
public int CaptureEffect
{
get
{
if ( m_Parent != null )
return m_Parent.CaptureEffect;
else
return 0;
}
}
/// <summary>
/// Sets the BoltOnDeath property on the BChessboard
/// </summary>
public bool BoltOnDeath
{
get
{
if ( m_Parent != null )
return m_Parent.BoltOnDeath;
else
return false;
}
}
/// <summary>
/// Gets the orientation of the BChessboard
/// </summary>
public BoardOrientation Orientation
{
get
{
if ( m_Parent != null )
return m_Parent.Orientation;
else
return BoardOrientation.NorthSouth;
}
}
/// <summary>
/// States whether other players can get on the board
/// </summary>
public bool AllowSpectators
{
get { return m_AllowSpectators; }
set { m_AllowSpectators = value; }
}
/// <summary>
/// Gets the BChessboard region
/// </summary>
public ChessRegion Region
{
get { return m_Region; }
}
#endregion
public ChessGame( ChessControl parent, Mobile owner, Rectangle2D bounds, int z )
{
m_Parent = parent;
m_Bounds = bounds;
m_Z = z;
m_BlackOwner = Utility.RandomBool();
if ( m_BlackOwner )
m_Black = owner;
else
m_White = owner;
m_AllowSpectators = m_Parent.AllowSpectators;
// Owner.SendGump( new StartGameGump( Owner, this, true, m_AllowSpectators ) );
Owner.SendGump( new ChessSetGump( Owner, this, true, m_AllowSpectators ) );
// Owner.Target = new ChessTarget( this, Owner, "Please select your partner...",
// new ChessTargetCallback( ChooseOpponent ) );
EventSink.Login += new LoginEventHandler(OnPlayerLogin);
EventSink.Disconnected += new DisconnectedEventHandler(OnPlayerDisconnected);
m_Timer = new ChessTimer( this );
}
#region Game Startup
/// <summary>
/// This function is called when one of the two players initializing the game decides to cancel
/// </summary>
/// <param name="from">The player refusing</param>
public void CancelGameStart( Mobile from )
{
if ( from == Owner )
{
// End this game
if ( Guest != null )
{
Guest.SendMessage( 0x40, "The owner of this game decided to cancel." );
Guest.CloseGump( typeof( StartGameGump ) );
}
if ( from.Target != null && from.Target is ChessTarget )
(from.Target as ChessTarget).Remove( from );
Cleanup();
}
else if ( from == Guest )
{
Guest = null;
Owner.SendGump( new StartGameGump( Owner, this, true, m_AllowSpectators ) );
Owner.Target = new ChessTarget( this, Owner, "The selected partner refused the game. Please select another partner...",
new ChessTargetCallback( ChooseOpponent ) );
}
}
/// <summary>
/// The guest accepted the game
/// </summary>
/// <param name="guest">The player accepting the game</param>
public void AcceptGame( Mobile guest )
{
if ( Owner == null )
{
guest.SendMessage( 0x40, "Your partner canceled the game" );
return;
}
m_GameStart = DateTime.Now;
m_Timer.OnGameStart();
m_Status = GameStatus.WhiteToMove;
Guest = guest;
Owner.CloseGump( typeof( Arya.Chess.StartGameGump ) );
m_Board = new BChessboard( m_Black, m_White, m_Z, m_Bounds, this, m_Parent.ChessSet, m_Parent.WhiteHue, m_Parent.BlackHue, m_Parent.WhiteMinorHue, m_Parent.BlackMinorHue, m_Parent.OverrideMinorHue );
m_MoveTime = DateTime.Now;
// Create the region
m_Region = new ChessRegion( m_Parent.Map, this, m_AllowSpectators, m_Bounds, m_Z );
m_Region.Register();
SendAllGumps( null, null );
}
/// <summary>
/// Callback for choosing a partner for the game
/// </summary>
public void ChooseOpponent( Mobile from, object targeted )
{
Mobile m = targeted as Mobile;
if ( m == null || ! m.Player || m.NetState == null )
{
Owner.SendGump( new StartGameGump( Owner, this, true, m_AllowSpectators ) );
Owner.Target = new ChessTarget( this, Owner, "You must select a player. Please select another partner...",
new ChessTargetCallback( ChooseOpponent ) );
}
else if ( m == from )
{
from.SendMessage( 0x40, "You can't play against yourself" );
Owner.SendGump( new StartGameGump( Owner, this, true, m_AllowSpectators ) );
Owner.Target = new ChessTarget( this, Owner, "You must select a player. Please select another partner...",
new ChessTargetCallback( ChooseOpponent ) );
}
else
{
Guest = m;
Owner.SendGump( new StartGameGump( Owner, this, true, m_AllowSpectators ) );
Guest.SendGump( new StartGameGump( Guest, this, false, m_AllowSpectators ) );
}
}
#endregion
#region Event Handlers
/// <summary>
/// Verify if a player is logging back in after disconnecting
/// </summary>
private void OnPlayerLogin(LoginEventArgs e)
{
if ( ! m_Pending )
return;
if ( m_White == null || m_Black == null )
return;
if ( e.Mobile == m_White || e.Mobile == m_Black )
{
if ( m_White.NetState != null && m_Black.NetState != null )
{
m_Pending = false;
// Both players are back and playing
m_Timer.OnPlayerConnected();
m_White.CloseGump( typeof( EndGameGump ) );
m_Black.CloseGump( typeof( EndGameGump ) );
if ( m_Status == GameStatus.BlackPromotion )
{
// Black
SendAllGumps( "Waiting for black to promote their pawn", "Please promote your pawn" );
m_Black.SendGump( new PawnPromotionGump( m_Black, this ) );
}
else if ( m_Status == GameStatus.WhitePromotion )
{
// White
SendAllGumps( "Please promote your pawn", "Waiting for white to promote their pawn" );
m_White.SendGump( new PawnPromotionGump( m_White, this ) );
}
else
SendAllGumps( null, null );
}
}
}
/// <summary>
/// Verify if one of the players disconnects
/// </summary>
private void OnPlayerDisconnected(DisconnectedEventArgs e)
{
if ( e.Mobile != m_Black && e.Mobile != m_White )
return;
if ( m_Status == GameStatus.Setup )
{
Cleanup(); // No game to loose, just end.
return;
}
if ( m_Status == GameStatus.Over )
{
// If game is over, logging out = confirming game over through the gump
NotifyGameOver( e.Mobile );
return;
}
// Game in progress
m_Pending = true;
if ( m_Black != null && m_Black.NetState != null )
{
m_Black.CloseGump( typeof( GameGump ) );
m_Black.SendGump( new EndGameGump( m_Black, this, false,
"Your partner has been disconnected", ChessConfig.DisconnectTimeOut.Minutes ) );
}
if ( m_White != null && m_White.NetState != null )
{
m_White.CloseGump( typeof( GameGump ) );
m_White.SendGump( new EndGameGump( m_White, this, false,
"Your partner has been disconnected", ChessConfig.DisconnectTimeOut.Minutes ) );
}
if ( m_Timer != null )
m_Timer.OnPlayerDisconnected();
}
#endregion
/// <summary>
/// Gets the color of a mobile
/// </summary>
/// <param name="m">The mobile examined</param>
/// <returns>The color of the player</returns>
public ChessColor GetColor( Mobile m )
{
if ( m == m_Black )
return ChessColor.Black;
else
return ChessColor.White;
}
#region Moving Pieces
/// <summary>
/// Sends the move request target
/// </summary>
/// <param name="m">The player that must make the move</param>
public void SendMoveTarget( Mobile m )
{
if ( GetColor( m ) == ChessColor.White )
m_Status = GameStatus.WhiteToMove;
else
m_Status = GameStatus.BlackToMove;
m.Target = new ChessTarget( this, m, "Select the piece you wish to move...",
new ChessTargetCallback( OnPickPieceTarget ) );
}
/// <summary>
/// Callback for selecting the piece to move
/// </summary>
public void OnPickPieceTarget( Mobile from, object targeted )
{
m_Black.CloseGump( typeof( EndGameGump ) );
m_White.CloseGump( typeof( EndGameGump ) );
if ( ! ( targeted is IPoint2D ) )
{
from.SendMessage( 0x40, "Invalid selection" );
SendMoveTarget( from );
return;
}
BaseChessPiece piece = m_Board[ m_Board.WorldToBoard( new Point2D( targeted as IPoint2D ) ) ];
if ( piece == null || piece.Color != GetColor( from ) )
{
from.SendMessage( 0x40, "Invalid selection" );
SendMoveTarget( from );
return;
}
m_MovingPiece = piece;
from.Target = new ChessTarget( this, from, "Where do you wish to move?",
new ChessTargetCallback( OnPieceMove ) );
}
/// <summary>
/// Callback for the move finalization
/// </summary>
public void OnPieceMove( Mobile from, object targeted )
{
string err = null;
if ( ! ( targeted is IPoint2D ) )
{
err = "Invalid Move";
m_MovingPiece = null;
if ( GetColor( from ) == ChessColor.Black )
SendAllGumps( null, err );
else
SendAllGumps( err, null );
return;
}
if ( ! m_Board.TryMove( ref err, m_MovingPiece, new Point2D( targeted as IPoint2D ) ) )
{
m_MovingPiece = null;
if ( GetColor( from ) == ChessColor.Black )
SendAllGumps( null, err );
else
SendAllGumps( err, null );
return;
}
// Move has been made. Wait until it's over
if ( m_Status == GameStatus.WhiteToMove )
{
m_Status = GameStatus.WhiteMoving;
SendAllGumps( "Making your move", null );
}
else
{
m_Status = GameStatus.BlackMoving;
SendAllGumps( null, "Making your move" );
}
}
/// <summary>
/// This function is called when a move is completed, and the next step in game should be performed
/// </summary>
public void OnMoveOver( Move move, string whiteMsg, string blackMsg )
{
m_Timer.OnMoveMade();
if ( move != null && move.Piece is Pawn && ( move.Piece as Pawn ).ShouldBePromoted )
{
// A pawn should be promoted
m_PromotedPawn = move.Piece as Pawn;
if ( m_Status == GameStatus.BlackMoving )
{
// Black
m_Status = GameStatus.BlackPromotion;
SendAllGumps( "Waiting for black to promote their pawn", "Please promote your pawn" );
m_Black.SendGump( new PawnPromotionGump( m_Black, this ) );
}
else
{
// White
m_Status = GameStatus.WhitePromotion;
SendAllGumps( "Please promote your pawn", "Waiting for white to promote their pawn" );
m_White.SendGump( new PawnPromotionGump( m_White, this ) );
}
return;
}
if ( m_Status == GameStatus.BlackMoving || m_Status == GameStatus.BlackPromotion )
{
m_BlackTime += ( DateTime.Now.Subtract( m_MoveTime ) );
m_Status = GameStatus.WhiteToMove;
}
else if ( m_Status == GameStatus.WhiteMoving || m_Status == GameStatus.WhitePromotion )
{
m_WhiteTime += ( DateTime.Now.Subtract( m_MoveTime ) );
m_Status = GameStatus.BlackToMove;
}
m_MoveTime = DateTime.Now;
SendAllGumps( null, null );
}
/// <summary>
/// The user decided to promote a pawn
/// </summary>
/// <param name="type">The piece the pawn should promote to</param>
public void OnPawnPromoted( PawnPromotion type )
{
m_Board.OnPawnPromoted( m_PromotedPawn, type );
m_PromotedPawn = null;
}
/// <summary>
/// This function sends pending gumps to players notifying them to hurry to make a move
/// </summary>
public void OnMoveTimeout()
{
if ( m_Black.NetState != null )
{
m_Black.SendGump( new EndGameGump( m_Black, this, false, string.Format( "No move made in {0} minutes", ChessConfig.MoveTimeOut.Minutes ), ChessConfig.EndGameTimerOut.Minutes ) );
}
if ( m_White.NetState != null )
{
m_White.SendGump( new EndGameGump( m_White, this, false, string.Format( "No move made in {0} minutes", ChessConfig.MoveTimeOut.Minutes ), ChessConfig.EndGameTimerOut.Minutes ) );
}
}
#endregion
/// <summary>
/// Sends the game and score gumps to both player
/// </summary>
/// <param name="whiteMsg">The message displayed to white</param>
/// <param name="blackMsg">The message displayed to black</param>
public void SendAllGumps( string whiteMsg, string blackMsg )
{
if ( m_White == null || m_Black == null )
return;
if ( m_Pending )
{
whiteMsg = "This game is temporarily stopped";
blackMsg = whiteMsg;
}
m_Black.SendGump( new GameGump(
m_Black, this, ChessColor.Black, blackMsg,
! m_Pending && m_Status == GameStatus.BlackToMove,
m_Status == GameStatus.BlackMoving ) );
m_White.SendGump( new GameGump(
m_White, this, ChessColor.White, whiteMsg,
! m_Pending && m_Status == GameStatus.WhiteToMove,
m_Status == GameStatus.WhiteMoving ) );
int[] white = m_Board.GetCaptured( ChessColor.White );
int[] black = m_Board.GetCaptured( ChessColor.Black );
int ws = m_Board.GetScore( ChessColor.White );
int bs = m_Board.GetScore( ChessColor.Black );
m_White.SendGump( new ScoreGump( m_White, this, white, black, ws, bs ) );
m_Black.SendGump( new ScoreGump( m_Black, this, white, black, ws, bs ) );
}
#region End Game
/// <summary>
/// Notifies the parent object to clean up this game
/// </summary>
private void ParentCleanup()
{
m_Parent.OnGameOver();
}
/// <summary>
/// Cleans up the resources used by this game
/// </summary>
public void Cleanup()
{
EventSink.Disconnected -= new DisconnectedEventHandler( OnPlayerDisconnected );
EventSink.Login -= new LoginEventHandler( OnPlayerLogin );
if ( m_Board != null )
{
m_Board.Delete();
}
if ( m_Timer != null )
{
m_Timer.Stop();
m_Timer = null;
}
if ( m_Black != null && m_Black.Target != null && m_Black.Target is ChessTarget )
( m_Black.Target as ChessTarget ).Remove( m_Black );
if ( m_White != null && m_White.Target != null && m_White.Target is ChessTarget )
( m_White.Target as ChessTarget ).Remove( m_White );
if ( m_Black != null && m_Black.NetState != null )
{
m_Black.CloseGump( typeof( StartGameGump ) );
m_Black.CloseGump( typeof( GameGump ) );
m_Black.CloseGump( typeof( EndGameGump ) );
m_Black.CloseGump( typeof( PawnPromotionGump ) );
m_Black.CloseGump( typeof( ScoreGump ) );
}
if ( m_White != null && m_White.NetState != null )
{
m_White.CloseGump( typeof( StartGameGump ) );
m_White.CloseGump( typeof( GameGump ) );
m_White.CloseGump( typeof( EndGameGump ) );
m_White.CloseGump( typeof( PawnPromotionGump ) );
m_White.CloseGump( typeof( ScoreGump ) );
}
if ( m_Region != null )
{
m_Region.Unregister();
m_Region = null;
}
ParentCleanup();
}
/// <summary>
/// Notifies that the game has ended
/// </summary>
/// <param name="winner">The winner of the game, null for a stall</param>
public void EndGame( Mobile winner )
{
m_Status = GameStatus.Over;
m_Timer.OnGameOver();
if ( winner != null )
{
GiveWinnerBook( winner );
}
string msg = null;
if ( winner != null )
msg = string.Format( "Winner: {0}", winner.Name );
else
msg = "Game Stalled";
m_Black.SendGump( new EndGameGump( m_Black, this, true, msg, -1 ) );
m_White.SendGump( new EndGameGump( m_White, this, true, msg, -1 ) );
}
/// <summary>
/// This function is called by the gumps when players acknowledge the end of the game
/// </summary>
/// <param name="m">The mobile acknowledging the end of the game</param>
public void NotifyGameOver( Mobile m )
{
if ( m_Black == m )
{
m_Black.CloseGump( typeof( StartGameGump ) );
m_Black.CloseGump( typeof( GameGump ) );
m_Black.CloseGump( typeof( EndGameGump ) );
m_Black.CloseGump( typeof( PawnPromotionGump ) );
m_Black.CloseGump( typeof( ScoreGump ) );
m_Black = null;
}
if ( m_White == m )
{
m_White.CloseGump( typeof( StartGameGump ) );
m_White.CloseGump( typeof( GameGump ) );
m_White.CloseGump( typeof( EndGameGump ) );
m_White.CloseGump( typeof( PawnPromotionGump ) );
m_White.CloseGump( typeof( ScoreGump ) );
m_White = null;
}
if ( m_Black == null && m_White == null )
{
Cleanup();
}
}
/// <summary>
/// Gives the winner the book with the sum up of the game
/// </summary>
/// <param name="to">The winner of the game</param>
public void GiveWinnerBook( Mobile to )
{
Mobile winner = to;
Mobile looser = null;
TimeSpan winTime = TimeSpan.Zero;
TimeSpan looseTime = TimeSpan.Zero;
int winnerScore = 0;
int looserScore = 0;
if ( winner == m_Black )
{
looser = m_White;
looseTime = m_WhiteTime;
winTime = m_BlackTime;
winnerScore = m_Board.GetScore( ChessColor.Black );
looserScore = m_Board.GetScore( ChessColor.White );
}
else
{
looser = m_Black;
looseTime = m_BlackTime;
winTime = m_WhiteTime;
winnerScore = m_Board.GetScore( ChessColor.White );
looserScore = m_Board.GetScore( ChessColor.Black );
}
if ( winner == null || looser == null )
return;
WinnerPaper paper = new WinnerPaper( winner, looser, DateTime.Now - m_GameStart, winTime, looseTime, winnerScore, looserScore );
if ( to.Backpack != null )
to.Backpack.AddItem( paper );
}
#endregion
#region Appearance
/// <summary>
/// Changes the board's chess set
/// </summary>
public void SetChessSet( ChessSet chessset )
{
if ( m_Board != null )
m_Board.ChessSet = chessset;
else
m_Parent.SetChessSet( chessset ); // This allows players to choose their own set
}
/// <summary>
/// Resets the pieces hues
/// </summary>
/// <param name="white"></param>
/// <param name="black"></param>
public void SetHues( int white, int black, int whiteMinor, int blackMinor )
{
if ( m_Board != null )
{
m_Board.WhiteHue = white;
m_Board.BlackHue = black;
m_Board.WhiteMinorHue = whiteMinor;
m_Board.BlackMinorHue = blackMinor;
}
}
/// <summary>
/// Sets the orientation of the board
/// </summary>
/// <param name="orientation"></param>
public void SetOrientation( BoardOrientation orientation )
{
if ( m_Board != null )
m_Board.Orientation = orientation;
}
/// <summary>
/// Sets the flag that makes pieces ignore their minor hue
/// </summary>
/// <param name="doOverride"></param>
public void SetMinorHueOverride( bool doOverride )
{
if ( m_Board != null )
m_Board.OverrideMinorHue = doOverride;
}
#endregion
#region Misc
/// <summary>
/// Verifies if a specified mobile is a player in the game
/// </summary>
/// <param name="m"></param>
public bool IsPlayer( Mobile m )
{
return m == m_Black || m == m_White;
}
#endregion
}
}

View File

@@ -0,0 +1,188 @@
using System;
using System.Collections;
using Server;
using Server.Items;
using Server.Mobiles;
namespace Arya.Chess
{
/// <summary>
/// The basic mobile that will be used as the actual chess piece
/// </summary>
public class ChessMobile : BaseCreature
{
/// <summary>
/// The chess piece that owns this NPC
/// </summary>
private BaseChessPiece m_Piece;
/// <summary>
/// Specifies the location of the next position of this piece
/// </summary>
private Point3D m_NextMove = Point3D.Zero;
/// <summary>
/// The list of waypoints used by this NPC
/// </summary>
private ArrayList m_WayPoints;
public ChessMobile( BaseChessPiece piece ) : base( AIType.AI_Use_Default, FightMode.None, 1, 1, 0.2, 0.2 )
{
m_WayPoints = new ArrayList();
InitStats( 25, 100, 100 );
m_Piece = piece;
Blessed = true;
Paralyzed = true;
Direction = m_Piece.Facing;
}
#region Serialization
public ChessMobile( Serial serial ) : base( serial )
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize( writer );
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize( reader );
Delete();
}
#endregion
#region Movement on the BChessboard
/// <summary>
/// Places the piece on the board for the first time
/// </summary>
/// <param name="location">The location where the piece should be placed</param>
/// <param name="map">The map where the game takes place</param>
public void Place( Point3D location, Map map )
{
MoveToWorld( location, map );
FixedParticles( 0x373A, 1, 15, 5012, Hue, 2, EffectLayer.Waist );
}
/// <summary>
/// Moves the NPC to the specified location
/// </summary>
/// <param name="to">The location the NPC should move to</param>
public void GoTo( Point2D to )
{
AI = AIType.AI_Melee;
m_NextMove = new Point3D( to, Z );
if ( m_Piece is Knight )
{
WayPoint end = new WayPoint();
WayPoint start = new WayPoint();
end.MoveToWorld( m_NextMove, Map );
// This is a knight, so do L shaped move
int dx = to.X - X;
int dy = to.Y - Y;
Point3D p = Location; // Point3D is a value type
if ( Math.Abs( dx ) == 1 )
p.X += dx;
else
p.Y += dy;
start.MoveToWorld( p, Map );
start.NextPoint = end;
CurrentWayPoint = start;
m_WayPoints.Add( start );
m_WayPoints.Add( end );
}
else
{
WayPoint wp = new WayPoint();
wp.MoveToWorld( m_NextMove, Map );
CurrentWayPoint = wp;
m_WayPoints.Add( wp );
}
Paralyzed = false;
}
protected override void OnLocationChange(Point3D oldLocation)
{
if ( m_NextMove == Point3D.Zero || m_NextMove != Location )
return;
// The NPC is at the waypoint
AI = AIType.AI_Use_Default;
CurrentWayPoint = null;
Paralyzed = true;
foreach( WayPoint wp in m_WayPoints )
wp.Delete();
m_WayPoints.Clear();
m_NextMove = Point3D.Zero;
Direction = m_Piece.Facing;
m_Piece.OnMoveOver();
Server.Timer.DelayCall( TimeSpan.FromMilliseconds( 500 ), TimeSpan.FromMilliseconds( 500 ), 1, new TimerStateCallback ( OnFacingTimer ), null );
}
private void OnFacingTimer( object state )
{
if ( ! Deleted && m_Piece != null )
{
Direction = m_Piece.Facing;
}
}
#endregion
public override bool HandlesOnSpeech(Mobile from)
{
return false;
}
public override void OnDelete()
{
if ( m_Piece != null )
m_Piece.OnPieceDeleted();
CurrentWayPoint = null;
if ( m_WayPoints != null && m_WayPoints.Count > 0 )
{
foreach( WayPoint wp in m_WayPoints )
wp.Delete();
m_WayPoints.Clear();
}
base.OnDelete ();
}
public override bool OnMoveOver(Mobile m)
{
return true;
}
public override bool CanPaperdollBeOpenedBy(Mobile from)
{
return false;
}
}
}

View File

@@ -0,0 +1,155 @@
using System;
using System.Collections;
using Server;
using Server.Regions;
namespace Arya.Chess
{
public class ChessRegion : Region
{
/// <summary>
/// Specifies whether spectators should be allowed on the BChessboard or not
/// </summary>
private bool m_AllowSpectators = false;
/// <summary>
/// The game that's being held on the BChessboard
/// </summary>
private ChessGame m_Game;
/// <summary>
/// The bounds of the region
/// </summary>
private Rectangle2D m_Bounds;
/// <summary>
/// The bounds of the BChessboard
/// </summary>
private Rectangle2D m_BoardBounds;
/// <summary>
/// The height of the BChessboard
/// </summary>
private int m_Height;
public bool AllowSpectators
{
get { return m_AllowSpectators; }
set
{
if ( value != m_AllowSpectators )
{
m_AllowSpectators = value;
ForceExpel();
}
}
}
public ChessRegion( Map map, ChessGame game, bool allowSpectators, Rectangle2D bounds, int height ) : base( "Chessboard", map, 100, bounds )
{
m_Game = game;
m_AllowSpectators = allowSpectators;
// Make the region larger so that people can't cast invisibility outside
// m_Bounds = new Rectangle2D( bounds.X - 12, bounds.Y - 12, bounds.Width + 24, bounds.Height + 24 );
// m_BoardBounds = bounds;
m_Height = height;
// Coords = new ArrayList();
// Coords.Add( m_Bounds );
}
public override void OnLocationChanged(Mobile m, Point3D oldLocation)
{
if ( m_Game == null || m is ChessMobile || m_AllowSpectators || m_Game.IsPlayer( m ) )
base.OnLocationChanged (m, oldLocation);
else if ( m_BoardBounds.Contains( m.Location ) && m.AccessLevel < AccessLevel.GameMaster )
{
m.SendMessage( 0x40, "Spectators aren't allowed on the chessboard" );
// Expel
if ( ! m_BoardBounds.Contains( oldLocation as IPoint2D ) )
m.Location = oldLocation;
else
m.Location = new Point3D( m_BoardBounds.X - 1, m_BoardBounds.Y - 1, m_Height );
}
else
base.OnLocationChanged( m, oldLocation );
}
public override bool OnBeginSpellCast(Mobile m, ISpell s)
{
if ( s is Server.Spells.Sixth.InvisibilitySpell )
{
m.SendMessage( 0x40, "You can't cast that spell when you're close to a chessboard" );
return false;
}
else
{
return base.OnBeginSpellCast (m, s);
}
}
// Don't announce
public override void OnEnter(Mobile m)
{
}
public override void OnExit(Mobile m)
{
}
public override bool AllowSpawn()
{
return false;
}
public override void OnSpeech(SpeechEventArgs args)
{
if ( m_Game != null && m_Game.IsPlayer( args.Mobile ) && m_Game.AllowTarget )
{
if ( args.Speech.ToLower().IndexOf( ChessConfig.ResetKeyword.ToLower() ) > -1 )
m_Game.SendAllGumps( null, null );
}
base.OnSpeech( args );
}
private void ForceExpel()
{
if ( m_Game != null && ! m_AllowSpectators )
{
IPooledEnumerable en = Map.GetMobilesInBounds( m_BoardBounds );
ArrayList expel = new ArrayList();
try
{
foreach( Mobile m in en )
{
if ( m.Player && ! m_Game.IsPlayer( m ) )
{
expel.Add( m );
}
}
}
finally
{
en.Free();
}
foreach( Mobile m in expel )
{
m.SendMessage( 0x40, "Spectators aren't allowed on the chessboard" );
m.Location = new Point3D( m_BoardBounds.X - 1, m_BoardBounds.Y - 1, m_Height );
}
}
}
// public override void Register()
// {
// base.Register();
// ForceExpel();
// }
}
}

View File

@@ -0,0 +1,75 @@
using System;
using Server;
using Server.Targeting;
namespace Arya.Chess
{
public delegate void ChessTargetCallback( Mobile from, object targeted );
/// <summary>
/// General purpose target for the chess system
/// </summary>
public class ChessTarget : Target
{
/// <summary>
/// The message for the target request
/// </summary>
private string m_Message;
/// <summary>
/// The callback for this target
/// </summary>
private ChessTargetCallback m_Callback;
/// <summary>
/// The chess game managing this target
/// </summary>
private ChessGame m_Game;
/// <summary>
/// Flag for a target used outside a game
/// </summary>
private bool m_IgnoreGame = false;
public ChessTarget( ChessGame game, Mobile m, string message, ChessTargetCallback callback ) : base( -1, true, TargetFlags.None )
{
m_Message = message;
m_Callback = callback;
m_Game = game;
if ( message != null )
m.SendMessage( 0x40, message );
}
public ChessTarget( Mobile m, string message, ChessTargetCallback callback ) : base( -1, true, TargetFlags.None )
{
m_IgnoreGame = true;
m_Message = message;
m_Callback = callback;
if ( message != null )
m.SendMessage( 0x40, message );
}
protected override void OnTarget(Mobile from, object targeted)
{
if ( !m_IgnoreGame && ( m_Game == null || !m_Game.AllowTarget ) )
return;
if ( m_Callback != null )
{
try
{
m_Callback.DynamicInvoke( new object[] { from, targeted } );
}
catch ( Exception err )
{
Console.WriteLine( err.ToString() );
}
}
}
public void Remove( Mobile m )
{
Invoke( m, new Point3D( 0, 0, 0 ) );
}
}
}

View File

@@ -0,0 +1,131 @@
using System;
using Server;
namespace Arya.Chess
{
public class ChessTimer
{
private InternalTimer m_Timer;
private DateTime m_LastMove = DateTime.MaxValue;
private DateTime m_Disconnect = DateTime.MaxValue;
private DateTime m_GameStart;
private DateTime m_EndGame = DateTime.MaxValue;
private ChessGame m_Game;
public ChessTimer( ChessGame game )
{
m_Game = game;
m_Timer = new InternalTimer( this );
m_Timer.Start();
m_GameStart = DateTime.Now;
}
public void Stop()
{
if ( m_Timer != null && m_Timer.Running )
{
m_Timer.Stop();
m_Timer = null;
}
}
public void OnTick()
{
if ( m_Game == null )
{
m_Timer.Stop();
return;
}
if ( m_GameStart != DateTime.MaxValue )
{
// Still starting the game
if ( ( DateTime.Now - m_GameStart ) >= ChessConfig.GameStartTimeOut )
{
m_Game.Cleanup();
}
}
if ( m_EndGame != DateTime.MaxValue )
{
if ( ( DateTime.Now - m_EndGame ) >= ChessConfig.EndGameTimerOut )
{
m_Game.Cleanup();
}
return; // Waiting for end game, don't bother with other checks
}
if ( m_LastMove != DateTime.MaxValue )
{
// Now playing
if ( ( DateTime.Now - m_LastMove ) >= ChessConfig.MoveTimeOut )
{
m_EndGame = DateTime.Now;
m_Game.OnMoveTimeout();
return;
}
}
if ( m_Disconnect != DateTime.MaxValue )
{
// A player has been disconnected
if ( ( DateTime.Now - m_Disconnect ) >= ChessConfig.DisconnectTimeOut )
{
m_Game.Cleanup();
}
}
}
public void OnGameStart()
{
m_GameStart = DateTime.MaxValue;
m_LastMove = DateTime.Now;
}
public void OnMoveMade()
{
m_LastMove = DateTime.Now;
m_EndGame = DateTime.MaxValue;
}
public void OnPlayerDisconnected()
{
if ( m_Disconnect == DateTime.MaxValue )
m_Disconnect = DateTime.Now;
}
public void OnPlayerConnected()
{
m_Disconnect = DateTime.MaxValue;
}
public void OnGameOver()
{
m_EndGame = DateTime.Now;
}
private class InternalTimer : Timer
{
private ChessTimer m_Parent;
public InternalTimer( ChessTimer parent ) : base( TimeSpan.FromSeconds( 15 ), TimeSpan.FromSeconds( 15 ) )
{
Priority = TimerPriority.FiveSeconds;
m_Parent = parent;
}
protected override void OnTick()
{
if ( m_Parent != null )
m_Parent.OnTick();
else
Stop();
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,97 @@
using System;
using Server;
using Server.Gumps;
namespace Arya.Chess
{
public class ChessHelpGump : Gump
{
private const int LabelHue = 0x480;
private const int GreenHue = 0x40;
public ChessHelpGump( Mobile m ) : base( 150, 150 )
{
m.CloseGump( typeof( ChessHelpGump ) );
MakeGump();
}
private void MakeGump()
{
this.Closable=true;
this.Disposable=true;
this.Dragable=true;
this.Resizable=false;
this.AddPage(0);
this.AddBackground(0, 0, 420, 271, 9300);
this.AddAlphaRegion( 0, 0, 420, 271 );
this.AddLabel(134, 5, GreenHue, @"Chess Game Information");
this.AddButton(20, 32, 5601, 5605, 1, GumpButtonType.Reply, 0);
this.AddLabel(45, 30, LabelHue, @"Basic rules and pieces moves");
this.AddButton(20, 57, 5601, 5605, 2, GumpButtonType.Reply, 0);
this.AddLabel(45, 55, LabelHue, @"General Chess FAQ");
this.AddButton(20, 82, 5601, 5605, 3, GumpButtonType.Reply, 0);
this.AddLabel(45, 80, LabelHue, @"Check, Checkmate and Stalemate FAQ");
this.AddButton(20, 107, 5601, 5605, 4, GumpButtonType.Reply, 0);
this.AddLabel(45, 105, LabelHue, @"Castle FAQ");
this.AddLabel(45, 120, LabelHue, @"Note: To castle in Battle Chess, select the King and move it");
this.AddLabel(45, 135, LabelHue, @"on the Rook (or do exactly the opposite)");
this.AddButton(20, 162, 5601, 5605, 5, GumpButtonType.Reply, 0);
this.AddLabel(45, 160, LabelHue, @"The En Passant Move");
this.AddButton(20, 207, 5601, 5605, 6, GumpButtonType.Reply, 0);
this.AddLabel(20, 185, GreenHue, @"Pieces FAQs");
this.AddLabel(40, 205, LabelHue, @"Pawn");
this.AddButton(85, 207, 5601, 5605, 7, GumpButtonType.Reply, 0);
this.AddLabel(105, 205, LabelHue, @"Knight");
this.AddButton(155, 207, 5601, 5605, 8, GumpButtonType.Reply, 0);
this.AddLabel(175, 205, LabelHue, @"Queen");
this.AddButton(220, 207, 5601, 5605, 9, GumpButtonType.Reply, 0);
this.AddLabel(240, 205, LabelHue, @"King");
this.AddButton(20, 242, 5601, 5605, 0, GumpButtonType.Reply, 0);
this.AddLabel(40, 240, LabelHue, @"Exit");
}
public override void OnResponse(Server.Network.NetState sender, RelayInfo info)
{
string web = null;
switch ( info.ButtonID )
{
case 1 : web = "http://www.chessvariants.com/d.chess/chess.html";
break;
case 2 : web = "http://www.chessvariants.com/d.chess/faq.html";
break;
case 3 : web = "http://www.chessvariants.com/d.chess/matefaq.html";
break;
case 4 : web = "http://www.chessvariants.com/d.chess/castlefaq.html";
break;
case 5 : web = "http://www.chessvariants.com/d.chess/enpassant.html";
break;
case 6 : web = "http://www.chessvariants.com/d.chess/pawnfaq.html";
break;
case 7 : web = "http://www.chessvariants.com/d.chess/knightfaq.html";
break;
case 8 : web = "http://www.chessvariants.com/d.chess/queenfaq.html";
break;
case 9 : web = "http://www.chessvariants.com/d.chess/kingfaq.html";
break;
}
if ( web != null )
{
sender.Mobile.LaunchBrowser( web );
sender.Mobile.SendGump( this );
}
}
}
}

View File

@@ -0,0 +1,132 @@
using System;
using System.Reflection;
using Server;
using Server.Gumps;
namespace Arya.Chess
{
/// <summary>
/// Summary description for ChessSetGump.
/// </summary>
public class ChessSetGump : Gump
{
private const int LabelHue = 0x480;
private const int GreenHue = 0x40;
private static string[] m_Sets;
/// <summary>
/// Gets the list of chess sets available
/// </summary>
private static string[] Sets
{
get
{
if ( m_Sets == null )
m_Sets = Enum.GetNames( typeof( Arya.Chess.ChessSet ) );
return m_Sets;
}
}
private ChessGame m_Game;
private Mobile m_User;
private bool m_IsOwner;
private bool m_AllowSpectators;
private int m_Page = 0;
public ChessSetGump( Mobile m, ChessGame game, bool isOwner, bool allowSpectators, int page ) : base( 200, 200 )
{
m_Game = game;
m_User = m;
m_IsOwner = isOwner;
m_AllowSpectators = allowSpectators;
m_Page = page;
m_User.CloseGump( typeof( ChessSetGump ) );
MakeGump();
}
public ChessSetGump( Mobile m, ChessGame game, bool isOwner, bool allowSpectators ) : this( m, game, isOwner, allowSpectators, 0 )
{
}
private void MakeGump()
{
this.Closable=false;
this.Disposable=true;
this.Dragable=true;
this.Resizable=false;
this.AddPage(0);
this.AddBackground(0, 0, 320, 170, 9250);
this.AddAlphaRegion(0, 0, 320, 170);
for ( int i = 0; i < 4 && 4 * m_Page + i < Sets.Length; i++ )
{
AddButton( 35, 45 + i * 20, 5601, 5605, 10 + 4 * m_Page + i, GumpButtonType.Reply, 0 );
AddLabel( 60, 43 + i * 20, LabelHue, Sets[ 4 * m_Page + i ] );
}
if ( m_Page > 0 )
{
this.AddButton(15, 15, 5603, 5607, 1, GumpButtonType.Reply, 0);
}
int totalPages = ( Sets.Length - 1 ) / 4;
// Prev page : 1
// Next page : 2
if ( totalPages > m_Page )
{
this.AddButton(35, 15, 5601, 5605, 2, GumpButtonType.Reply, 0);
}
this.AddLabel(60, 13, GreenHue, @"Chess set selection");
// Cancel 3
this.AddButton(15, 130, 4020, 4021, 3, GumpButtonType.Reply, 0);
this.AddLabel(55, 130, GreenHue, @"Cancel Game");
}
public override void OnResponse(Server.Network.NetState sender, RelayInfo info)
{
switch ( info.ButtonID )
{
case 0 : return;
case 1:
sender.Mobile.SendGump( new ChessSetGump( m_User, m_Game, m_IsOwner, m_AllowSpectators, --m_Page ) );
break;
case 2:
sender.Mobile.SendGump( new ChessSetGump( m_User, m_Game, m_IsOwner, m_AllowSpectators, ++m_Page ) );
break;
case 3:
m_Game.CancelGameStart( sender.Mobile );
break;
default:
int index = info.ButtonID - 10;
ChessSet s = (ChessSet) Enum.Parse( typeof( Arya.Chess.ChessSet ), Sets[ index ], false );
m_Game.SetChessSet( s );
sender.Mobile.SendGump( new StartGameGump( sender.Mobile, m_Game, m_IsOwner, m_AllowSpectators ) );
sender.Mobile.Target = new ChessTarget( m_Game, sender.Mobile, "Please select your parnter...",
new ChessTargetCallback( m_Game.ChooseOpponent ) );
break;
}
}
}
}

View File

@@ -0,0 +1,65 @@
using System;
using Server;
using Server.Gumps;
namespace Arya.Chess
{
public class EndGameGump : Gump
{
private const int LabelHue = 0x480;
private const int GreenHue = 0x40;
private ChessGame m_Game;
private bool m_GameOver;
public EndGameGump( Mobile m, ChessGame game, bool over, string details, int timeout ) : base( 200, 200 )
{
m.CloseGump( typeof( EndGameGump ) );
m_Game = game;
m_GameOver = over;
this.Closable=false;
this.Disposable=true;
this.Dragable=true;
this.Resizable=false;
this.AddPage(0);
this.AddBackground(0, 0, 265, 160, 9250);
this.AddImageTiled(0, 0, 265, 160, 9304);
this.AddImageTiled(1, 1, 263, 158, 9274);
this.AddAlphaRegion(1, 1, 263, 158);
// Button 1 : End Game
this.AddButton(10, 127, 5601, 5605, 1, GumpButtonType.Reply, 0);
this.AddLabel(10, 10, LabelHue, string.Format( "This game is : {0}", over ? "Over" : "Pending" ) );
this.AddLabel(10, 30, LabelHue, @"Details");
this.AddLabel(30, 55, GreenHue, details);
this.AddLabel(30, 125, LabelHue, @"End Game");
if ( timeout > -1 )
{
this.AddLabel(10, 80, LabelHue, string.Format( "Wait {0} minutes before the game ends", timeout ) );
this.AddLabel(10, 95, LabelHue, @"automatically. Do not close this gump.");
}
}
public override void OnResponse(Server.Network.NetState sender, RelayInfo info)
{
if ( info.ButtonID == 1 )
{
if ( m_GameOver )
{
// Reset the game
m_Game.NotifyGameOver( sender.Mobile );
}
else
{
// Force end the game
m_Game.Cleanup();
}
}
}
}
}

View File

@@ -0,0 +1,112 @@
using System;
using Server;
using Server.Gumps;
namespace Arya.Chess
{
/// <summary>
/// Main game gump
/// </summary>
public class GameGump : Gump
{
private const int LabelHue = 0x480;
private const int GreenHue = 0x40;
private ChessGame m_Game;
private bool m_Move;
private bool m_Moving;
private string m_Message;
private ChessColor m_Color;
public GameGump( Mobile m, ChessGame game, ChessColor color, string message, bool move, bool moving ): base( 60, 25 )
{
m.CloseGump( typeof( GameGump ) );
m_Game = game;
m_Message = message;
m_Color = color;
m_Move = move;
m_Moving = moving;
if ( move && ! moving )
m_Game.SendMoveTarget( m );
MakeGump();
}
private void MakeGump()
{
this.Closable=false;
this.Disposable=true;
this.Dragable=true;
this.Resizable=false;
this.AddPage(0);
this.AddBackground(0, 0, 555, 50, 9250);
this.AddImageTiled(0, 0, 555, 50, 9304);
this.AddImageTiled(1, 1, 553, 48, 9274);
this.AddAlphaRegion(1, 1, 553, 48);
if ( m_Color == ChessColor.White )
{
this.AddImage(5, 5, 2331);
this.AddLabel(30, 5, LabelHue, @"You are WHITE");
}
else
{
this.AddImage(5, 5, 2338);
this.AddLabel(30, 5, LabelHue, @"You are BLACK");
}
string msg = null;
if ( m_Moving )
msg = "Making your move";
else if ( m_Move )
msg = "Make your move";
else
msg = "Waiting for opponent to move";
this.AddLabel(165, 5, LabelHue, msg);
// B1 : Make move
if ( m_Move )
this.AddButton(145, 7, 5601, 5605, 1, GumpButtonType.Reply, 0);
// B2 : Chess Help
this.AddButton(365, 7, 5601, 5605, 2, GumpButtonType.Reply, 0);
this.AddLabel(385, 5, LabelHue, @"Chess Help");
// B3 : End Game
this.AddButton(460, 7, 5601, 5605, 3, GumpButtonType.Reply, 0);
this.AddLabel(480, 5, LabelHue, @"End Game");
if ( m_Message != null )
this.AddLabel(5, 25, GreenHue, m_Message );
}
public override void OnResponse(Server.Network.NetState sender, RelayInfo info)
{
switch ( info.ButtonID )
{
case 1 : // Make move
sender.Mobile.SendGump( new GameGump( sender.Mobile, m_Game, m_Color, m_Message, m_Move, m_Moving ) );
break;
case 2: // Chess Help
sender.Mobile.SendGump( new ChessHelpGump( sender.Mobile ) );
sender.Mobile.SendGump( this );
break;
case 3: // End game
m_Game.Cleanup();
break;
}
}
}
}

View File

@@ -0,0 +1,83 @@
using System;
using Server;
using Server.Gumps;
namespace Arya.Chess
{
public class PawnPromotionGump : Gump
{
private const int LabelHue = 0x480;
private const int GreenHue = 0x40;
ChessGame m_Game;
public PawnPromotionGump( Mobile m, ChessGame game ) : base( 200, 200 )
{
m.CloseGump( typeof( PawnPromotionGump ) );
m_Game = game;
MakeGump();
}
private void MakeGump()
{
this.Closable=false;
this.Disposable=true;
this.Dragable=true;
this.Resizable=false;
this.AddPage(0);
this.AddBackground(0, 0, 255, 185, 9200);
this.AddImageTiled(0, 0, 255, 185, 9304);
this.AddImageTiled(1, 1, 253, 183, 9274);
this.AddAlphaRegion(1, 1, 253, 183);
this.AddLabel(20, 10, GreenHue, @"Your pawn is being promoted!");
this.AddLabel(20, 35, LabelHue, @"Promote to:");
this.AddButton(35, 70, 2337, 2344, 1, GumpButtonType.Reply, 0);
this.AddLabel(25, 120, LabelHue, @"Queen");
this.AddButton(85, 70, 2333, 2340, 2, GumpButtonType.Reply, 0);
this.AddLabel(80, 120, LabelHue, @"Rook");
this.AddButton(135, 70, 2335, 2344, 3, GumpButtonType.Reply, 0);
this.AddLabel(130, 120, LabelHue, @"Knight");
this.AddButton(195, 70, 2332, 2339, 4, GumpButtonType.Reply, 0);
this.AddLabel(185, 120, LabelHue, @"Bishop");
this.AddButton(25, 152, 9702, 248, 5, GumpButtonType.Reply, 0);
this.AddLabel(50, 150, 0, @"Do not promote pawn");
}
public override void OnResponse(Server.Network.NetState sender, RelayInfo info)
{
PawnPromotion type = PawnPromotion.None;
switch ( info.ButtonID )
{
case 0 :
return; // This fixes a crash when staff deletes the pawn being promoted
case 1 : type = PawnPromotion.Queen;
break;
case 2 : type = PawnPromotion.Rook;
break;
case 3 : type = PawnPromotion.Knight;
break;
case 4 : type = PawnPromotion.Bishop;
break;
case 5: type = PawnPromotion.None;
break;
}
m_Game.OnPawnPromoted( type );
}
}
}

View File

@@ -0,0 +1,63 @@
using System;
using Server;
using Server.Gumps;
namespace Arya.Chess
{
/// <summary>
/// Summary description for ScoreGump.
/// </summary>
public class ScoreGump : Gump
{
private ChessGame m_Game;
private const int LabelHue = 0x480;
private const int GreenHue = 0x40;
public ScoreGump( Mobile m, ChessGame game, int[] white, int[] black, int totwhite, int totblack ) : base( 0, 25 )
{
m.CloseGump( typeof( ScoreGump ) );
m_Game = game;
MakeGump( white, black, totwhite, totblack );
}
private void MakeGump( int[] white, int[] black, int whitescore, int blackscore )
{
this.Closable=true;
this.Disposable=true;
this.Dragable=true;
this.Resizable=false;
this.AddPage(0);
this.AddBackground(0, 0, 60, 345, 9350);
this.AddAlphaRegion(0, 0, 60, 345);
this.AddImage(5, 5, 2336);
this.AddImage(30, 6, 2343);
this.AddImage(5, 50, 2335);
this.AddImage(30, 50, 2342);
this.AddImage(5, 105, 2332);
this.AddImage(30, 105, 2339);
this.AddImage(5, 160, 2333);
this.AddImage(30, 160, 2340);
this.AddImage(5, 220, 2337);
this.AddImage(30, 220, 2344);
this.AddImageTiled(0, 285, 60, 1, 5124);
this.AddImage(10, 305, 2331);
this.AddImage(10, 325, 2338);
this.AddLabel(11, 33, LabelHue, white[0].ToString() );
this.AddLabel(5, 285, GreenHue, @"Score");
this.AddLabel(36, 33, LabelHue, black[0].ToString() );
this.AddLabel(11, 87, LabelHue, white[1].ToString() );
this.AddLabel(36, 87, LabelHue, black[1].ToString() );
this.AddLabel(11, 142, LabelHue, white[2].ToString() );
this.AddLabel(36, 142, LabelHue, black[2].ToString() );
this.AddLabel(11, 200, LabelHue, white[3].ToString() );
this.AddLabel(36, 200, LabelHue, black[3].ToString() );
this.AddLabel(11, 260, LabelHue, white[4].ToString() );
this.AddLabel(36, 260, LabelHue, black[4].ToString() );
this.AddLabel(30, 302, LabelHue, whitescore.ToString() );
this.AddLabel(30, 322, LabelHue, blackscore.ToString() );
}
}
}

View File

@@ -0,0 +1,125 @@
using System;
using Server;
using Server.Gumps;
namespace Arya.Chess
{
/// <summary>
/// This gump is used to start the game
/// </summary>
public class StartGameGump : Gump
{
private const int LabelHue = 0x480;
private const int GreenHue = 0x40;
private ChessGame m_Game;
private Mobile m_User;
private bool m_IsOwner;
private bool m_AllowSpectators;
public StartGameGump( Mobile m, ChessGame game, bool isOwner, bool allowSpectators ) : base( 200, 200 )
{
m_Game = game;
m_User = m;
m_IsOwner = isOwner;
m_AllowSpectators = allowSpectators;
m_User.CloseGump( typeof( StartGameGump ) );
MakeGump();
}
private void MakeGump()
{
this.Closable=false;
this.Disposable=true;
this.Dragable=true;
this.Resizable=false;
this.AddPage(0);
int height = 75;
if ( m_IsOwner )
height = 110;
this.AddBackground(0, 0, 300, height, 9250);
this.AddImageTiled(0, 0, 300, height, 9304);
this.AddImageTiled(1, 1, 298, height - 2, 9274);
this.AddAlphaRegion(1, 1, 298, height - 2);
if ( m_IsOwner )
{
if ( m_Game.Guest == null )
this.AddLabel(10, 5, GreenHue, @"Starting new chess game");
else
this.AddLabel(10, 5, GreenHue, @"Waiting for partner to accept");
this.AddImageTiled(10, 25, 280, 1, 9304);
// Bring again target : 1
if ( m_Game.Guest == null )
{
this.AddButton(15, 30, 5601, 5605, 1, GumpButtonType.Reply, 0);
this.AddLabel(35, 28, LabelHue, @"Please select your opponent...");
}
// Cancel : 0
this.AddButton(15, 50, 5601, 5605, 2, GumpButtonType.Reply, 0);
this.AddLabel(35, 48, LabelHue, @"Cancel");
int bid = m_AllowSpectators ? 2153 : 2151;
this.AddButton( 10, 75, bid, bid, 3, GumpButtonType.Reply, 0 );
this.AddLabel( 45, 80, LabelHue, "Allow spectators on the Chessboard" );
}
else
{
this.AddLabel(10, 5, GreenHue, string.Format( "Play chess with {0}?", m_Game.Owner.Name ) );
this.AddImageTiled(10, 25, 280, 1, 9304);
// Accept : 1
this.AddButton(15, 30, 5601, 5605, 1, GumpButtonType.Reply, 0);
this.AddLabel(35, 28, LabelHue, @"Accept");
// Refuse : 0
this.AddButton(15, 50, 5601, 5605, 2, GumpButtonType.Reply, 0);
this.AddLabel(35, 48, LabelHue, @"Refuse");
}
}
public override void OnResponse(Server.Network.NetState sender, RelayInfo info)
{
if ( m_IsOwner )
{
if ( info.ButtonID == 3 )
{
// Switch the allow spectators flag
m_Game.AllowSpectators = !m_AllowSpectators;
sender.Mobile.SendGump( new StartGameGump( sender.Mobile, m_Game, m_IsOwner, !m_AllowSpectators ) );
}
else if ( info.ButtonID == 2 )
{
m_Game.CancelGameStart( sender.Mobile );
}
else if ( info.ButtonID == 1 )
{
sender.Mobile.Target = new ChessTarget( m_Game, sender.Mobile, "Please select your partner...",
new ChessTargetCallback( m_Game.ChooseOpponent ) );
sender.Mobile.SendGump( new StartGameGump( sender.Mobile, m_Game, m_IsOwner, m_AllowSpectators ) );
}
}
else
{
if ( info.ButtonID == 2 )
{
m_Game.CancelGameStart( sender.Mobile );
}
else if ( info.ButtonID == 1 )
{
m_Game.AcceptGame( sender.Mobile );
}
}
}
}
}

View File

@@ -0,0 +1,508 @@
using System;
using Server;
namespace Arya.Chess
{
/// <summary>
/// This is the control stone that allows player to play chess
/// </summary>
public class ChessControl : Item
{
#region Variables
private ChessGame m_Game;
private Rectangle2D m_Bounds;
private int m_SquareWidth = 2;
private int m_BoardHeight = 0;
private ChessSet m_ChessSet = ChessSet.Classic;
private int m_WhiteHue = 91;
private int m_BlackHue = 437;
private int m_AttackEffect = 14068; // Fire snake
private int m_CaptureEffect = 14186; // Blue/Gold Sparkle 2
private bool m_BoltOnDeath = true;
private bool m_AllowSpectators = false;
private BoardOrientation m_Orientation = BoardOrientation.NorthSouth;
private int m_BlackMinorHue = 447;
private int m_WhiteMinorHue = 96;
private bool m_OverrideMinorHue = false;
#endregion
#region Properties
[ CommandProperty( AccessLevel.GameMaster ) ]
public Rectangle2D Bounds
{
get { return m_Bounds; }
}
[ CommandProperty( AccessLevel.GameMaster ) ]
public Point2D BoardNorthWestCorner
{
get { return m_Bounds.Start; }
set
{
m_Bounds.Start = value;
m_Bounds.Width = 8 * m_SquareWidth;
m_Bounds.Height = 8 * m_SquareWidth;
InvalidateProperties();
}
}
[ CommandProperty( AccessLevel.GameMaster ) ]
public int SquareWidth
{
get { return m_SquareWidth; }
set
{
if ( value < 1 )
return;
m_SquareWidth = value;
if ( m_Bounds.Start != Point2D.Zero )
{
m_Bounds.Width = 8 * m_SquareWidth;
m_Bounds.Height = 8 * m_SquareWidth;
InvalidateProperties();
}
}
}
[ CommandProperty( AccessLevel.GameMaster ) ]
public int WhiteHue
{
get { return m_WhiteHue; }
set
{
if ( value < 0 || value > 3000 )
return;
if ( value == m_WhiteHue )
return;
m_WhiteHue = value;
if ( m_Game != null )
m_Game.SetHues( m_WhiteHue, m_BlackHue, m_WhiteMinorHue, m_BlackMinorHue );
}
}
[ CommandProperty( AccessLevel.GameMaster ) ]
public int BlackHue
{
get { return m_BlackHue; }
set
{
if ( value < 0 || value > 3000 )
return;
if ( value == m_BlackHue )
return;
m_BlackHue = value;
if ( m_Game != null )
m_Game.SetHues( m_WhiteHue, m_BlackHue, m_WhiteMinorHue, m_BlackMinorHue );
}
}
[ CommandProperty( AccessLevel.GameMaster ) ]
public int WhiteMinorHue
{
get { return m_WhiteMinorHue; }
set
{
if ( value < 0 || value > 3000 )
return;
if ( value == m_WhiteMinorHue )
return;
m_WhiteMinorHue = value;
if ( m_Game != null )
m_Game.SetHues( m_WhiteHue, m_BlackHue, m_WhiteMinorHue, m_BlackMinorHue );
}
}
[ CommandProperty( AccessLevel.GameMaster ) ]
public int BlackMinorHue
{
get { return m_BlackMinorHue; }
set
{
if ( value < 0 || value > 3000 )
return;
if ( value == m_BlackMinorHue )
return;
m_BlackMinorHue = value;
if ( m_Game != null )
m_Game.SetHues( m_WhiteHue, m_BlackHue, m_WhiteMinorHue, m_BlackMinorHue );
}
}
[ CommandProperty( AccessLevel.GameMaster ) ]
public bool OverrideMinorHue
{
get { return m_OverrideMinorHue; }
set
{
if ( value != m_OverrideMinorHue )
{
m_OverrideMinorHue = value;
if ( m_Game != null )
m_Game.SetMinorHueOverride( m_OverrideMinorHue );
}
}
}
[ CommandProperty( AccessLevel.GameMaster ) ]
public int AttackEffect
{
get { return m_AttackEffect; }
set { m_AttackEffect = value; }
}
[ CommandProperty( AccessLevel.GameMaster ) ]
public int CaptureEffect
{
get { return m_CaptureEffect; }
set { m_CaptureEffect = value; }
}
[ CommandProperty( AccessLevel.GameMaster ) ]
public bool BoltOnDeath
{
get { return m_BoltOnDeath; }
set { m_BoltOnDeath = value; }
}
[ CommandProperty( AccessLevel.GameMaster ) ]
public int BoardHeight
{
get { return m_BoardHeight; }
set { m_BoardHeight = value; }
}
[ CommandProperty( AccessLevel.GameMaster ) ]
public ChessSet ChessSet
{
get { return m_ChessSet; }
set
{
m_ChessSet = value;
if ( m_Game != null )
m_Game.SetChessSet( m_ChessSet );
}
}
[ CommandProperty( AccessLevel.GameMaster ) ]
public bool AllowSpectators
{
get
{
if ( m_Game != null && m_Game.Region != null )
return m_Game.Region.AllowSpectators;
else
return m_AllowSpectators;
}
set
{
m_AllowSpectators = value;
if ( m_Game != null && m_Game.Region != null )
{
m_Game.Region.AllowSpectators = m_AllowSpectators;
InvalidateProperties();
}
}
}
[ CommandProperty( AccessLevel.GameMaster ) ]
public BoardOrientation Orientation
{
get { return m_Orientation; }
set
{
m_Orientation = value;
if ( m_Game != null )
m_Game.SetOrientation( m_Orientation );
}
}
#endregion
[ Constructable ]
public ChessControl() : base( 3796 )
{
Movable = false;
Hue = 1285;
Name = "Battle Chess";
m_Bounds = new Rectangle2D( 0, 0, 0, 0 );
}
public ChessControl( Serial serial ) : base( serial )
{
}
#region Serialization
public override void Serialize(GenericWriter writer)
{
base.Serialize (writer);
writer.Write( 3 ); // Version;
// Version 3
writer.Write( m_OverrideMinorHue );
writer.Write( m_AllowSpectators );
// Version 2
writer.Write( (byte) m_Orientation );
writer.Write( m_BlackMinorHue );
writer.Write( m_WhiteMinorHue );
// Version 1
writer.Write( (int) m_ChessSet );
writer.Write( m_WhiteHue );
writer.Write( m_BlackHue );
writer.Write( m_AttackEffect );
writer.Write( m_CaptureEffect );
writer.Write( m_BoltOnDeath );
// Version 0
writer.Write( m_Bounds );
writer.Write( m_SquareWidth );
writer.Write( m_BoardHeight );
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize (reader);
int version = reader.ReadInt();
switch ( version )
{
case 3:
m_OverrideMinorHue = reader.ReadBool();
m_AllowSpectators = reader.ReadBool();
goto case 2;
case 2 :
m_Orientation = (BoardOrientation) reader.ReadByte();
m_BlackMinorHue = reader.ReadInt();
m_WhiteMinorHue = reader.ReadInt();
goto case 1;
case 1:
m_ChessSet = ( ChessSet ) reader.ReadInt();
m_WhiteHue = reader.ReadInt();
m_BlackHue = reader.ReadInt();
m_AttackEffect = reader.ReadInt();
m_CaptureEffect = reader.ReadInt();
m_BoltOnDeath = reader.ReadBool();
goto case 0;
case 0:
m_Bounds = reader.ReadRect2D();
m_SquareWidth = reader.ReadInt();
m_BoardHeight = reader.ReadInt();
break;
}
}
#endregion
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties (list);
string status = "Not Configured";
if ( m_Bounds.Width > 0 )
{
if ( m_Game == null )
status = "Ready";
else
status = "Game in progress";
}
list.Add( 1060658, "Game Status\t{0}", status );
if ( m_Game != null )
{
bool spect = m_AllowSpectators;
if ( m_Game.Region != null )
spect = m_Game.Region.AllowSpectators;
list.Add( 1060659, "Spectators on the Chessboard\t{0}",
spect ? "Allowed" : "Not Allowed" );
list.Add( 1060660, "If you loose your target say\t{0}", ChessConfig.ResetKeyword );
}
}
public override void OnDoubleClick(Mobile from)
{
if ( m_Bounds.Width == 0 )
{
// Not configured yet
if ( from.AccessLevel >= AccessLevel.GameMaster )
{
from.Target = new ChessTarget( from, "Target the north west corner of the chessboard you wish to create",
new ChessTargetCallback( OnBoardTarget ) );
}
else
{
from.SendMessage( 0x40, "This chess board isn't ready for a game yet. Please contact a game master for assistance with its configuration." );
}
}
else if ( m_Game != null )
{
if ( m_Game.IsPlayer( from ) && m_Game.AllowGame )
m_Game.SendAllGumps( null, null );
else
from.SendMessage( 0x40, "A chess game is currently in progress. Please try again later." );
}
else
{
m_Game = new ChessGame( this, from, m_Bounds, m_BoardHeight );
InvalidateProperties();
}
}
public void OnGameOver()
{
m_Game = null;
InvalidateProperties();
}
private void OnBoardTarget( Mobile from, object targeted )
{
IPoint3D p = targeted as IPoint3D;
if ( p == null )
{
from.SendMessage( 0x40, "Invalid location" );
return;
}
BuildBoard( this, new Point3D( p ), Map );
InvalidateProperties();
}
public override void OnDelete()
{
if ( m_Game != null )
m_Game.Cleanup();
base.OnDelete();
}
public void SetChessSet( ChessSet s )
{
m_ChessSet = s;
}
#region Board Building
private static void BuildBoard( ChessControl chess, Point3D p, Map map )
{
chess.m_BoardHeight = p.Z + 5; // Placing stairs on the specified point
chess.BoardNorthWestCorner = new Point2D( p.X, p.Y );
#region Board Tiles
int stairNW = 1909;
int stairSE = 1910;
int stairSW = 1911;
int stairNE = 1912;
int stairS = 1901;
int stairE = 1902;
int stairN = 1903;
int stairW = 1904;
int black = 1295;
int white = 1298;
#endregion
for ( int x = 0; x < 8; x++ )
{
for ( int y = 0; y < 8; y++ )
{
int tile = 0;
if ( x % 2 == 0 )
{
if ( y % 2 == 0 )
tile = black;
else
tile = white;
}
else
{
if ( y % 2 == 0 )
tile = white;
else
tile = black;
}
if ( chess.Orientation == BoardOrientation.EastWest ) // Invert tiles if the orientation is EW
{
if ( tile == white )
tile = black;
else
tile = white;
}
for ( int kx = 0; kx < chess.m_SquareWidth; kx++ )
{
for ( int ky = 0; ky < chess.m_SquareWidth; ky++ )
{
Server.Items.Static s = new Server.Items.Static( tile );
Point3D target = new Point3D( p.X + x * chess.m_SquareWidth + kx, p.Y + y * chess.m_SquareWidth + ky, chess.m_BoardHeight );
s.MoveToWorld( target, map );
}
}
}
}
Point3D nw = new Point3D( p.X - 1, p.Y - 1, p.Z );
Point3D ne = new Point3D( p.X + 8 * chess.m_SquareWidth, p.Y - 1, p.Z );
Point3D se = new Point3D( p.X + 8 * chess.m_SquareWidth, p.Y + 8 * chess.m_SquareWidth, p.Z );
Point3D sw = new Point3D( p.X - 1, p.Y + 8 * chess.m_SquareWidth, p.Z );
new Server.Items.Static( stairNW ).MoveToWorld( nw, map );
new Server.Items.Static( stairNE ).MoveToWorld( ne, map );
new Server.Items.Static( stairSE ).MoveToWorld( se, map );
new Server.Items.Static( stairSW ).MoveToWorld( sw, map );
for ( int x = 0; x < 8 * chess.m_SquareWidth; x++ )
{
Point3D top = new Point3D( p.X + x, p.Y - 1, p.Z );
Point3D bottom = new Point3D( p.X + x, p.Y + 8 * chess.m_SquareWidth, p.Z );
Point3D left = new Point3D( p.X - 1, p.Y + x, p.Z );
Point3D right = new Point3D( p.X + chess.m_SquareWidth * 8, p.Y + x, p.Z );
new Server.Items.Static( stairN ).MoveToWorld( top, map );
new Server.Items.Static( stairS ).MoveToWorld( bottom, map );
new Server.Items.Static( stairW ).MoveToWorld( left, map );
new Server.Items.Static( stairE ).MoveToWorld( right, map );
}
}
#endregion
}
}

View File

@@ -0,0 +1,87 @@
using System;
using Server;
using Server.Items;
namespace Arya.Chess
{
[ Flipable( 5357, 5358 ) ]
public class WinnerPaper : Item
{
private string m_Winner;
private string m_Looser;
private DateTime m_GameEnd;
private TimeSpan m_GameTime;
private TimeSpan m_WinnerTime;
private TimeSpan m_LooserTime;
private int m_WinnerScore;
private int m_LooserScore;
public WinnerPaper( Mobile winner, Mobile looser, TimeSpan gameTime, TimeSpan winnerTime, TimeSpan looserTime, int winnerScore, int looserScore) : base( 5357 )
{
Hue = 1159;
Weight = 0.2;
m_Winner = winner.Name;
m_Looser = looser.Name;
m_GameEnd = DateTime.Now;
m_GameTime = gameTime;
m_WinnerTime = winnerTime;
m_LooserTime = looserTime;
m_WinnerScore = winnerScore;
m_LooserScore = looserScore;
Name = string.Format( "{0} won a fair chess game vs {1}", m_Winner, m_Looser );
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties (list);
list.Add( 1060658, "Date\t{0}", m_GameEnd.ToLongDateString() );
list.Add( 1060659, "Total Game Time\t{0} Hours, {1} Minutes, {2} Seconds", m_GameTime.Hours, m_GameTime.Minutes, m_GameTime.Seconds );
list.Add( 1060660, "{0}'s Game Time\t{1} Hours, {2} Minutes, {3} Seconds", m_Winner, m_WinnerTime.Hours, m_WinnerTime.Minutes, m_WinnerTime.Seconds );
list.Add( 1060661, "{0}'s Game Time\t{1} Hours, {2} Minutes, {3} Seconds", m_Looser, m_LooserTime.Hours, m_LooserTime.Minutes, m_LooserTime.Seconds );
list.Add( 1060662, "{0}'s Score\t{1}", m_Winner, m_WinnerScore );
list.Add( 1060663, "{0}'s Score\t{1}", m_Looser, m_LooserScore );
}
public WinnerPaper( Serial serial ) : base( serial )
{
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize (reader);
int version = reader.ReadInt();
m_Winner = reader.ReadString();
m_Looser = reader.ReadString();
m_GameEnd = reader.ReadDateTime();
m_GameTime = reader.ReadTimeSpan();
m_WinnerTime = reader.ReadTimeSpan();
m_LooserTime = reader.ReadTimeSpan();
m_WinnerScore = reader.ReadInt();
m_LooserScore = reader.ReadInt();
}
public override void Serialize(GenericWriter writer)
{
base.Serialize (writer);
writer.Write( 0 );
writer.Write( m_Winner );
writer.Write( m_Looser );
writer.Write( m_GameEnd );
writer.Write( m_GameTime );
writer.Write( m_WinnerTime );
writer.Write( m_LooserTime );
writer.Write( m_WinnerScore );
writer.Write( m_LooserScore );
}
}
}

View File

@@ -0,0 +1,96 @@
using System;
using Server;
namespace Arya.Chess
{
/// <summary>
/// Describes a piece move
/// </summary>
public class Move
{
private Point2D m_From;
private Point2D m_To;
private BaseChessPiece m_Piece;
private BaseChessPiece m_Captured;
private bool m_EnPassant = false;
/// <summary>
/// Gets the initial position of the piece
/// </summary>
public Point2D From
{
get { return m_From; }
}
/// <summary>
/// Gets the target destination of the move
/// </summary>
public Point2D To
{
get { return m_To; }
}
/// <summary>
/// Gets the chess piece performing this move
/// </summary>
public BaseChessPiece Piece
{
get { return m_Piece; }
}
/// <summary>
/// Gets the piece captured by this move
/// </summary>
public BaseChessPiece CapturedPiece
{
get { return m_Captured; }
}
/// <summary>
/// Specifies if this move captures a piece
/// </summary>
public bool Capture
{
get { return m_Captured != null; }
}
/// <summary>
/// The color of the player making this move
/// </summary>
public ChessColor Color
{
get { return m_Piece.Color; }
}
/// <summary>
/// Gets the color of the opponent of the player who made the move
/// </summary>
public ChessColor EnemyColor
{
get { return m_Piece.EnemyColor; }
}
/// <summary>
/// Specifies if the capture is made EnPassant
/// </summary>
public bool EnPassant
{
get { return m_EnPassant; }
set { m_EnPassant = value; }
}
/// <summary>
/// Creates a new Move object without capturing a piece
/// </summary>
/// <param name="piece">The chess piece performing the move</param>
/// <param name="target">The target location of the move</param>
public Move( BaseChessPiece piece, Point2D target )
{
m_Piece = piece;
m_From = m_Piece.Position;
m_To = target;
m_Captured = m_Piece.GetCaptured( target, ref m_EnPassant );
}
}
}

View File

@@ -0,0 +1,211 @@
using System;
using System.Collections;
using Server;
using Server.Items;
namespace Arya.Chess
{
public class Bishop : BaseChessPiece
{
public static int GetGumpID( ChessColor color )
{
return color == ChessColor.Black ? 2339 : 2332;
}
public override int Power
{
get
{
return 3;
}
}
public Bishop( BChessboard board, ChessColor color, Point2D position ) : base( board, color, position )
{
}
public override void InitializePiece()
{
m_Piece = new ChessMobile( this );
m_Piece.Name = string.Format( "Bishop [{0}]", m_Color.ToString() );
switch ( m_BChessboard.ChessSet )
{
case ChessSet.Classic : CreateClassic();
break;
case ChessSet.Fantasy : CreateFantasy();
break;
case ChessSet.FantasyGiant : CreateFantasyGiant();
break;
case ChessSet.Animal : CreateAnimal();
break;
case ChessSet.Undead : CreateUndead();
break;
}
}
private void CreateUndead()
{
m_MoveSound = 415;
m_CaptureSound = 1004;
m_DeathSound = 1005;
m_Piece.BodyValue = 78; // Liche
m_Piece.Hue = Hue;
}
private void CreateAnimal()
{
m_MoveSound = 858;
m_CaptureSound = 616;
m_DeathSound = 623;
m_Piece.BodyValue = 80; // Giant toad
m_Piece.Hue = Hue;
}
private void CreateFantasyGiant()
{
m_MoveSound = 373;
m_CaptureSound = 372;
m_DeathSound = 376;
m_Piece.BodyValue = 316; // Wanderer of the void
m_Piece.Hue = Hue;
}
private void CreateFantasy()
{
m_MoveSound = 579;
m_CaptureSound = 283;
m_DeathSound = 250;
m_Piece.BodyValue = 124; // Evil mage
m_Piece.Hue = Hue;
}
private void CreateClassic()
{
m_MoveSound = 251;
m_CaptureSound = 773;
m_DeathSound = 1063;
m_Piece.Female = false;
m_Piece.BodyValue = 0x190;
if ( m_BChessboard.OverrideMinorHue )
m_Piece.Hue = Hue;
else
m_Piece.Hue = m_BChessboard.SkinHue;
Item item = null;
item = new HoodedShroudOfShadows( Hue );
item.Name = "Bishop's Robe";
m_Piece.AddItem( item );
item = new Boots( MinorHue );
m_Piece.AddItem( item );
item = new QuarterStaff();
item.Hue = MinorHue;
m_Piece.AddItem( item );
}
public override bool CanMoveTo(Point2D newLocation, ref string err)
{
if ( ! base.CanMoveTo (newLocation, ref err) )
return false;
int dx = newLocation.X - m_Position.X;
int dy = newLocation.Y - m_Position.Y;
if ( Math.Abs( dx ) != Math.Abs( dy ) )
{
err = "Bishops can move only on diagonals";
return false; // Not a diagonal movement
}
int xDirection = dx > 0 ? 1 : -1;
int yDirection = dy > 0 ? 1 : -1;
if ( Math.Abs( dx ) > 1 )
{
// Verify that the path to target is empty
for ( int i = 1; i < Math.Abs( dx ); i++ ) // Skip the bishop square and stop before target
{
int xOffset = xDirection * i;
int yOffset = yDirection * i;
if ( m_BChessboard[ m_Position.X + xOffset, m_Position.Y + yOffset ] != null )
{
err = "Bishops can't move over other pieces";
return false;
}
}
}
// Verify target piece
BaseChessPiece piece = m_BChessboard[ newLocation ];
if ( piece == null || piece.Color != m_Color )
{
return true;
}
else
{
err = "You can't capture pieces of your own color";
return false;
}
}
public override ArrayList GetMoves(bool capture)
{
ArrayList moves = new ArrayList();
int[] xDirection = new int[] { -1, 1, -1, 1 };
int[] yDirection = new int[] { -1, 1, 1, -1 };
for ( int i = 0; i < 4; i++ )
{
int xDir = xDirection[ i ];
int yDir = yDirection[ i ];
int offset = 1;
while ( true )
{
Point2D p = new Point2D( m_Position.X + offset * xDir, m_Position.Y + offset * yDir );
if ( ! m_BChessboard.IsValid( p ) )
break;
BaseChessPiece piece = m_BChessboard[ p ];
if ( piece == null )
{
moves.Add( p );
offset++;
continue;
}
if ( capture && piece.Color != m_Color )
{
moves.Add( p );
break;
}
break;
}
}
return moves;
}
}
}

View File

@@ -0,0 +1,240 @@
using System;
using System.Collections;
using Server;
using Server.Items;
namespace Arya.Chess
{
public class King : BaseChessPiece
{
private int m_CheckSound;
private int m_CheckMateSound;
public override int Power
{
get
{
return 100; // Useless
}
}
public King( BChessboard board, ChessColor color, Point2D position ) : base( board, color, position )
{
}
public override void InitializePiece()
{
m_Piece = new ChessMobile( this );
m_Piece.Name = string.Format( "King [{0}]", m_Color.ToString() );
switch ( m_BChessboard.ChessSet )
{
case ChessSet.Classic : CreateClassic();
break;
case ChessSet.Fantasy : CreateFantasy();
break;
case ChessSet.FantasyGiant : CreateFantasyGiant();
break;
case ChessSet.Animal : CreateAnimal();
break;
case ChessSet.Undead : CreateUndead();
break;
}
}
private void CreateUndead()
{
m_MoveSound = 1163;
m_CaptureSound = 1162;
m_DeathSound = 361;
m_CheckSound = 772;
m_CheckMateSound = 716;
m_Piece.BodyValue = 148; // Skeletal mage
m_Piece.Hue = Hue;
}
private void CreateAnimal()
{
m_MoveSound = 95;
m_CaptureSound = 1223;
m_DeathSound = 98;
m_CheckSound = 98;
m_CheckMateSound = 99;
m_Piece.BodyValue = 213; // Polar bear
m_Piece.Hue = Hue;
}
private void CreateFantasyGiant()
{
m_MoveSound = 1152;
m_CaptureSound = 1150;
m_DeathSound = 0;
m_CheckSound = 1152;
m_CheckMateSound = 1149;
m_Piece.BodyValue = 311; // Shadow knight
m_Piece.Hue = Hue;
}
private void CreateFantasy()
{
m_MoveSound = 610;
m_CaptureSound = 606;
m_DeathSound = 0;
m_CheckSound = 604;
m_CheckMateSound = 613;
m_Piece.BodyValue = 767; // Betrayer
m_Piece.Hue = Hue;
}
private void CreateClassic()
{
m_MoveSound = 1055;
m_CaptureSound = 1068;
m_DeathSound = 0;
m_CheckSound = 1086;
m_CheckMateSound = 1088;
m_Piece.Female = false;
m_Piece.BodyValue = 0x190;
if ( m_BChessboard.OverrideMinorHue )
m_Piece.Hue = Hue;
else
m_Piece.Hue = m_BChessboard.SkinHue;
m_Piece.AddItem( new ShortHair( m_BChessboard.OverrideMinorHue ? Hue : m_BChessboard.HairHue ) );
Item item = null;
item = new Boots( MinorHue );
m_Piece.AddItem( item );
item = new LongPants( Hue );
m_Piece.AddItem( item );
item = new FancyShirt( Hue );
m_Piece.AddItem( item );
item = new Doublet( MinorHue );
m_Piece.AddItem( item );
item = new Cloak( MinorHue );
m_Piece.AddItem( item );
item = new Scepter();
item.Hue = MinorHue;
m_Piece.AddItem( item );
}
public override bool CanMoveTo(Point2D newLocation, ref string err)
{
if ( ! base.CanMoveTo (newLocation, ref err) )
return false;
// Verify if this is a castle
BaseChessPiece rook = m_BChessboard[ newLocation ];
if ( rook is Rook && rook.Color == m_Color )
{
// Trying to castle
return m_BChessboard.AllowCastle( this, rook, ref err );
}
int dx = newLocation.X - m_Position.X;
int dy = newLocation.Y - m_Position.Y;
if ( Math.Abs( dx ) > 1 || Math.Abs( dy ) > 1 )
{
err = "The can king can move only 1 tile at a time";
return false; // King can move only 1 tile away from its position
}
// Verify target piece
BaseChessPiece piece = m_BChessboard[ newLocation ];
if ( piece == null || piece.Color != m_Color )
{
return true;
}
else
{
err = "You can't capture pieces of your same color";
return false;
}
}
public override ArrayList GetMoves(bool capture)
{
ArrayList moves = new ArrayList();
for ( int dx = -1; dx <= 1; dx++ )
{
for ( int dy = -1; dy <= 1; dy++ )
{
if ( dx == 0 && dy == 0 )
continue; // Can't move to same spot
Point2D p = new Point2D( m_Position.X + dx, m_Position.Y + dy );
if ( ! m_BChessboard.IsValid( p ) )
continue;
BaseChessPiece piece = m_BChessboard[ p ];
if ( piece == null )
moves.Add( p );
else if ( capture && piece.Color != m_Color )
moves.Add( p );
}
}
return moves;
}
public override bool IsCastle(Point2D loc)
{
Rook rook = m_BChessboard[ loc ] as Rook;
string err = null;
return rook != null && rook.Color == m_Color && m_BChessboard.AllowCastle( this, rook, ref err );
}
public void EndCastle( Point2D location )
{
m_HasMoved = true;
m_Move = new Move( this, location );
Point2D worldLocation = m_BChessboard.BoardToWorld( location );
m_Piece.GoTo( worldLocation );
}
public void PlayCheck()
{
m_BChessboard.PlaySound( m_Piece, m_CheckSound );
m_Piece.Say( "*CHECK*" );
}
public void PlayCheckMate()
{
m_BChessboard.PlaySound( m_Piece, m_CheckMateSound );
m_Piece.Say( "CHECKMATE" );
}
public void PlayStaleMate()
{
m_BChessboard.PlaySound( m_Piece, m_CheckSound );
m_Piece.Say( "STALEMATE" );
}
}
}

View File

@@ -0,0 +1,209 @@
using System;
using System.Collections;
using Server;
using Server.Items;
namespace Arya.Chess
{
public class Knight : BaseChessPiece
{
public static int GetGumpID( ChessColor color )
{
return color == ChessColor.Black ? 2342 : 2335;
}
public override int Power
{
get
{
return 3;
}
}
public Knight( BChessboard board, ChessColor color, Point2D position ) : base( board, color, position )
{
}
public override void InitializePiece()
{
m_Piece = new ChessMobile( this );
m_Piece.Name = string.Format( "Knight [{0}]", m_Color.ToString() );
switch ( m_BChessboard.ChessSet )
{
case ChessSet.Classic : CreateClassic();
break;
case ChessSet.Fantasy : CreateFantasy();
break;
case ChessSet.FantasyGiant : CreateFantasyGiant();
break;
case ChessSet.Animal : CreateAnimal();
break;
case ChessSet.Undead : CreateUndead();
break;
}
}
private void CreateUndead()
{
m_MoveSound = 588;
m_CaptureSound = 1164;
m_DeathSound = 416;
m_Piece.Female = false;
m_Piece.BodyValue = 0x190;
m_Piece.AddItem( new HoodedShroudOfShadows( Hue ) );
Server.Mobiles.SkeletalMount mount = new Server.Mobiles.SkeletalMount();
mount.Hue = MinorHue;
mount.Rider = m_Piece;
m_Piece.Direction = Facing;
}
private void CreateAnimal()
{
m_MoveSound = 183;
m_CaptureSound = 1011;
m_DeathSound = 185;
m_Piece.BodyValue = 292; // Pack llama
m_Piece.Hue = Hue;
}
private void CreateFantasyGiant()
{
m_MoveSound = 875;
m_CaptureSound = 378;
m_DeathSound = 879;
m_Piece.BodyValue = 315; // Flesh renderer
m_Piece.Hue = Hue;
}
private void CreateFantasy()
{
m_MoveSound = 762;
m_CaptureSound = 758;
m_DeathSound = 759;
m_Piece.BodyValue = 101; // Centaur
m_Piece.Hue = Hue;
}
private void CreateClassic()
{
m_MoveSound = 588;
m_CaptureSound = 168;
m_DeathSound = 170;
m_Piece.Female = false;
m_Piece.BodyValue = 0x190;
if ( m_BChessboard.OverrideMinorHue )
m_Piece.Hue = Hue;
else
m_Piece.Hue = m_BChessboard.SkinHue;
m_Piece.AddItem( new PonyTail( m_BChessboard.OverrideMinorHue ? Hue : m_BChessboard.HairHue ) );
Item item = null;
item = new PlateLegs();
item.Hue = Hue;
m_Piece.AddItem( item );
item = new PlateChest();
item.Hue = Hue;
m_Piece.AddItem( item );
item = new PlateArms();
item.Hue = Hue;
m_Piece.AddItem( item );
item = new PlateGorget();
item.Hue = Hue;
m_Piece.AddItem( item );
item = new PlateGloves();
item.Hue = Hue;
m_Piece.AddItem( item );
item = new Doublet( MinorHue );
m_Piece.AddItem( item );
item = new Lance();
item.Hue = MinorHue;
m_Piece.AddItem( item );
Server.Mobiles.Horse horse = new Server.Mobiles.Horse();
horse.BodyValue = 200;
horse.Hue = MinorHue;
horse.Rider = m_Piece;
m_Piece.Direction = Facing;
}
public override bool CanMoveTo(Point2D newLocation, ref string err)
{
if ( ! base.CanMoveTo (newLocation, ref err) )
return false;
// Care only about absolutes for knights
int dx = Math.Abs( newLocation.X - m_Position.X );
int dy = Math.Abs( newLocation.Y - m_Position.Y );
if ( ! ( ( dx == 1 && dy == 2 ) || ( dx == 2 && dy == 1 ) ) )
{
err = "Knights can only make L shaped moves (2-3 tiles length)";
return false; // Wrong move
}
// Verify target piece
BaseChessPiece piece = m_BChessboard[ newLocation ];
if ( piece == null || piece.Color != m_Color )
return true;
else
{
err = "You can't capture pieces of your same color";
return false;
}
}
public override ArrayList GetMoves(bool capture)
{
ArrayList moves = new ArrayList();
for ( int dx = -2; dx <= 2; dx++ )
{
for ( int dy = -2; dy <= 2; dy++ )
{
if ( ! ( ( Math.Abs( dx ) == 1 && Math.Abs( dy ) == 2 ) || ( Math.Abs( dx ) == 2 && Math.Abs( dy ) == 1 ) ) )
continue;
Point2D p = new Point2D( m_Position.X + dx, m_Position.Y + dy );
if ( ! m_BChessboard.IsValid( p ) )
continue;
BaseChessPiece piece = m_BChessboard[ p ];
if ( piece == null )
moves.Add( p );
else if ( capture && piece.Color != m_Color )
moves.Add( p );
}
}
return moves;
}
}
}

View File

@@ -0,0 +1,348 @@
using System;
using System.Collections;
using Server;
using Server.Items;
namespace Arya.Chess
{
public class Pawn : BaseChessPiece
{
public static int GetGumpID( ChessColor color )
{
return color == ChessColor.Black ? 2343 : 2336;
}
public override int Power
{
get
{
return 1;
}
}
public override bool AllowEnPassantCapture
{
get
{
return m_EnPassantRisk;
}
set { m_EnPassantRisk = value; }
}
private bool m_EnPassantRisk = false;
public Pawn( BChessboard board, ChessColor color, Point2D position ) : base( board, color, position )
{
}
public override void InitializePiece()
{
m_Piece = new ChessMobile( this );
m_Piece.Name = string.Format( "Pawn [{0}]", m_Color.ToString() );
switch ( m_BChessboard.ChessSet )
{
case ChessSet.Classic : CreateClassic();
break;
case ChessSet.Fantasy : CreateFantasy();
break;
case ChessSet.FantasyGiant : CreateFantasyGiant();
break;
case ChessSet.Animal : CreateAnimal();
break;
case ChessSet.Undead : CreateUndead();
break;
}
}
private void CreateUndead()
{
m_MoveSound = 451;
m_CaptureSound = 1169;
m_DeathSound = 455;
m_Piece.BodyValue = 56; // Skeleton
m_Piece.Hue = Hue;
}
private void CreateAnimal()
{
m_MoveSound = 1217;
m_CaptureSound = 226;
m_DeathSound = 228;
m_Piece.BodyValue = 221; // Walrus
m_Piece.Hue = Hue;
}
private void CreateFantasyGiant()
{
m_MoveSound = 709;
m_CaptureSound = 712;
m_DeathSound = 705;
m_Piece.BodyValue = 303; // Devourer
m_Piece.Hue = Hue;
}
private void CreateFantasy()
{
m_MoveSound = 408;
m_CaptureSound = 927;
m_DeathSound = 411;
m_Piece.BodyValue = 776; // Horde Minion
m_Piece.Hue = Hue;
}
private void CreateClassic()
{
m_MoveSound = 821;
m_CaptureSound = 1094;
m_DeathSound = 1059;
m_Piece.Female = false;
m_Piece.BodyValue = 0x190;
if ( m_BChessboard.OverrideMinorHue )
m_Piece.Hue = Hue;
else
m_Piece.Hue = m_BChessboard.SkinHue;
m_Piece.AddItem( new ShortHair( m_BChessboard.OverrideMinorHue ? Hue : m_BChessboard.HairHue ) );
Item item = null;
item = new ChainChest();
item.Hue = Hue;
m_Piece.AddItem( item );
item = new ChainLegs();
item.Hue = MinorHue;
m_Piece.AddItem( item );
item = new Boots();
item.Hue = Hue;
m_Piece.AddItem( item );
item = new Buckler();
item.Hue = MinorHue;
m_Piece.AddItem( item );
item = new Scimitar();
item.Hue = MinorHue;
m_Piece.AddItem( item );
}
public override bool CanMoveTo(Point2D newLocation, ref string err)
{
if ( ! base.CanMoveTo (newLocation, ref err) )
return false;
if ( newLocation.X == m_Position.X )
{
// Regular move
int dy = newLocation.Y - m_Position.Y;
// Trying to move more than two pieces, or more than one piece after the first move
if ( Math.Abs( dy ) > 2 || ( Math.Abs( dy ) ) > 1 && m_HasMoved )
{
err = "You can move only 1 tile at a time, or 2 if it's the pawn's first move";
return false;
}
// Verify direction
if ( m_Color == ChessColor.Black && dy < 0 )
{
err = "You can't move pawns backwards";
return false;
}
if ( m_Color == ChessColor.White && dy > 0 )
{
err = "You can't move pawns backwards";
return false;
}
// Verify if there are pieces (any) on the target squares
for ( int i = 1; i <= Math.Abs( dy ); i++ )
{
int offset = m_Color == ChessColor.Black ? i : -i;
if ( m_BChessboard[ m_Position.X, m_Position.Y + offset ] != null )
{
err = "Pawns can't move over other pieces, and capture in diagonal";
return false;
}
}
return true;
}
else
{
// Trying to capture?
int dx = newLocation.X - m_Position.X;
int dy = newLocation.Y - m_Position.Y;
if ( Math.Abs( dx ) != 1 || Math.Abs( dy ) != 1 )
{
err = "Pawns move straight ahead, or capture in diagonal only";
return false;
}
// Verify direction
if ( m_Color == ChessColor.Black && dy < 0 )
{
err = "You can't move pawns backwards";
return false;
}
if ( m_Color == ChessColor.White && dy > 0 )
{
err = "You can't move pawns backwards";
return false;
}
// Verify if there's a piece to capture
BaseChessPiece piece = m_BChessboard[ newLocation ];
if ( piece != null && piece.Color != m_Color )
return true;
else
{
// Verify for an en passant capture
Point2D passant = new Point2D( m_Position.X + dx, m_Position.Y );
BaseChessPiece target = m_BChessboard[ passant ];
if ( target != null && target.AllowEnPassantCapture && target.Color != m_Color )
return true;
else
{
err = "You must capture a piece when moving in diagonal";
return false;
}
}
}
}
public override ArrayList GetMoves(bool capture)
{
ArrayList moves = new ArrayList();
int direction = m_Color == ChessColor.Black ? 1 : -1;
Point2D step = new Point2D( m_Position.X, m_Position.Y + direction );
if ( m_BChessboard.IsValid( step ) && m_BChessboard[ step ] == null )
{
moves.Add( step );
// Verify if this pawn can make a second step
step.Y += direction;
if ( ! m_HasMoved && m_BChessboard[ step ] == null )
moves.Add( step ); // Point2D is a value type
}
if ( capture )
{
// Verify captures too
Point2D p1 = new Point2D( m_Position.X + 1, m_Position.Y + direction );
Point2D p2 = new Point2D( m_Position.X - 1, m_Position.Y + direction );
if ( m_BChessboard.IsValid( p1 ) )
{
BaseChessPiece piece1 = m_BChessboard[ p1 ];
if ( piece1 != null && piece1.Color != m_Color )
moves.Add( p1 );
else
{
Point2D pass1 = new Point2D( m_Position.X - 1, m_Position.Y );
if ( m_BChessboard.IsValid( pass1 ) )
{
BaseChessPiece passpiece1 = m_BChessboard[ pass1 ];
if ( passpiece1 != null && passpiece1.Color != m_Color && passpiece1.AllowEnPassantCapture )
moves.Add( p1 );
}
}
}
if ( m_BChessboard.IsValid( p2 ) )
{
BaseChessPiece piece2 = m_BChessboard[ p2 ];
if ( piece2 != null && piece2.Color != m_Color )
moves.Add( p2 );
else
{
Point2D pass2 = new Point2D( m_Position.X + 1, m_Position.Y );
if ( m_BChessboard.IsValid( p2 ) )
{
BaseChessPiece passpiece2 = m_BChessboard[ pass2 ];
if ( passpiece2 != null && passpiece2.AllowEnPassantCapture && passpiece2.Color != m_Color )
moves.Add( pass2 );
}
}
}
}
return moves;
}
/// <summary>
/// States whether this pawn has reached the other side of the board and should be promoted
/// </summary>
public bool ShouldBePromoted
{
get
{
if ( m_Color == ChessColor.White && m_Position.Y == 0 )
return true;
else if ( m_Color == ChessColor.Black && m_Position.Y == 7 )
return true;
else
return false;
}
}
public override void MoveTo(Move move)
{
// Set En Passant flags
int dy = Math.Abs( move.To.Y - m_Position.Y );
if ( ! m_HasMoved && dy == 2 )
{
m_EnPassantRisk = true;
}
base.MoveTo (move);
}
public override BaseChessPiece GetCaptured(Point2D at, ref bool enpassant)
{
BaseChessPiece basePiece = base.GetCaptured (at, ref enpassant);
if ( basePiece != null && basePiece.Color != m_Color )
return basePiece; // Normal capture
if ( at.X == m_Position.X )
return null; // Straight movement
Point2D p = new Point2D( at.X, m_Position.Y );
basePiece = m_BChessboard[ p ];
if ( basePiece != null && basePiece.Color != m_Color )
{
enpassant = true;
return basePiece;
}
else
return null;
}
}
}

View File

@@ -0,0 +1,251 @@
using System;
using System.Collections;
using Server;
using Server.Items;
namespace Arya.Chess
{
/// <summary>
/// Summary description for Queen.
/// </summary>
public class Queen : BaseChessPiece
{
public static int GetGumpID( ChessColor color )
{
return color == ChessColor.Black ? 2344 : 2377;
}
public override int Power
{
get
{
return 9;
}
}
public Queen( BChessboard board, ChessColor color, Point2D position ) : base( board, color, position )
{
}
public override void InitializePiece()
{
m_Piece = new ChessMobile( this );
m_Piece.Name = string.Format( "Queen [{0}]", m_Color.ToString() );
switch ( m_BChessboard.ChessSet )
{
case ChessSet.Classic : CreateClassic();
break;
case ChessSet.Fantasy : CreateFantasy();
break;
case ChessSet.FantasyGiant : CreateFantasyGiant();
break;
case ChessSet.Animal : CreateAnimal();
break;
case ChessSet.Undead: CreateUndead();
break;
}
}
private void CreateUndead()
{
m_MoveSound = 896;
m_CaptureSound = 382;
m_DeathSound = 1202;
m_Piece.BodyValue = 310; // Wailing banshee
m_Piece.Hue = Hue;
}
private void CreateAnimal()
{
m_MoveSound = 123;
m_CaptureSound = 120;
m_DeathSound = 124;
m_Piece.BodyValue = 216; // Cow
m_Piece.Hue = Hue;
}
private void CreateFantasyGiant()
{
m_MoveSound = 883;
m_CaptureSound = 880;
m_DeathSound = 888;
m_Piece.BodyValue = 174; // Semidar
m_Piece.Hue = Hue;
}
private void CreateFantasy()
{
m_MoveSound = 1200;
m_CaptureSound = 1201;
m_DeathSound = 1202;
m_Piece.BodyValue = 149; // Succubus
m_Piece.Hue = Hue;
}
private void CreateClassic()
{
m_MoveSound = 823;
m_CaptureSound = 824;
m_DeathSound = 814;
m_Piece.Female = true;
m_Piece.BodyValue = 0x191;
if ( m_BChessboard.OverrideMinorHue )
m_Piece.Hue = Hue;
else
m_Piece.Hue = m_BChessboard.SkinHue;
m_Piece.AddItem( new LongHair( m_BChessboard.OverrideMinorHue ? Hue : m_BChessboard.HairHue ) );
Item item = null;
item = new FancyDress( Hue );
m_Piece.AddItem( item );
item = new Sandals( MinorHue );
m_Piece.AddItem( item );
item = new Scepter();
item.Hue = MinorHue;
m_Piece.AddItem( item );
}
public override bool CanMoveTo(Point2D newLocation, ref string err)
{
if ( ! base.CanMoveTo (newLocation, ref err) )
return false;
int dx = newLocation.X - m_Position.X;
int dy = newLocation.Y - m_Position.Y;
if ( dx == 0 || dy == 0 )
{
// Straight movement
if ( Math.Abs( dx ) > 1 ) // If it's just 1 step no need to check for intermediate pieces
{
int direction = dx > 0 ? 1 : -1;
// Moving along X axis
for ( int i = 1; i < Math.Abs( dx ); i++ )
{
int offset = direction * i;
if ( m_BChessboard[ m_Position.X + offset, m_Position.Y ] != null )
{
err = "The queen can't move over other pieces";
return false;
}
}
}
else if ( Math.Abs( dy ) > 1 )
{
// Moving along Y axis
int direction = dy > 0 ? 1 : -1;
for ( int i = 1; i < Math.Abs( dy ); i++ )
{
int offset = direction * i;
if ( m_BChessboard[ m_Position.X, m_Position.Y + offset ] != null )
{
err = "The queen can't move over other pieces";
return false;
}
}
}
}
else
{
// Diagonal movement
if ( Math.Abs( dx ) != Math.Abs( dy ) )
{
err = "The queen moves only on straight lines or diagonals";
return false; // Uneven
}
if ( Math.Abs( dx ) > 1 )
{
int xDirection = dx > 0 ? 1 : -1;
int yDirection = dy > 0 ? 1 : -1;
for ( int i = 1; i < Math.Abs( dx ); i++ )
{
int xOffset = xDirection * i;
int yOffset = yDirection * i;
if ( m_BChessboard[ m_Position.X + xOffset, m_Position.Y + yOffset ] != null )
{
err = "The queen can't move over other pieces";
return false;
}
}
}
}
// Verify target piece
BaseChessPiece piece = m_BChessboard[ newLocation ];
if ( piece == null || piece.Color != m_Color )
return true;
else
{
err = "You can't capture pieces of your same color";
return false;
}
}
public override ArrayList GetMoves(bool capture)
{
ArrayList moves = new ArrayList();
int[] xDirection = new int[] { -1, 1, -1, 1, 1, -1, 0, 0 };
int[] yDirection = new int[] { -1, 1, 1, -1, 0, 0, 1, -1 };
for ( int i = 0; i < 8; i++ )
{
int xDir = xDirection[ i ];
int yDir = yDirection[ i ];
int offset = 1;
while ( true )
{
Point2D p = new Point2D( m_Position.X + offset * xDir, m_Position.Y + offset * yDir );
if ( ! m_BChessboard.IsValid( p ) )
break;
BaseChessPiece piece = m_BChessboard[ p ];
if ( piece == null )
{
moves.Add( p );
offset++;
continue;
}
if ( capture && piece.Color != m_Color )
{
moves.Add( p );
break;
}
break;
}
}
return moves;
}
}
}

View File

@@ -0,0 +1,286 @@
using System;
using System.Collections;
using Server;
using Server.Items;
namespace Arya.Chess
{
public class Rook : BaseChessPiece
{
private bool m_Castle;
public static int GetGumpID( ChessColor color )
{
return color == ChessColor.Black ? 2340 : 2333;
}
public override int Power
{
get
{
return 5;
}
}
public Rook( BChessboard board, ChessColor color, Point2D position ) : base( board, color, position )
{
}
public override void InitializePiece()
{
m_Piece = new ChessMobile( this );
m_Piece.Name = string.Format( "Rook [{0}]", m_Color.ToString() );
switch ( m_BChessboard.ChessSet )
{
case ChessSet.Classic : CreateClassic();
break;
case ChessSet.Fantasy : CreateFantasy();
break;
case ChessSet.FantasyGiant : CreateFantasyGiant();
break;
case ChessSet.Animal : CreateAnimal();
break;
case ChessSet.Undead : CreateUndead();
break;
}
}
private void CreateUndead()
{
m_MoveSound = 880;
m_CaptureSound = 357;
m_DeathSound = 1156;
m_Piece.BodyValue = 154; // Mummy
m_Piece.Hue = Hue;
}
private void CreateAnimal()
{
m_MoveSound = 159;
m_CaptureSound = 158;
m_DeathSound = 162;
m_Piece.BodyValue = 29; // Gorilla
m_Piece.Hue = Hue;
}
private void CreateFantasyGiant()
{
m_MoveSound = 767;
m_CaptureSound = 367;
m_DeathSound = 371;
m_Piece.BodyValue = 312; // Abysmal Horror
m_Piece.Hue = Hue;
}
private void CreateFantasy()
{
m_MoveSound = 461;
m_CaptureSound = 463;
m_DeathSound = 465;
m_Piece.Female = false;
m_Piece.BodyValue = 55; // Troll
m_Piece.Hue = Hue;
}
private void CreateClassic()
{
m_MoveSound = 287;
m_CaptureSound = 268;
m_DeathSound = 269;
m_Piece.Female = false;
m_Piece.BodyValue = 14;
m_Piece.Hue = Hue;
}
public override bool CanMoveTo(Point2D newLocation, ref string err)
{
if ( ! base.CanMoveTo (newLocation, ref err) )
return false;
// Verify if this is a castle
BaseChessPiece king = m_BChessboard[ newLocation ];
if ( king is King && king.Color == m_Color )
{
// Trying to castle
return m_BChessboard.AllowCastle( king, this, ref err );
}
int dx = newLocation.X - m_Position.X;
int dy = newLocation.Y - m_Position.Y;
// Rooks can only move in one direction
if ( dx != 0 && dy != 0 )
{
err = "Rooks can only move on straight lines";
return false;
}
if ( dx != 0 )
{
// Moving on the X axis
int direction = dx > 0 ? 1 : -1;
if ( Math.Abs( dx ) > 1 )
{
// Verify that the cells in between are empty
for ( int i = 1; i < Math.Abs( dx ); i++ ) // Start 1 tile after the rook, and stop one tile before destination
{
int offset = direction * i;
if ( m_BChessboard[ m_Position.X + offset, m_Position.Y ] != null )
{
err = "Rooks can't move over pieces";
return false; // There's a piece on the
}
}
}
// Verify if there's a piece to each at the end
BaseChessPiece piece = m_BChessboard[ newLocation ];
if ( piece == null || piece.Color != m_Color )
return true;
else
{
err = "You can't capture pieces of your same color";
return false;
}
}
else
{
// Moving on the Y axis
int direction = dy > 0 ? 1 : -1;
if ( Math.Abs( dy ) > 1 )
{
// Verify that the cells in between are empty
for ( int i = 1; i < Math.Abs( dy ); i++ )
{
int offset = direction * i;
if ( m_BChessboard[ m_Position.X, m_Position.Y + offset ] != null )
{
err = "The rook can't move over other pieces";
return false; // Piece on the way
}
}
}
// Verify for piece at end
BaseChessPiece piece = m_BChessboard[ newLocation ];
if ( piece == null || piece.Color != m_Color )
return true;
else
{
err = "You can't capture pieces of your same color";
return false;
}
}
}
public override ArrayList GetMoves(bool capture)
{
ArrayList moves = new ArrayList();
int[] xDirection = new int[] { -1, 1, 0, 0 };
int[] yDirection = new int[] { 0, 0, 1, -1 };
for ( int i = 0; i < 4; i++ )
{
int xDir = xDirection[ i ];
int yDir = yDirection[ i ];
int offset = 1;
while ( true )
{
Point2D p = new Point2D( m_Position.X + offset * xDir, m_Position.Y + offset * yDir );
if ( ! m_BChessboard.IsValid( p ) )
break;
BaseChessPiece piece = m_BChessboard[ p ];
if ( piece == null )
{
moves.Add( p );
offset++;
continue;
}
if ( capture && piece.Color != m_Color )
{
moves.Add( p );
break;
}
break;
}
}
return moves;
}
public override bool IsCastle(Point2D loc)
{
King king = m_BChessboard[ loc ] as King;
string err = null;
return king != null && king.Color == m_Color && m_BChessboard.AllowCastle( king, this, ref err );
}
public void Castle()
{
m_Castle = true;
int dx = 0;
if ( m_Position.X == 0 )
dx = 3;
else if ( m_Position.X == 7 )
dx = -2;
Move move = new Move( this, new Point2D( m_Position.X + dx, m_Position.Y ) );
MoveTo( move );
}
public override void OnMoveOver()
{
if ( ! m_Castle )
base.OnMoveOver ();
else
{
m_Castle = false;
m_BChessboard.ApplyMove( m_Move );
King king = m_BChessboard.GetKing( m_Color ) as King;
int dx = 0;
if ( m_Position.X == 3 )
dx = -2;
else
dx = 2;
king.EndCastle( new Point2D( king.Position.X + dx, king.Position.Y ) );
}
}
}
}

View File

@@ -0,0 +1,402 @@
using System;
using System.Collections;
using Server;
using Server.Items;
namespace Arya.Chess
{
/// <summary>
/// Defines the two colors used in the chess game
/// </summary>
public enum ChessColor
{
Black,
White
}
/// <summary>
/// This abstract class defines the basic features of a chess piece
/// </summary>
public abstract class BaseChessPiece
{
#region Variables
/// <summary>
/// This represents the NPC that corresponds to this chess piece
/// </summary>
protected ChessMobile m_Piece;
/// <summary>
/// The BChessboard object parent of this chess piece
/// </summary>
protected BChessboard m_BChessboard;
/// <summary>
/// The color of this piece
/// </summary>
protected ChessColor m_Color;
/// <summary>
/// The position of the chess piece on the board
/// </summary>
protected Point2D m_Position;
/// <summary>
/// Specifies if this piece has been killed
/// </summary>
protected bool m_Dead = false;
/// <summary>
/// Specifies if the piece has already been moved or not
/// </summary>
protected bool m_HasMoved = false;
/// <summary>
/// The move this piece is performing
/// </summary>
protected Move m_Move;
/// <summary>
/// The sound made when the piece moves
/// </summary>
protected int m_MoveSound;
/// <summary>
/// The sound made when the piece captures
/// </summary>
protected int m_CaptureSound;
/// <summary>
/// The sound made when the piece is captured
/// </summary>
protected int m_DeathSound;
#endregion
#region Properties
/// <summary>
/// Gets the NPC corresponding to this chess piece
/// </summary>
public ChessMobile Piece
{
get { return m_Piece; }
}
/// <summary>
/// Gets the color of this piece
/// </summary>
public ChessColor Color
{
get { return m_Color; }
}
/// <summary>
/// Gets the color of the enemy
/// </summary>
public ChessColor EnemyColor
{
get
{
if ( m_Color == ChessColor.Black )
return ChessColor.White;
else
return ChessColor.Black;
}
}
/// <summary>
/// Gets or sets the position of this chess piece.
/// This does NOT move the chess piece on the chess board
/// </summary>
public Point2D Position
{
get { return m_Position; }
set { m_Position = value; }
}
/// <summary>
/// Gets the facing for the NPC when it's standing
/// </summary>
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;
}
}
}
/// <summary>
/// Gets the hue used to color items for this piece
/// </summary>
public virtual int Hue
{
get
{
if ( m_Color == ChessColor.Black )
return m_BChessboard.BlackHue;
else
return m_BChessboard.WhiteHue;
}
}
/// <summary>
/// Gets the opposite hue for this piece
/// </summary>
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;
}
}
/// <summary>
/// Gets the power value of this piece
/// </summary>
public abstract int Power
{
get;
}
/// <summary>
/// States whether this piece has already moved
/// </summary>
public virtual bool HasMoved
{
get { return m_HasMoved; }
}
/// <summary>
/// Specifies if this piece can be captured by a pawn en passant
/// </summary>
public virtual bool AllowEnPassantCapture
{
get { return false; }
set {}
}
#endregion
/// <summary>
/// Creates a new chess piece object
/// </summary>
/// <param name="board">The BChessboard object hosting this piece</param>
/// <param name="color">The color of this piece</param>
/// <param name="position">The initial position on the board</param>
public BaseChessPiece( BChessboard board, ChessColor color, Point2D position )
{
m_BChessboard = board;
m_Color = color;
m_Position = position;
CreatePiece();
}
#region NPC Creation
/// <summary>
/// Creates the NPC that will represent this piece and places it in the correct world location
/// </summary>
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 );
}
/// <summary>
/// Creates and initializes the chess piece NPC
/// </summary>
/// <returns></returns>
public abstract void InitializePiece();
/// <summary>
/// Rebuilds the NPC applying any changes made to the appearance
/// </summary>
public virtual void Rebuild()
{
Die( false );
CreatePiece();
m_Dead = false;
}
#endregion
#region Piece Movement
/// <summary>
/// Verifies if this piece can move to a specified location.
/// </summary>
/// <param name="newLocation">The new location</param>
/// <param name="err">Will hold the eventual error message</param>
/// <returns>True if the move is allowed, false otherwise.</returns>
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;
}
}
/// <summary>
/// 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.
/// </summary>
/// <param name="move">The move performed</param>
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 );
}
/// <summary>
/// This function is called by the NPC when its move is over
/// </summary>
public virtual void OnMoveOver()
{
m_BChessboard.OnMoveOver( m_Move );
m_Move = null;
m_Piece.Direction = Facing;
}
/// <summary>
/// Gets the list of possible moves this piece can perform
/// </summary>
/// <param name="capture">Specifies whether the moves should include squares where a piece would be captured</param>
/// <returns>An ArrayList objects of Point2D values</returns>
public abstract ArrayList GetMoves( bool capture );
/// <summary>
/// Gets the piece that this piece would capture when moving to a specific location.
/// This function assumes that the square can be reached.
/// </summary>
/// <param name="at">The target location with the potential capture</param>
/// <param name="enpassant">Will hold a value stating whether this move is made en passant</param>
/// <returns>A BaseChessPiece if a capture is possible, null otherwise</returns>
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;
}
/// <summary>
/// Verifies if a given move would be a castle
/// </summary>
/// <param name="loc">The target location</param>
/// <returns>True if the move is a castle</returns>
public virtual bool IsCastle( Point2D loc )
{
return false;
}
#endregion
#region Deletion and killing
/// <summary>
/// This function is invoked whenever a piece NPC is deleted
/// </summary>
public virtual void OnPieceDeleted()
{
if ( ! m_Dead )
{
m_BChessboard.OnStaffDelete();
}
}
/// <summary>
/// This function is invoked when the piece is captured and the NPC should be removed from the board
/// </summary>
/// <param name="sound">Specifies if to play the death sound</param>
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();
}
/// <summary>
/// Forces the deletion of this piece
/// </summary>
public virtual void ForceDelete()
{
if ( m_Piece != null && ! m_Piece.Deleted )
{
m_Dead = true;
m_Piece.Delete();
}
}
#endregion
}
}

View File

@@ -0,0 +1,889 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Server;
using Server.ContextMenus;
using Server.Gumps;
using Solaris.BoardGames;
namespace Server.Items
{
public enum BoardGameState
{
Disabled = 0,
Inactive = 1,
Pending = 2,
Recruiting = 3,
Active = 4,
GameOver = 5
}
//the main control object for a boardgame system. Each board game needs exactly one control object
public abstract class BoardGameControlItem : Item
{
public virtual string GameName{ get{ return "-UNDEFINED-"; } }
public virtual string GameDescription{ get{ return "-UNDEFINED-"; } }
public virtual string GameRules{ get{ return "-UNDEFINED-"; } }
public virtual bool CanCastSpells{ get{ return true; } }
public virtual bool CanUseSkills{ get{ return true; } }
public virtual bool CanUsePets{ get{ return true; } }
public virtual bool UseFromBackpack{ get{ return true; } }
public virtual TimeSpan WinDelay{ get{ return TimeSpan.Zero; } }
protected BoardGameState _State;
protected WinnerTimer _WinnerTimer;
protected EndGameTimer _EndGameTimer;
//valid distance from the control item
public virtual int UseRange{ get{ return 10; } }
public virtual int MinPlayers{ get{ return 0; } }
public virtual int MaxPlayers{ get{ return 0; } }
public int CurrentMaxPlayers;
protected int _CostToPlay;
//the list of all players participating in the game
protected List<Mobile> _Players;
//the list of all players pending a decision when interacting with the boardgame controller
protected List<Mobile> _PendingPlayers;
//the defined region where the game is taking place
public Rectangle3D GameZone;
protected Point3D _BoardOffset;
public Point3D BoardOffset{ get{ return _BoardOffset; } }
protected bool _SettingsReady;
public bool SettingsReady
{
get{ return _SettingsReady; }
set
{
_SettingsReady = value;
if( _SettingsReady && Players.Count == CurrentMaxPlayers && _State < BoardGameState.Active && _State != BoardGameState.Disabled )
{
InitializeGame();
}
}
}
[CommandProperty( AccessLevel.GameMaster )]
public Point3D BoardLocation
{
get
{
return new Point3D( X + _BoardOffset.X, Y + _BoardOffset.Y, Z + _BoardOffset.Z );
}
set
{
Point3D location = value;
_BoardOffset = new Point3D( location.X - X, location.Y - Y, location.Z - Z );
UpdatePosition();
}
}
protected Map _BoardMap;
[CommandProperty( AccessLevel.GameMaster )]
public Map BoardMap
{
get{ return _BoardMap; }
set
{
_BoardMap = value;
UpdatePosition();
}
}
[CommandProperty( AccessLevel.GameMaster )]
public bool ForceGameOver
{
get{ return false; }
set
{
if( value )
{
EndGame();
}
}
}
protected bool _AllowPlayerConfiguration;
[CommandProperty( AccessLevel.GameMaster )]
public bool AllowPlayerConfiguration
{
get{ return _AllowPlayerConfiguration; }
set
{
_AllowPlayerConfiguration = value;
if( _State != BoardGameState.Recruiting )
{
_SettingsReady = !value;
}
}
}
//these hold the height and width of the game board
protected int _BoardWidth;
protected int _BoardHeight;
[CommandProperty( AccessLevel.GameMaster )]
public virtual int BoardWidth
{
get
{
return _BoardWidth;
}
set
{
if( (int)_State <= (int)BoardGameState.Recruiting )
{
_BoardWidth = value;
ResetBoard();
}
}
}
[CommandProperty( AccessLevel.GameMaster )]
public virtual int BoardHeight
{
get
{
return _BoardHeight;
}
set
{
if( (int)_State <= (int)BoardGameState.Recruiting )
{
_BoardHeight = value;
ResetBoard();
}
}
}
//the list of all items used as background for the game board
protected List<GamePiece> _BackgroundItems;
protected BoardGameRegion _BoardGameRegion;
[CommandProperty( AccessLevel.GameMaster )]
public BoardGameState State
{
get
{
return _State;
}
set
{
_State = value;
InvalidateProperties();
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int CostToPlay
{
get{ return _CostToPlay; }
set
{
_CostToPlay = value;
InvalidateProperties();
}
}
public List<Mobile> Players
{
get
{
if( _Players == null )
{
_Players = new List<Mobile>();
}
return _Players;
}
}
public List<Mobile> PendingPlayers
{
get
{
if( _PendingPlayers == null )
{
_PendingPlayers = new List<Mobile>();
}
return _PendingPlayers;
}
}
public List<GamePiece> BackgroundItems
{
get
{
if( _BackgroundItems == null )
{
_BackgroundItems = new List<GamePiece>();
}
return _BackgroundItems;
}
}
//main constructor
public BoardGameControlItem() : base( 4006 ) //default itemid 4006: checkerboard
{
_AllowPlayerConfiguration = true;
CurrentMaxPlayers = MinPlayers;
InitializeControl();
}
//deserialization constructor
public BoardGameControlItem( Serial serial ) : base( serial )
{
}
//this method initializes the game control and connects it with this item
protected virtual void InitializeControl()
{
ResetBoard();
Movable = UseFromBackpack;
}
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
{
base.GetContextMenuEntries( from, list );
list.Add( new ViewBoardGameScoresEntry( from, this, 1 ) );
if( from.AccessLevel >= AccessLevel.GameMaster )
{
list.Add( new ResetBoardGameScoresEntry( from, this, 2 ) );
}
}
//this method builds the game board
public virtual void BuildBoard()
{
}
//this resets the gameboard and refreshes it
public virtual void ResetBoard()
{
WipeBoard();
BuildBoard();
}
protected virtual void PrimePlayers()
{
foreach( Mobile player in Players )
{
player.CloseGump( typeof( AwaitRecruitmentGump ) );
player.CloseGump( typeof( SelectStyleGump ) );
}
}
public virtual void WipeBoard()
{
foreach( GamePiece piece in BackgroundItems )
{
piece.BoardGameControlItem = null; //detach reference to this boardgame so that it doesn't wipe the board itself
piece.Delete();
}
if( _BoardGameRegion != null )
{
_BoardGameRegion.Unregister();
}
_BackgroundItems = null;
}
//this moves the players into the board, gives them the equipment they need, and starts the game
protected virtual void StartGame()
{
//define and clear the game field, then rebuild it
ResetBoard();
//move players into the board, give them game interface items, or otherwise get them set up
PrimePlayers();
}
public virtual void EndGame()
{
if( _WinnerTimer != null )
{
_WinnerTimer.Stop();
_WinnerTimer = null;
}
_PendingPlayers = null;
_SettingsReady = !_AllowPlayerConfiguration;
InvalidateProperties();
foreach( Mobile player in Players )
{
player.CloseGump( typeof( BoardGameGump ) );
}
}
protected void StartEndGameTimer( TimeSpan delay )
{
if( _EndGameTimer != null )
{
_EndGameTimer.Stop();
_EndGameTimer = null;
}
_EndGameTimer = new EndGameTimer( this, delay );
_EndGameTimer.Start();
}
//this triggers the actual engame detection
protected virtual void OnEndGameTimer()
{
if( _EndGameTimer != null )
{
_EndGameTimer.Stop();
_EndGameTimer = null;
}
}
protected virtual void AnnounceWinner()
{
_State = BoardGameState.GameOver;
if( _WinnerTimer == null )
{
_WinnerTimer = new WinnerTimer( this, WinDelay );
_WinnerTimer.Start();
}
}
//this method is called by the control item when a player doubleclicks it
public override void OnDoubleClick( Mobile from )
{
if( CanUse( from ) )
{
OnUse( from );
}
}
public virtual bool CanUse( Mobile from )
{
//if they've logged out
if( from.NetState == null )
{
return false;
}
if( UseFromBackpack )
{
if( !IsChildOf( from.Backpack ) )
{
from.SendMessage( "This must be in your backpack to use." );
return false;
}
}
else
{
if( !from.InRange( this, UseRange ) )
{
from.SendMessage( "You are out of range." );
return false;
}
}
return CheckRequirements( from );
}
public virtual bool CheckRequirements( Mobile from )
{
if( !CanUsePets && from.Followers > 0 )
{
from.SendMessage( "You are not allowed to have pets in this game." );
return false;
}
if( !CheckCost( from, false ) )
{
from.SendMessage( "You lack the gold to play this game." );
return false;
}
return true;
}
//this checks for money, and withdraws it if necessary
public bool CheckCost( Mobile from, bool withdraw )
{
if( CostToPlay == 0 )
{
return true;
}
Gold gold = (Gold)from.Backpack.FindItemByType( typeof( Gold ) );
if( gold == null || gold.Amount < CostToPlay )
{
Container bankbox = from.FindBankNoCreate();
if( bankbox != null )
{
gold = (Gold)bankbox.FindItemByType( typeof( Gold ) );
if( gold != null && gold.Amount >= CostToPlay )
{
if( withdraw )
{
bankbox.ConsumeTotal( typeof( Gold ), CostToPlay );
}
return true;
}
}
return false;
}
if( withdraw )
{
from.Backpack.ConsumeTotal( typeof( Gold ), CostToPlay );
}
return true;
}
//updates all game pieces position
public virtual void UpdatePosition()
{
if( _BoardMap == null || _BoardMap == Map.Internal )
{
_BoardMap = Map;
}
foreach( GamePiece piece in BackgroundItems )
{
piece.UpdatePosition();
}
if( _BoardGameRegion != null )
{
_BoardGameRegion.Unregister();
}
_BoardGameRegion = new BoardGameRegion( this );
_BoardGameRegion.Register();
}
//mouse-over properties info
public override void GetProperties( ObjectPropertyList list )
{
base.GetProperties( list );
list.Add( 1070722, "Status: " + Enum.GetName( typeof( BoardGameState ), _State ) ); //~1_NOTHING~
list.Add( 1060658, "Cost to play\t{0}", CostToPlay.ToString() ); // ~1_val~: ~2_val~
}
//this method is called when a successful OnDoubleClick method is performed
protected virtual void OnUse( Mobile from )
{
switch( _State )
{
case BoardGameState.Disabled:
{
DisabledGame( from );
break;
}
case BoardGameState.Inactive:
{
OfferNewGame( from );
break;
}
case BoardGameState.Pending:
{
GamePending( from );
break;
}
case BoardGameState.Recruiting:
{
OfferRecruiting( from );
break;
}
case BoardGameState.Active:
{
GameActive( from );
break;
}
case BoardGameState.GameOver:
{
GameOver( from );
break;
}
}
}
protected virtual void DisabledGame( Mobile from )
{
if( from.AccessLevel < AccessLevel.GameMaster )
{
from.SendMessage( "That game has been disabled by staff." );
}
}
protected virtual void OfferNewGame( Mobile from )
{
PendingPlayers.Add( from );
State = BoardGameState.Pending;
from.SendGump( new OfferNewGameGump( from, this, true ) );
}
protected virtual void GamePending( Mobile from )
{
from.SendMessage( "This game is pending use from another player. Please try again later." );
}
protected virtual void OfferRecruiting( Mobile from )
{
if( PendingPlayers.IndexOf( from ) == -1 )
{
if( PendingPlayers.Count < CurrentMaxPlayers )
{
PendingPlayers.Add( from );
from.SendGump( new OfferNewGameGump( from, this, false ) );
}
else
{
from.SendMessage( "This game has enough players attempting to start a game. Please try again later." );
}
}
else
{
from.SendGump( new AwaitRecruitmentGump( from, this ) );
}
}
protected virtual void GameActive( Mobile from )
{
if( Players.IndexOf( from ) == -1 )
{
from.SendMessage( "A game is already in progess. Please try again later." );
}
}
protected virtual void GameOver( Mobile from )
{
from.SendMessage( "The last game has just ended. Please try again later." );
}
//this is called by the recruitment gump when a player agrees to play the game
public virtual void AddPlayer( Mobile from )
{
Players.Add( from );
from.SendGump( new AwaitRecruitmentGump( from, this ) );
if( Players.Count == CurrentMaxPlayers && SettingsReady )
{
InitializeGame();
}
else
{
State = BoardGameState.Recruiting;
}
}
public void InitializeGame()
{
//perform final check on all players to make sure they're still good to play
Mobile toboot = null;
foreach( Mobile player in Players )
{
if( !CanUse( player ) )
{
player.SendMessage( "You can no longer enter the game, and have been removed from the list." );
toboot = player;
break;
}
}
if( toboot != null )
{
if( Players.IndexOf( toboot ) == 0 )
{
_SettingsReady = !_AllowPlayerConfiguration;
}
RemovePlayer( toboot );
return;
}
_PendingPlayers = null;
State = BoardGameState.Active;
foreach( Mobile player in Players )
{
CheckCost( player, true );
player.SendMessage( "Game on!" );
}
//Start the game!
StartGame();
}
//this is called by the await recruitment gump when the player chooses to cancel waiting
public virtual void RemovePlayer( Mobile from )
{
from.CloseGump( typeof( AwaitRecruitmentGump ) );
from.CloseGump( typeof( SelectStyleGump ) );
Players.Remove( from );
PendingPlayers.Remove( from );
if( Players.Count == 0 )
{
State = BoardGameState.Inactive;
_SettingsReady = !_AllowPlayerConfiguration;
}
}
//these are used to update all movable addon components
public override void OnLocationChange( Point3D oldLoc )
{
if ( Deleted )
{
return;
}
UpdatePosition();
}
//these are used to update all movable addon components
public override void OnMapChange()
{
if ( Deleted )
{
return;
}
UpdatePosition();
}
public override void Delete()
{
if( _WinnerTimer != null )
{
_WinnerTimer.Stop();
_WinnerTimer = null;
}
if( _EndGameTimer != null )
{
_EndGameTimer.Stop();
_EndGameTimer = null;
}
base.Delete();
}
//this cleans up all movable addon components, and removes the reference to this addon in the key item
public override void OnAfterDelete()
{
base.OnAfterDelete();
if( _WinnerTimer != null )
{
_WinnerTimer.Stop();
_WinnerTimer = null;
}
foreach( GamePiece piece in BackgroundItems )
{
if( piece != null && !piece.Deleted )
{
piece.Delete();
}
}
if( _BoardGameRegion != null )
{
_BoardGameRegion.Unregister();
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 2 );
writer.Write( BoardMap );
writer.Write( _AllowPlayerConfiguration );
writer.Write( (int)_State );
writer.Write( _CostToPlay );
writer.Write( CurrentMaxPlayers );
writer.Write( _BoardWidth );
writer.Write( _BoardHeight );
writer.Write( GameZone.Start.X );
writer.Write( GameZone.Start.Y );
writer.Write( GameZone.Start.Z );
writer.Write( GameZone.End.X );
writer.Write( GameZone.End.Y );
writer.Write( GameZone.End.Z );
writer.Write( _BoardOffset.X );
writer.Write( _BoardOffset.Y );
writer.Write( _BoardOffset.Z );
writer.Write( Players.Count );
foreach( Mobile mobile in Players )
{
writer.Write( mobile );
}
writer.Write( BackgroundItems.Count );
foreach( GamePiece piece in BackgroundItems )
{
writer.Write( (Item)piece );
}
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
if( version >= 2 )
{
_BoardMap = reader.ReadMap();
}
else
{
_BoardMap = Map;
}
if( version >= 1 )
{
_AllowPlayerConfiguration = reader.ReadBool();
}
else
{
_AllowPlayerConfiguration = true;
}
State = (BoardGameState)reader.ReadInt();
_CostToPlay = reader.ReadInt();
CurrentMaxPlayers = reader.ReadInt();
_BoardWidth = reader.ReadInt();
_BoardHeight = reader.ReadInt();
GameZone = new Rectangle3D( new Point3D( reader.ReadInt(), reader.ReadInt(), reader.ReadInt() ), new Point3D( reader.ReadInt(), reader.ReadInt(), reader.ReadInt() ) );
_BoardOffset = new Point3D( reader.ReadInt(), reader.ReadInt(), reader.ReadInt() );
int count = reader.ReadInt();
for( int i = 0; i < count; i++ )
{
Players.Add( reader.ReadMobile() );
}
count = reader.ReadInt();
for( int i = 0; i < count; i++ )
{
BackgroundItems.Add( (GamePiece)reader.ReadItem() );
}
if( _State == BoardGameState.Pending || _State == BoardGameState.Recruiting )
{
_State = BoardGameState.Inactive;
_Players = null;
}
_BoardGameRegion = new BoardGameRegion( this );
_BoardGameRegion.Register();
_SettingsReady = !_AllowPlayerConfiguration;
}
protected class EndGameTimer : Timer
{
private BoardGameControlItem _ControlItem;
public EndGameTimer( BoardGameControlItem controlitem, TimeSpan delay ) : base( delay, TimeSpan.FromSeconds( 1.0 ) )
{
_ControlItem = controlitem;
}
protected override void OnTick()
{
_ControlItem.OnEndGameTimer();
}
}
//this timer delays the game a bit, so the winner can stand proud over the game
protected class WinnerTimer : Timer
{
private BoardGameControlItem _ControlItem;
public WinnerTimer( BoardGameControlItem controlitem, TimeSpan delay ) : base( delay, TimeSpan.FromSeconds( 1.0 ) )
{
_ControlItem = controlitem;
}
protected override void OnTick()
{
_ControlItem.EndGame();
Stop();
}
}
}
}

View File

@@ -0,0 +1,333 @@
using System;
using System.IO;
using System.Collections.Generic;
using Server;
namespace Solaris.BoardGames
{
//this data class is used to keep track of player scores for various boardgames
public class BoardGameData
{
public const string SAVE_PATH = @"Saves\BoardGame Data";
public const string FILENAME = "boardgames.bin";
protected static List<BoardGameData> _GameData;
public static List<BoardGameData> GameData
{
get
{
if( _GameData == null )
{
_GameData = new List<BoardGameData>();
}
return _GameData;
}
}
protected string _GameName;
protected List<BoardGamePlayerScore> _Scores;
public string GameName{ get{ return _GameName; } }
public List<BoardGamePlayerScore> Scores
{
get
{
if( _Scores == null )
{
_Scores = new List<BoardGamePlayerScore>();
}
return _Scores;
}
}
protected BoardGameData( string gamename )
{
_GameName = gamename;
}
protected BoardGameData( GenericReader reader )
{
Deserialize( reader );
}
protected virtual void Serialize( GenericWriter writer )
{
writer.Write( 0 );
writer.Write( _GameName );
writer.Write( Scores.Count );
foreach( BoardGamePlayerScore score in Scores )
{
score.Serialize( writer );
}
}
protected virtual void Deserialize( GenericReader reader )
{
int version = reader.ReadInt();
_GameName = reader.ReadString();
int count = reader.ReadInt();
for( int i = 0; i < count; i++ )
{
BoardGamePlayerScore playerscore = new BoardGamePlayerScore( reader );
if( playerscore.Player != null && !playerscore.Player.Deleted )
{
Scores.Add( playerscore );
}
}
}
protected static BoardGamePlayerScore GetScoreData( string gamename, Mobile player )
{
List<BoardGamePlayerScore> scores = GetScores( gamename );
if( scores == null )
{
BoardGameData gamedata = new BoardGameData( gamename );
GameData.Add( gamedata );
scores = gamedata.Scores;
}
int index = BoardGamePlayerScore.IndexOf( scores, player );
if( index == -1 )
{
BoardGamePlayerScore newscore = new BoardGamePlayerScore( player );
scores.Add( newscore );
return newscore;
}
else
{
return scores[ index ];
}
}
public static List<BoardGamePlayerScore> GetScores( string gamename )
{
int gameindex = IndexOf( gamename );
if( gameindex == -1 )
{
return null;
}
else
{
return GameData[ gameindex ].Scores;
}
}
public static void SetScore( string gamename, Mobile player, int score )
{
BoardGamePlayerScore scoredata = GetScoreData( gamename, player );
if( scoredata != null )
{
scoredata.Score = score;
}
else
{
}
}
public static int GetScore( string gamename, Mobile player )
{
BoardGamePlayerScore scoredata = GetScoreData( gamename, player );
if( scoredata != null )
{
return scoredata.Score;
}
else
{
return 0;
}
}
public static void ChangeScore( string gamename, Mobile player, int delta )
{
SetScore( gamename, player, Math.Max( 0, GetScore( gamename, player ) + delta ) );
}
public static void AddWin( string gamename, Mobile player )
{
BoardGamePlayerScore playerscore = GetScoreData( gamename, player );
playerscore.Wins += 1;
}
public static void AddLose( string gamename, Mobile player )
{
BoardGamePlayerScore playerscore = GetScoreData( gamename, player );
playerscore.Losses += 1;
}
public static void ResetScores( string gamename )
{
int gameindex = IndexOf( gamename );
if( gameindex > -1 )
{
GameData.RemoveAt( gameindex );
}
}
public static int IndexOf( string gamename )
{
for( int i = 0; i < GameData.Count; i++ )
{
if( GameData[i].GameName == gamename )
{
return i;
}
}
return -1;
}
public static void Configure()
{
EventSink.WorldLoad += new WorldLoadEventHandler( OnLoad );
EventSink.WorldSave += new WorldSaveEventHandler( OnSave );
}
public static void OnSave( WorldSaveEventArgs e )
{
if( !Directory.Exists( SAVE_PATH ) )
{
Directory.CreateDirectory( SAVE_PATH );
}
GenericWriter writer = new BinaryFileWriter( Path.Combine( SAVE_PATH, FILENAME ), true );
writer.Write( 0 );
writer.Write( GameData.Count );
foreach( BoardGameData data in GameData )
{
data.Serialize( writer );
}
writer.Close();
}
public static void OnLoad()
{
//don't load the file if it don't exist!
if( !File.Exists( Path.Combine( SAVE_PATH, FILENAME ) ) )
{
return;
}
using( FileStream bin = new FileStream( Path.Combine( SAVE_PATH, FILENAME ), FileMode.Open, FileAccess.Read, FileShare.Read ) )
{
GenericReader reader = new BinaryFileReader( new BinaryReader( bin ) );
int version = reader.ReadInt();
int count = reader.ReadInt();
for( int i = 0; i < count; i++ )
{
GameData.Add( new BoardGameData( reader ) );
}
reader.End();
}
}
}
public class BoardGamePlayerScore : IComparable
{
protected Mobile _Player;
public Mobile Player{ get{ return _Player; } }
public int Score;
public int Wins;
public int Losses;
public BoardGamePlayerScore( Mobile player ) : this( player, 0 )
{
}
public BoardGamePlayerScore( Mobile player, int score )
{
_Player = player;
Score = score;
}
//deserialize constructor
public BoardGamePlayerScore( GenericReader reader )
{
Deserialize( reader );
}
public int CompareTo( object obj )
{
if( !( obj is BoardGamePlayerScore ) )
{
return 0;
}
BoardGamePlayerScore comparescore = (BoardGamePlayerScore)obj;
return -Score.CompareTo( comparescore.Score );
}
public virtual void Serialize( GenericWriter writer )
{
writer.Write( 0 );
writer.Write( _Player );
writer.Write( Score );
writer.Write( Wins );
writer.Write( Losses );
}
public virtual void Deserialize( GenericReader reader )
{
int version = reader.ReadInt();
_Player = reader.ReadMobile();
Score = reader.ReadInt();
Wins = reader.ReadInt();
Losses = reader.ReadInt();
}
public static int IndexOf( List<BoardGamePlayerScore> scores, Mobile player )
{
if( scores == null )
{
return -1;
}
for( int i = 0; i < scores.Count; i++ )
{
if( scores[i].Player == player )
{
return i;
}
}
return -1;
}
}
}

View File

@@ -0,0 +1,43 @@
using System;
using Server;
using Server.Accounting;
namespace Solaris.BoardGames
{
//this class defines all data access for tracking player scores within boardgames
public class BoardGamePlayer
{
//current plan is to use account tags.
//TODO: explore XML tags and such to better integrate with XML quest systems?
//this sets the players score for a particular game type
public static bool SetScore( Mobile mobile, string gametype, int score )
{
if( mobile.Account == null )
{
return false;
}
Account acct = (Account)mobile.Account;
acct.SetTag( "BoardGames-" + gametype, score.ToString() );
return true;
}
public static int GetScore( Mobile mobile, string gametype )
{
try
{
Account acct = (Account)mobile.Account;
return Convert.ToInt32( acct.GetTag( "BoardGames-" + gametype ) );
}
catch
{
return -1;
}
}
}
}

View File

@@ -0,0 +1,108 @@
using Server;
using System;
using System.Collections;
using Server.Items;
using Server.Spells;
using Server.Mobiles;
using Server.Regions;
namespace Solaris.BoardGames
{
//a boardgame region is a custom region that handles rules for players within the region (no casting, no pets, etc)
public class BoardGameRegion : GuardedRegion
{
protected static int _RegionIndex = 0;
protected BoardGameControlItem _BoardGameControlItem;
public static string GetUniqueName( BoardGameControlItem controlitem )
{
return controlitem.GameName + " " + ( _RegionIndex++ ).ToString();
}
public BoardGameControlItem BoardGameControlItem
{
get{ return _BoardGameControlItem; }
}
public BoardGameRegion( BoardGameControlItem controlitem ): base( GetUniqueName( controlitem ), controlitem.Map, 255, controlitem.GameZone )
{
Disabled = true;
_BoardGameControlItem = controlitem;
}
public override bool AllowHousing(Mobile from, Point3D p)
{
return false;
}
public override bool AllowSpawn()
{
return false;
}
public override bool CanUseStuckMenu( Mobile m )
{
return false;
}
public override bool OnDamage( Mobile m, ref int Damage )
{
return false;
}
public override bool OnBeginSpellCast( Mobile from, ISpell s )
{
if( from.AccessLevel > AccessLevel.Player )
{
return true;
}
return _BoardGameControlItem.CanCastSpells;
}
public override void OnEnter( Mobile m )
{
m.SendMessage( "Entering boardgame" );
if( _BoardGameControlItem.Players.IndexOf( m ) == -1 && m.AccessLevel == AccessLevel.Player )
{
m.SendMessage( "You are not allowed in there." );
m.MoveToWorld( _BoardGameControlItem.Location, _BoardGameControlItem.Map );
}
}
public override void OnExit( Mobile m )
{
m.SendMessage( "Exiting boardgame" );
}
public override bool OnSkillUse( Mobile m, int skill )
{
return _BoardGameControlItem.CanUseSkills;
}
public override bool OnMoveInto( Mobile m, Direction d, Point3D newLocation, Point3D oldLocation )
{
if( m is BaseCreature && !_BoardGameControlItem.CanUsePets )
{
return false;
}
if( _BoardGameControlItem.Players.IndexOf( m ) == -1 )
{
if( !( m is PlayerMobile ) || m.AccessLevel > AccessLevel.Player )
{
return true;
}
return false;
}
return true;
}
public override bool OnDoubleClick( Mobile m, object o )
{
//TODO: put shrunken pet control here
return base.OnDoubleClick( m, o );
}
}
}

View File

@@ -0,0 +1,56 @@
using System;
using Server;
using Server.ContextMenus;
using Server.Gumps;
using Server.Items;
namespace Solaris.BoardGames
{
public class ViewBoardGameScoresEntry : ContextMenuEntry
{
Mobile _From;
BoardGameControlItem _ControlItem;
//3006239 = "View events"
public ViewBoardGameScoresEntry( Mobile from, BoardGameControlItem controlitem, int index ) : base( 6239, index )
{
_From = from;
_ControlItem = controlitem;
}
public override void OnClick()
{
if ( _ControlItem == null || _ControlItem.Deleted )
{
return;
}
_From.SendGump( new BoardGameScoresGump( _From, _ControlItem ) );
}
}
public class ResetBoardGameScoresEntry : ContextMenuEntry
{
Mobile _From;
BoardGameControlItem _ControlItem;
//3006162 = "Reset Game"
public ResetBoardGameScoresEntry( Mobile from, BoardGameControlItem controlitem, int index ) : base( 6162, index )
{
_From = from;
_ControlItem = controlitem;
}
public override void OnClick()
{
if ( _ControlItem == null || _ControlItem.Deleted )
{
return;
}
_From.SendGump( new ConfirmResetGameScoreGump( _From, _ControlItem ) );
}
}
}

View File

@@ -0,0 +1,158 @@
using System;
using Server;
using Server.Items;
namespace Solaris.BoardGames
{
//a gamepiece behaves much like an addon component
public class GamePiece : Item
{
//offset from the boardgame control item
public Point3D Offset;
//reference to the LOSBlocker used to block line of sight thru this gamepiece
public LOSBlocker _Blocker;
//reference to the boardgame control item that this piece belongs to
public BoardGameControlItem BoardGameControlItem;
//randomize itemid constructor
public GamePiece( int itemidmin, int itemidmax, string name ) : this( Utility.RandomMinMax( itemidmin, itemidmax ), name )
{
}
//randomize itemid constructor
public GamePiece( int itemidmin, int itemidmax, string name, bool blocklos ) : this( Utility.RandomMinMax( itemidmin, itemidmax ), name, blocklos )
{
}
//default no block los constructor
public GamePiece( int itemid, string name ) : this( itemid, name, false )
{
}
//master constructor
public GamePiece( int itemid, string name, bool blocklos ) : base( itemid )
{
Movable = false;
Name = name;
if( blocklos )
{
_Blocker = new LOSBlocker();
}
}
//deserialize constructor
public GamePiece( Serial serial ) : base( serial )
{
}
public void RegisterToBoardGameControlItem( BoardGameControlItem boardgamecontrolitem, Point3D offset )
{
BoardGameControlItem = boardgamecontrolitem;
Offset = offset;
UpdatePosition();
}
//move the item based on its position with respect to the boardgame control item
public void UpdatePosition()
{
if( BoardGameControlItem != null )
{
MoveToWorld( new Point3D( BoardGameControlItem.X + BoardGameControlItem.BoardOffset.X + Offset.X, BoardGameControlItem.Y + BoardGameControlItem.BoardOffset.Y + Offset.Y, BoardGameControlItem.Z + BoardGameControlItem.BoardOffset.Z + Offset.Z ), BoardGameControlItem.BoardMap );
}
else
{
Delete();
}
}
public override void OnLocationChange( Point3D old )
{
if( BoardGameControlItem != null )
{
BoardGameControlItem.Location = new Point3D( X - BoardGameControlItem.BoardOffset.X - Offset.X, Y - BoardGameControlItem.BoardOffset.Y - Offset.Y, Z - BoardGameControlItem.BoardOffset.Z - Offset.Z );
}
if( _Blocker != null )
{
_Blocker.MoveToWorld( Location, Map );
}
}
public override void OnMapChange()
{
if( BoardGameControlItem != null && BoardGameControlItem.BoardMap != Map )
{
BoardGameControlItem.BoardMap = Map;
}
if( _Blocker != null )
{
_Blocker.MoveToWorld( Location, Map );
}
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
if( BoardGameControlItem != null )
{
BoardGameControlItem.Delete();
}
if( _Blocker != null )
{
_Blocker.Delete();
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 1 );
writer.Write( (Item)_Blocker );
writer.Write( (Item)BoardGameControlItem );
writer.Write( Offset.X );
writer.Write( Offset.Y );
writer.Write( Offset.Z );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch( version )
{
default:
case 1:
{
_Blocker = (LOSBlocker)reader.ReadItem();
goto case 0;
}
case 0:
{
BoardGameControlItem = (BoardGameControlItem)reader.ReadItem();
Offset.X = reader.ReadInt();
Offset.Y = reader.ReadInt();
Offset.Z = reader.ReadInt();
break;
}
}
}
}
}

View File

@@ -0,0 +1,48 @@
using System;
using Server;
using Server.Items;
using Server.Network;
using Solaris.BoardGames;
namespace Server.Gumps
{
//offers a new game to a player
public class AwaitRecruitmentGump : BoardGameGump
{
public override int Height{ get{ return 200; } }
public override int Width{ get{ return 400; } }
public AwaitRecruitmentGump( Mobile owner, BoardGameControlItem controlitem ) : base( owner, controlitem )
{
//force it so players can't close this gump
Closable = false;
AddLabel( 40, 20, 1152, "Game:" );
AddLabel( 140, 20, 1172, _ControlItem.GameName );
AddHtml( 40, 50, Width - 80, 80, "You are waiting for more players to join this game. When there are enough, this window will automatically close and the game will start. If you wish to cancel waiting, click the Cancel button.", true, false );
AddButton( 160, 160, 0xF1, 0xF2, 1, GumpButtonType.Reply, 0 );
}
protected override void DeterminePageLayout()
{
}
public override void OnResponse( NetState sender, RelayInfo info )
{
int buttonid = info.ButtonID;
//cancel button
if( buttonid == 1 )
{
_Owner.CloseGump( typeof( SelectStyleGump ) );
_ControlItem.RemovePlayer( _Owner );
_Owner.SendMessage( "You are no longer waiting to play this game." );
}
}
}
}

View File

@@ -0,0 +1,77 @@
using System;
using Server;
using Server.Items;
using Server.Network;
using Solaris.BoardGames;
namespace Server.Gumps
{
//main gump class for boardgames
public class BoardGameGump : Gump
{
public virtual int Height{ get{ return 100; } }
public virtual int Width{ get{ return 100; } }
//reference to the control system for the boardgame
protected BoardGameControlItem _ControlItem;
protected Mobile _Owner;
public BoardGameGump( Mobile owner, BoardGameControlItem controlitem ) : base( 50, 50 )
{
_Owner = owner;
_ControlItem = controlitem;
_Owner.CloseGump( typeof( BoardGameGump ) );
DrawBackground();
}
protected virtual void DrawBackground()
{
AddPage(0);
//determine page layout, sizes, and what gets displayed where
DeterminePageLayout();
AddBackground( 0, 0, Width, Height, 9270 );
AddImageTiled( 11, 10, Width - 22, Height - 20, 2624 );
AddAlphaRegion( 11, 10, Width - 22, Height - 20 );
}
protected virtual void DeterminePageLayout()
{
}
public void AddTextField( int x, int y, int width, int height, int index, string text )
{
AddImageTiled( x - 2, y - 2, width + 4, height + 4, 0xA2C );
AddAlphaRegion( x -2, y - 2, width + 4, height + 4 );
AddTextEntry( x + 2, y + 2, width - 4, height - 4, 1153, index, text );
}
public string GetTextField( RelayInfo info, int index )
{
TextRelay relay = info.GetTextEntry( index );
return ( relay == null ? null : relay.Text.Trim() );
}
public override void OnResponse( NetState sender, RelayInfo info )
{
}
}
}

View File

@@ -0,0 +1,27 @@
using System;
using Server;
using Server.Items;
using Server.Network;
using Solaris.BoardGames;
namespace Server.Gumps
{
public class BoardGameLostGump : BoardGameGump
{
public override int Height{ get{ return 140; } }
public override int Width{ get{ return 300; } }
public BoardGameLostGump( Mobile owner, BoardGameControlItem controlitem ) : base( owner, controlitem )
{
AddLabel( 40, 20, 1152, "Game:" );
AddLabel( 140, 20, 1172, _ControlItem.GameName );
AddLabel( 40, 50, 1152, "You've lost the game!" );
//TODO: add info about points earned?
AddButton( 100, 80, 0xF7, 0xF8, 0, GumpButtonType.Reply, 0 );
}
}
}

View File

@@ -0,0 +1,135 @@
using System;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.Network;
using Solaris.BoardGames;
namespace Server.Gumps
{
public class BoardGameScoresGump : BoardGameGump
{
public const int ENTRIES_PER_PAGE = 10;
public override int Height{ get{ return 440; } }
public override int Width{ get{ return 350; } }
protected List<BoardGamePlayerScore> _PlayerScores;
protected int _X;
protected int _Y;
//maximum entry listing height, for multi-page calculation
public int MaxEntryDisplayHeight{ get{ return 300; } }
//line spacing between entries
public int EntryLineSpacing{ get{ return 20; } }
protected int _Page;
//this is determined based on the number of entries and the maximum number to display per page
protected int _MaxPages;
public BoardGameScoresGump( Mobile owner, BoardGameControlItem controlitem ) : this( owner, controlitem, 0 )
{
}
public BoardGameScoresGump( Mobile owner, BoardGameControlItem controlitem, int page ) : base( owner, controlitem )
{
_Page = page;
AddLabel( 40, 20, 1152, "Game:" );
AddLabel( 140, 20, 1172, _ControlItem.GameName );
AddLabel( 40, 50, 1152, "Scores" );
_PlayerScores = BoardGameData.GetScores( controlitem.GameName );
if( _PlayerScores == null || _PlayerScores.Count == 0 )
{
AddLabel( 40, 80, 1152, "- NO SCORES SET YET -" );
return;
}
_PlayerScores.Sort();
_X = 20;
_Y = 80;
_MaxPages = _PlayerScores.Count / ENTRIES_PER_PAGE + 1;
if( _PlayerScores.Count % ENTRIES_PER_PAGE == 0 )
{
_MaxPages -= 1;
}
_Page = Math.Max( 0, Math.Min( _Page, _MaxPages ) );
int listingstart = _Page * ENTRIES_PER_PAGE;
int listingend = Math.Min( _PlayerScores.Count, (_Page + 1 ) * ENTRIES_PER_PAGE );
AddLabel( _X, _Y, 1152, "Name" );
AddLabel( _X + 150, _Y, 1152, "Score" );
AddLabel( _X+ 200, _Y, 1152, "Wins" );
AddLabel( _X + 250, _Y, 1152, "Losses" );
for( int i = listingstart; i < listingend; i++ )
{
AddLabel( _X, _Y += 20, 1152, _PlayerScores[i].Player.Name );
AddLabel( _X + 150, _Y, 1152, _PlayerScores[i].Score.ToString() );
AddLabel( _X + 200, _Y, 1152, _PlayerScores[i].Wins.ToString() );
AddLabel( _X + 250, _Y, 1152, _PlayerScores[i].Losses.ToString() );
}
AddPageButtons();
AddButton( 60, Height - 40, 0xF7, 0xF8, 0, GumpButtonType.Reply, 0 );
}
protected void AddPageButtons()
{
//page buttons
_Y = Height - 90;
if ( _Page > 0 )
{
AddButton( 20, _Y, 0x15E3, 0x15E7, 4, GumpButtonType.Reply, 0 );
}
else
{
AddImage( 20, _Y, 0x25EA );
}
AddLabel( 40, _Y, 88, "Previous Page" );
if ( _Page < _MaxPages - 1 )
{
AddButton( Width - 40, _Y, 0x15E1, 0x15E5, 5, GumpButtonType.Reply, 0 );
}
else
{
AddImage( Width - 40, _Y, 0x25E6 );
}
AddLabel( Width - 120, _Y, 88, "Next Page" );
AddLabel( Width / 2 - 10, _Y, 88, String.Format( "({0}/{1})", _Page + 1, _MaxPages ) );
}
public override void OnResponse( NetState sender, RelayInfo info )
{
int buttonid = info.ButtonID;
if( buttonid == 4 )
{
_Owner.SendGump( new BoardGameScoresGump( _Owner, _ControlItem, _Page - 1 ) );
}
else if( buttonid == 5 )
{
_Owner.SendGump( new BoardGameScoresGump( _Owner, _ControlItem, _Page + 1 ) );
}
}
}
}

View File

@@ -0,0 +1,32 @@
using System;
using Server;
using Server.Items;
using Server.Network;
using Solaris.BoardGames;
namespace Server.Gumps
{
public class BoardGameWonGump : BoardGameGump
{
public override int Height{ get{ return 140; } }
public override int Width{ get{ return 300; } }
public BoardGameWonGump( Mobile owner, BoardGameControlItem controlitem ) : base( owner, controlitem )
{
AddLabel( 40, 20, 1152, "Game:" );
AddLabel( 140, 20, 1172, _ControlItem.GameName );
AddLabel( 40, 50, 1152, "Congratulations, you won the game!!" );
//TODO: add info about points earned?
AddButton( 100, 80, 0xF7, 0xF8, 0, GumpButtonType.Reply, 0 );
}
public override void OnResponse( NetState sender, RelayInfo info )
{
_ControlItem.EndGame();
}
}
}

View File

@@ -0,0 +1,43 @@
using System;
using Server;
using Server.Items;
using Server.Network;
using Solaris.BoardGames;
namespace Server.Gumps
{
public class ConfirmResetGameScoreGump : BoardGameGump
{
public override int Height{ get{ return 200; } }
public override int Width{ get{ return 400; } }
protected int _Y = 30;
protected int _X = 20;
public ConfirmResetGameScoreGump( Mobile owner, BoardGameControlItem controlitem ) : base( owner, controlitem )
{
AddLabel( 40, 20, 1152, "Game:" );
AddLabel( 140, 20, 1172, _ControlItem.GameName );
AddHtml( 40, 50, Width - 80, 80, "You are about to reset all the score data for " + _ControlItem.GameName + ". Once you do this, it cannot be undone. Are you sure you wish to do this?", true, false );
AddButton( 30, 160, 0xF7, 0xF8, 1, GumpButtonType.Reply, 0 );
AddButton( 160, 160, 0xF1, 0xF2, 0, GumpButtonType.Reply, 0 );
}
public override void OnResponse( NetState state, RelayInfo info )
{
Mobile from = state.Mobile;
if( info.ButtonID == 1 )
{
BoardGameData.ResetScores( _ControlItem.GameName );
_Owner.SendMessage( "You have now reset all the scores." );
}
}
}
}

View File

@@ -0,0 +1,104 @@
using System;
using Server;
using Server.Items;
using Server.Network;
using Solaris.BoardGames;
namespace Server.Gumps
{
//offers a new game to a player
public class OfferNewGameGump : BoardGameGump
{
protected bool _ControlNumberOfPlayers;
public override int Height{ get{ return 500; } }
public override int Width{ get{ return 400; } }
public OfferNewGameGump( Mobile owner, BoardGameControlItem controlitem, bool controlnumberofplayers ) : base( owner, controlitem )
{
_ControlNumberOfPlayers = controlnumberofplayers;
AddLabel( 40, 20, 1152, "Game:" );
AddLabel( 140, 20, 1172, _ControlItem.GameName );
AddLabel( 40, 50, 1152, "Description:" );
AddHtml( 40, 70, 300, 100, _ControlItem.GameDescription, true, true );
AddLabel( 40, 180, 1152, "Rules:" );
AddHtml( 40, 200, 300, 150, _ControlItem.GameRules, true, true );
if( _ControlItem.CostToPlay > 0 )
{
AddLabel( 40, 370, 1152, "Cost to play:" );
AddLabel( 240, 370, 1172, _ControlItem.CostToPlay.ToString() + " gold" );
}
if( _ControlItem.MaxPlayers != _ControlItem.MinPlayers )
{
AddLabel( 40, 430, 1152, "# of players (" + _ControlItem.MinPlayers.ToString() + "-" + _ControlItem.MaxPlayers.ToString() + "):" );
if( _ControlNumberOfPlayers )
{
AddLabel( 60, 410, 1172, "Pick the number of players" );
AddTextField( 240, 430, 30, 20, 0, _ControlItem.CurrentMaxPlayers.ToString() );
}
else
{
AddLabel( 240, 430, 1152, _ControlItem.CurrentMaxPlayers.ToString() );
}
}
AddLabel( 40, 470, 1152, "Play this game?" );
AddButton( 200, 460, 0xF7, 0xF8, 1, GumpButtonType.Reply, 0 );
AddButton( 300, 460, 0xF1, 0xF2, 0, GumpButtonType.Reply, 0 );
}
protected override void DeterminePageLayout()
{
}
public override void OnResponse( NetState sender, RelayInfo info )
{
int buttonid = info.ButtonID;
//cancel or right click
if( buttonid == 0 )
{
_ControlItem.RemovePlayer( _Owner );
_Owner.SendMessage( "You decide not to play this game" );
}
else
{
if( _ControlItem.MaxPlayers != _ControlItem.MinPlayers && _ControlNumberOfPlayers )
{
try
{
_ControlItem.CurrentMaxPlayers = Int32.Parse( GetTextField( info, 0 ) );
if( _ControlItem.CurrentMaxPlayers > _ControlItem.MaxPlayers || _ControlItem.CurrentMaxPlayers < _ControlItem.MinPlayers )
{
throw( new Exception() );
}
}
catch
{
_Owner.SendMessage( "Invalid number of players selected. Please try again." );
_Owner.SendGump( new OfferNewGameGump( _Owner, _ControlItem, _ControlNumberOfPlayers ) );
return;
}
}
_Owner.SendMessage( "You have signed up for this game." );
_ControlItem.AddPlayer( _Owner );
}
}
}
}

View File

@@ -0,0 +1,95 @@
using System;
using Server;
using Server.Items;
using Server.Network;
using Solaris.BoardGames;
namespace Server.Gumps
{
public class SelectStyleGump : Gump
{
public virtual int Height{ get{ return 150; } }
public virtual int Width{ get{ return 200; } }
protected int _Y = 30;
protected int _X = 20;
protected BoardGameControlItem _ControlItem;
public SelectStyleGump( Mobile owner, BoardGameControlItem controlitem ) : base( 450, 80 )
{
Closable = false;
owner.CloseGump( typeof( SelectStyleGump ) );
_ControlItem = controlitem;
if( _ControlItem.Players.IndexOf( owner ) == -1 )
{
return;
}
AddPage( 0 );
AddBackground( 0, 0, Width, Height, 0x1400 );
AddLabel( 20, 60, 1152, "# of players (" + _ControlItem.MinPlayers.ToString() + "-" + _ControlItem.MaxPlayers.ToString() + "):" );
int minplayers = Math.Max( _ControlItem.MinPlayers, _ControlItem.Players.Count );
if( _ControlItem.MaxPlayers != _ControlItem.MinPlayers && !_ControlItem.SettingsReady )
{
AddLabel( 20, 40, 1172, "Pick the number of players" );
AddTextField( 150, 60, 30, 20, 0, _ControlItem.CurrentMaxPlayers.ToString() );
AddButton( 182, 62, 0x4B9, 0x4BA, 500, GumpButtonType.Reply, 0 );
}
else
{
AddLabel( 150, 60, 1152, _ControlItem.CurrentMaxPlayers.ToString() );
}
//AddButton( Width - 15, 0, 3, 4, 0, GumpButtonType.Reply, 0 );
}
public void AddTextField( int x, int y, int width, int height, int index, string text )
{
AddImageTiled( x - 2, y - 2, width + 4, height + 4, 0xA2C );
AddAlphaRegion( x -2, y - 2, width + 4, height + 4 );
AddTextEntry( x + 2, y + 2, width - 4, height - 4, 1153, index, text );
}
public string GetTextField( RelayInfo info, int index )
{
TextRelay relay = info.GetTextEntry( index );
return ( relay == null ? null : relay.Text.Trim() );
}
public override void OnResponse( NetState state, RelayInfo info )
{
Mobile from = state.Mobile;
if( _ControlItem.Players.IndexOf( from ) != 0 )
{
return;
}
try
{
if( !_ControlItem.SettingsReady )
{
_ControlItem.CurrentMaxPlayers = Math.Max( Int32.Parse( GetTextField( info, 0 ) ), _ControlItem.Players.Count );
if( _ControlItem.CurrentMaxPlayers > _ControlItem.MaxPlayers || _ControlItem.CurrentMaxPlayers < _ControlItem.MinPlayers )
{
throw( new Exception() );
}
}
}
catch
{
from.SendMessage( "Invalid number of players selected. Please try again." );
}
}
}
}

View File

@@ -0,0 +1,622 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Server;
using Server.Gumps;
using Server.Network;
using Solaris.BoardGames;
namespace Server.Items
{
//a test of the boardgame system
public class BombermanControlItem : BoardGameControlItem
{
public override string GameName{ get{ return "Bomberman"; } }
public override string GameDescription{ get{ return "Blow up walls and players with bombs. Collect upgrades to improve your number of bombs, blast size, etc."; } }
public override string GameRules
{
get
{
return "Each game can have up to eight players, and everyone starts in a corner or edge of the arena. " +
"A bomb bag is placed in the players' backpacks. Players use this bag to place bombs at their feet. " +
"A bomb will detonate after some time, and has a limited blast size. The number of bombs any player can place at any time is limited.<BR><BR>" +
"Players must blast at the breakable walls to navigate the arena. " +
"While blasting, upgrades can be found which improve the blast size or number of bombs a player can place at once. " +
"There is also a detonator upgrade that lets a player choose when they want their bombs to blow up. " +
"Watch out for other players' blasts! A bomb can trigger another bomb to go off, creating interesting chain reactions!<BR><BR>" +
"The game ends when there is only one player left standing. ";
}
}
public override bool CanCastSpells{ get{ return false; } }
public override bool CanUseSkills{ get{ return false; } }
public override bool CanUsePets{ get{ return false; } }
public override TimeSpan WinDelay{ get{ return TimeSpan.FromSeconds( 5 ); } }
//bomberman main controller must be accessed from ground
public override bool UseFromBackpack{ get{ return false; } }
//only 1 to 8 players allowed in a bomberman game
public override int MinPlayers{ get{ return 2; } }
public override int MaxPlayers{ get{ return 8; } }
protected BombermanStyle _Style;
[CommandProperty( AccessLevel.GameMaster )]
public BombermanStyle Style
{
get{ return _Style; }
set
{
if( (int)_State <= (int)BoardGameState.Recruiting )
{
_Style = value;
ResetBoard();
}
}
}
//reference to be bomb bags that are handed out for the game
protected List<BombBag> _BombBags;
public List<BombBag> BombBags
{
get
{
if( _BombBags == null )
{
_BombBags = new List<BombBag>();
}
return _BombBags;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public override int BoardWidth
{
get
{
_BoardWidth = Math.Max( BombermanSettings.MIN_BOARD_SIZE, Math.Min( BombermanSettings.MAX_BOARD_SIZE, _BoardWidth ) );
return _BoardWidth;
}
set
{
if( (int)_State <= (int)BoardGameState.Recruiting )
{
_BoardWidth = Math.Max( BombermanSettings.MIN_BOARD_SIZE, Math.Min( BombermanSettings.MAX_BOARD_SIZE, value ) );
if( ( _BoardWidth & 1 ) == 0 )
{
_BoardWidth += 1;
}
ResetBoard();
}
}
}
[CommandProperty( AccessLevel.GameMaster )]
public override int BoardHeight
{
get
{
_BoardHeight = Math.Max( BombermanSettings.MIN_BOARD_SIZE, Math.Min( BombermanSettings.MAX_BOARD_SIZE, _BoardHeight ) );
return _BoardHeight;
}
set
{
if( (int)_State <= (int)BoardGameState.Recruiting )
{
_BoardHeight = Math.Max( BombermanSettings.MIN_BOARD_SIZE, Math.Min( BombermanSettings.MAX_BOARD_SIZE, value ) );
if( ( _BoardHeight & 1 ) == 0 )
{
_BoardHeight += 1;
}
ResetBoard();
}
}
}
protected int _DefaultMaxBombs = 2;
protected int _DefaultBombStrength = 1;
protected bool _DefaultDetonatorMode = false;
protected bool _DefaultBaddaBoom = false;
[CommandProperty( AccessLevel.GameMaster )]
public int DefaultMaxBombs
{
get{ return _DefaultMaxBombs; }
set
{
_DefaultMaxBombs = Math.Max( 1, value );
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int DefaultBombStrength
{
get{ return _DefaultBombStrength; }
set
{
_DefaultBombStrength = Math.Max( 1, value );
}
}
[CommandProperty( AccessLevel.GameMaster )]
public bool DefaultDetonatorMode
{
get{ return _DefaultDetonatorMode; }
set
{
_DefaultDetonatorMode = value;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public bool DefaultBaddaBoom
{
get{ return _DefaultBaddaBoom; }
set
{
_DefaultBaddaBoom = value;
}
}
//main constructor
[Constructable]
public BombermanControlItem()
{
ItemID = 0xED4; //guild gravestone
Name = "Bomberman Game Controller";
BoardWidth = BombermanSettings.DEFAULT_BOARD_SIZE;
BoardHeight = BombermanSettings.DEFAULT_BOARD_SIZE;
_State = BoardGameState.Inactive;
_BoardOffset = new Point3D( 2, 2, 0 );
}
//deserialization constructor
public BombermanControlItem( Serial serial ) : base( serial )
{
}
//this method initializes the game control and connects it with this item
protected override void InitializeControl()
{
base.InitializeControl();
}
public override void UpdatePosition()
{
GameZone = new Rectangle3D( new Point3D( X + BoardOffset.X, Y + BoardOffset.X, BoardOffset.Z - 100 ), new Point3D( X + BoardOffset.X + BoardWidth, Y + BoardOffset.Y + BoardHeight, BoardOffset.Z + 100 ) );
base.UpdatePosition();
}
public override void AddPlayer( Mobile m )
{
base.AddPlayer( m );
PublicOverheadMessage( MessageType.Regular, 1153, false, "Adding " + m.Name + " to the game!" );
//if this is the first player to be added, they can also choose the board style
if( Players.Count == 1 && _AllowPlayerConfiguration )
{
PublicOverheadMessage( MessageType.Regular, 1153, false, Players[0].Name + " is now in charge of this game!" );
m.SendGump( new SelectBombermanStyleGump( m, this ) );
}
if( Players.Count < CurrentMaxPlayers )
{
int requiredplayers = CurrentMaxPlayers - Players.Count;
PublicOverheadMessage( MessageType.Regular, 1153, false, requiredplayers.ToString() + " more needed!" );
}
else
{
PublicOverheadMessage( MessageType.Regular, 1153, false, Players[0].Name + " needs to confirm style!" );
}
}
public override void RemovePlayer( Mobile m )
{
if( Players.IndexOf( m ) > -1 )
{
PublicOverheadMessage( MessageType.Regular, 1153, false, "Removing " + m.Name + " from the game!" );
}
if( Players.IndexOf( m ) == 0 && Players.Count > 1 )
{
PublicOverheadMessage( MessageType.Regular, 1153, false, Players[1].Name + " is now in charge of this game!" );
SettingsReady = false;
Players[1].SendGump( new SelectBombermanStyleGump( Players[1], this ) );
Players[1].SendMessage( "You are now in charge of setting up the game!" );
}
base.RemovePlayer( m );
if( Players.Count > 0 )
{
int requiredplayers = CurrentMaxPlayers - Players.Count;
PublicOverheadMessage( MessageType.Regular, 1153, false, requiredplayers.ToString() + " more needed!" );
}
else
{
PublicOverheadMessage( MessageType.Regular, 1153, false, "No more players... resetting." );
}
}
public override void BuildBoard()
{
UpdatePosition();
for( int i = 0; i < BoardWidth; i++ )
{
for( int j = 0; j < BoardHeight; j++ )
{
//build the ground
BombermanFloorTile groundpiece = new BombermanFloorTile( _Style );
groundpiece.RegisterToBoardGameControlItem( this, new Point3D( i, j,0 ) );
BackgroundItems.Add( groundpiece );
//build the outer walls and inner grid walls
if( i == 0 || i == BoardWidth - 1 || j == 0 || j == BoardHeight - 1 || j % 2 == 0 && i % 2 == 0 )
{
IndestructableWall wallpiece = new IndestructableWall( _Style, true );
wallpiece.RegisterToBoardGameControlItem( this, new Point3D( i, j, 0 ) );
BackgroundItems.Add( wallpiece );
}
else
{
if( _State == BoardGameState.Active ) //if a game is active, then build obstacles and such
{
//don't put obstacles in the player starting positions
if( i < 3 && j < 3 || i > BoardWidth - 4 && j < 3 || i < 3 && j > BoardHeight - 4 || i > BoardWidth - 4 && j > BoardHeight - 4 )
{
continue;
}
else if( j > BoardHeight / 2 - 2 && j < BoardHeight / 2 + 2 && ( i < 3 || i > BoardWidth - 4 ) )
{
continue;
}
else if( i > BoardWidth / 2 - 2 && i < BoardWidth / 2 + 2 && ( j < 3 || j > BoardHeight - 4 ) )
{
continue;
}
//obstacles
if( Utility.RandomDouble() < BombermanSettings.OBSTACLE_CHANCE )
{
DestructableWall wallpiece = new DestructableWall( _Style );
wallpiece.RegisterToBoardGameControlItem( this, new Point3D( i, j, 0 ) );
BackgroundItems.Add( wallpiece );
}
}
}
}
}
base.BuildBoard();
}
protected override void PrimePlayers()
{
base.PrimePlayers();
for( int i = 0; i < Players.Count; i++ )
{
Mobile player = Players[i];
Point3D movepoint;
switch( i )
{
case 0:
{
movepoint = new Point3D( X + BoardOffset.X + 1, Y + BoardOffset.Y + 1, Z + BoardOffset.Z );
break;
}
case 1:
{
movepoint = new Point3D( X + BoardOffset.X + BoardWidth - 2, Y + BoardOffset.Y + 1, Z + BoardOffset.Z );
break;
}
case 2:
{
movepoint = new Point3D( X + BoardOffset.X + 1, Y + BoardOffset.Y + BoardHeight - 2, Z + BoardOffset.Z );
break;
}
case 3:
{
movepoint = new Point3D( X + BoardOffset.X + + BoardWidth - 2, Y + BoardOffset.Y + + BoardHeight - 2, Z + BoardOffset.Z );
break;
}
case 4:
{
movepoint = new Point3D( X + BoardOffset.X + BoardWidth / 2, Y + BoardOffset.Y + 1, Z + BoardOffset.Z );
break;
}
case 5:
{
movepoint = new Point3D( X + BoardOffset.X + BoardWidth - 2, Y + BoardOffset.Y + BoardHeight / 2, Z + BoardOffset.Z );
break;
}
case 6:
{
movepoint = new Point3D( X + BoardOffset.X + BoardWidth / 2, Y + BoardOffset.Y + BoardHeight - 2, Z + BoardOffset.Z );
break;
}
case 7:
default:
{
movepoint = new Point3D( X + BoardOffset.X + 1, Y + BoardOffset.Y + BoardHeight / 2, Z + BoardOffset.Z );
break;
}
}
player.MoveToWorld( movepoint, BoardMap );
BombBag bag = new BombBag( this, _DefaultMaxBombs, _DefaultBombStrength );
BombBags.Add( bag );
bag.Owner = player;
player.Backpack.DropItem( bag );
if( _DefaultDetonatorMode )
{
BombDetonator detonator = new BombDetonator( bag );
bag.Detonator = detonator;
player.Backpack.DropItem( detonator );
}
bag.BaddaBoom = _DefaultBaddaBoom;
}
}
public void CheckForMobileVictims( Point3D location, Map map, BombBag sourcebag )
{
IPooledEnumerable ie = map.GetMobilesInRange( location, 0 );
List<Mobile> tomove = new List<Mobile>();
foreach( Mobile m in ie )
{
if( Players.IndexOf( m ) > -1 )
{
if( m != sourcebag.Owner )
{
m.SendMessage( "You've been blown up by " + sourcebag.Owner.Name + "'s blast!" );
sourcebag.Owner.SendMessage( "You've blown " + m.Name + "!" );
//handle scoring
BoardGameData.ChangeScore( GameName, sourcebag.Owner, BombermanSettings.KILL_SCORE );
BoardGameData.ChangeScore( GameName, m, BombermanSettings.DEATH_SCORE );
PublicOverheadMessage( MessageType.Regular, 1153, false, sourcebag.Owner.Name + " has blown up " + m.Name + "!" );
}
else
{
m.SendMessage( "You just blew yourself up!!" );
PublicOverheadMessage( MessageType.Regular, 1153, false, m.Name + " has just blown themself up!" );
BoardGameData.ChangeScore( GameName, m, BombermanSettings.SUICIDE_SCORE );
}
BoardGameData.AddLose( GameName, m );
m.PlaySound( m.Female? 0x32E : 0x549 );
//0x54A - yelp1
tomove.Add( m );
}
}
ie.Free();
foreach( Mobile m in tomove )
{
m.MoveToWorld( new Point3D( X - 1, Y - 1, Z ), Map );
m.SendGump( new BoardGameLostGump( m, this ) );
Players.Remove( m );
BombBag bag = (BombBag)m.Backpack.FindItemByType( typeof( BombBag ) );
if( bag != null )
{
//don't let players run around blowing stuff up outside the game while they wait for others to finish
bag.Active = false;
}
//start the timer to check for endgame, delay for 1s
}
//test big bomb chain!
StartEndGameTimer( TimeSpan.FromSeconds( 1 ) );
}
//TODO: move into base group?
protected override void OnEndGameTimer()
{
base.OnEndGameTimer();
if( Players.Count < 2 )
{
AnnounceWinner();
}
}
protected override void AnnounceWinner()
{
base.AnnounceWinner();
if( Players.Count == 1 )
{
Players[0].SendGump( new BoardGameWonGump( Players[0], this ) );
BoardGameData.ChangeScore( GameName, Players[0], BombermanSettings.WIN_SCORE );
BoardGameData.AddWin( GameName, Players[0] );
BombBag bag = (BombBag)Players[0].Backpack.FindItemByType( typeof( BombBag ) );
if( bag != null )
{
//don't let players run around blowing stuff up outside the game while they wait for others to finish
bag.Active = false;
}
PublicOverheadMessage( MessageType.Regular, 1153, false, Players[0].Name + " wins the game!" );
}
else
{
PublicOverheadMessage( MessageType.Regular, 1153, false, "It's a draw!" );
}
}
public override void EndGame()
{
base.EndGame();
if( Map != null )
{
IPooledEnumerable ie = Map.GetItemsInBounds( new Rectangle2D( new Point2D( GameZone.Start.X, GameZone.Start.Y ), new Point2D( GameZone.End.X, GameZone.End.Y ) ) );
List<BombermanUpgrade> todelete = new List<BombermanUpgrade>();
foreach( Item item in ie )
{
if( item is BombermanUpgrade )
{
todelete.Add( (BombermanUpgrade)item );
}
}
ie.Free();
foreach( BombermanUpgrade item in todelete )
{
item.Destroy();
}
//there should only be one left.. the winner
foreach( Mobile player in Players )
{
player.MoveToWorld( new Point3D( X - 1, Y - 1, Z ), Map );
}
}
foreach( BombBag bag in BombBags )
{
if( bag != null )
{
bag.Delete();
}
}
_BombBags = null;
//announce winner?
if( Players.Count == 1 )
{
Players[0].SendMessage( "You've won the game!" );
}
_Players = null;
_State = BoardGameState.Inactive;
InvalidateProperties();
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
foreach( BombBag bag in BombBags )
{
if( bag != null )
{
bag.Delete();
}
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
writer.Write( (int)_Style );
writer.Write( _DefaultMaxBombs );
writer.Write( _DefaultBombStrength );
writer.Write( _DefaultDetonatorMode );
writer.Write( _DefaultBaddaBoom );
writer.Write( BombBags.Count );
foreach( BombBag bag in BombBags )
{
writer.Write( (Item)bag );
}
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
_Style = (BombermanStyle)reader.ReadInt();
_DefaultMaxBombs = reader.ReadInt();
_DefaultBombStrength = reader.ReadInt();
_DefaultDetonatorMode = reader.ReadBool();
_DefaultBaddaBoom = reader.ReadBool();
int count = reader.ReadInt();
for( int i = 0; i < count; i++ )
{
BombBags.Add( (BombBag)reader.ReadItem() );
}
}
}
}

View File

@@ -0,0 +1,163 @@
using System;
using Server;
namespace Solaris.BoardGames
{
public enum BombermanStyle
{
Default = 0,
Rocky = 1,
Woodland = 2,
Warehouse = 3,
Ruins,
Graveyard,
Crystal,
}
//all the default settings for the bomberman game, in a convenient place
public class BombermanSettings
{
//min, max, and default bomberman playing field settings
public const int MAX_BOARD_SIZE = 65;
public const int MIN_BOARD_SIZE = 11;
public const int DEFAULT_BOARD_SIZE = 21;
//chance that a destructable wall will be generated when the gameboard is being built
public const double OBSTACLE_CHANCE = 0.7;
//delay before explosion, in seconds
public const int EXPLODE_DELAY = 3;
//propagation delay of bomb blast, in milliseconds
public const int BLAST_DELAY = 50;
//chance that a demolished wall will spawn an upgrade
public const double UPGRADE_SPAWN_CHANCE = .2;
public const int KILL_SCORE = 1;
public const int DEATH_SCORE = -1;
public const int WIN_SCORE = 2;
public const int SUICIDE_SCORE = -2;
//time until an upgrade will disappear, in seconds
public const int UPGRADE_DECAY_DELAY = 20;
public static int GetDestructableWallID( BombermanStyle style )
{
switch( style )
{
default:
case BombermanStyle.Default:
{
return 1900;
}
case BombermanStyle.Rocky:
{
return Utility.RandomMinMax( 0x1363, 0x136D );
}
case BombermanStyle.Woodland:
{
return Utility.RandomMinMax( 0xCC8, 0xCC9 );
}
case BombermanStyle.Warehouse:
{
return Utility.RandomMinMax( 0xE3C, 0xE3F );
}
case BombermanStyle.Ruins:
{
return Utility.RandomMinMax( 0x3B7, 0x3BD );
}
case BombermanStyle.Graveyard:
{
return Utility.RandomMinMax( 0x1AD8, 0x1ADC );
}
case BombermanStyle.Crystal:
{
return Utility.RandomMinMax( 0x2224, 0x222C );
}
}
}
public static int GetIndestructableWallID( BombermanStyle style )
{
switch( style )
{
default:
case BombermanStyle.Default:
{
return 1801;
}
case BombermanStyle.Rocky:
{
return 0x177A;
}
case BombermanStyle.Woodland:
{
return Utility.RandomList( new int[]{ 0xE57, 0xE59 } );
}
case BombermanStyle.Warehouse:
{
return Utility.RandomList( new int[]{ 0x720, 0x721 } );
}
case BombermanStyle.Ruins:
{
return Utility.RandomMinMax( 0x3BE, 0x3C1 );
}
case BombermanStyle.Graveyard:
{
return Utility.RandomMinMax( 0x1165, 0x1184 );
}
case BombermanStyle.Crystal:
{
return Utility.RandomList( new int[]{ 0x35EB, 0x35EC, 0x35EF, 0x35F6, 0x35F7 } );
}
}
}
public static int GetFloorTileID( BombermanStyle style )
{
switch( style )
{
default:
case BombermanStyle.Default:
{
return 0x496;
}
case BombermanStyle.Rocky:
{
return Utility.RandomMinMax( 0x53B, 0x53F );
}
case BombermanStyle.Woodland:
{
return Utility.RandomMinMax( 0x177D, 0x1781 );
}
case BombermanStyle.Warehouse:
{
return Utility.RandomMinMax( 0x4A9, 0x4AC );
}
case BombermanStyle.Ruins:
{
return Utility.RandomMinMax( 0x525, 0x528 );
}
case BombermanStyle.Graveyard:
{
return Utility.RandomMinMax( 0x515, 0x518 );
}
case BombermanStyle.Crystal:
{
return Utility.RandomMinMax( 0x579, 0x57E );
}
}
}
}
}

View File

@@ -0,0 +1,110 @@
using System;
using Server;
using Server.Items;
using Server.Network;
using Solaris.BoardGames;
namespace Server.Gumps
{
public class SelectBombermanStyleGump : SelectStyleGump
{
public override int Height{ get{ return 200 + Enum.GetNames( typeof( BombermanStyle ) ).Length * 20; } }
public SelectBombermanStyleGump( Mobile owner, BoardGameControlItem controlitem ) : base( owner, controlitem )
{
if( _ControlItem.Players.IndexOf( owner ) == -1 )
{
return;
}
AddLabel( 20, 14, 1152, "Bomberman Board Style" );
//AddButton( Width - 15, 0, 3, 4, 0, GumpButtonType.Reply, 0 );
string[] stylenames = Enum.GetNames( typeof( BombermanStyle ) );
_Y += 50;
foreach( string stylename in stylenames )
{
int index = (int)Enum.Parse( typeof( BombermanStyle ), stylename );
int buttonid = ( (int)((BombermanControlItem)_ControlItem).Style == index ? 0x2C92 : 0x2C88 );
AddButton( _X, _Y += 20, buttonid, buttonid, index + 1, GumpButtonType.Reply, 0 );
AddLabel( _X + 20, _Y - 2, 1152, stylename );
}
AddLabel( _X, _Y += 30, 1152, "Width:" );
AddLabel( _X + 90, _Y, 1152, "Height:" );
if( !_ControlItem.SettingsReady )
{
AddTextField( _X + 50, _Y, 30, 20, 1, _ControlItem.BoardWidth.ToString() );
AddTextField( _X + 140, _Y, 30, 20, 2, _ControlItem.BoardHeight.ToString() );
}
else
{
AddLabel( _X + 50, _Y, 1152, _ControlItem.BoardWidth.ToString() );
AddLabel( _X + 140, _Y, 1152, _ControlItem.BoardHeight.ToString() );
}
AddLabel( _X, _Y += 40, 1152, "Ready to start:" );
int startgamebuttonid = _ControlItem.SettingsReady ? 0xD3: 0xD2;
AddButton( _X + 120, _Y, startgamebuttonid, startgamebuttonid, 1000, GumpButtonType.Reply, 0 );
}
public override void OnResponse( NetState state, RelayInfo info )
{
base.OnResponse( state, info );
Mobile from = state.Mobile;
if( _ControlItem.Players.IndexOf( from ) != 0 )
{
return;
}
try
{
if( !_ControlItem.SettingsReady )
{
_ControlItem.BoardWidth = Int32.Parse( GetTextField( info, 1 ) );
_ControlItem.BoardHeight = Int32.Parse( GetTextField( info, 2 ) );
}
}
catch
{
}
int selection = info.ButtonID - 1;
if( selection >= 0 && !_ControlItem.SettingsReady )
{
try
{
if( info.ButtonID < 100 )
{
((BombermanControlItem)_ControlItem).Style = (BombermanStyle)selection;
}
}
catch
{
from.SendMessage( "Invalid value" );
}
}
if( info.ButtonID == 1000 )
{
_ControlItem.SettingsReady = !_ControlItem.SettingsReady;
}
if( !_ControlItem.SettingsReady || _ControlItem.Players.Count != _ControlItem.CurrentMaxPlayers )
{
from.SendGump( new SelectBombermanStyleGump( from, _ControlItem ) );
}
}
}
}

View File

@@ -0,0 +1,369 @@
using System;
using Server;
using Server.Items;
namespace Solaris.BoardGames
{
//a bomb - has a reference to a bomb candle that sits above it
public class Bomb : GamePiece
{
protected BombCandle _Candle;
protected DetonatorReceiver _Detonator;
protected BaddaBoom _BaddaBoom;
public BombBag BombBag;
public Mobile Planter;
protected FuseTimer _FuseTimer;
protected int _Strength;
//master constructor
public Bomb( BombBag bombbag ) : base( 0x2256, bombbag == null ? "Bomb" : bombbag.Owner.Name + "'s Bomb" )
{
Hue = 1;
//link this bomb up to the bomb bag it came from
BombBag = bombbag;
Planter = BombBag.Owner;
_Strength = BombBag.BombStrength;
if( BombBag.BaddaBoom )
{
_BaddaBoom = new BaddaBoom( this );
}
else
{
_Candle = new BombCandle( this );
}
if( BombBag.Detonator != null )
{
_Detonator = new DetonatorReceiver( this );
}
else
{
StartFuse();
}
}
//deserialize constructor
public Bomb( Serial serial ) : base( serial )
{
}
//start the timer for the explosion
public void StartFuse()
{
_FuseTimer = new FuseTimer( this );
_FuseTimer.Start();
}
public void Explode()
{
Explode( BlastDirection.None );
}
public void Explode( BlastDirection inhibitdirection )
{
if( _FuseTimer != null )
{
_FuseTimer.Stop();
_FuseTimer = null;
}
if( BombBag != null )
{
BombBag.Bombs.Remove( this );
}
//sound effect of explosion
Effects.PlaySound( Location, Map, Utility.RandomList( 0x11B, 0x305, 0x306, 0x307, 0x11C, 0x308, 0x11D, 0x309, 0x4CF, 0x11E, 0x207 ) );
//bomb explosion graphics effect: 0x36CB
Effects.SendLocationEffect( new Point3D( X + 1, Y + 1, Z ), Map, 0x36CB, 10 );
//set off fire blowout
foreach( int blastdirection in Enum.GetValues( typeof( BlastDirection ) ) )
{
BlastDirection curdirection = (BlastDirection)blastdirection;
if( curdirection != BlastDirection.None && curdirection != inhibitdirection )
{
BombBlast blast = new BombBlast( Location, Map, curdirection, BombBag, Planter, _Strength - 1, _BaddaBoom != null );
}
}
//check for damagable at spot
if( BombBag != null && !BombBag.Deleted )
{
BombBag.ControlItem.CheckForMobileVictims( Location, Map, BombBag );
}
Delete();
}
public override void OnLocationChange( Point3D old )
{
if ( _Candle != null )
{
_Candle.Location = new Point3D( X, Y, Z + 3 );
}
if ( _Detonator != null )
{
_Detonator.Location = new Point3D( X, Y, Z + 2 );
}
if( _BaddaBoom != null )
{
_BaddaBoom.Location = new Point3D( X, Y, Z + 2 );
}
}
public override void OnMapChange()
{
if ( _Candle != null )
{
_Candle.Map = Map;
}
if ( _Detonator != null )
{
_Detonator.Map = Map;
}
if( _BaddaBoom != null )
{
_BaddaBoom.Map = Map;
}
}
public override void Delete()
{
//stop the fuse first, before beginning the delete process!
if( _FuseTimer != null )
{
_FuseTimer.Stop();
_FuseTimer = null;
}
base.Delete();
}
public override void OnAfterDelete()
{
if( _Candle != null && !_Candle.Deleted )
{
_Candle.Delete();
}
if( _Detonator != null && !_Detonator.Deleted )
{
_Detonator.Delete();
}
if( _BaddaBoom != null && !_BaddaBoom.Deleted )
{
_BaddaBoom.Delete();
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
writer.Write( (Item)BombBag );
writer.Write( _Strength );
writer.Write( (Item)_Candle );
writer.Write( (Item)_Detonator );
writer.Write( (Item)_BaddaBoom );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
BombBag = (BombBag)reader.ReadItem();
_Strength = reader.ReadInt();
_Candle = (BombCandle)reader.ReadItem();
_Detonator = (DetonatorReceiver)reader.ReadItem();
_BaddaBoom = (BaddaBoom)reader.ReadItem();
if( _Detonator == null )
{
StartFuse();
}
}
protected class FuseTimer : Timer
{
private Bomb _Bomb;
public FuseTimer( Bomb bomb ) : base( TimeSpan.FromSeconds( BombermanSettings.EXPLODE_DELAY ), TimeSpan.FromSeconds( 1.0 ) )
{
Priority = TimerPriority.TwoFiftyMS;
_Bomb = bomb;
}
protected override void OnTick()
{
if( !_Bomb.Deleted && _Bomb.Map != null )
{
_Bomb.Explode();
}
}
}
}
public class BombCandle : GamePiece
{
Bomb _Bomb;
public BombCandle( Bomb bomb ) : base( 0x1430, bomb.Name )
{
Hue = 1;
_Bomb = bomb;
}
public BombCandle( Serial serial ) : base( serial )
{
}
public override void OnAfterDelete()
{
if ( _Bomb != null && !_Bomb.Deleted )
{
_Bomb.Delete();
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
writer.Write( (Item)_Bomb );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
_Bomb = (Bomb)reader.ReadItem();
}
}
public class DetonatorReceiver : GamePiece
{
Bomb _Bomb;
public DetonatorReceiver( Bomb bomb ) : base( 0xF13, bomb.Name )
{
_Bomb = bomb;
}
public DetonatorReceiver( Serial serial ) : base( serial )
{
}
public override void OnAfterDelete()
{
if ( _Bomb != null && !_Bomb.Deleted )
{
_Bomb.Delete();
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
writer.Write( (Item)_Bomb );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
_Bomb = (Bomb)reader.ReadItem();
}
}
//this bomb upgrade makes the bomb blasts tear thru breakable obstacles
public class BaddaBoom : GamePiece
{
Bomb _Bomb;
public BaddaBoom( Bomb bomb ) : base( 0x1858, "If you can read this, you are probably going to die..." )
{
Hue = 1161;
_Bomb = bomb;
}
public BaddaBoom( Serial serial ) : base( serial )
{
}
public override void OnAfterDelete()
{
if ( _Bomb != null && !_Bomb.Deleted )
{
_Bomb.Delete();
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
writer.Write( (Item)_Bomb );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
_Bomb = (Bomb)reader.ReadItem();
}
}
}

View File

@@ -0,0 +1,267 @@
//To enable RunUO 2.0 RC1 compatibility, uncomment the following line
//#define RunUO2RC1
using System;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.Network;
namespace Solaris.BoardGames
{
//a bomb - has a reference to a bomb candle that sits above it
public class BombBag : Item
{
protected bool _Active;
protected Mobile _Owner;
public Mobile Owner
{
get{ return _Owner; }
set
{
_Owner = value;
//disable any speed boost from polymorph, so it's fair for all players
#if RunUO2RC1
Owner.Send( Server.Network.SpeedBoost.Disabled );
#else
Owner.Send( SpeedControl.Disable );
#endif
}
}
public int MaxBombs;
public int BombStrength;
protected bool _SpeedUpgraded;
public BombDetonator Detonator;
//this indicates if the bombs have unstoppable blasts
public bool BaddaBoom;
protected List<Bomb> _Bombs;
public bool Active
{
get{ return _Active; }
set
{
_Active = value;
if( Detonator != null )
{
Detonator.Active = value;
}
}
}
public List<Bomb> Bombs
{
get
{
if( _Bombs == null )
{
_Bombs = new List<Bomb>();
}
return _Bombs;
}
}
public BombermanControlItem ControlItem;
//master constructor
public BombBag( BombermanControlItem controlitem, int maxbombs, int bombstrength ) : base( 0xE76 )
{
ControlItem = controlitem;
Hue = 1161;
Name = "Bomb Bag";
//locked down in backpack
Movable = false;
MaxBombs = maxbombs;
BombStrength = bombstrength;
Active = true;
}
//deserialize constructor
public BombBag( Serial serial ) : base( serial )
{
}
public override void OnDoubleClick( Mobile from )
{
if( Owner == null )
{
from.SendMessage( "You are now the owner of this bomb bag!" );
Owner = from;
}
//make sure the person using the bomb bag is the owner, and that it's in their backpack
if( from != Owner || !IsChildOf( from.Backpack ) || !Active )
{
from.SendMessage( "You cannot use that" );
return;
}
if( from.Followers > 0 )
{
from.SendMessage( "You can't use this with pets!" );
return;
}
//check if there's a bomb at feet already
if( BombAtFeet( from ) )
{
from.SendMessage( "There is a bomb at your feet already!" );
return;
}
if( Bombs.Count < MaxBombs )
{
Bomb newbomb = new Bomb( this );
Owner.PlaySound( 0x42 );
newbomb.MoveToWorld( new Point3D( Owner.X, Owner.Y, Owner.Z ), Owner.Map );
Bombs.Add( newbomb );
from.SendMessage( "Planting bomb!" );
}
else
{
from.SendMessage( "You have too many bombs on the field." );
}
}
//boosts the player walking speed
public void SpeedBoost()
{
_SpeedUpgraded = true;
#if RunUO2RC1
Owner.Send( Server.Network.SpeedBoost.Enabled );
#else
Owner.Send( SpeedControl.MountSpeed );
#endif
}
public void DetonateFirstBomb()
{
if( Bombs.Count > 0 )
{
Bombs[0].Explode();
}
}
//TODO: find a better place for this, like in the BombermanControlItem?
public static bool BombAtFeet( Mobile player )
{
IPooledEnumerable ie = player.Map.GetItemsInRange( player.Location, 0 );
bool founditem = false;
foreach( Item item in ie )
{
if( item is Bomb )
{
founditem = true;
break;
}
}
ie.Free();
return founditem;
}
public override void OnAfterDelete()
{
foreach( Bomb bomb in Bombs )
{
if( bomb != null )
{
bomb.Delete();
}
}
if( Detonator != null && !Detonator.Deleted )
{
Detonator.Delete();
}
if( _SpeedUpgraded )
{
#if RunUO2RC1
Owner.Send( Server.Network.SpeedBoost.Disabled );
#else
Owner.Send( SpeedControl.Disable );
#endif
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
writer.Write( Owner );
writer.Write( MaxBombs );
writer.Write( BombStrength );
writer.Write( _SpeedUpgraded );
writer.Write( (Item)Detonator );
writer.Write( (Item)ControlItem );
writer.Write( Bombs.Count );
foreach( Bomb bomb in Bombs )
{
writer.Write( (Item)bomb );
}
writer.Write( Active );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
_Owner = reader.ReadMobile();
MaxBombs = reader.ReadInt();
BombStrength = reader.ReadInt();
_SpeedUpgraded = reader.ReadBool();
Detonator = (BombDetonator)reader.ReadItem();
ControlItem = (BombermanControlItem)reader.ReadItem();
int count = reader.ReadInt();
for( int i = 0; i < count; i++ )
{
Bombs.Add( (Bomb)reader.ReadItem() );
}
Active = reader.ReadBool();
}
}
}

View File

@@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.Network;
namespace Solaris.BoardGames
{
//a detonator allows the player to select when their bombs explode
public class BombDetonator : Item
{
public bool Active;
public Mobile Owner;
protected BombBag _BombBag;
//master constructor
public BombDetonator( BombBag bag ) : base( 0xFC1 )
{
_BombBag = bag;
Hue = 1161;
Name = "Detonator";
//locked down in backpack
Movable = false;
Active = true;
}
//deserialize constructor
public BombDetonator( Serial serial ) : base( serial )
{
}
public override void OnDoubleClick( Mobile from )
{
if( Owner == null )
{
Owner = from;
}
//make sure the person using the detonator is the owner, and that it's in their backpack
if( from != Owner || !IsChildOf( from.Backpack ) || !Active )
{
from.SendMessage( "You cannot use that" );
return;
}
if( _BombBag != null )
{
_BombBag.DetonateFirstBomb();
}
}
public override void OnAfterDelete()
{
if( _BombBag != null && !_BombBag.Deleted )
{
_BombBag.Delete();
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
writer.Write( (Item)_BombBag );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
_BombBag = (BombBag)reader.ReadItem();
}
}
}

View File

@@ -0,0 +1,38 @@
using System;
using Server;
using Server.Items;
namespace Solaris.BoardGames
{
//a bomberman obstacle defines the object types
public class BombermanFloorTile : BombermanObstacle
{
public BombermanFloorTile( BombermanStyle style ) : base( BombermanSettings.GetFloorTileID( style ), "Floor" )
{
if( style == BombermanStyle.Default )
{
Hue = 0x237;
}
}
//deserialize constructor
public BombermanFloorTile( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,62 @@
using System;
using Server;
using Server.Items;
namespace Solaris.BoardGames
{
//a bomberman obstacle defines the object types
public class BombermanObstacle : GamePiece
{
public virtual bool Destructable{ get{ return false; } }
//randomize itemid constructors
public BombermanObstacle( int itemidmin, int itemidmax, string name ) : this( Utility.RandomMinMax( itemidmin, itemidmax ), name )
{
}
public BombermanObstacle( int itemidmin, int itemidmax, string name, bool blocklos ) : this( Utility.RandomMinMax( itemidmin, itemidmax ), name, blocklos )
{
}
//default no LOS blocker constructor
public BombermanObstacle( int itemid, string name ) : this( itemid, name, false )
{
}
//master constructor
public BombermanObstacle( int itemid, string name, bool blocklos ) : base( itemid, name, blocklos )
{
}
//deserialize constructor
public BombermanObstacle( Serial serial ) : base( serial )
{
}
public virtual void Destroy()
{
if( BoardGameControlItem != null )
{
BoardGameControlItem.BackgroundItems.Remove( this );
BoardGameControlItem = null;
}
Delete();
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,56 @@
using System;
using Server;
using Server.Items;
namespace Solaris.BoardGames
{
//a bomberman obstacle defines the object types
public class DestructableWall : BombermanObstacle
{
public override bool Destructable{ get{ return true; } }
public DestructableWall( BombermanStyle style ) : base( BombermanSettings.GetDestructableWallID( style ), "Bombable Wall" )
{
if( style == BombermanStyle.Default )
{
Hue = 0x3BB;
}
}
//deserialize constructor
public DestructableWall( Serial serial ) : base( serial )
{
}
public override void Destroy()
{
//spawn powerup
if( Utility.RandomDouble() < BombermanSettings.UPGRADE_SPAWN_CHANCE )
{
if( BoardGameControlItem.State == BoardGameState.Active )
{
BombermanUpgrade upgrade = BombermanUpgrade.GetRandomUpgrade();
upgrade.RegisterToBoardGameControlItem( BoardGameControlItem, new Point3D( Offset.X, Offset.Y, Offset.Z + 3 ) );
}
}
base.Destroy();
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,38 @@
using System;
using Server;
using Server.Items;
namespace Solaris.BoardGames
{
//a bomberman obstacle defines the object types
public class IndestructableWall : BombermanObstacle
{
public IndestructableWall( BombermanStyle style, bool blocklos ) : base( BombermanSettings.GetIndestructableWallID( style ), "Wall", blocklos )
{
if( style == BombermanStyle.Default )
{
Hue = 0x3E4;
}
}
//deserialize constructor
public IndestructableWall( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,50 @@
using System;
using Server;
using Server.Items;
namespace Solaris.BoardGames
{
//this causes unstoppable explosions
public class BaddaBoomUpgrade : BombermanUpgrade
{
public BaddaBoomUpgrade() : base( 0x1858, "Big BaddaBoom Upgrade" )
{
Hue = 1161;
}
//deserialize constructor
public BaddaBoomUpgrade( Serial serial ) : base( serial )
{
}
protected override void Upgrade( Mobile m )
{
base.Upgrade( m );
BombBag bag = (BombBag)m.Backpack.FindItemByType( typeof( BombBag ) );
if( bag != null )
{
bag.BaddaBoom = true;
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,48 @@
using System;
using Server;
using Server.Items;
namespace Solaris.BoardGames
{
//a bomberman obstacle defines the object types
public class BlastStrengthUpgrade : BombermanUpgrade
{
public BlastStrengthUpgrade() : base( 0x283B, "Blast Strength Upgrade" )
{
Hue = 1161;
}
//deserialize constructor
public BlastStrengthUpgrade( Serial serial ) : base( serial )
{
}
protected override void Upgrade( Mobile m )
{
base.Upgrade( m );
BombBag bag = (BombBag)m.Backpack.FindItemByType( typeof( BombBag ) );
if( bag != null )
{
bag.BombStrength += 1;
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,48 @@
using System;
using Server;
using Server.Items;
namespace Solaris.BoardGames
{
//a bomberman obstacle defines the object types
public class BombCountUpgrade : BombermanUpgrade
{
public BombCountUpgrade() : base( 0x284F, "Bomb Count Upgrade" )
{
Hue = 1;
}
//deserialize constructor
public BombCountUpgrade( Serial serial ) : base( serial )
{
}
protected override void Upgrade( Mobile m )
{
base.Upgrade( m );
BombBag bag = (BombBag)m.Backpack.FindItemByType( typeof( BombBag ) );
if( bag != null )
{
bag.MaxBombs += 1;
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,141 @@
using System;
using Server;
using Server.Items;
namespace Solaris.BoardGames
{
//bomberman upgrades are upgrades that are randomly found while demolishing the game field
public abstract class BombermanUpgrade : BombermanObstacle
{
public override bool Destructable{ get{ return true; } }
public override bool HandlesOnMovement{ get{ return true; } } // Tell the core that we implement OnMovement
protected DecayTimer _DecayTimer;
public BombermanUpgrade( int itemid, string name ) : base( itemid, name )
{
StartDecayTimer();
}
//deserialize constructor
public BombermanUpgrade( Serial serial ) : base( serial )
{
}
protected void StartDecayTimer()
{
_DecayTimer = new DecayTimer( this );
_DecayTimer.Start();
}
public override void OnMovement( Mobile m, Point3D oldLocation )
{
base.OnMovement( m, oldLocation );
if( BoardGameControlItem == null )
{
return;
}
//ignore anyone who is not a player of this game
if( BoardGameControlItem.Players.IndexOf( m ) == -1 )
{
return;
}
if( m.Location == oldLocation )
return;
if( m.InRange( this, 0 ) )
{
Upgrade( m );
Destroy();
}
}
protected virtual void Upgrade( Mobile m )
{
m.SendMessage( "You picked up an upgrade!" );
m.PlaySound( m.Female ? 0x337 : 0x44A );
}
public override void OnAfterDelete()
{
if( _DecayTimer != null )
{
_DecayTimer.Stop();
_DecayTimer = null;
}
base.OnAfterDelete();
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
StartDecayTimer();
}
protected class DecayTimer : Timer
{
private BombermanUpgrade _BombermanUpgrade;
public DecayTimer( BombermanUpgrade upgrade ) : base( TimeSpan.FromSeconds( BombermanSettings.UPGRADE_DECAY_DELAY ), TimeSpan.FromSeconds( 1.0 ) )
{
_BombermanUpgrade = upgrade;
}
protected override void OnTick()
{
_BombermanUpgrade.Destroy();
}
}
public static BombermanUpgrade GetRandomUpgrade()
{
double prizeroll = Utility.RandomDouble();
if( prizeroll < .1 )
{
return new SpeedUpgrade();
}
else if( prizeroll < .15 )
{
return new DetonatorUpgrade();
}
else if( prizeroll < .2 )
{
return new BaddaBoomUpgrade();
}
else if( prizeroll < .6 )
{
return new BlastStrengthUpgrade();
}
else
{
return new BombCountUpgrade();
}
}
}
}

View File

@@ -0,0 +1,52 @@
using System;
using Server;
using Server.Items;
namespace Solaris.BoardGames
{
//a bomberman obstacle defines the object types
public class DetonatorUpgrade : BombermanUpgrade
{
public DetonatorUpgrade() : base( 0xFC1, "Detonator" )
{
Hue = 1161;
}
//deserialize constructor
public DetonatorUpgrade( Serial serial ) : base( serial )
{
}
protected override void Upgrade( Mobile m )
{
base.Upgrade( m );
BombBag bag = (BombBag)m.Backpack.FindItemByType( typeof( BombBag ) );
if( bag != null && bag.Detonator == null )
{
BombDetonator detonator = new BombDetonator( bag );
bag.Detonator = detonator;
m.Backpack.DropItem( detonator );
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,48 @@
using System;
using Server;
using Server.Items;
namespace Solaris.BoardGames
{
//a bomberman obstacle defines the object types
public class SpeedUpgrade : BombermanUpgrade
{
public SpeedUpgrade() : base( 0x2308, "Speed Upgrade" )
{
Hue = 1152;
}
//deserialize constructor
public SpeedUpgrade( Serial serial ) : base( serial )
{
}
protected override void Upgrade( Mobile m )
{
base.Upgrade( m );
BombBag bag = (BombBag)m.Backpack.FindItemByType( typeof( BombBag ) );
if( bag != null )
{
bag.SpeedBoost();
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,190 @@
using System;
using Server;
namespace Solaris.BoardGames
{
public enum BlastDirection
{
None = 0x0,
West = 0x1,
North = 0x2,
East = 0x4,
South = 0x8
}
public class BombBlast
{
protected Point3D _Location;
protected Map _Map;
protected int _DeltaX;
protected int _DeltaY;
protected BlastDirection _Direction;
protected Mobile _Planter;
protected bool _BaddaBoom;
protected BombBag _BombBag;
protected int _Strength;
protected BlastTimer _BlastTimer;
public BombBlast( Point3D location, Map map, BlastDirection direction, BombBag bombbag, Mobile planter, int strength, bool baddaboom )
{
_Direction = direction;
_DeltaX = ( _Direction == BlastDirection.West ? -1 : 0 ) + ( _Direction == BlastDirection.East ? 1 : 0 );
_DeltaY = ( _Direction == BlastDirection.North ? -1 : 0 ) + ( _Direction == BlastDirection.South ? 1 : 0 );
_Location = new Point3D( location.X + _DeltaX, location.Y + _DeltaY, location.Z );
_Map = map;
_BombBag = bombbag;
_Planter = planter;
_Strength = strength;
_BaddaBoom = baddaboom;
_BlastTimer = new BlastTimer( this );
_BlastTimer.Start();
//check for any victims of the blast
if( _BombBag != null && !_BombBag.Deleted )
{
_BombBag.ControlItem.CheckForMobileVictims( _Location, _Map, _BombBag );
}
}
public void Explode()
{
if( _BlastTimer != null )
{
_BlastTimer.Stop();
_BlastTimer = null;
}
if( _Map == null )
{
return;
}
IPooledEnumerable ie = _Map.GetItemsInRange( _Location, 0 );
bool hitwall = false;
foreach( Item item in ie )
{
if( item is BombermanObstacle && !( item is BombermanFloorTile ) )
{
BombermanObstacle obstacle = (BombermanObstacle)item;
if( obstacle.Destructable )
{
obstacle.Destroy();
}
else
{
hitwall = true;
_Strength = 0;
}
//stop the fires here if you don't have a baddaboom bomb
if( !_BaddaBoom )
{
_Strength = 0;
}
break;
}
if( item is Bomb )
{
Bomb bomb = (Bomb)item;
//reassign who planted it so that the bomb who originally exploded will get credit for any kills
bomb.Planter = _BombBag.Owner;
bomb.Explode( ReverseDirection( _Direction ) );
//stop the fires here
_Strength = 0;
break;
}
}
ie.Free();
if( !hitwall )
{
RenderBlast();
}
//check for any victims of the blast
if( _BombBag != null && !_BombBag.Deleted )
{
_BombBag.ControlItem.CheckForMobileVictims( _Location, _Map, _BombBag );
}
if( !hitwall )
{
}
if( _Strength > 0 )
{
BombBlast newblast = new BombBlast( _Location, _Map, _Direction, _BombBag, _Planter, _Strength - 1, _BaddaBoom );
}
}
protected void RenderBlast()
{
Effects.SendLocationEffect( new Point3D( _Location.X + 1, _Location.Y + 1, _Location.Z ), _Map, Utility.RandomList( 0x36CB, 0x36BD, 0x36B0 ), 10 );
}
//this determines the opposite direction to the specified blast direction
protected BlastDirection ReverseDirection( BlastDirection direction )
{
switch( direction )
{
case BlastDirection.West:
{
return( BlastDirection.East );
}
case BlastDirection.East:
{
return( BlastDirection.West );
}
case BlastDirection.North:
{
return( BlastDirection.South );
}
case BlastDirection.South:
{
return( BlastDirection.North );
}
}
return BlastDirection.None;
}
protected class BlastTimer : Timer
{
private BombBlast _BombBlast;
public BlastTimer( BombBlast bombblast ) : base( TimeSpan.FromMilliseconds( BombermanSettings.BLAST_DELAY ), TimeSpan.FromSeconds( 1.0 ) )
{
_BombBlast = bombblast;
}
protected override void OnTick()
{
_BombBlast.Explode();
}
}
}
}

View File

@@ -0,0 +1,113 @@
Board Games and Bomberman - developed by Fenn of BES Oasis shard
=========================
If you choose to use this or develop on this, please leave this file intact.
Version: Last Modified Wednesday, May 6, 2009
========
Changelog:
==========
-Version 2009-05-05
-Improved user interface for registering players to the bomberman game. The first person to register can control the number of players while others register. Also, the control stone is more verbose
-Increased region priority around boargame. It now properly blocks spells and skills if the boardgame is contained within another region
-Added more verbose reports from the stone during bomberman game.
-Version 2009-05-01
-Fixed a long-annoying bug that causes the Bomberman game to break after a game ends. (thanks mikeymaze and fcondon!)
-Version 2009-01-26
-When the bomb is deleted, the fuse is stopped first. This may prevent bombs that blow up while being deleted. Also added some extra checks just in case. (thanks nevar2006!)
-Restructured the gameover condition. Now a tie game is properly detected, and Bomberman does not get broken when two players die at the same time. (thanks test444!)
-Plugged a crash bug when a broken boardgame is deleted.
-Version 2009-01-18
-Fixed a crash issue that was only apparent on RC1 servers. The game should now be playable with RC1 servers. (thanks purplemouse91!)
-Added a preventative measure to keep players from fooling around with pets while playing Bomberman. Players, consider this your one and only warning! (Thanks Robbie!)
-Added a staff-only context menu command that clears the game scores of the selected boardgame type (thanks oiii88!)
-Version 2009-01-15
-Added compatibility code for RunUO 2.0 RC1 servers. If you are running on a RC1-based server, open the file BoardGames\Bomberman\Items\BombBag.cs
and uncomment the second line.
-Added LOSBlockers to Bomberman's indestructable walls. This will remove any chance of PvP interference from external players. (thanks Hammerhand!)
-Added a delay to the end of the game, and win/lose gumps sent to the winner/losers of the game. (thanks test444!)
-Added staff-controllable property AllowPlayerConfiguration to BoardGameControlItem. When this is set false, the players can no longer adjust
the game's size and artwork style. Default is true. (thanks test444!)
-Added a scorekeeping system that tracks players wins, losses, and "score". Points are awarded or deducted based on whether they win, lose, blow
up another player, or blow themselves up. The score points awarded can be adjusted in the BombermanSettings.cs file. Players can view this
score listing by using the context menu on the control item. (thanks mikeymaze!)
-Improved staff control of board position with respect to controller position. When you [props the control stone, the new properties BoardLocation
and BoardMap will let the staff member choose where to position the board explicitly. Note that the board is still tied to the stone. If you
move the stone east by 5 tiles, the board, wherever it is, will also move east by 5 tiles. However, the map of the board is no longer tied to the
map of the stone, and can be set independent to the stone position. (thanks test444!)
-Version 2009-01-12
-initial release
Compatibility:
--------------
This was developed using a freshly downloaded RunUO 2.0 SVN server
-RunUO RC1 (check the Notes section for details)
-RunUO RC2
-RunUO 2.0 SVN version 300 (downloaded October 7, 2008)
Notes:
------
If you wish to use this script on a RC1-based server, you will need to edit one file. Open the file BoardGames\Bomberman\Items\BombBag.cs
and uncomment the second line. This sets it so the speedboost upgrade in Bomberman will use the correct syntax for a RC1 server.
Overview:
---------
The BoardGame system provides a base for the Bomberman system. The basic system is designed to automatically generate a collection of items to be
used in some kind of game. Players interact with a control item, and the game gets underway when all conditions are met. The game runs automatically,
moving players into the board game when it starts, and out of the game when its over. It is intended to run without any staff support.
The Bomberman game is an implementation of this base system, where players navigate an arena, cutting their way through destroyable walls, trying
to blow each other up with bombs. A bomb bag is placed in the players' backpacks. Players use this bag to place bombs at their feet.
A bomb will detonate after some time, and has a limited blast size. The number of bombs any player can place at any time is limited.
Players must blast at the breakable walls to navigate the arena. While blasting, upgrades can be found which improve the blast size or number of
bombs a player can place at once. There is also a detonator upgrade that lets a player choose when they want their bombs to blow up, and a
"big badda boom" upgrade that causes bombs to tear through destructable walls to their maximum blast size. A bomb can trigger another bomb to go off,
creating interesting chain reactions. The game ends when there is only one player left standing.
Staff can set up the game by adding the constructable BombermanControlItem device. The field is automatically generated to the southeast of the control
device. Some consideration will be needed to properly place the gamefield. Luckily, the control item and game field can be moved together like an
addon. There are various properties accessible to staff, including game field size, style, and default bomb upgrade settings.
When a player uses the control item, they are given some information and instructions related to the game. The first person to use the
control item can select the number of players, as well as some game properties. For Bomberman, they can choose the playfield size, and
the artwork style. When the required number of players have signed up for the game, the players will be automatically transported onto
the game field.
Additional controls are accessible to the staff, via the properties gump. For bomberman, staff can adjust the default upgrade
configuration for each player when they start the game. In the case of an emergency, staff can force a game over. Additionally, staff
can adjust the game artwork style and board size manually. Finally, staff can configure the game to charge gold when players play the game.
For the developer, there are various properties that can be adjusted. in the file BoardGames\Bomberman\BombermanSettings.cs, there are
various constants and variables that can be modified to suit your shard's needs.
Installation:
-------------
Basic installation: Drop this entire folder somewhere in your Scripts Directory. Be mindful of class name conflicts.
Deinstallation:
---------------
Basic deinstallation: Remove this entire folder from your scripts directory.
Contact:
--------
Questions, comments? Contact me at the RunUO Forums under username Fenn.

View File

@@ -0,0 +1,20 @@
//indicate # of players
//make some way of changing # of players when people are waiting on the setup gump
//when player 1 leaves, give the next in line the setup gump
make list of who is signed up, who is waiting
list players left in game
//announce # of players required when player join/leave
kick a player if they log out in game
spectator mode for players who want to watch
//block all hiding and stealth
create game queue when other people are waiting for game to finish

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,361 @@
using System;
using Server;
using Server.Network;
using Server.Mobiles;
using Server.Items;
namespace Server.Gumps
{
public class DoNDAdminGump : Gump
{
private Item i_Stone;
public Item Stone
{
get{ return i_Stone; }
set{ i_Stone = value; }
}
public DoNDAdminGump( Item i ) : base( 0, 0 )
{
DoNDAdminStone si = i as DoNDAdminStone;
if ( si == null )
return;
Stone = si;
Closable = true;
Disposable = true;
Dragable = true;
AddPage(0);
AddBackground(0, 0, 194, 204, 9200);
AddBackground(44, 6, 100, 40, 9200);
AddBackground(1, 47, 192, 64, 9200);
AddBackground(2, 111, 191, 88, 9200);
AddLabel(47, 5, 1160, @"Deal or No Deal");
AddLabel(59, 25, 1160, @"Admin Menu");
AddLabel(4, 50, 62, @"Total Games Played : " + si.Game);
AddLabel(4, 70, 62, @"Total Gold Taken : " + si.Game*50000);
AddLabel(4, 90, 33, @"Total Gold Given : " + si.Cash);
AddLabel(4, 115, 52, @"DeBug Mode");
AddButton(126, 115, 247, 248, 1, GumpButtonType.Reply, 0);
if ( si.DeBugger == false )
AddLabel(90, 115, 33, @"Off");
if ( si.DeBugger == true )
AddLabel(90, 115, 57, @"On");
AddLabel(4, 140, 1161, @"MoTD Commercial");
AddButton(126, 140, 247, 248, 2, GumpButtonType.Reply, 0);
AddLabel(4, 165, 1161, @"Replay (hours)");
AddTextEntry(90, 165, 25, 20, 33, 0, @"" + si.Replay);
AddButton(126, 165, 247, 248, 3, GumpButtonType.Reply, 0);
}
public override void OnResponse(NetState sender, RelayInfo info)
{
Mobile from = sender.Mobile;
PlayerMobile pm = from as PlayerMobile;
if ( pm == null )
return;
TextRelay entry0 = info.GetTextEntry(0);
string text0 = (entry0 == null ? "" : entry0.Text.Trim());
DoNDAdminStone si = Stone as DoNDAdminStone;
if ( si == null )
return;
switch(info.ButtonID)
{
case 0:
{
break;
}
case 1:
{
if ( si.DeBugger == false )
{
pm.SendMessage(57, pm.Name + "DeBug turned On!");
si.DeBugger = true;
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDAdminGump( si ) );
if (pm.HasGump( typeof( DebugGump )))
pm.CloseGump( typeof( DebugGump ) );
pm.SendGump( new DebugGump( pm ) );
break;
}
if ( si.DeBugger == true )
{
pm.SendMessage(33, pm.Name + "DeBug turned Off!");
si.DeBugger = false;
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDCommercialGump( pm ) );
if (pm.HasGump( typeof( DebugGump )))
pm.CloseGump( typeof( DebugGump ) );
break;
}
break;
}
case 2:
{
pm.SendMessage( pm.Name + ", Accessing the Commercial Text Editor!");
if (pm.HasGump( typeof( DoNDCommercialGump )))
pm.CloseGump( typeof( DoNDCommercialGump ) );
pm.SendGump( new DoNDCommercialGump( pm ) );
break;
}
case 3:
{
if ( text0 == null )
{
pm.SendMessage( pm.Name + ", you can only set it from 2 - 24 hours!");
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDAdminGump( si ) );
break;
}
if ( text0 == "0" )
{
pm.SendMessage( pm.Name + ", you can only set it from 2 - 24 hours!");
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDAdminGump( si ) );
break;
}
if ( text0 == "1" )
{
pm.SendMessage( pm.Name + ", you can only set it from 2 - 24 hours!");
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDAdminGump( si ) );
break;
}
if ( text0 == "2" )
{
si.Replay = 2;
pm.SendMessage( pm.Name + ", your replay is set for 2 game hours!");
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDAdminGump( si ) );
break;
}
if ( text0 == "3" )
{
si.Replay = 3;
pm.SendMessage( pm.Name + ", your replay is set for 3 game hours!");
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDAdminGump( si ) );
break;
}
if ( text0 == "4" )
{
si.Replay = 4;
pm.SendMessage( pm.Name + ", your replay is set for 4 game hours!");
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDAdminGump( si ) );
break;
}
if ( text0 == "5" )
{
si.Replay = 5;
pm.SendMessage( pm.Name + ", your replay is set for 5 game hours!");
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDAdminGump( si ) );
break;
}
if ( text0 == "6" )
{
si.Replay = 6;
pm.SendMessage( pm.Name + ", your replay is set for 6 game hours!");
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDAdminGump( si ) );
break;
}
if ( text0 == "7" )
{
si.Replay = 7;
pm.SendMessage( pm.Name + ", your replay is set for 7 game hours!");
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDAdminGump( si ) );
break;
}
if ( text0 == "8" )
{
si.Replay = 8;
pm.SendMessage( pm.Name + ", your replay is set for 8 game hours!");
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDAdminGump( si ) );
break;
}
if ( text0 == "9" )
{
si.Replay = 9;
pm.SendMessage( pm.Name + ", your replay is set for 9 game hours!");
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDAdminGump( si ) );
break;
}
if ( text0 == "10" )
{
si.Replay = 10;
pm.SendMessage( pm.Name + ", your replay is set for 10 game hours!");
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDAdminGump( si ) );
break;
}
if ( text0 == "11" )
{
si.Replay = 11;
pm.SendMessage( pm.Name + ", your replay is set for 11 game hours!");
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDAdminGump( si ) );
break;
}
if ( text0 == "12" )
{
si.Replay = 12;
pm.SendMessage( pm.Name + ", your replay is set for 12 game hours!");
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDAdminGump( si ) );
break;
}
if ( text0 == "13" )
{
si.Replay = 13;
pm.SendMessage( pm.Name + ", your replay is set for 13 game hours!");
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDAdminGump( si ) );
break;
}
if ( text0 == "14" )
{
si.Replay = 14;
pm.SendMessage( pm.Name + ", your replay is set for 14 game hours!");
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDAdminGump( si ) );
break;
}
if ( text0 == "15" )
{
si.Replay = 15;
pm.SendMessage( pm.Name + ", your replay is set for 15 game hours!");
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDAdminGump( si ) );
break;
}
if ( text0 == "16" )
{
si.Replay = 16;
pm.SendMessage( pm.Name + ", your replay is set for 16 game hours!");
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDAdminGump( si ) );
break;
}
if ( text0 == "17" )
{
si.Replay = 17;
pm.SendMessage( pm.Name + ", your replay is set for 17 game hours!");
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDAdminGump( si ) );
break;
}
if ( text0 == "18" )
{
si.Replay = 18;
pm.SendMessage( pm.Name + ", your replay is set for 18 game hours!");
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDAdminGump( si ) );
break;
}
if ( text0 == "19" )
{
si.Replay = 19;
pm.SendMessage( pm.Name + ", your replay is set for 19 game hours!");
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDAdminGump( si ) );
break;
}
if ( text0 == "20" )
{
si.Replay = 20;
pm.SendMessage( pm.Name + ", your replay is set for 20 game hours!");
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDAdminGump( si ) );
break;
}
if ( text0 == "21" )
{
si.Replay = 21;
pm.SendMessage( pm.Name + ", your replay is set for 21 game hours!");
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDAdminGump( si ) );
break;
}
if ( text0 == "22" )
{
si.Replay = 22;
pm.SendMessage( pm.Name + ", your replay is set for 22 game hours!");
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDAdminGump( si ) );
break;
}
if ( text0 == "23" )
{
si.Replay = 23;
pm.SendMessage( pm.Name + ", your replay is set for 23 game hours!");
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDAdminGump( si ) );
break;
}
if ( text0 == "24" )
{
si.Replay = 24;
pm.SendMessage( pm.Name + ", your replay is set for 24 game hours!");
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDAdminGump( si ) );
break;
}
pm.SendMessage( pm.Name + ", you can only set it from 2 - 24 hours!");
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDAdminGump( si ) );
break;
}
}
}
}
}

View File

@@ -0,0 +1,131 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Mobiles;
using Server.Items;
using Server.Network;
namespace Server.Gumps
{
public class DoNDCommercialGump : Gump
{
private Item i_Stone;
public Item Stone
{
get{ return i_Stone; }
set{ i_Stone = value; }
}
public DoNDCommercialGump( Mobile m ) : base( 0, 0 )
{
PlayerMobile pm = m as PlayerMobile;
if (pm == null || pm.Backpack == null)
return;
List<Item> toCheck = new List<Item>();
foreach (Item item in World.Items.Values)
{
if (item is Item)
{
if (item is DoNDAdminStone)
{
toCheck.Add(item);
continue;
}
}
}
for ( int i = 0; i < toCheck.Count; i++ )
{
if ( toCheck[i] != null )
Stone = toCheck[i];
}
Item di = pm.Backpack.FindItemByType(typeof(DoNDGameDeed) );
DoNDGameDeed gd = di as DoNDGameDeed;
DoNDAdminStone si = Stone as DoNDAdminStone;
if ( si == null )
return;
toCheck.Clear();
Closable = false;
Disposable = false;
Dragable = false;
AddPage(0);
AddBackground(2, 2, 796, 558, 9200);
AddBackground(349, 10, 100, 61, 9200);
AddLabel(352, 16, 47, @"Deal or No Deal");
AddLabel(363, 39, 47, @"Shard News");
if ( gd != null )
AddHtml( 19, 83, 765, 439, @si.SCommercial, (bool)true, (bool)true);
if ( gd != null )
AddButton(368, 533, 247, 244, 0, GumpButtonType.Reply, 0);
if ( gd == null && pm.AccessLevel > AccessLevel.GameMaster )
AddTextEntry(18, 83, 765, 436, 1161, 0, @"" + si.SCommercial);
if ( gd == null && pm.AccessLevel > AccessLevel.GameMaster )
AddButton(368, 533, 247, 244, 1, GumpButtonType.Reply, 0);
}
public override void OnResponse(NetState sender, RelayInfo info)
{
Mobile from = sender.Mobile;
TextRelay entry0 = info.GetTextEntry(0);
string text0 = (entry0 == null ? "" : entry0.Text.Trim());
PlayerMobile pm = from as PlayerMobile;
if (pm == null || pm.Backpack == null)
return;
Item di = pm.Backpack.FindItemByType(typeof(DoNDGameDeed) );
DoNDGameDeed gd = di as DoNDGameDeed;
DoNDAdminStone si = Stone as DoNDAdminStone;
switch(info.ButtonID)
{
case 0:
{
if ( gd == null )
return;
gd.Commercial = false;
if (pm.HasGump( typeof( DoNDCommercialGump )))
pm.CloseGump( typeof( DoNDCommercialGump ) );
break;
}
case 1:
{
if ( si == null )
break;
if ( text0 == null )
{
pm.SendMessage( pm.Name + ", you've not entered any text, please type something!");
if (pm.HasGump( typeof( DoNDCommercialGump )))
pm.CloseGump( typeof( DoNDCommercialGump ) );
pm.SendGump( new DoNDCommercialGump( pm ) );
break;
}
si.SCommercial = text0;
pm.SendMessage( pm.Name + ", your text has been saved and will be used for the commercial!");
if (pm.HasGump( typeof( DoNDCommercialGump )))
pm.CloseGump( typeof( DoNDCommercialGump ) );
break;
}
}
}
}
}

View File

@@ -0,0 +1,151 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Network;
namespace Server.Gumps
{
public class DebugGump : Gump
{
public DebugGump( Mobile m ) : base( 0, 0 )
{
PlayerMobile pm = m as PlayerMobile;
if (pm == null || pm.Backpack == null)
return;
Item di = pm.Backpack.FindItemByType(typeof(DoNDGameDeed) );
if ( di == null )
return;
DoNDGameDeed gd = di as DoNDGameDeed;
if ( gd == null )
return;
Closable = true;
Disposable = true;
Dragable = true;
AddPage(0);
AddBackground(5, 2, 280, 593, 9270);
AddBackground(17, 35, 256, 547, 9200);
AddBackground(221, 129, 100, 372, 9200);
AddLabel(48, 15, 1160, @"Deal or No Deal DeBug Bool Menu");
AddLabel(20, 40, 57, @"Deal On : " + gd.DealOn);
AddLabel(20, 60, 57, @"Game Start : " + gd.GameStart);
AddLabel(20, 80, 57, @"Game Over : " + gd.GameOver);
AddLabel(20, 100, 57, @"Case Select : " + gd.CaseSel);
AddLabel(20, 120, 57, @"Offer Select : " + gd.OfferSel);
AddLabel(20, 140, 57, @"Deal : " + gd.Deal);
AddLabel(20, 160, 57, @"No Deal : " + gd.NoDeal);
AddLabel(20, 180, 57, @"Trade : " + gd.Trade);
AddLabel(20, 200, 57, @"No Trade : " + gd.NoTrade);
AddLabel(20, 220, 57, @"Help : " + gd.DHelp);
AddLabel(20, 240, 57, @"Close Case : " + gd.CloseCase);
AddLabel(20, 260, 57, @"Commercial : " + gd.Commercial);
AddLabel(20, 280, 57, @"Deal 1 : " + gd.DA1);
AddLabel(20, 300, 57, @"Deal 2 : " + gd.DA2);
AddLabel(20, 320, 57, @"Deal 3 : " + gd.DA3);
AddLabel(20, 340, 57, @"Deal 4 : " + gd.DA4);
AddLabel(20, 360, 57, @"Deal 5 : " + gd.DA5);
AddLabel(20, 380, 57, @"Deal 6 : " + gd.DA6);
AddLabel(20, 400, 57, @"Deal 7 : " + gd.DA7);
AddLabel(20, 420, 57, @"Deal 8 : " + gd.DA8);
AddLabel(20, 440, 57, @"Deal 9 : " + gd.DA9);
AddLabel(20, 460, 57, @"PO : " + gd.PO);
AddLabel(20, 480, 57, @"GO : " + gd.GO);
AddLabel(20, 500, 57, @"PA : " + gd.PA);
AddLabel(20, 520, 57, @"PC : " + gd.PC);
AddLabel(20, 540, 57, @"TL : " + gd.TL);
AddLabel(20, 560, 57, @"Replay : " + gd.DReplay);
AddLabel(240, 137, 1160, @"Pick Order");
if ( gd.StageOne == true )
AddLabel(235, 157, 57, @"Stage One");
if ( gd.StageTwo == true )
AddLabel(235, 177, 57, @"Stage Two");
if ( gd.StageThree == true )
AddLabel(235, 197, 57, @"Stage Three");
if ( gd.StageFour == true )
AddLabel(235, 117, 57, @"Stage Four");
if ( gd.StageFive == true )
AddLabel(235, 237, 57, @"Stage Five");
if ( gd.StageSix == true )
AddLabel(235, 257, 57, @"Stage Six");
if ( gd.StageSeven == true )
AddLabel(235, 277, 57, @"Stage Seven");
if ( gd.StageEight == true )
AddLabel(235, 297, 57, @"Stage Eight");
if ( gd.StageNine == true )
AddLabel(235, 317, 57, @"Stage Nine");
if ( gd.StageTen == true )
AddLabel(235, 337, 57, @"Stage Ten");
if ( gd.SubStageOne == true )
AddLabel(235, 357, 57, @"Sub One");
if ( gd.SubStageTwo == true )
AddLabel(235, 377, 57, @"Sub Two");
if ( gd.SubStageThree == true )
AddLabel(235, 397, 57, @"Sub Three");
if ( gd.SubStageFour == true )
AddLabel(235, 417, 57, @"Sub Four");
if ( gd.SubStageFive == true )
AddLabel(235, 437, 57, @"Sub Five");
if ( gd.SubStageSix == true )
AddLabel(235, 457, 57, @"Sub Six");
if ( gd.SubStageOne2 == true )
AddLabel(235, 357, 57, @"Sub One");
if ( gd.SubStageTwo2 == true )
AddLabel(235, 377, 57, @"Sub Two");
if ( gd.SubStageThree2 == true )
AddLabel(235, 397, 57, @"Sub Three");
if ( gd.SubStageFour2 == true )
AddLabel(235, 417, 57, @"Sub Four");
if ( gd.SubStageFive2 == true )
AddLabel(235, 437, 57, @"Sub Five");
if ( gd.SubStageOne3 == true )
AddLabel(235, 357, 57, @"Sub One");
if ( gd.SubStageTwo3 == true )
AddLabel(235, 377, 57, @"Sub Two");
if ( gd.SubStageThree3 == true )
AddLabel(235, 397, 57, @"Sub Three");
if ( gd.SubStageFour3 == true )
AddLabel(235, 417, 57, @"Sub Four");
if ( gd.SubStageOne4 == true )
AddLabel(235, 357, 57, @"Sub One");
if ( gd.SubStageTwo4 == true )
AddLabel(235, 377, 57, @"Sub Two");
if ( gd.SubStageThree4 == true )
AddLabel(235, 397, 57, @"Sub Three");
if ( gd.SubStageOne5 == true )
AddLabel(235, 357, 57, @"Sub One");
if ( gd.SubStageTwo5 == true )
AddLabel(235, 377, 57, @"Sub Two");
if ( gd.SubStageOne6 == true )
AddLabel(235, 357, 57, @"Sub One");
if ( gd.SubStageOne7 == true )
AddLabel(235, 357, 57, @"Sub One");
if ( gd.SubStageOne8 == true )
AddLabel(235, 357, 57, @"Sub One");
if ( gd.SubStageOne9 == true )
AddLabel(235, 357, 57, @"Sub One");
if ( gd.Banker == true )
AddLabel(235, 477, 33, @"Banker");
}
}
}

View File

@@ -0,0 +1,658 @@
using System;
using Server;
using Server.Network;
using Server.Mobiles;
using Server.Items;
namespace Server.Gumps
{
public class DoNDMainGump : Gump
{
public DoNDMainGump( Mobile m, Item i ) : base( 0, -25 )
{
PlayerMobile pm = m as PlayerMobile;
if ( pm == null )
return;
if ( i == null )
return;
DoNDGameDeed gd = i as DoNDGameDeed;
//Main Gump Props
Closable = false;
Disposable = false;
Dragable = true;
//Page #
AddPage(0);
//Title Deal or No Deal
AddImage(328, 431, 100);
AddLabel(342, 450, 1160, @"DEAL");
AddLabel(381, 450, 1160, @"or");
AddLabel(401, 450, 1160, @"NO DEAL");
//Backgrounds
AddBackground(0, 320, 119, 280, 9500);
AddBackground(681, 320, 119, 280, 9500);
AddBackground(118, 469, 564, 131, 9500);
AddBackground(129, 486, 100, 100, 9300);
AddBackground(234, 486, 244, 98, 9350);
AddBackground(484, 484, 185, 99, 9400);
//Prize Backgrounds
AddImage(4, 436, 2062);
AddImage(4, 456, 2062);
AddImage(4, 476, 2062);
AddImage(4, 496, 2062);
AddImage(4, 516, 2062);
AddImage(4, 536, 2062);
AddImage(4, 556, 2062);
AddImage(4, 575, 2062);
AddImage(4, 356, 2062);
AddImage(4, 336, 2062);
AddImage(4, 376, 2062);
AddImage(4, 396, 2062);
AddImage(4, 416, 2062);
AddImage(685, 436, 2062);
AddImage(685, 456, 2062);
AddImage(685, 476, 2062);
AddImage(685, 496, 2062);
AddImage(685, 516, 2062);
AddImage(685, 536, 2062);
AddImage(685, 556, 2062);
AddImage(685, 575, 2062);
AddImage(685, 356, 2062);
AddImage(685, 336, 2062);
AddImage(685, 376, 2062);
AddImage(685, 396, 2062);
AddImage(685, 416, 2062);
//Left Side Prizes (1160 true / 1151 false)
if ( gd.Zero == true )
AddLabel(43, 335, 1160, @"Prize");
if ( gd.Zero == false )
AddLabel(43, 335, 1151, @"Prize");
if ( gd.One == true )
AddLabel(50, 356, 1160, @"$1");
if ( gd.One == false )
AddLabel(50, 356, 1151, @"$1");
if ( gd.Five == true )
AddLabel(49, 375, 1160, @"$5");
if ( gd.Five == false )
AddLabel(49, 375, 1151, @"$5");
if ( gd.Ten == true )
AddLabel(45, 394, 1160, @"$10");
if ( gd.Ten == false )
AddLabel(45, 394, 1151, @"$10");
if ( gd.TweFive == true )
AddLabel(43, 415, 1160, @"$25");
if ( gd.TweFive == false )
AddLabel(43, 415, 1151, @"$25");
if ( gd.Fifty == true )
AddLabel(43, 435, 1160, @"$50");
if ( gd.Fifty == false )
AddLabel(43, 435, 1151, @"$50");
if ( gd.SevFive == true )
AddLabel(43, 455, 1160, @"$75");
if ( gd.SevFive == false )
AddLabel(43, 455, 1151, @"$75");
if ( gd.OneH == true )
AddLabel(41, 474, 1160, @"$100");
if ( gd.OneH == false )
AddLabel(41, 474, 1151, @"$100");
if ( gd.TwoH == true )
AddLabel(38, 494, 1160, @"$200");
if ( gd.TwoH == false )
AddLabel(38, 494, 1151, @"$200");
if ( gd.ThreeH == true )
AddLabel(38, 514, 1160, @"$300");
if ( gd.ThreeH == false )
AddLabel(38, 514, 1151, @"$300");
if ( gd.FourH == true )
AddLabel(38, 535, 1160, @"$400");
if ( gd.FourH == false )
AddLabel(38, 535, 1151, @"$400");
if ( gd.FiveH == true )
AddLabel(38, 555, 1160, @"$500");
if ( gd.FiveH == false )
AddLabel(38, 555, 1151, @"$500");
if ( gd.SevFiveH == true )
AddLabel(38, 574, 1160, @"$750");
if ( gd.SevFiveH == false )
AddLabel(38, 574, 1151, @"$750");
//Right Side Prizes (1160 true / 1151 false)
if ( gd.OneTH == true )
AddLabel(714, 335, 1160, @"$1,000");
if ( gd.OneTH == false )
AddLabel(714, 335, 1151, @"$1,000");
if ( gd.FiveTH == true )
AddLabel(713, 354, 1160, @"$5,000");
if ( gd.FiveTH == false )
AddLabel(713, 354, 1151, @"$5,000");
if ( gd.TenTH == true )
AddLabel(711, 375, 1160, @"$10,000");
if ( gd.TenTH == false )
AddLabel(711, 375, 1151, @"$10,000");
if ( gd.TweFiveTH == true )
AddLabel(710, 395, 1160, @"$25,000");
if ( gd.TweFiveTH == false )
AddLabel(710, 395, 1151, @"$25,000");
if ( gd.FiftyTH == true )
AddLabel(710, 414, 1160, @"$50,000");
if ( gd.FiftyTH == false )
AddLabel(710, 414, 1151, @"$50,000");
if ( gd.SevFiveTH == true )
AddLabel(710, 435, 1160, @"$75,000");
if ( gd.SevFiveTH == false )
AddLabel(710, 435, 1151, @"$75,000");
if ( gd.OneHT == true )
AddLabel(708, 455, 1160, @"$100,000");
if ( gd.OneHT == false )
AddLabel(708, 455, 1151, @"$100,000");
if ( gd.TwoHT == true )
AddLabel(705, 475, 1160, @"$200,000");
if ( gd.TwoHT == false )
AddLabel(705, 475, 1151, @"$200,000");
if ( gd.ThreeHT == true )
AddLabel(705, 495, 1160, @"$300,000");
if ( gd.ThreeHT == false )
AddLabel(705, 495, 1151, @"$300,000");
if ( gd.FourHT == true )
AddLabel(706, 515, 1160, @"$400,000");
if ( gd.FourHT == false )
AddLabel(706, 515, 1151, @"$400,000");
if ( gd.FiveHT == true )
AddLabel(706, 535, 1160, @"$500,000");
if ( gd.FiveHT == false )
AddLabel(706, 535, 1151, @"$500,000");
if ( gd.SevFiveHT == true )
AddLabel(706, 555, 1160, @"$750,000");
if ( gd.SevFiveHT == false )
AddLabel(706, 555, 1151, @"$750,000");
if ( gd.OneMil == true )
AddLabel(701, 574, 1160, @"$1,000,000");
if ( gd.OneMil == false )
AddLabel(701, 574, 1151, @"$1,000,000");
//Case's to Pick (in order from 1 - 6)
AddLabel(134, 491, 1160, @"Case's to Pick");
if ( gd.SubStageOne == true )
{
AddImage(139, 525, 2225);
AddImage(169, 525, 2226);
AddImage(198, 525, 2227);
AddImage(138, 557, 2228);
AddImage(168, 557, 2229);
AddImage(198, 557, 2230);
}
if ( gd.SubStageTwo == true )
{
AddImage(139, 525, 2225);
AddImage(169, 525, 2226);
AddImage(198, 525, 2227);
AddImage(138, 557, 2228);
AddImage(168, 557, 2229);
}
if ( gd.SubStageThree == true )
{
AddImage(139, 525, 2225);
AddImage(169, 525, 2226);
AddImage(198, 525, 2227);
AddImage(138, 557, 2228);
}
if ( gd.SubStageFour == true )
{
AddImage(139, 525, 2225);
AddImage(169, 525, 2226);
AddImage(198, 525, 2227);
}
if ( gd.SubStageFive == true )
{
AddImage(139, 525, 2225);
AddImage(169, 525, 2226);
}
if ( gd.SubStageSix == true )
{
AddImage(139, 525, 2225);
}
if ( gd.SubStageOne2 == true )
{
AddImage(139, 525, 2225);
AddImage(169, 525, 2226);
AddImage(198, 525, 2227);
AddImage(138, 557, 2228);
AddImage(168, 557, 2229);
}
if ( gd.SubStageTwo2 == true )
{
AddImage(139, 525, 2225);
AddImage(169, 525, 2226);
AddImage(198, 525, 2227);
AddImage(138, 557, 2228);
}
if ( gd.SubStageThree2 == true )
{
AddImage(139, 525, 2225);
AddImage(169, 525, 2226);
AddImage(198, 525, 2227);
}
if ( gd.SubStageFour2 == true )
{
AddImage(139, 525, 2225);
AddImage(169, 525, 2226);
}
if ( gd.SubStageFive2 == true )
{
AddImage(139, 525, 2225);
}
if ( gd.SubStageOne3 == true )
{
AddImage(139, 525, 2225);
AddImage(169, 525, 2226);
AddImage(198, 525, 2227);
AddImage(138, 557, 2228);
}
if ( gd.SubStageTwo3 == true )
{
AddImage(139, 525, 2225);
AddImage(169, 525, 2226);
AddImage(198, 525, 2227);
}
if ( gd.SubStageThree3 == true )
{
AddImage(139, 525, 2225);
AddImage(169, 525, 2226);
}
if ( gd.SubStageFour3 == true )
{
AddImage(139, 525, 2225);
}
if ( gd.SubStageOne4 == true )
{
AddImage(139, 525, 2225);
AddImage(169, 525, 2226);
AddImage(198, 525, 2227);
}
if ( gd.SubStageTwo4 == true )
{
AddImage(139, 525, 2225);
AddImage(169, 525, 2226);
}
if ( gd.SubStageThree4 == true )
{
AddImage(139, 525, 2225);
}
if ( gd.SubStageOne5 == true )
{
AddImage(139, 525, 2225);
AddImage(169, 525, 2226);
}
if ( gd.SubStageTwo5 == true )
{
AddImage(139, 525, 2225);
}
if ( gd.SubStageOne6 == true )
{
AddImage(139, 525, 2225);
}
if ( gd.SubStageOne7 == true )
{
AddImage(139, 525, 2225);
}
if ( gd.SubStageOne8 == true )
{
AddImage(139, 525, 2225);
}
if ( gd.SubStageOne9 == true )
{
AddImage(139, 525, 2225);
}
//Previous Bank Offers
AddLabel(506, 489, 1160, @"Previous Bank Offer's");
AddLabel(492, 507, 1160, @"1 : " + gd.DA1);
AddLabel(489, 525, 1160, @"2 : " + gd.DA2);
AddLabel(489, 543, 1160, @"3 : " + gd.DA3);
AddLabel(489, 561, 1160, @"4 : " + gd.DA4);
AddLabel(575, 507, 1160, @"5 : " + gd.DA5);
AddLabel(575, 525, 1160, @"6 : " + gd.DA6);
AddLabel(575, 543, 1160, @"7 : " + gd.DA7);
AddLabel(575, 561, 1160, @"8 : " + gd.DA8);
//Game Information Menu
AddLabel(281, 490, 1160, @"Game Information Menu");
if ( gd.PA == 0 )
AddHtml( 243, 514, 223, 60, @"Please pick your case! type Case# or Help", (bool)true, (bool)true);
if ( gd.DHelp == true )
AddHtml( 243, 514, 223, 60, @"This area will always have next game step information when playing deal or no deal, the game is speech driven so you'll have to type in all of your choices. The choices that are avalible jurying the game are : Deal : NoDeal : Trade : NoTrade : Case# : EndGame : Help : The explaination of each command are listed here : Deal, say this to accept Banker's Deal when you get Banker's offer. NoDeal, say this to reject the Banker's offer. Trade, say this to trade case at the end of game. NoTrade, say this to keep your case at the end of game. Case#, say Case and replace the # with the case number you want to pick. EndGame, say this to end the game at anytime jurying a game. Help, say this to get this help section. HearOffer, say this to hear the bankers offer!", (bool)true, (bool)true);
if ( gd.DHelp != true )
{
if ( gd.StageOne == true )
{
if ( gd.SubStageOne == true )
AddHtml( 243, 514, 223, 60, @"Pick Six Case's! type Case#", (bool)true, (bool)true);
if ( gd.SubStageTwo == true )
AddHtml( 243, 514, 223, 60, @"Pick Five Case's! type Case#", (bool)true, (bool)true);
if ( gd.SubStageThree == true )
AddHtml( 243, 514, 223, 60, @"Pick Four case's! type Case#", (bool)true, (bool)true);
if ( gd.SubStageFour == true )
AddHtml( 243, 514, 223, 60, @"Pick Three Case's! type Case#", (bool)true, (bool)true);
if ( gd.SubStageFive == true )
AddHtml( 243, 514, 223, 60, @"Pick Two Case's! type Case#", (bool)true, (bool)true);
if ( gd.SubStageSix == true )
AddHtml( 243, 514, 223, 60, @"Pick One Case! type Case#", (bool)true, (bool)true);
if ( gd.Banker == true && gd.OfferSel == true )
AddHtml( 243, 514, 223, 60, @"Take Banker's offer? type Deal or NoDeal", (bool)true, (bool)true);
if ( gd.Banker == false && gd.OfferSel == true )
AddHtml( 243, 514, 223, 60, @"Check out Banker's Offer! type HearOffer", (bool)true, (bool)true);
}
if ( gd.StageTwo == true )
{
if ( gd.SubStageOne2 == true )
AddHtml( 243, 514, 223, 60, @"Pick Five Case's! type Case#", (bool)true, (bool)true);
if ( gd.SubStageTwo2 == true )
AddHtml( 243, 514, 223, 60, @"Pick Four case's! type Case#", (bool)true, (bool)true);
if ( gd.SubStageThree2 == true )
AddHtml( 243, 514, 223, 60, @"Pick Three Case's! type Case#", (bool)true, (bool)true);
if ( gd.SubStageFour2 == true )
AddHtml( 243, 514, 223, 60, @"Pick Two Case's! type Case#", (bool)true, (bool)true);
if ( gd.SubStageFive2 == true )
AddHtml( 243, 514, 223, 60, @"Pick One Case! type Case#", (bool)true, (bool)true);
if ( gd.Banker == true && gd.OfferSel == true )
AddHtml( 243, 514, 223, 60, @"Take Banker's offer? type Deal or NoDeal", (bool)true, (bool)true);
if ( gd.Banker == false && gd.OfferSel == true )
AddHtml( 243, 514, 223, 60, @"Check out Banker's Offer! type HearOffer", (bool)true, (bool)true);
}
if ( gd.StageThree == true )
{
if ( gd.SubStageOne3 == true )
AddHtml( 243, 514, 223, 60, @"Pick Four case's! type Case#", (bool)true, (bool)true);
if ( gd.SubStageTwo3 == true )
AddHtml( 243, 514, 223, 60, @"Pick Three Case's! type Case#", (bool)true, (bool)true);
if ( gd.SubStageThree3 == true )
AddHtml( 243, 514, 223, 60, @"Pick Two Case's! type Case#", (bool)true, (bool)true);
if ( gd.SubStageFour3 == true )
AddHtml( 243, 514, 223, 60, @"Pick One Case! type Case#", (bool)true, (bool)true);
if ( gd.Banker == true && gd.OfferSel == true )
AddHtml( 243, 514, 223, 60, @"Take Banker's offer? type Deal or NoDeal", (bool)true, (bool)true);
if ( gd.Banker == false && gd.OfferSel == true )
AddHtml( 243, 514, 223, 60, @"Check out Banker's Offer! type HearOffer", (bool)true, (bool)true);
}
if ( gd.StageFour == true )
{
if ( gd.SubStageOne4 == true )
AddHtml( 243, 514, 223, 60, @"Pick Three Case's! type Case#", (bool)true, (bool)true);
if ( gd.SubStageTwo4 == true )
AddHtml( 243, 514, 223, 60, @"Pick Two Case's! type Case#", (bool)true, (bool)true);
if ( gd.SubStageThree4 == true )
AddHtml( 243, 514, 223, 60, @"Pick One Case! type Case#", (bool)true, (bool)true);
if ( gd.Banker == true && gd.OfferSel == true )
AddHtml( 243, 514, 223, 60, @"Take Banker's offer? type Deal or NoDeal", (bool)true, (bool)true);
if ( gd.Banker == false && gd.OfferSel == true )
AddHtml( 243, 514, 223, 60, @"Check out Banker's Offer! type HearOffer", (bool)true, (bool)true);
}
if ( gd.StageFive == true )
{
if ( gd.SubStageOne5 == true )
AddHtml( 243, 514, 223, 60, @"Pick Two Case's! type Case#", (bool)true, (bool)true);
if ( gd.SubStageTwo5 == true )
AddHtml( 243, 514, 223, 60, @"Pick One Case! type Case#", (bool)true, (bool)true);
if ( gd.Banker == true && gd.OfferSel == true )
AddHtml( 243, 514, 223, 60, @"Take Banker's offer? type Deal or NoDeal", (bool)true, (bool)true);
if ( gd.Banker == false && gd.OfferSel == true )
AddHtml( 243, 514, 223, 60, @"Check out Banker's Offer! type HearOffer", (bool)true, (bool)true);
}
if ( gd.StageSix == true )
{
if ( gd.SubStageOne6 == true )
AddHtml( 243, 514, 223, 60, @"Pick One Case! type Case#", (bool)true, (bool)true);
if ( gd.Banker == true && gd.OfferSel == true )
AddHtml( 243, 514, 223, 60, @"Take Banker's offer? type Deal or NoDeal", (bool)true, (bool)true);
if ( gd.Banker == false && gd.OfferSel == true )
AddHtml( 243, 514, 223, 60, @"Check out Banker's Offer! type HearOffer", (bool)true, (bool)true);
}
if ( gd.StageSeven == true )
{
if ( gd.SubStageOne7 == true )
AddHtml( 243, 514, 223, 60, @"Pick One Case! type Case#", (bool)true, (bool)true);
if ( gd.Banker == true && gd.OfferSel == true )
AddHtml( 243, 514, 223, 60, @"Take Banker's offer? type Deal or NoDeal", (bool)true, (bool)true);
if ( gd.Banker == false && gd.OfferSel == true )
AddHtml( 243, 514, 223, 60, @"Check out Banker's Offer! type HearOffer", (bool)true, (bool)true);
}
if ( gd.StageEight == true )
{
if ( gd.SubStageOne8 == true )
AddHtml( 243, 514, 223, 60, @"Pick One Case! type Case#", (bool)true, (bool)true);
if ( gd.Banker == true && gd.OfferSel == true )
AddHtml( 243, 514, 223, 60, @"Take Banker's offer? type Deal or NoDeal", (bool)true, (bool)true);
if ( gd.Banker == false && gd.OfferSel == true )
AddHtml( 243, 514, 223, 60, @"Check out Banker's Offer! type HearOffer", (bool)true, (bool)true);
}
if ( gd.StageNine == true )
{
if ( gd.SubStageOne9 == true )
AddHtml( 243, 514, 223, 60, @"Pick One Case! type Case#", (bool)true, (bool)true);
if ( gd.Banker == true && gd.OfferSel == true )
AddHtml( 243, 514, 223, 60, @"Take Banker's offer? type Deal or NoDeal", (bool)true, (bool)true);
if ( gd.Banker == false && gd.OfferSel == true )
AddHtml( 243, 514, 223, 60, @"Check out Banker's Offer! type HearOffer", (bool)true, (bool)true);
}
if ( gd.StageTen == true )
{
if ( gd.Trade == false )
{
if ( gd.NoTrade == true )
AddHtml( 243, 514, 223, 60, @"Checking Last Case", (bool)true, (bool)true);
if ( gd.NoTrade == false )
AddHtml( 243, 514, 223, 60, @"Trade Case? type Trade or NoTrade", (bool)true, (bool)true);
}
if ( gd.Trade == true )
AddHtml( 243, 514, 223, 60, @"Trading Case's", (bool)true, (bool)true);
}
}
//Awaiting Answer Gump
if ( gd.OfferSel == true )
{
AddBackground(139, 512, 79, 69, 9200);
AddImage(150, 516, 223);
}
if ( gd.StageTen == true )
{
AddBackground(139, 512, 79, 69, 9200);
AddImage(150, 516, 223);
}
//Case Ammount Gump
if ( gd.CloseCase == false && gd.Banker == false )
{
if ( gd.PC != 0 && gd.PO > 0 )
{
Timer i_timer = new CloseCaseTimer( pm, gd );
i_timer.Start();
AddImage(297, 157, 75);
if ( gd.PC == 1 )
{
AddLabel(359, 234, 1160, @"$1,000,000");
}
if ( gd.PC == 2 )
{
AddLabel(362, 234, 1160, @"$750,000");
}
if ( gd.PC == 3 )
{
AddLabel(362, 234, 1160, @"$500,000");
}
if ( gd.PC == 4 )
{
AddLabel(362, 234, 1160, @"$400,000");
}
if ( gd.PC == 5 )
{
AddLabel(362, 234, 1160, @"$300,000");
}
if ( gd.PC == 6 )
{
AddLabel(362, 234, 1160, @"$200,000");
}
if ( gd.PC == 7 )
{
AddLabel(362, 234, 1160, @"$100,000");
}
if ( gd.PC == 8 )
{
AddLabel(365, 234, 1160, @"$75,000");
}
if ( gd.PC == 9 )
{
AddLabel(365, 234, 1160, @"$50,000");
}
if ( gd.PC == 10 )
{
AddLabel(365, 234, 1160, @"$25,000");
}
if ( gd.PC == 11 )
{
AddLabel(365, 234, 1160, @"$10,000");
}
if ( gd.PC == 12 )
{
AddLabel(368, 234, 1160, @"$5,000");
}
if ( gd.PC == 13 )
{
AddLabel(368, 234, 1160, @"$1,000");
}
if ( gd.PC == 14 )
{
AddLabel(371, 234, 1160, @"$750");
}
if ( gd.PC == 15 )
{
AddLabel(371, 234, 1160, @"$500");
}
if ( gd.PC == 16 )
{
AddLabel(371, 234, 1160, @"$400");
}
if ( gd.PC == 17 )
{
AddLabel(371, 234, 1160, @"$300");
}
if ( gd.PC == 18 )
{
AddLabel(371, 234, 1160, @"$200");
}
if ( gd.PC == 19 )
{
AddLabel(371, 234, 1160, @"$100");
}
if ( gd.PC == 20 )
{
AddLabel(374, 234, 1160, @"$75");
}
if ( gd.PC == 21 )
{
AddLabel(374, 234, 1160, @"$50");
}
if ( gd.PC == 22 )
{
AddLabel(374, 234, 1160, @"$25");
}
if ( gd.PC == 23 )
{
AddLabel(374, 234, 1160, @"$10");
}
if ( gd.PC == 24 )
{
AddLabel(377, 234, 1160, @"$5");
}
if ( gd.PC == 25 )
{
AddLabel(377, 234, 1160, @"$1");
}
if ( gd.PC == 26 )
{
AddLabel(368, 234, 1160, @"Prize");
}
}
}
//Bank Offer Gump
if ( gd.OfferSel == true && gd.Banker == true )
{
if ( gd.StageOne == true )
{
AddImage(298, 156, 67);
AddLabel(361, 214, 36, @"Banks Offer");
AddLabel(364, 233, 1160, @"$" + gd.DA1);
}
if ( gd.StageTwo == true )
{
AddImage(298, 156, 67);
AddLabel(361, 214, 36, @"Banks Offer");
AddLabel(364, 233, 1160, @"$" + gd.DA2);
}
if ( gd.StageThree == true )
{
AddImage(298, 156, 67);
AddLabel(361, 214, 36, @"Banks Offer");
AddLabel(364, 233, 1160, @"$" + gd.DA3);
}
if ( gd.StageFour == true )
{
AddImage(298, 156, 67);
AddLabel(361, 214, 36, @"Banks Offer");
AddLabel(364, 233, 1160, @"$" + gd.DA4);
}
if ( gd.StageFive == true )
{
AddImage(298, 156, 67);
AddLabel(361, 214, 36, @"Banks Offer");
AddLabel(364, 233, 1160, @"$" + gd.DA5);
}
if ( gd.StageSix == true )
{
AddImage(298, 156, 67);
AddLabel(361, 214, 36, @"Banks Offer");
AddLabel(364, 233, 1160, @"$" + gd.DA6);
}
if ( gd.StageSeven == true )
{
AddImage(298, 156, 67);
AddLabel(361, 214, 36, @"Banks Offer");
AddLabel(364, 233, 1160, @"$" + gd.DA7);
}
if ( gd.StageEight == true )
{
AddImage(298, 156, 67);
AddLabel(361, 214, 36, @"Banks Offer");
AddLabel(364, 233, 1160, @"$" + gd.DA8);
}
if ( gd.StageNine == true )
{
AddImage(298, 156, 67);
AddLabel(361, 214, 36, @"Banks Offer");
AddLabel(364, 233, 1160, @"$" + gd.DA9);
}
}
//Bankers Calling Gump
if ( gd.OfferSel == true && gd.StageTen != true )
{
AddLabel(10, 275, 36, @"Banker's Calling");
AddImage(12, 250, 40);
AddImage(12, 260, 40);
AddImage(12, 270, 40);
AddImage(12, 293, 40);
AddImage(12, 303, 40);
AddImage(12, 313, 40);
AddLabel(690, 275, 36, @"Banker's Calling");
AddImage(692, 250, 40);
AddImage(692, 260, 40);
AddImage(692, 270, 40);
AddImage(692, 293, 40);
AddImage(692, 303, 40);
AddImage(692, 313, 40);
}
//Text Command Entry Area
AddBackground(1, 600, 797, 27, 9200);
AddLabel(200, 604, 51, @"<Type in Game Commands Here : Case#, Deal, NoDeal, HearOffer, Trade, NoTrade, EndGame, Help>");
//Credits
AddLabel(349, 581, 1152, @"By : Tiamat13");
}
}
}

View File

@@ -0,0 +1,694 @@
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class DoNDStageAddon : BaseAddon
{
public override BaseAddonDeed Deed
{
get
{
return new DoNDStageAddonDeed();
}
}
[ Constructable ]
public DoNDStageAddon()
{
AddonComponent ac;
ac = new AddonComponent( 1809 );
AddComponent( ac, 0, 7, 3 );
ac = new AddonComponent( 1802 );
AddComponent( ac, 1, 7, 3 );
ac = new AddonComponent( 1807 );
AddComponent( ac, 2, 7, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 7, -5, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 7, -4, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 7, -3, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 7, -2, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 7, -1, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 7, 0, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 7, 1, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 7, 2, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 7, 3, 3 );
ac = new AddonComponent( 1807 );
AddComponent( ac, 7, 4, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -3, -4, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -3, -3, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -3, -2, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -2, -4, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -2, -3, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -2, -2, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -1, -4, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -1, -3, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -1, -2, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 0, -4, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 0, -3, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 0, -2, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 1, -4, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 1, -3, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 1, -2, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 2, -4, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 2, -3, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 2, -2, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 3, -4, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 3, -3, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 3, -2, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 4, -4, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 4, -3, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 4, -2, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 5, -4, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 5, -3, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 5, -2, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 1, -1, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 1, 0, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -3, -4, 8 );
ac = new AddonComponent( 1807 );
AddComponent( ac, 5, -3, 8 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -2, -4, 8 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -2, -3, 8 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -1, -4, 8 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -1, -3, 8 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 0, -4, 8 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 0, -3, 8 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 1, -4, 8 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 1, -3, 8 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 2, -4, 8 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 2, -3, 8 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 3, -4, 8 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 3, -3, 8 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 4, -4, 8 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 4, -3, 8 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 5, -4, 8 );
ac = new AddonComponent( 1809 );
AddComponent( ac, -3, -3, 8 );
ac = new AddonComponent( 1807 );
AddComponent( ac, 4, -4, 13 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -1, -4, 13 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 0, -4, 13 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 1, -4, 13 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 2, -4, 13 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 3, -4, 13 );
ac = new AddonComponent( 1809 );
AddComponent( ac, -2, -4, 13 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 2, -1, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 2, 0, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 3, -1, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -1, -1, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 0, -1, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 0, 0, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -5, -5, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -4, -5, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -3, -5, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -2, -5, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -1, -5, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 0, -5, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 1, -5, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 2, -5, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 3, -5, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 4, -5, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 5, -5, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 6, -5, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -5, -4, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -5, -3, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -5, -2, 3 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, 4, -1, 6 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -5, -1, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -5, 0, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 5, 0, 0 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 2, 0, 1 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 6, 0, 0 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, 4, 0, 6 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 6, -1, 0 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 6, -4, 0 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 6, -3, 0 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 6, -2, 0 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -4, 0, 0 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -3, 0, 0 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -2, 0, 0 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -1, 0, 1 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -4, -1, 0 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -3, -1, 0 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -2, -1, 0 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -4, -4, 0 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -4, -3, 0 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -4, -2, 0 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 3, 0, 5 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -1, 0, 5 );
ac = new AddonComponent( 4554 );
AddComponent( ac, -1, 0, 11 );
ac = new AddonComponent( 4554 );
AddComponent( ac, 3, 0, 11 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 4, 0, 0 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, 6, 0, 6 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 5, -1, 0 );
ac = new AddonComponent( 272 );
AddComponent( ac, 6, -2, 8 );
ac = new AddonComponent( 272 );
AddComponent( ac, 6, -1, 8 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, 5, 0, 6 );
ac = new AddonComponent( 272 );
AddComponent( ac, -5, -4, 8 );
ac = new AddonComponent( 272 );
AddComponent( ac, -5, -3, 8 );
ac = new AddonComponent( 271 );
AddComponent( ac, 6, -5, 6 );
ac = new AddonComponent( 271 );
AddComponent( ac, -4, -5, 8 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, -2, -1, 6 );
ac = new AddonComponent( 272 );
AddComponent( ac, 6, 0, 8 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, -4, -2, 6 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, -4, -1, 6 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, -4, -4, 6 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, -4, -3, 6 );
ac = new AddonComponent( 272 );
AddComponent( ac, 6, -4, 8 );
ac = new AddonComponent( 272 );
AddComponent( ac, 6, -3, 8 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, -2, 0, 6 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, -3, 0, 6 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, -3, -1, 6 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, 5, -1, 6 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, 6, -4, 6 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, 6, -2, 6 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, 6, -3, 6 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 4, -1, 0 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, 6, -1, 6 );
ac = new AddonComponent( 3518 );
AddComponent( ac, 4, -1, 6 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, -4, 0, 6 );
ac = new AddonComponent( 272 );
AddComponent( ac, -5, -2, 8 );
ac = new AddonComponent( 272 );
AddComponent( ac, -5, -1, 8 );
ac = new AddonComponent( 272 );
AddComponent( ac, -5, 0, 8 );
ac = new AddonComponent( 273 );
AddComponent( ac, -5, -5, 8 );
ac = new AddonComponent( 2769 );
AddComponent( ac, 1, -1, 9 );
ac = new AddonComponent( 2770 );
AddComponent( ac, 2, 0, 9 );
ac = new AddonComponent( 2771 );
AddComponent( ac, -1, -2, 9 );
ac = new AddonComponent( 2772 );
AddComponent( ac, 0, 0, 9 );
ac = new AddonComponent( 2773 );
AddComponent( ac, 3, -2, 9 );
ac = new AddonComponent( 2775 );
AddComponent( ac, 0, -2, 9 );
ac = new AddonComponent( 2775 );
AddComponent( ac, 1, -2, 9 );
ac = new AddonComponent( 2775 );
AddComponent( ac, 2, -2, 9 );
ac = new AddonComponent( 2777 );
AddComponent( ac, 1, 0, 9 );
ac = new AddonComponent( 2776 );
AddComponent( ac, 2, -1, 9 );
ac = new AddonComponent( 2774 );
AddComponent( ac, 0, -1, 9 );
ac = new AddonComponent( 2772 );
AddComponent( ac, -1, -1, 9 );
ac = new AddonComponent( 2777 );
AddComponent( ac, 0, -1, 9 );
ac = new AddonComponent( 2777 );
AddComponent( ac, 2, -1, 9 );
ac = new AddonComponent( 2770 );
AddComponent( ac, 3, -1, 9 );
ac = new AddonComponent( 3339 );
AddComponent( ac, -3, -1, 7 );
ac = new AddonComponent( 3337 );
AddComponent( ac, 5, -1, 8 );
ac = new AddonComponent( 3338 );
AddComponent( ac, -4, -3, 8 );
ac = new AddonComponent( 3336 );
AddComponent( ac, 5, -1, 8 );
ac = new AddonComponent( 3336 );
AddComponent( ac, -3, 0, 8 );
ac = new AddonComponent( 7949 );
AddComponent( ac, 6, -1, 8 );
ac = new AddonComponent( 7949 );
AddComponent( ac, 6, -4, 8 );
ac = new AddonComponent( 7949 );
AddComponent( ac, 6, -3, 8 );
ac = new AddonComponent( 7949 );
AddComponent( ac, 6, -2, 8 );
ac = new AddonComponent( 7952 );
AddComponent( ac, -4, -4, 8 );
ac = new AddonComponent( 3518 );
AddComponent( ac, -4, 1, 6 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 1, 1, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 1, 2, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 1, 3, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 0, 5, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 0, 4, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -1, 3, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 0, 2, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 0, 3, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 2, 2, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 2, 3, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 1, 4, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 3, 3, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 1, 5, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 1, 6, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 2, 4, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 2, 5, 3 );
ac = new AddonComponent( 1803 );
AddComponent( ac, 3, 5, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 4, 3, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 5, 3, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 6, 3, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 3, 1, 0 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -2, 3, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -3, 3, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -4, 3, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -5, 1, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -5, 2, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -5, 3, 3 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 2, 1, 0 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 4, 1, 0 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, 6, 2, 6 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 5, 1, 0 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 6, 1, 0 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 3, 2, 0 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 4, 2, 0 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 5, 2, 0 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 6, 2, 0 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, 6, 1, 6 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -4, 1, 0 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -3, 1, 0 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -2, 1, 0 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -1, 1, 0 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -4, 2, 0 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -3, 2, 0 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -2, 2, 0 );
ac = new AddonComponent( 1801 );
AddComponent( ac, -1, 2, 0 );
ac = new AddonComponent( 1805 );
AddComponent( ac, -1, 5, 3 );
ac = new AddonComponent( 1809 );
AddComponent( ac, -1, 6, 3 );
ac = new AddonComponent( 1807 );
AddComponent( ac, 3, 6, 3 );
ac = new AddonComponent( 1809 );
AddComponent( ac, -5, 4, 3 );
ac = new AddonComponent( 1815 );
AddComponent( ac, 2, 6, 3 );
ac = new AddonComponent( 1815 );
AddComponent( ac, 3, 4, 3 );
ac = new AddonComponent( 1817 );
AddComponent( ac, 0, 6, 3 );
ac = new AddonComponent( 1817 );
AddComponent( ac, -1, 4, 3 );
ac = new AddonComponent( 1802 );
AddComponent( ac, 4, 4, 3 );
ac = new AddonComponent( 1802 );
AddComponent( ac, 5, 4, 3 );
ac = new AddonComponent( 1802 );
AddComponent( ac, 6, 4, 3 );
ac = new AddonComponent( 1802 );
AddComponent( ac, -4, 4, 3 );
ac = new AddonComponent( 1802 );
AddComponent( ac, -3, 4, 3 );
ac = new AddonComponent( 1802 );
AddComponent( ac, -2, 4, 3 );
ac = new AddonComponent( 7620 );
AddComponent( ac, 2, 2, 8 );
ac = new AddonComponent( 1801 );
AddComponent( ac, 0, 1, 0 );
ac = new AddonComponent( 7621 );
AddComponent( ac, 0, 2, 8 );
ac = new AddonComponent( 7622 );
AddComponent( ac, 1, 2, 8 );
ac = new AddonComponent( 7617 );
AddComponent( ac, 2, 3, 7 );
ac = new AddonComponent( 7617 );
AddComponent( ac, 0, 3, 7 );
ac = new AddonComponent( 271 );
AddComponent( ac, -4, 2, 8 );
ac = new AddonComponent( 271 );
AddComponent( ac, -3, 2, 8 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, 5, 1, 6 );
ac = new AddonComponent( 271 );
AddComponent( ac, 4, 2, 8 );
ac = new AddonComponent( 271 );
AddComponent( ac, 5, 2, 8 );
ac = new AddonComponent( 270 );
AddComponent( ac, 6, 2, 8 );
ac = new AddonComponent( 271 );
AddComponent( ac, 3, 2, 8 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, -1, 2, 6 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, 0, 1, 6 );
ac = new AddonComponent( 271 );
AddComponent( ac, -2, 2, 8 );
ac = new AddonComponent( 271 );
AddComponent( ac, -1, 2, 8 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, -2, 2, 6 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, -1, 1, 6 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, -3, 2, 6 );
ac = new AddonComponent( 272 );
AddComponent( ac, 6, 1, 8 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, -2, 1, 6 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, -3, 1, 6 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, -4, 2, 6 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, 4, 2, 6 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, 4, 1, 6 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, 5, 2, 6 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, 3, 1, 6 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, 3, 2, 6 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, 2, 1, 6 );
ac = new AddonComponent( 7385 );
ac.Hue = 184;
AddComponent( ac, -4, 1, 6 );
ac = new AddonComponent( 272 );
AddComponent( ac, -5, 1, 8 );
ac = new AddonComponent( 272 );
AddComponent( ac, -5, 2, 8 );
ac = new AddonComponent( 7617 );
AddComponent( ac, 1, 3, 7 );
ac = new AddonComponent( 7619 );
AddComponent( ac, 1, 3, 8 );
ac = new AddonComponent( 7619 );
AddComponent( ac, 2, 3, 8 );
ac = new AddonComponent( 7619 );
AddComponent( ac, 0, 3, 8 );
ac = new AddonComponent( 2769 );
AddComponent( ac, 1, 4, 9 );
ac = new AddonComponent( 2769 );
AddComponent( ac, 1, 5, 9 );
ac = new AddonComponent( 2776 );
AddComponent( ac, 2, 5, 9 );
ac = new AddonComponent( 2777 );
AddComponent( ac, 1, 6, 9 );
ac = new AddonComponent( 2776 );
AddComponent( ac, 2, 4, 9 );
ac = new AddonComponent( 2775 );
AddComponent( ac, 1, 3, 9 );
ac = new AddonComponent( 2770 );
AddComponent( ac, 2, 6, 9 );
ac = new AddonComponent( 2771 );
AddComponent( ac, 0, 3, 9 );
ac = new AddonComponent( 2772 );
AddComponent( ac, 0, 6, 9 );
ac = new AddonComponent( 2773 );
AddComponent( ac, 2, 3, 9 );
ac = new AddonComponent( 2774 );
AddComponent( ac, 0, 4, 9 );
ac = new AddonComponent( 2774 );
AddComponent( ac, 0, 5, 9 );
ac = new AddonComponent( 3339 );
AddComponent( ac, 5, 1, 7 );
ac = new AddonComponent( 3338 );
AddComponent( ac, -2, 1, 8 );
ac = new AddonComponent( 3338 );
AddComponent( ac, 2, 1, 8 );
ac = new AddonComponent( 3380 );
AddComponent( ac, 4, 1, 8 );
ac = new AddonComponent( 7950 );
AddComponent( ac, -3, 2, 8 );
ac = new AddonComponent( 7950 );
AddComponent( ac, -1, 2, 8 );
ac = new AddonComponent( 7951 );
AddComponent( ac, -2, 2, 8 );
ac = new AddonComponent( 7951 );
AddComponent( ac, 3, 2, 8 );
ac = new AddonComponent( 7951 );
AddComponent( ac, 4, 2, 8 );
ac = new AddonComponent( 3380 );
AddComponent( ac, -2, 1, 8 );
ac = new AddonComponent( 4553 );
AddComponent( ac, 3, 3, 8 );
ac = new AddonComponent( 4553 );
AddComponent( ac, -1, 3, 8 );
}
public DoNDStageAddon( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 ); // Version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
public class DoNDStageAddonDeed : BaseAddonDeed
{
public override BaseAddon Addon
{
get
{
return new DoNDStageAddon();
}
}
[Constructable]
public DoNDStageAddonDeed()
{
Name = "DoNDStage";
}
public DoNDStageAddonDeed( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 ); // Version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,40 @@
using System;
using Server.Network;
using Server.Items;
namespace Server.Items
{
public class DoNDCase : BaseEquipableLight
{
public override int LitItemID{ get { return 0xEFA; } }
public override int UnlitItemID{ get { return 0xEFA; } }
[Constructable]
public DoNDCase() : base( 0xEFA )
{
Layer = Layer.TwoHanded;
Light = LightType.Circle150;
Movable = false;
}
public DoNDCase( Serial serial ) : base( serial )
{
}
public override bool DisplayLootType{ get{ return false; } }
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,85 @@
using System;
namespace Server.Items
{
[Flipable( 0x1F00, 0x1EFF )]
public class GirlsDress : FancyDress
{
[Constructable]
public GirlsDress()
{
int hours, minutes;
Server.Items.Clock.GetTime( this.Map, this.X, this.Y, out hours, out minutes );
Name = "Fancy Dress";
Weight = 3.0;
if ( hours == 1 )
Hue = 6;
if ( hours == 2 )
Hue = 11;
if ( hours == 3 )
Hue = 16;
if ( hours == 4 )
Hue = 21;
if ( hours == 5 )
Hue = 26;
if ( hours == 6 )
Hue = 31;
if ( hours == 7 )
Hue = 36;
if ( hours == 8 )
Hue = 41;
if ( hours == 9 )
Hue = 46;
if ( hours == 10 )
Hue = 51;
if ( hours == 11 )
Hue = 56;
if ( hours == 12 )
Hue = 61;
if ( hours == 13 )
Hue = 66;
if ( hours == 14 )
Hue = 71;
if ( hours == 15 )
Hue = 76;
if ( hours == 16 )
Hue = 81;
if ( hours == 17 )
Hue = 86;
if ( hours == 18 )
Hue = 91;
if ( hours == 19 )
Hue = 96;
if ( hours == 20 )
Hue = 101;
if ( hours == 21 )
Hue = 106;
if ( hours == 22 )
Hue = 111;
if ( hours == 23 )
Hue = 116;
if ( hours == 24 )
Hue = 121;
}
public GirlsDress( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,87 @@
using System;
namespace Server.Items
{
[FlipableAttribute( 0x170d, 0x170e )]
public class GirlsSandals : Sandals
{
public override CraftResource DefaultResource{ get{ return CraftResource.RegularLeather; } }
[Constructable]
public GirlsSandals()
{
int hours, minutes;
Server.Items.Clock.GetTime( this.Map, this.X, this.Y, out hours, out minutes );
Name = "Sandals";
Weight = 1.0;
if ( hours == 1 )
Hue = 6;
if ( hours == 2 )
Hue = 11;
if ( hours == 3 )
Hue = 16;
if ( hours == 4 )
Hue = 21;
if ( hours == 5 )
Hue = 26;
if ( hours == 6 )
Hue = 31;
if ( hours == 7 )
Hue = 36;
if ( hours == 8 )
Hue = 41;
if ( hours == 9 )
Hue = 46;
if ( hours == 10 )
Hue = 51;
if ( hours == 11 )
Hue = 56;
if ( hours == 12 )
Hue = 61;
if ( hours == 13 )
Hue = 66;
if ( hours == 14 )
Hue = 71;
if ( hours == 15 )
Hue = 76;
if ( hours == 16 )
Hue = 81;
if ( hours == 17 )
Hue = 86;
if ( hours == 18 )
Hue = 91;
if ( hours == 19 )
Hue = 96;
if ( hours == 20 )
Hue = 101;
if ( hours == 21 )
Hue = 106;
if ( hours == 22 )
Hue = 111;
if ( hours == 23 )
Hue = 116;
if ( hours == 24 )
Hue = 121;
}
public GirlsSandals( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,34 @@
using System;
namespace Server.Items
{
[FlipableAttribute( 0x1efd, 0x1efe )]
public class HoweyJacket : Doublet
{
[Constructable]
public HoweyJacket()
{
Name = "Dress Jacket";
Weight = 2.0;
Hue = 1175;
}
public HoweyJacket( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,34 @@
using System;
namespace Server.Items
{
[FlipableAttribute( 0x1539, 0x153a )]
public class HoweyPants : LongPants
{
[Constructable]
public HoweyPants()
{
Name = "Dress Pants";
Weight = 2.0;
Hue = 1175;
}
public HoweyPants( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,85 @@
using System;
namespace Server.Items
{
[FlipableAttribute( 0x1efd, 0x1efe )]
public class HoweyShirt : FancyShirt
{
[Constructable]
public HoweyShirt()
{
int hours, minutes;
Server.Items.Clock.GetTime( this.Map, this.X, this.Y, out hours, out minutes );
Name = "Dress Shirt";
Weight = 2.0;
if ( hours == 1 )
Hue = 6;
if ( hours == 2 )
Hue = 11;
if ( hours == 3 )
Hue = 16;
if ( hours == 4 )
Hue = 21;
if ( hours == 5 )
Hue = 26;
if ( hours == 6 )
Hue = 31;
if ( hours == 7 )
Hue = 36;
if ( hours == 8 )
Hue = 41;
if ( hours == 9 )
Hue = 46;
if ( hours == 10 )
Hue = 51;
if ( hours == 11 )
Hue = 56;
if ( hours == 12 )
Hue = 61;
if ( hours == 13 )
Hue = 66;
if ( hours == 14 )
Hue = 71;
if ( hours == 15 )
Hue = 76;
if ( hours == 16 )
Hue = 81;
if ( hours == 17 )
Hue = 86;
if ( hours == 18 )
Hue = 91;
if ( hours == 19 )
Hue = 96;
if ( hours == 20 )
Hue = 101;
if ( hours == 21 )
Hue = 106;
if ( hours == 22 )
Hue = 111;
if ( hours == 23 )
Hue = 116;
if ( hours == 24 )
Hue = 121;
}
public HoweyShirt( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,36 @@
using System;
namespace Server.Items
{
[FlipableAttribute( 0x170f, 0x1710 )]
public class HoweyShoes : Shoes
{
public override CraftResource DefaultResource{ get{ return CraftResource.RegularLeather; } }
[Constructable]
public HoweyShoes()
{
Name = "Dress Shoes";
Weight = 2.0;
Hue = 1175;
}
public HoweyShoes( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,34 @@
using System;
using Server;
namespace Server.Items
{
public class DoNDBankerDoll : Item
{
[Constructable]
public DoNDBankerDoll() : base( 0x2106 )
{
Name = "The Banker";
Hue = 33;
LootType = LootType.Blessed;
}
public DoNDBankerDoll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,115 @@
using System;
using Server;
namespace Server.Items
{
public class DoNDDoll : Item
{
[Constructable]
public DoNDDoll() : base( 0x2107 )
{
int hours, minutes;
Server.Items.Clock.GetTime( this.Map, this.X, this.Y, out hours, out minutes );
switch ( Utility.Random( 26 ) )
{
default:
case 0: Name = "Claudia"; break;
case 1: Name = "Stacey"; break;
case 2: Name = "Lisa"; break;
case 3: Name = "Keltie"; break;
case 4: Name = "Ursula"; break;
case 5: Name = "Megan"; break;
case 6: Name = "Sara"; break;
case 7: Name = "Lauren"; break;
case 8: Name = "Patricia"; break;
case 9: Name = "Anya"; break;
case 10: Name = "Katie"; break;
case 11: Name = "Jill"; break;
case 12: Name = "Leyla"; break;
case 13: Name = "Pilar"; break;
case 14: Name = "Brooke"; break;
case 15: Name = "Krissy"; break;
case 16: Name = "Jenelle"; break;
case 17: Name = "Marisa"; break;
case 18: Name = "Mylinda"; break;
case 19: Name = "Alike"; break;
case 20: Name = "Tameka"; break;
case 21: Name = "Lianna"; break;
case 22: Name = "Aubrie"; break;
case 23: Name = "Kelly"; break;
case 24: Name = "Hayley Marie"; break;
case 25: Name = "Lindsay"; break;
}
LootType = LootType.Blessed;
if ( hours == 1 )
Hue = 6;
if ( hours == 2 )
Hue = 11;
if ( hours == 3 )
Hue = 16;
if ( hours == 4 )
Hue = 21;
if ( hours == 5 )
Hue = 26;
if ( hours == 6 )
Hue = 31;
if ( hours == 7 )
Hue = 36;
if ( hours == 8 )
Hue = 41;
if ( hours == 9 )
Hue = 46;
if ( hours == 10 )
Hue = 51;
if ( hours == 11 )
Hue = 56;
if ( hours == 12 )
Hue = 61;
if ( hours == 13 )
Hue = 66;
if ( hours == 14 )
Hue = 71;
if ( hours == 15 )
Hue = 76;
if ( hours == 16 )
Hue = 81;
if ( hours == 17 )
Hue = 86;
if ( hours == 18 )
Hue = 91;
if ( hours == 19 )
Hue = 96;
if ( hours == 20 )
Hue = 101;
if ( hours == 21 )
Hue = 106;
if ( hours == 22 )
Hue = 111;
if ( hours == 23 )
Hue = 116;
if ( hours == 24 )
Hue = 121;
}
public DoNDDoll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,33 @@
using System;
using Server;
namespace Server.Items
{
public class DoNDHoweyDoll : Item
{
[Constructable]
public DoNDHoweyDoll() : base( 0x2106 )
{
Name = "Howey Mandel";
LootType = LootType.Blessed;
}
public DoNDHoweyDoll( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,89 @@
using System;
using Server.Mobiles;
namespace Server.Items
{
public class DoNDReplayDeed : Item
{
private int m_RP1 = 0;
private int m_RPM1 = 0;
private int m_Replay = 0;
public int RP1
{
get{ return m_RP1; }
set{ m_RP1 = value; }
}
public int RPM1
{
get{ return m_RPM1; }
set{ m_RPM1 = value; }
}
public int RReplay
{
get{ return m_Replay; }
set{ m_Replay = value; }
}
[Constructable]
public DoNDReplayDeed( Mobile m, Item i ) : base( 0x14EF )
{
PlayerMobile pm = m as PlayerMobile;
if ( pm == null )
return;
DoNDGameDeed gd = i as DoNDGameDeed;
if ( gd == null )
return;
RReplay = gd.DReplay;
Name = "DoND Replay Deed for : " + pm.Name;
LootType = LootType.Blessed;
Weight = 0.0;
Visible = false;
Movable = false;
}
public override bool DisplayLootType{ get{ return false; } }
public DoNDReplayDeed( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.Write( (int)m_RP1 );
writer.Write( (int)m_RPM1 );
writer.Write( (int)m_Replay );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 0:
{
m_RP1 = (int)reader.ReadInt();
m_RPM1 = (int)reader.ReadInt();
m_Replay = (int)reader.ReadInt();
break;
}
}
}
}
}

View File

@@ -0,0 +1,211 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server.Mobiles;
using Server.Gumps;
namespace Server.Items
{
public class DoNDAdminStone : Item
{
private int i_Game;
private int i_Cash;
private int i_Replay;
private bool b_DeBug;
private bool b_Howey;
private string s_Commercial;
public int Game
{
get{ return i_Game; }
set{ i_Game = value; }
}
public int Cash
{
get{ return i_Cash; }
set{ i_Cash = value; }
}
public int Replay
{
get{ return i_Replay; }
set{ i_Replay = value; }
}
public bool DeBugger
{
get{ return b_DeBug; }
set{ b_DeBug = value; }
}
public bool SHowey
{
get{ return b_Howey; }
set{ b_Howey = value; }
}
public string SCommercial
{
get{ return s_Commercial; }
set{ s_Commercial = value; }
}
[Constructable]
public DoNDAdminStone() : base( 0xED4 )
{
Name = "Deal or No Deal : System Off";
Movable = false;
Hue = 5;
SCommercial = "Please edit this text to anything you want the player to read when the commercial appears to the player playing Deal or No Deal";
Replay = 24;
}
public override void OnDoubleClick( Mobile from )
{
PlayerMobile pm = from as PlayerMobile;
if ( pm == null )
return;
if ( pm.AccessLevel < AccessLevel.Administrator )
{
pm.SendMessage( pm.Name + ", Your not the Administrator, please send a page to activate Deal or No Deal!");
return;
}
if ( Visible == true )
{
pm.SendMessage( pm.Name + ", The Game started, if you want to remove system, just delete the Stage, Howey and Stone!");
SpawnStage(this);
pm.BoltEffect( 0 );
pm.PlaySound( 41 );
Visible = false;
pm.Z +=5;
Name = "Deal or No Deal : System On : Howey Not Spawned";
return;
}
if ( pm.InRange( this, 5 ) && DeBugger == false )
{
if ( SHowey == false )
SpawnHowey(this);
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDAdminGump( this ) );
pm.SendMessage( pm.Name + ", Howey Spawned!");
return;
}
if ( DeBugger == true )
{
if (pm.HasGump( typeof( DebugGump )))
pm.CloseGump( typeof( DebugGump ) );
pm.SendGump( new DebugGump( pm ) );
if (pm.HasGump( typeof( DoNDAdminGump )))
pm.CloseGump( typeof( DoNDAdminGump ) );
pm.SendGump( new DoNDAdminGump( this ) );
return;
}
return;
}
public static void SpawnStage( Item target )
{
DoNDAdminStone it = target as DoNDAdminStone;
if ( it == null )
return;
Map map = it.Map;
if ( map == null )
return;
DoNDStageAddon stage = new DoNDStageAddon();
Point3D loc = it.Location;
int x = it.X-1;
int y = it.Y;
int z = it.Z-2;
loc = new Point3D( x, y, z );
stage.MoveToWorld( loc, map );
it.Z +=6;
}
public static void SpawnHowey( Item target )
{
DoNDAdminStone it = target as DoNDAdminStone;
if ( it == null )
return;
Map map = it.Map;
if ( map == null )
return;
Howey howey = new Howey( it );
Point3D loc = it.Location;
int x = it.X;
int y = it.Y+1;
int z = it.Z;
loc = new Point3D( x, y, z );
howey.MoveToWorld( loc, map );
it.Name = "Deal or No Deal : System On : Howey Spawned";
howey.FixedParticles( 0x37CC, 1, 40, 97, 3, 9917, EffectLayer.Waist );
howey.FixedParticles( 0x374A, 1, 15, 9502, 97, 3, (EffectLayer)255 );
it.SHowey = true;
}
public DoNDAdminStone( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.Write( (int)i_Game );
writer.Write( (int)i_Cash );
writer.Write( (int)i_Replay );
writer.Write( (bool)b_DeBug );
writer.Write( (bool)b_Howey );
writer.Write( (string)s_Commercial );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 0:
{
i_Game = (int)reader.ReadInt();
i_Cash = (int)reader.ReadInt();
i_Replay = (int)reader.ReadInt();
b_DeBug = (bool)reader.ReadBool();
b_Howey = (bool)reader.ReadBool();
s_Commercial = (string)reader.ReadString();
break;
}
}
}
}
}

View File

@@ -0,0 +1,38 @@
using System;
using Server;
using Server.Mobiles;
namespace Server.Items
{
public class DoNDGameTicket : Item
{
[Constructable]
public DoNDGameTicket() : base( 0x14EF )
{
Name = "DoND Game Ticket";
Hue = 1161;
LootType = LootType.Blessed;
}
public override bool DisplayLootType{ get{ return false; } }
public DoNDGameTicket( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,54 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Items;
namespace Server.Mobiles
{
public class DoNDLogin
{
public static void Initialize()
{
EventSink.Login += new LoginEventHandler( OnLogin );
}
private static void OnLogin( LoginEventArgs e )
{
if ( e.Mobile is PlayerMobile )
{
PlayerMobile pm = (PlayerMobile)e.Mobile;
if (pm == null || pm.Backpack == null)
return;
Item check = pm.Backpack.FindItemByType(typeof(DoNDGameDeed) );
if ( check != null )
check.Delete();
if ( pm.Frozen == true )
pm.Frozen = false;
Item check2 = pm.Backpack.FindItemByType(typeof(DoNDReplayDeed) );
if ( check2 == null )
return;
DoNDReplayDeed rd = check2 as DoNDReplayDeed;
if ( rd == null )
return;
if ( rd.RP1 < 24 )
{
Timer i_timer = new PlayerReplayTimer( pm );
i_timer.Start();
}
if ( rd.RP1 >= 24 )
rd.Delete();
}
}
}
}

View File

@@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using Server;
namespace Server.Mobiles
{
public class GameVendor : BaseVendor
{
private List<SBInfo> m_SBInfos = new List<SBInfo>();
protected override List<SBInfo> SBInfos{ get { return m_SBInfos; } }
[Constructable]
public GameVendor() : base( "the Live Game Ticket Seller" )
{
}
public override void InitSBInfo()
{
m_SBInfos.Add( new SBGameVendor() );
}
public GameVendor( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using Server.Items;
namespace Server.Mobiles
{
public class SBGameVendor : SBInfo
{
private List<GenericBuyInfo> m_BuyInfo = new InternalBuyInfo();
private IShopSellInfo m_SellInfo = new InternalSellInfo();
public SBGameVendor()
{
}
public override IShopSellInfo SellInfo { get { return m_SellInfo; } }
public override List<GenericBuyInfo> BuyInfo { get { return m_BuyInfo; } }
public class InternalBuyInfo : List<GenericBuyInfo>
{
public InternalBuyInfo()
{
Add( new GenericBuyInfo( typeof( DoNDGameTicket ), 50000, 20, 0x14EF, 1161 ) );
}
}
public class InternalSellInfo : GenericSellInfo
{
public InternalSellInfo()
{
Add( typeof( DoNDGameTicket ), 25000 );
}
}
}
}

View File

@@ -0,0 +1,69 @@
using System;
using Server;
using Server.Items;
namespace Server.Mobiles
{
public class Girls : BaseCreature
{
[Constructable]
public Girls( int i, Mobile m, Mobile bm ) : base( AIType.AI_Animal, FightMode.Aggressor, 20, 1, 0.2, 0.4 )
{
PlayerMobile pm = m as PlayerMobile;
if ( pm == null )
return;
Howey bc = bm as Howey;
if ( bc == null )
return;
Body = 0x191;
CantWalk = true;
Blessed = true;
Frozen = true;
AddItem( new GirlsDress() );
AddItem( new GirlsSandals() );
Item item = new DoNDCase();
item.Name = "Case #" + i;
item.Hue = 986;
item.LootType = LootType.Blessed;
EquipItem( item );
Direction = Direction.South;
}
public override void OnThink()
{
Direction = Direction.South;
if ( Frozen == false )
Frozen = true;
base.OnThink();
return;
}
public Girls( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,49 @@
using System;
using Server;
using Server.Gumps;
using Server.Mobiles;
namespace Server.Items
{
public class CloseCaseTimer : Timer
{
private Item item;
private Mobile mobile;
public CloseCaseTimer( Mobile m, Item i ) : base( TimeSpan.FromSeconds( 1 ) )
{
mobile = m;
item = i;
}
protected override void OnTick()
{
PlayerMobile pm = mobile as PlayerMobile;
if ( pm == null )
{
this.Stop();
return;
}
DoNDGameDeed gd = item as DoNDGameDeed;
if ( gd == null )
{
this.Stop();
return;
}
if( gd.Deleted )
{
this.Stop();
return;
}
gd.CloseCase = true;
if (pm.HasGump( typeof( DoNDMainGump )))
pm.CloseGump( typeof( DoNDMainGump ) );
pm.SendGump( new DoNDMainGump( pm, gd ) );
this.Stop();
}
}
}

View File

@@ -0,0 +1,132 @@
using System;
using Server;
using Server.Gumps;
using Server.Mobiles;
namespace Server.Items
{
public class CloseGameTimer : Timer
{
private Item item;
private Mobile pmobile;
private Mobile bmobile;
public CloseGameTimer( Mobile m, Mobile bm, Item i ) : base( TimeSpan.FromSeconds( 3 ) )
{
pmobile = m;
bmobile = bm;
item = i;
}
protected override void OnTick()
{
PlayerMobile pm = pmobile as PlayerMobile;
if ( pm == null || pm.Backpack == null )
{
this.Stop();
return;
}
Howey bc = bmobile as Howey;
if ( bc == null )
{
this.Stop();
return;
}
DoNDGameDeed gd = item as DoNDGameDeed;
if ( gd == null )
{
this.Stop();
return;
}
if( gd.Deleted )
{
this.Stop();
return;
}
if ( gd.GameOver == false && gd.NoTrade == true )
{
bc.Say( pm.Name + ", Your case had....!");
GameSystem.PrizeCheck( pm, bc );
if ( bc.DeBugger == true )
Console.WriteLine( "DeBug : System, Close Game Timer, NoTrade OK" );
this.Stop();
}
bc.DealOn = false;
bc.AL = 0;
bc.cnt = 0;
pm.Frozen = false;
bc.CD1 = false;
bc.CD2 = false;
bc.CD3 = false;
bc.CD4 = false;
bc.CD5 = false;
bc.CD6 = false;
bc.CD7 = false;
bc.CD8 = false;
bc.CD9 = false;
bc.CD10 = false;
bc.CD11 = false;
bc.CD12 = false;
bc.CD13 = false;
bc.CD14 = false;
bc.CD15 = false;
bc.CD16 = false;
bc.CD17 = false;
bc.CD18 = false;
bc.CD19 = false;
bc.CD20 = false;
bc.CD21 = false;
bc.CD22 = false;
bc.CD23 = false;
bc.CD24 = false;
bc.CD25 = false;
bc.CD26 = false;
if (pm.HasGump( typeof( DoNDMainGump )))
pm.CloseGump( typeof( DoNDMainGump ) );
bc.Say( pm.Name + ", Thanks for playing Deal or No Deal!");
bc.Hidden = true;
bc.FixedParticles( 0x37CC, 1, 40, 97, 3, 9917, EffectLayer.Waist );
bc.FixedParticles( 0x374A, 1, 15, 9502, 97, 3, (EffectLayer)255 );
Console.WriteLine( "A Player has Ended Deal or No Deal : Game Over" );
Item ri = pm.Backpack.FindItemByType(typeof(DoNDReplayDeed) );
if ( ri != null )
{
if ( bc.DeBugger == true )
Console.WriteLine( "DeBug : System, Close Game Timer, Found Replay Deed OK" );
this.Stop();
return;
}
if ( pm.AccessLevel < AccessLevel.GameMaster )
pm.AddToBackpack( new DoNDReplayDeed( pm, gd ) );
gd.Delete();
if ( pm.AccessLevel < AccessLevel.GameMaster )
{
pm.SendMessage( 33, pm.Name + ", You'll need to wait in order to play again!");
Timer p_timer = new PlayerReplayTimer( pm );
p_timer.Start();
}
if ( bc.DeBugger == true )
Console.WriteLine( "DeBug : System, Close Game Timer, End Game OK" );
this.Stop();
}
}
}

View File

@@ -0,0 +1,42 @@
using System;
using Server;
using Server.Items;
namespace Server.Mobiles
{
public class HoweyResetTimer : Timer
{
private Item item;
private Mobile bmobile;
public HoweyResetTimer( Item i, Mobile m ) : base( TimeSpan.FromSeconds( 5 ) )
{
item = i;
bmobile = m;
}
protected override void OnTick()
{
DoNDAdminStone si = item as DoNDAdminStone;
if ( si == null )
{
this.Stop();
return;
}
Howey bc = bmobile as Howey;
if ( bc == null )
{
this.Stop();
return;
}
DoNDAdminStone.SpawnHowey( si );
if ( bc.DeBugger == true )
Console.WriteLine( "DeBug : System, Howey Reset Timer OK" );
this.Stop();
}
}
}

View File

@@ -0,0 +1,64 @@
using System;
using Server;
using Server.Mobiles;
namespace Server.Items
{
public class ItemDeleteTimer : Timer
{
private Item item;
private Mobile pmobile;
private Mobile bmobile;
public ItemDeleteTimer( Mobile m, Mobile bm, Item i ) : base( TimeSpan.FromSeconds( 1 ) )
{
pmobile = m;
bmobile = bm;
item = i;
}
protected override void OnTick()
{
DoNDGameDeed gd = item as DoNDGameDeed;
if ( gd == null )
{
this.Stop();
return;
}
if( gd.Deleted )
{
this.Stop();
return;
}
PlayerMobile pm = pmobile as PlayerMobile;
if ( pm == null )
{
this.Stop();
return;
}
Howey bc = bmobile as Howey;
if ( bc == null )
{
this.Stop();
return;
}
if ( gd.GameOver == false )
{
this.Start();
return;
}
GameSystem.EndDDGame( pm, bc );
if ( bc.DeBugger == true )
Console.WriteLine( "DeBug : System, Item Delete Timer OK" );
this.Stop();
}
}
}

View File

@@ -0,0 +1,76 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.Gumps;
namespace Server.Mobiles
{
public class MobileDeleteTimer : Timer
{
private Mobile pmobile;
private Mobile bmobile;
private Mobile m_DG;
public Mobile DG
{
get{ return m_DG; }
set{ m_DG = value; }
}
public MobileDeleteTimer( Mobile pmm, Mobile bcc ) : base( TimeSpan.FromSeconds( 1 ) )
{
pmobile = pmm;
bmobile = bcc;
}
protected override void OnTick()
{
Howey bc = bmobile as Howey;
if ( bc == null )
{
this.Stop();
return;
}
PlayerMobile pm = pmobile as PlayerMobile;
if ( pm == null || pm.Backpack == null )
{
GameSystem.EndDDGame( pm, bc );
this.Stop();
return;
}
Item check = pm.Backpack.FindItemByType(typeof(DoNDGameDeed) );
DoNDGameDeed gd = check as DoNDGameDeed;
if ( gd == null )
{
this.Stop();
return;
}
if ( gd.Commercial == true )
{
if (pm.HasGump( typeof( DoNDCommercialGump )))
pm.CloseGump( typeof( DoNDCommercialGump ) );
pm.SendGump( new DoNDCommercialGump( pm ) );
}
if ( gd.GameOver == false )
{
this.Start();
return;
}
GameSystem.EndDDGame( pm, bc );
if ( bc.DeBugger == true )
Console.WriteLine( "DeBug : System, Mobile Delete Timer OK" );
this.Stop();
}
}
}

View File

@@ -0,0 +1,65 @@
using System;
using Server;
using Server.Items;
namespace Server.Mobiles
{
public class PlayerReplayTimer : Timer
{
private Mobile pmobile;
public PlayerReplayTimer( Mobile m ) : base( TimeSpan.FromMinutes( 1 ) )
{
pmobile = m;
}
protected override void OnTick()
{
PlayerMobile pm = pmobile as PlayerMobile;
if ( pm == null || pm.Backpack == null )
{
this.Stop();
return;
}
Item check = pm.Backpack.FindItemByType(typeof(DoNDReplayDeed) );
if ( check == null )
{
this.Stop();
return;
}
DoNDReplayDeed gd = check as DoNDReplayDeed;
if ( gd == null )
{
this.Stop();
return;
}
gd.RPM1 +=1;
if ( gd.RPM1 == 60 )
{
gd.RP1 +=1;
gd.RPM1 = 0;
this.Start();
return;
}
if ( gd.RP1 == gd.RReplay )
{
pm.SendMessage( pm.Name + ", You can now play Deal or No Deal!");
gd.Delete();
return;
}
if ( gd.RP1 < gd.RReplay )
{
this.Start();
return;
}
}
}
}

View File

@@ -0,0 +1,118 @@
using System;
using Server;
using Server.Gumps;
using Server.Items;
namespace Server.Mobiles
{
public class PlayerResetTimer : Timer
{
private Mobile pmobile;
private Mobile bmobile;
public PlayerResetTimer( Mobile m, Mobile bm ) : base( TimeSpan.FromMinutes( 1 ) )
{
pmobile = m;
bmobile = bm;
}
protected override void OnTick()
{
PlayerMobile pm = pmobile as PlayerMobile;
if ( pm == null || pm.Backpack == null )
{
this.Stop();
return;
}
Howey bc = bmobile as Howey;
if ( bc == null )
{
this.Stop();
return;
}
Item check = pm.Backpack.FindItemByType(typeof(DoNDGameDeed) );
if ( check == null )
{
this.Stop();
return;
}
DoNDGameDeed gd = check as DoNDGameDeed;
if ( gd == null )
{
this.Stop();
return;
}
gd.TL +=1;
if ( gd.TL < 5 )
{
this.Start();
return;
}
if ( gd.TL == 5 )
{
pm.SendMessage( 33,pm.Name + ", You only have limited time to play");
gd.TL = 20 - gd.TL;
pm.SendMessage( 33,gd.TL + " Minutes Left to Play!");
gd.TL = 20 - gd.TL;
this.Start();
return;
}
if ( gd.TL != 5 && gd.TL < 10 )
{
this.Start();
return;
}
if ( gd.TL == 10 )
{
pm.SendMessage( 33,pm.Name + ", You only have limited time to play");
gd.TL = 20 - gd.TL;
pm.SendMessage( 33,gd.TL + " Minutes Left to Play!");
gd.TL = 20 - gd.TL;
this.Start();
return;
}
if ( gd.TL != 10 && gd.TL < 15 )
{
this.Start();
return;
}
if ( gd.TL < 20 )
{
pm.SendMessage( 33,pm.Name + ", You only have limited time to play");
gd.TL = 20 - gd.TL;
pm.SendMessage( 33,gd.TL + " Minutes Left to Play!");
gd.TL = 20 - gd.TL;
this.Start();
return;
}
pm.SendMessage( 33,pm.Name + ", Times up, Game Over!");
if( gd != null )
{
if (pm.HasGump( typeof( DoNDMainGump )))
pm.CloseGump( typeof( DoNDMainGump ) );
gd.GameOver = true;
GameSystem.EndDDGame( pm, bc );
if ( bc.DeBugger == true )
Console.WriteLine( "DeBug : System, Player Reset Timer OK" );
gd.TL = 0;
this.Stop();
}
}
}
}

View File

@@ -0,0 +1,6 @@
Liars Dice for UO copyright information, released under GPL 3.0 license
Any redistribution, source code or game must retain the original attribution(s) to the author Bobby Kramer.
In addition, you may not use this software/algorithm in any way proprietary,
without explicit permission from Bobby Kramer.

View File

@@ -0,0 +1,78 @@
/**
LIARS DICE for Ultima Online
Copyright: Bobby Kramer 2011, http://www.panthar.net
Released under GPL V3.
*/
using System;
using Server;
using Server.Gumps;
using Server.Network;
using Server.Commands;
using Server.LiarsDice;
using System.Collections.Generic;
namespace Server.Gumps
{
public class CallBluffGump : Gump
{
private const int LEFT_BAR=25;
private DiceState ds;
private int[] Dice1Values = new int[] { 2,6,5,4,3,2,1,6,6,6,6,6,5,5,5,5,4,4,4,3,3};
private int[] Dice2Values = new int[] { 1,6,5,4,3,2,1,5,4,3,2,1,4,3,2,1,3,2,1,2,1};
public CallBluffGump(DiceState _ds, int bluffedRoll) : base( 325, 345){
this.ds = _ds;
AddCallBluffGump();
AddInformation(bluffedRoll);
}
public CallBluffGump(DiceState _ds) : base( 325, 345){
this.ds = _ds;
AddCallBluffGump();
}
public void AddCallBluffGump(){
this.Closable=false;
this.Disposable=false;
this.Dragable=true;
this.Resizable=false;
this.AddPage(0);
this.AddBackground(6, 4, 225, 150, 9200);
this.AddLabel(LEFT_BAR, 25, 0, @"Last Roll Before You:");
this.AddLabel(LEFT_BAR, 80, 32, @"Call Bluff:");
AddButton(LEFT_BAR, 110, 4005, 4006, 2, GumpButtonType.Reply, 3);
this.AddLabel(LEFT_BAR + 95, 80, 32, @"Accept Roll:");
AddButton(LEFT_BAR +95, 110, 4005, 4006, 3, GumpButtonType.Reply, 3);
}
private void AddInformation(int bluffedRoll){
this.DisplayDiceCombo(LEFT_BAR,50,Dice1Values[bluffedRoll],Dice2Values[bluffedRoll]);
}
/**
Displays a dice combo
*/
private void DisplayDiceCombo(int x, int y, int first_die, int second_die){
int swap=0;
if(second_die > first_die){
swap = first_die;
second_die = first_die;
second_die = swap;
}
AddImageTiled(x, y, 21, 21, 11280 + (first_die-1));
AddImageTiled(x+30, y, 21, 21, 11280 + (second_die-1));
}
public override void OnResponse( NetState state, RelayInfo info ){
int btd = info.ButtonID;
if(info.ButtonID == 2 || info.ButtonID == 3 ){
ds.UpdateGameChannel(state.Mobile,btd);
}
else{
state.Mobile.SendMessage( "Illegal option selected");
}
}
}
}

View File

@@ -0,0 +1,644 @@
/**
LIARS DICE for Ultima Online
Copyright: Bobby Kramer 2011, http://www.panthar.net
Released under GPL V3.
*/
using System;
using System.Collections.Generic;
using System.Reflection;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Network;
using Server.Gumps;
namespace Server.LiarsDice
{
public class MobileDiceStstatus{
private Mobile m;
private int tableBalance = 0;
private int prevRoll ;
private int prevRollOrBluff;
private DateTime dt;
public MobileDiceStstatus(Mobile _m, int _tableBalance){
this.m = _m;
this.tableBalance = _tableBalance;
}
/**
Get current mobile associated with object
*/
public Mobile getMobile(){
return this.m;
}
public void SetTimeStamp(DateTime _dt){
this.dt = _dt;
}
public DateTime GetTimeStamp(){
return this.dt;
}
/**
get table balance for player
*/
public int GetTableBalance(){
return this.tableBalance;
}
/**
Sets the table balance of the player
*/
public void SetTableBalance(int newVal){
this.tableBalance = newVal;
}
/**
Sets the actual PREVIOUS roll the player rolled
*/
public void SetPrevRoll( int _prevRoll){
this.prevRoll = _prevRoll;
}
/**
Gets the previous roll for use in bluff checking. This is the actual roll of the player
*/
public int GetPrevRoll(){
return this.prevRoll;
}
/**
Get the "bluffed" dice roll of the player on their previous roll
*/
public int GetPrevRollOrBluff(){
return this.prevRollOrBluff;
}
/**
Sets the prevRollOrBluff (the value the user "pretends" to have)
*/
public void SetPrevRollOrBluff(int _prevRollOrBluff){
this.prevRollOrBluff = _prevRollOrBluff;
}
/**
hackish way to roll MORE randomly like liars dice would
*/
public int Roll(){
Random random = new Random();
int tmp = random.Next(0, 35);
int roll=-1;
//best roll
if(tmp <= 1){
roll = 0;
}
//doubles
else if(tmp >= 30){
//lower porbability for doubles.
roll = random.Next(1, 6);
}
//all other rolls
else {
roll = random.Next(7, 20);
}
//set prev roll
this.prevRoll = roll;
return roll;
}
}
public class DiceState{
private const int DICE_RESET=20;
//wager per game
private int goldPerGame;
//game min/max balances for buy in
private int gameBalanceMin;
private int gameBalanceMax;
private int playerToActSeconds;
private int maxNumberOfPlayers;
//list of mobiles in the game
private List<MobileDiceStstatus> dicePlayers = new List<MobileDiceStstatus>();
//all the gumps
private GameDiceGump gdg;
private StatusDiceGump sdg;
private CallBluffGump cbg;
private ExitDiceGump edg;
private NewDiceGameGump ndgg;
//Timer for refreshing status gump
Timer statusGumpTimer;
//liars dice roll values
private int[] Dice1Values = new int[] { 2,6,5,4,3,2,1,6,6,6,6,6,5,5,5,5,4,4,4,3,3};
private int[] Dice2Values = new int[] { 1,6,5,4,3,2,1,5,4,3,2,1,4,3,2,1,3,2,1,2,1};
private int playerCnt = 0;
//player roll historys
private int updatedMobileIdx;
private int prevPlayerIdx;
private int nextPlayerIdx;
public DiceState(int _goldPerGame, int _gameBalanceMin, int _gameBalanceMax, int _playerToActSeconds, int _maxNumberOfPlayers){
this.goldPerGame = _goldPerGame;
this.gameBalanceMin = _gameBalanceMin;
this.gameBalanceMax = _gameBalanceMax;
this.playerToActSeconds = _playerToActSeconds;
this.maxNumberOfPlayers = _maxNumberOfPlayers;
gdg = new GameDiceGump(this);
sdg = new StatusDiceGump(this);
cbg = new CallBluffGump(this);
edg = new ExitDiceGump(this);
ndgg = new NewDiceGameGump(this,0);
//setup timer to kick player if applicable, really only applies to frozen character when you log off.
statusGumpTimer= Timer.DelayCall( TimeSpan.FromSeconds(15), new TimerCallback( StatusTimerCheck));
}
/**
Callacback to statusGumpTimer, create a new timer to call again
*/
public void StatusTimerCheck(){
if(this.updatedMobileIdx >= 0 && this.playerCnt > 0){
AddPlayerWaitingNoStatus(updatedMobileIdx);
}
statusGumpTimer = Timer.DelayCall( TimeSpan.FromSeconds(15), new TimerCallback( StatusTimerCheck));
}
/**
Displays status gump with no message to users, currently only used for the timer.
*/
public void AddPlayerWaitingNoStatus(int currentHighlightedPlayerIdx){
for (int i = 0; i < this.playerCnt; i++){
if ( dicePlayers[i].getMobile().HasGump(typeof(ExitDiceGump)) == false){
RemoveStatusGump(dicePlayers[i]);
PlayerWaiting(dicePlayers[i], currentHighlightedPlayerIdx);
}
}
}
/**
Adds player to the dice game, by adding them to the dicePlayers array, and starting game loop
if enough players.
*/
public MobileDiceStstatus AddPlayer(Mobile m, int tableBalance){
//create our data storage structure
MobileDiceStstatus mds = new MobileDiceStstatus(m, tableBalance);
if ( m.HasGump(typeof(GameDiceGump))){
m.CloseGump(typeof(GameDiceGump));
}
//is the mobile already in game?
for (int i = 0; i < this.playerCnt; i++){
if(m == dicePlayers[i].getMobile()){
m.SendMessage( "You are already playing!" );
return null;
}
}
//to many players already?
if(this.playerCnt >= this.maxNumberOfPlayers){
m.SendMessage( "Liars Dice is currently at it maximum capacity of " + this.maxNumberOfPlayers + " players, try again later.");
mds.getMobile().Frozen = false;
return mds;
}
//add to our main dice players list
dicePlayers.Add(mds);
//increment player count
this.playerCnt +=1;
//Wait for 2nd player before starting
if(dicePlayers.Count == 1){
AddPlayerWaiting(0);
m.SendMessage( "Must have at least 2 players to play! Waiting.." );
}
//Don't start with more than 2 ppl, otherwise we get missing gumps
else if(dicePlayers.Count == 2){
//start game at index 0 of player list
updatedMobileIdx = 0;
prevPlayerIdx = GetNextDicePlayerIdx(updatedMobileIdx);
nextPlayerIdx=GetNextDicePlayerIdx(updatedMobileIdx);
PlayerTurn(dicePlayers[updatedMobileIdx],DICE_RESET);
AddPlayerWaiting(updatedMobileIdx);
SetTimerAction(dicePlayers[prevPlayerIdx], dicePlayers[updatedMobileIdx]);
}else if(dicePlayers.Count > 2){
AddPlayerWaiting(updatedMobileIdx);
}
return mds;
}
/**
Way more complex code than it should actually be.. Removes a player, changes turn, updates bank balance
*/
public void RemovePlayer(Mobile m, bool exchangeBalance){
int exitMobileIdx = GetCurrentDicePlayerIdx(m);
int prevExitPlayerIdx = GetPrevDicePlayerIdx(exitMobileIdx);
//make the next updated mobile idx
MobileDiceStstatus mds = dicePlayers[exitMobileIdx] ;
RemoveGumps(mds); //remove all gumps from user exiting
int exitPlayerBal = mds.GetTableBalance();
int exitPrevPlayerBal = dicePlayers[prevExitPlayerIdx].GetTableBalance();
//only subtract balances, if exchangeBalance is true, and therefore player left the table, and not kicked out by
//a too low of balance
if(this.playerCnt > 1 && exchangeBalance == true){
if(exitMobileIdx == updatedMobileIdx){
//give previous player the balance
//give next player a fresh roll
mds.SetTableBalance(exitPlayerBal - this.goldPerGame);
dicePlayers[prevExitPlayerIdx].SetTableBalance(exitPrevPlayerBal + this.goldPerGame);
SendMessageAllPlayers("Player " + mds.getMobile().Name + " Left on his turn, so " + dicePlayers[prevPlayerIdx].getMobile().Name + " wins " + this.goldPerGame + " gp. from " + mds.getMobile().Name);
}else if(exitMobileIdx == prevPlayerIdx){
//give next player the balance.
//give current player a fresh roll
mds.SetTableBalance(exitPlayerBal - this.goldPerGame);
dicePlayers[updatedMobileIdx].SetTableBalance(exitPrevPlayerBal + this.goldPerGame);
SendMessageAllPlayers("Player " + mds.getMobile().Name + " Left the game before " + dicePlayers[updatedMobileIdx].getMobile().Name + " could make his decision, and so " + dicePlayers[updatedMobileIdx].getMobile().Name + " wins " + this.goldPerGame + " gp. from " + mds.getMobile().Name );
}
}
//deposite old money
Banker.Deposit( mds.getMobile(), mds.GetTableBalance() );
//update indexes of game
if(updatedMobileIdx >= exitMobileIdx && this.playerCnt > 1 ){
updatedMobileIdx -=1;
if(dicePlayers.Contains(mds)){
dicePlayers.Remove(mds);
}
this.playerCnt -=1;
//unfreeze character, used so they can't enter more than 1 game at time
mds.getMobile().Frozen = false;
prevPlayerIdx=GetPrevDicePlayerIdx(updatedMobileIdx);
nextPlayerIdx = GetNextDicePlayerIdx(updatedMobileIdx);
if(this.playerCnt < 2){
return;
}
PlayerTurn(dicePlayers[updatedMobileIdx], DICE_RESET);
AddPlayerWaiting(updatedMobileIdx);
SetTimerAction(dicePlayers[prevPlayerIdx], dicePlayers[updatedMobileIdx]);
}else if(this.playerCnt > 1){
if(dicePlayers.Contains(mds)){
dicePlayers.Remove(mds);
}
this.playerCnt -=1;
//unfreeze character, used so they can't enter more than 1 game at time
mds.getMobile().Frozen = false;
prevPlayerIdx=GetPrevDicePlayerIdx(updatedMobileIdx);
nextPlayerIdx = GetNextDicePlayerIdx(updatedMobileIdx);
if(this.playerCnt < 2){
return;
}
PlayerTurn(dicePlayers[updatedMobileIdx], DICE_RESET);
AddPlayerWaiting(updatedMobileIdx);
SetTimerAction(dicePlayers[prevPlayerIdx], dicePlayers[updatedMobileIdx]);
}else if (this.playerCnt == 1){
if(dicePlayers.Contains(mds)){
dicePlayers.Remove(mds);
}
this.playerCnt =0;
//unfreeze character, used so they can't enter more than 1 game at time
mds.getMobile().Frozen = false;
}
}
/**
Send the bluff decision gump to the next player, and send a callBluff gump to the user
*/
public void PlayBluffDecisionTurn(MobileDiceStstatus prevPlayer, MobileDiceStstatus currPlayer){
RemoveGumps(prevPlayer);
int prevRollOrBluff = prevPlayer.GetPrevRollOrBluff();
cbg = new CallBluffGump(this,prevRollOrBluff);
try{
currPlayer.getMobile().SendGump(cbg);
}catch{
SendMessageAllPlayers( "Player " + currPlayer.getMobile().Name + " was disconnected" );
RemovePlayer(currPlayer.getMobile(), true);
}
//do timer checking, since timer is a thread, when the callback occurs we just look at the "previous" player
SetTimerAction(prevPlayer, currPlayer);
}
/**
Player turn, with a dice level they must beat
*/
public void PlayerTurn(MobileDiceStstatus mds, int diceToBeat ){
RemoveGumps(mds);
//rolls and sets to previous
int currRoll = mds.Roll();
gdg = new GameDiceGump(this,currRoll,diceToBeat);
try{
mds.getMobile().SendGump(gdg);
}catch{
SendMessageAllPlayers("Player " + mds.getMobile().Name + " was disconnected" );
RemovePlayer(mds.getMobile(), true);
}
}
/**
Creates a status gump, with the current player highlighted in red.
*/
public void AddPlayerWaiting(int currentHighlightedPlayerIdx){
for (int i = 0; i < this.playerCnt; i++){
if ( dicePlayers[i].getMobile().HasGump(typeof(ExitDiceGump)) == false){
RemoveStatusGump(dicePlayers[i]);
PlayerWaiting(dicePlayers[i], currentHighlightedPlayerIdx);
if(this.playerCnt >= 2){
dicePlayers[i].getMobile().SendMessage( "It is now " + dicePlayers[currentHighlightedPlayerIdx].getMobile().Name + "'s turn, and he has " + this.playerToActSeconds + " seconds to act.");
}else{
dicePlayers[i].getMobile().SendMessage( dicePlayers[currentHighlightedPlayerIdx].getMobile().Name + " joined liars dice.");
}
}
}
}
/**
Basically the game loop, updates current player with decision/parses it
And then displays a status gump to the user
**/
public void UpdateGameChannelBluff(Mobile m, int diceRollTypeidx){
if(HasEnoughPlayers() == false){
RemoveGumps(dicePlayers[0]);
AddPlayerWaiting(0);
SendMessageAllPlayers( "There is no longer 2 players to play! Waiting.." );
return;
}
//initialize class variables.
prevPlayerIdx = GetCurrentDicePlayerIdx(m);
updatedMobileIdx = GetNextDicePlayerIdx(updatedMobileIdx);
nextPlayerIdx=GetNextDicePlayerIdx(updatedMobileIdx);
//set the roll/bluff to the previous
dicePlayers[prevPlayerIdx].SetPrevRollOrBluff(diceRollTypeidx);
//send current player and next player
PlayBluffDecisionTurn(dicePlayers[prevPlayerIdx], dicePlayers[updatedMobileIdx]);
AddPlayerWaiting(updatedMobileIdx);
}
/**
Basically just does the bluff/accepting of dice rolls
*/
public void UpdateGameChannel(Mobile m, int buttonId){
if(HasEnoughPlayers() == false){
RemoveGumps(dicePlayers[0]);
AddPlayerWaiting(0);
SendMessageAllPlayers( "There is no longer 2 players to play! Waiting.." );
return;
}
//after
if(buttonId == 3){
PlayerTurn(dicePlayers[updatedMobileIdx], dicePlayers[prevPlayerIdx].GetPrevRollOrBluff());
AddPlayerWaiting(updatedMobileIdx);
}else if(buttonId == 2){
int currPlayerBal = dicePlayers[updatedMobileIdx].GetTableBalance();
int prevPlayerBal = dicePlayers[prevPlayerIdx].GetTableBalance();
if(CheckBluff() == true){
//if lieing
dicePlayers[updatedMobileIdx].SetTableBalance(currPlayerBal + this.goldPerGame);
dicePlayers[prevPlayerIdx].SetTableBalance(prevPlayerBal - this.goldPerGame);
//get new previous player balance
prevPlayerBal = dicePlayers[prevPlayerIdx].GetTableBalance();
if(prevPlayerBal < this.goldPerGame){
SendMessageAllPlayers( m.Name + " called out " + dicePlayers[prevPlayerIdx].getMobile().Name + "'s bluff and won " + this.goldPerGame + " gp." );
SendMessageAllPlayers("Player " + dicePlayers[prevPlayerIdx].getMobile().Name + " does not have enough balance to continue playing, and so has been kicked out.");
RemovePlayer(dicePlayers[prevPlayerIdx].getMobile(), false);
}else{
//player keeps turn
PlayerTurn(dicePlayers[updatedMobileIdx],DICE_RESET);
AddPlayerWaiting(updatedMobileIdx);
SetTimerAction(dicePlayers[prevPlayerIdx], dicePlayers[updatedMobileIdx]);
SendMessageAllPlayers( m.Name + " called out " + dicePlayers[prevPlayerIdx].getMobile().Name + "'s bluff and won " + this.goldPerGame + " gp." );
}
}else{
//if telling truth
//subtract/add gold to balance
dicePlayers[updatedMobileIdx].SetTableBalance(currPlayerBal - this.goldPerGame);
dicePlayers[prevPlayerIdx].SetTableBalance(prevPlayerBal + this.goldPerGame);
currPlayerBal = dicePlayers[updatedMobileIdx].GetTableBalance();
if(currPlayerBal < this.goldPerGame){
SendMessageAllPlayers( m.Name + " called out " + dicePlayers[prevPlayerIdx].getMobile().Name + " and was telling the truth!");
SendMessageAllPlayers("Player " + dicePlayers[updatedMobileIdx].getMobile().Name + " does not have enough balance to continue playing, and so has been kicked out.");
RemovePlayer(dicePlayers[updatedMobileIdx].getMobile(), false);
}else{
SendMessageAllPlayers( m.Name + " called out " + dicePlayers[prevPlayerIdx].getMobile().Name + " and was telling the truth!");
//players then loses loses turn
prevPlayerIdx = updatedMobileIdx;
updatedMobileIdx = GetNextDicePlayerIdx(updatedMobileIdx);
PlayerTurn(dicePlayers[updatedMobileIdx],DICE_RESET);
AddPlayerWaiting(updatedMobileIdx);
SetTimerAction(dicePlayers[prevPlayerIdx], dicePlayers[updatedMobileIdx]);
}
}
}
}
/**
Shows exit gump
*/
public void ShowExitConfirmGump(Mobile m){
try{
while (m.HasGump(typeof(ExitDiceGump))){
m.CloseGump(typeof(ExitDiceGump));
}
m.SendGump(edg );
}catch{
SendMessageAllPlayers( "Player " + m.Name + " was disconnected" );
RemovePlayer(m, true);
}
}
/**
re-add the status dice gump
*/
public void AddStatusGump(Mobile m){
int noExitMobileIdx = GetCurrentDicePlayerIdx(m);
PlayerWaiting(dicePlayers[noExitMobileIdx],updatedMobileIdx);
}
/**
Shows new game gump
*/
public void ShowNewGameGump(Mobile m){
while (m.HasGump(typeof(NewDiceGameGump))){
m.CloseGump(typeof(NewDiceGameGump));
}
//only allow if more than number of player
if(this.playerCnt < this.maxNumberOfPlayers){
ndgg = new NewDiceGameGump(this,Banker.GetBalance( m ));
try{
m.SendGump(ndgg );
}catch{
SendMessageAllPlayers( "Player " + m.Name + " was disconnected" );
RemovePlayer(m, true);
}
}else{
m.Frozen = false;
m.SendMessage( "Liars Dice is currently at it maximum capacity of " + this.maxNumberOfPlayers + " players, try again later.");
}
}
/********************************** START OF PRIVATE FUNCTIONS *****************************/
/**
Sends a plyer waiting gump, create gumps with 3 status arrays
*/
public void PlayerWaiting(MobileDiceStstatus mds, int currentPlayerIdx){
string[] playerNames = this.GetPlayerNames();
int[] playerBalances = this.GetPlayerBalances();
int[] playPrevRollIdx = this.GetPlayerPrevRollOrBluff();
sdg = new StatusDiceGump(this,playerNames, playerBalances, playPrevRollIdx, currentPlayerIdx);
try{
bool success = mds.getMobile().SendGump(sdg);
//check to make sure the status gump was actually sent, and use THIS as our dissconnect protection
if(success == false){
SendMessageAllPlayers( "Player " + mds.getMobile().Name + " was disconnected" );
RemovePlayer(mds.getMobile(), true);
}
}catch{
SendMessageAllPlayers( "Player " + mds.getMobile().Name + " was disconnected" );
RemovePlayer(mds.getMobile(), true);
}
}
/**
Game timer limit on a player, warn/kick if necessary in the callbacks
*/
public void SetTimerAction(MobileDiceStstatus prevPlayer, MobileDiceStstatus currPlayer){
prevPlayer.SetTimeStamp(DateTime.Now);
currPlayer.SetTimeStamp(DateTime.Now);
//setup the "warning" timer
Timer timer = Timer.DelayCall( TimeSpan.FromSeconds(this.playerToActSeconds - 5), new TimerCallback( delegate( ) {
TimeSpan timeDiff = (DateTime.Now - currPlayer.GetTimeStamp());
//check time in miliseconds
if(timeDiff.TotalMilliseconds > ( (this.playerToActSeconds-5) * 1000)){
if(this.playerCnt > 1){
SendMessageAllPlayers( currPlayer.getMobile().Name + " has 5 seconds to act before being kicked!" );
}
}
} ) );
//setup timer to kick player if applicable
Timer timer2 = Timer.DelayCall( TimeSpan.FromSeconds( this.playerToActSeconds), new TimerCallback( delegate( ) {
TimeSpan timeDiff = (DateTime.Now - currPlayer.GetTimeStamp());
//check time in miliseconds
if(timeDiff.TotalMilliseconds > (this.playerToActSeconds * 1000)){
if(this.playerCnt > 1){
SendMessageAllPlayers( currPlayer.getMobile().Name + " ran out of time, and has been kicked from the game." );
RemovePlayer(currPlayer.getMobile(), true);
}
}
} ) );
}
/**
Get information about min/max allowed gold for this game
*/
public int getGameBalanceMin(){
return this.gameBalanceMin;
}
public int getGameBalanceMax(){
return this.gameBalanceMax;
}
/**
Find the index of the player that just submitted the gump
*/
private int GetCurrentDicePlayerIdx(Mobile m){
for (int i = 0; i < this.playerCnt; i++){
if(m == dicePlayers[i].getMobile()){
return i;
}
}
return -1;
}
/**
Get the next dice players index
*/
private int GetNextDicePlayerIdx(int currentIdx){
if( currentIdx >= 0 && currentIdx < (this.playerCnt-1)){
return (currentIdx + 1);
}else{
return 0;
}
}
/**
Get the prvious dice players index
*/
private int GetPrevDicePlayerIdx(int currentIdx){
if(currentIdx == 0){
return this.playerCnt-1;
}else if(currentIdx > 0){
return currentIdx -1;
}else {
//error
return -1;
}
}
/**
Checks a dice bluff
*/
private bool CheckBluff(){
int prevRoll = dicePlayers[prevPlayerIdx].GetPrevRoll();
int bluffedRoll = dicePlayers[prevPlayerIdx].GetPrevRollOrBluff();
if(prevRoll == bluffedRoll){
return false;
}else{
return true;
}
}
/**
Sends status message to all players
*/
private void SendMessageAllPlayers(string text){
for (int i = 0; i < this.playerCnt; i++){
dicePlayers[i].getMobile().SendMessage( text);
}
}
/**
Check if there is enough players in the area
*/
private bool HasEnoughPlayers(){
if(this.playerCnt >= 2){
return true;
}else{
return false;
}
}
/**
Get all player names
*/
private string[] GetPlayerNames(){
string[] playerNames = new string[playerCnt];
for (int i = 0; i < this.playerCnt; i++){
playerNames[i] = dicePlayers[i].getMobile().Name;
}
return playerNames;
}
/**
Get all player balances
*/
private int[] GetPlayerBalances(){
int[] playerBalances = new int[playerCnt];
for (int i = 0; i < this.playerCnt; i++){
playerBalances[i] = dicePlayers[i].GetTableBalance();
}
return playerBalances;
}
/**
Get player list for previous rolls.
*/
private int[] GetPlayerPrevRollOrBluff(){
int[] playerPrevRollOrBluff = new int[playerCnt];
for (int i = 0; i < this.playerCnt; i++){
playerPrevRollOrBluff[i] = dicePlayers[i].GetPrevRollOrBluff();
}
return playerPrevRollOrBluff;
}
/**
Remove just the status gump from a player
*/
public void RemoveStatusGump(MobileDiceStstatus mds){
try{
while (mds.getMobile().HasGump(typeof(StatusDiceGump))){
mds.getMobile().CloseGump(typeof(StatusDiceGump));
}
}catch{
SendMessageAllPlayers( "Player " + mds.getMobile().Name + " was disconnected" );
RemovePlayer(mds.getMobile(), true);
}
}
/**
Remove all gumps from a player
*/
private void RemoveGumps(MobileDiceStstatus mds){
try{
while (mds.getMobile().HasGump(typeof(NewDiceGameGump))){
mds.getMobile().CloseGump(typeof(NewDiceGameGump));
}
while (mds.getMobile().HasGump(typeof(ExitDiceGump))){
mds.getMobile().CloseGump(typeof(ExitDiceGump));
}
while (mds.getMobile().HasGump(typeof(StatusDiceGump))){
mds.getMobile().CloseGump(typeof(StatusDiceGump));
}
while ( mds.getMobile().HasGump(typeof(GameDiceGump))){
mds.getMobile().CloseGump(typeof(GameDiceGump));
}
while ( mds.getMobile().HasGump(typeof(CallBluffGump))){
mds.getMobile().CloseGump(typeof(CallBluffGump));
}
}catch{
SendMessageAllPlayers( "Player " + mds.getMobile().Name + " was disconnected" );
RemovePlayer(mds.getMobile(), true);
}
}
}
}

View File

@@ -0,0 +1,49 @@
/**
LIARS DICE for Ultima Online
Copyright: Bobby Kramer 2011, http://www.panthar.net
Released under GPL V3.
*/
using System;
using Server;
using Server.Gumps;
using Server.Network;
using Server.Commands;
using Server.LiarsDice;
using System.Collections.Generic;
namespace Server.Gumps
{
public class ExitDiceGump : Gump
{
private const int LEFT_BAR=25;
private DiceState ds;
public ExitDiceGump(DiceState _ds) : base( 325, 345)
{
this.ds = _ds;
this.Closable=false;
this.Disposable=false;
this.Dragable=true;
this.Resizable=false;
this.AddPage(0);
this.AddBackground(6, 4, 225, 150, 9200);
this.AddLabel(LEFT_BAR, 25, 0, @"Are You Sure You");
this.AddLabel(LEFT_BAR, 45, 0, @"Want To Exit?");
this.AddLabel(LEFT_BAR, 85, 32, @"Back");
AddButton(LEFT_BAR, 110, 4005, 4006, 1, GumpButtonType.Reply, 3);
this.AddLabel(LEFT_BAR + 95, 85, 32, @"Yes");
AddButton(LEFT_BAR +95, 110, 4017, 4018, 2, GumpButtonType.Reply, 3);
}
public override void OnResponse( NetState state, RelayInfo info ){
int btd = info.ButtonID;
if(info.ButtonID == 1 ){
ds.AddStatusGump(state.Mobile);
state.Mobile.SendMessage( "You decided not to exit Liars Dice!");
}else if(info.ButtonID == 2){
state.Mobile.SendMessage( "You exited Liars Dice!");
ds.RemovePlayer(state.Mobile,true);
}
else{
state.Mobile.SendMessage( "Illegal option selected");
}
}
}
}

View File

@@ -0,0 +1,122 @@
/**
LIARS DICE for Ultima Online
Copyright: Bobby Kramer 2011, http://www.panthar.net
Released under GPL V3.
*/
using System;
using Server;
using Server.Gumps;
using Server.Network;
using Server.Commands;
using System.Collections.Generic;
using Server.LiarsDice;
namespace Server.Gumps
{
public class GameDiceGump : Gump
{
private const int LEFT_BAR_SIDE=5;
private const int RADIO_WIDTH=30;
private const int LEFT_SIDE_WIDTH=120;
private DiceState ds;
private int currentRoll;
private int diceToBeat;
private int[] Dice1Values = new int[] { 2,6,5,4,3,2,1,6,6,6,6,6,5,5,5,5,4,4,4,3,3};
private int[] Dice2Values = new int[] { 1,6,5,4,3,2,1,5,4,3,2,1,4,3,2,1,3,2,1,2,1};
/**
Default constuctor, just set the values to {1,1}
*/
public GameDiceGump(DiceState _ds) : base( 0, 30 ){
this.ds = _ds;
this.currentRoll = 10;
this.diceToBeat = 20;
AddRollGump();
}
/**
Create new Dice Gump and set it's values to a given array)
*/
public GameDiceGump(DiceState _ds, int _currentRoll, int _diceToBeat) : base( 0, 30 ){
this.ds = _ds;
this.currentRoll = _currentRoll;
this.diceToBeat = _diceToBeat;
AddRollGump();
}
private void AddRollGump(){
this.Closable=false;
this.Disposable=false;
this.Dragable=true;
this.Resizable=false;
AddPage(0);
AddBackground(0, 1, 260, 440, 9200);
AddLabel(9, 24, 32, @"Your Actual Roll:");
AddLabel(9, 45, 0, @"Action");
AddLabel(150, 380, 32, @"Submit Roll");
AddButton(150, 400, 4005, 4006, 2, GumpButtonType.Reply, 3);
//show the current dice roll to screen of the player
this.DisplayRollDice();
//show dice selections to pretend to be
for ( int i = 0; i < 11; ++i )
{
if(i <= this.diceToBeat){
AddRadio( LEFT_BAR_SIDE, 70 + (i * 25), 210, 211, false, (i) );
this.DisplayDiceCombo(LEFT_BAR_SIDE + RADIO_WIDTH, 70 + (i * 25), this.Dice1Values[i],this.Dice2Values[i]);
}
}
for ( int i = 11; i < 21; ++i ){
if(i <= this.diceToBeat){
AddRadio( LEFT_BAR_SIDE+LEFT_SIDE_WIDTH, 70 + ((i-11) * 25), 210, 211, false, i );
this.DisplayDiceCombo(LEFT_BAR_SIDE + LEFT_SIDE_WIDTH + RADIO_WIDTH, 70 + ((i-11) * 25), this.Dice1Values[i],this.Dice2Values[i]);
}
}
}
private void DisplayRollDice(){
if(this.currentRoll >= 0 && this.currentRoll <= 20){
this.DisplayDiceCombo(125, 20, Dice1Values[this.currentRoll],Dice2Values[this.currentRoll]);
}
}
/**
* Die_num must be between 1 and 6, it subtracts one because thats how we access the id of the image
*/
private void DisplayDiceCombo(int x, int y, int first_die, int second_die){
int swap=0;
if(second_die > first_die){
swap = first_die;
second_die = first_die;
second_die = swap;
}
AddImageTiled(x, y, 21, 21, 11280 + (first_die-1));
AddImageTiled(x+30, y, 21, 21, 11280 + (second_die-1));
}
public override void OnResponse( NetState state, RelayInfo info ){
int btd = info.ButtonID;
if(info.ButtonID == 2){
//20 would be the lowest roll, since 0 is a index
bool switched = false;
for ( int i = 0; i <= this.diceToBeat; ++i ){
if(info.IsSwitched( i )){
switched = true;
ds.UpdateGameChannelBluff(state.Mobile, i);
return;
}
}
if(switched == false){
state.Mobile.SendMessage( "Please select a dice value!");
state.Mobile.SendGump(this);
}
}
else{
state.Mobile.SendMessage( "Illegal option selected");
}
}
}
}

View File

@@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

View File

@@ -0,0 +1,62 @@
/**
LIARS DICE for Ultima Online
Copyright: Bobby Kramer 2011, http://www.panthar.net
Released under GPL V3.
*/
using System;
using Server;
using Server.Mobiles;
using Server.Network;
using Server.Gumps;
using Server.LiarsDice;
namespace Server.Items
{
public class LiarsDice : Item
{
private const int GOLD_PER_GAME=5000;
private const int GAME_BALANCE_MIN=10000;
private const int GAME_BALANCE_MAX=300000;
private const int GAME_PLAYER_TO_ACT_SECONDS=25;
private const int GAME_MAX_PLAYERS = 10;
//the dicestate the item/command represents
static DiceState ds;
[Constructable]
public LiarsDice() : base( 0xFA7 )
{
this.Weight = 1.0;
this.Hue = 2117;
ds = new DiceState(GOLD_PER_GAME,GAME_BALANCE_MIN,GAME_BALANCE_MAX,GAME_PLAYER_TO_ACT_SECONDS,GAME_MAX_PLAYERS);
}
public LiarsDice( Serial serial ) : base( serial ){
this.Weight = 1.0;
this.Hue = 2117;
ds = new DiceState(GOLD_PER_GAME,GAME_BALANCE_MIN,GAME_BALANCE_MAX,GAME_PLAYER_TO_ACT_SECONDS,GAME_MAX_PLAYERS);
}
public override void OnDoubleClick( Mobile from )
{
if ( !from.InRange( this.GetWorldLocation(), 2 ) )
return;
int val = Banker.GetBalance( from );
//make sure user has enough gold in bank
if(val >= GAME_BALANCE_MIN){
from.Frozen = true;
ds.ShowNewGameGump(from);
}else{
from.SendMessage( "Sorry, but you must have at least " + GAME_BALANCE_MIN + " gold in your bank to play!" );
}
}
public override void Serialize( GenericWriter writer ){
base.Serialize( writer );
writer.Write( (int) 0 );
}
public override void Deserialize( GenericReader reader ){
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,81 @@
/**
LIARS DICE for Ultima Online
Copyright: Bobby Kramer 2011, http://www.panthar.net
Released under GPL V3.
*/
using System;
using Server;
using Server.Gumps;
using Server.Network;
using Server.Commands;
using Server.Mobiles;
using Server.LiarsDice;
using System.Collections.Generic;
namespace Server.Gumps
{
public class NewDiceGameGump : Gump
{
private const int LEFT_BAR=25;
private int bankBalance;
private DiceState ds;
public NewDiceGameGump(DiceState _ds, int _bankBalance) : base( 325, 345){
this.ds = _ds;
this.bankBalance = _bankBalance;
this.Closable=false;
this.Disposable=false;
this.Dragable=true;
this.Resizable=false;
this.AddPage(0);
this.AddBackground(6, 4, 190, 150, 9200);
this.AddLabel(LEFT_BAR, 20, 0, @"Liars Dice");
//this.AddLabel(LEFT_BAR, 40, 0, @"By: PanThar");
this.AddLabel(LEFT_BAR, 60, 32, @"Balance: " + bankBalance + " gp.");
AddImageTiled(LEFT_BAR, 80, 142, 21, 2501);
AddTextEntry( LEFT_BAR+7, 80, 200, 30, 255, 0, @"");
AddButton(LEFT_BAR, 110, 4005, 4006, 1, GumpButtonType.Reply, 3);
AddButton(LEFT_BAR +95, 110, 4017, 4018, 2, GumpButtonType.Reply, 3);
}
public override void OnResponse( NetState state, RelayInfo info ){
int btd = info.ButtonID;
Mobile m = state.Mobile;
if(info.ButtonID == 1 ){
TextRelay entry = info.GetTextEntry(0);
//parse out the text entry
try{
int balance = Banker.GetBalance(m);
int num = int.Parse(entry.Text);
int maxGameBal = ds.getGameBalanceMax();
//take out the full amount of bank if applicable
if(num > balance){
num = balance;
}
//if its over the max size, set num to it
if(num > maxGameBal){
num = maxGameBal;
m.SendMessage( "You entered more than the max of " + maxGameBal + " gp. on this table, you are buying in with the max instead." );
}
//check if they have minimum game balance
if(num >= ds.getGameBalanceMin()){
//withdrawl
Banker.Withdraw( m, num );
ds.AddPlayer(m,num);
}
else{
ds.ShowNewGameGump(m);
m.SendMessage( "You did not enter a sufficient minimum amount to play,try again." );
}
}catch{
m.Frozen = false;
m.SendMessage( "You did not enter a amount of gold to play with, try again." );
}
}else if(info.ButtonID == 2){
m.Frozen = false;
m.SendMessage( "You decided not to play Liars Dice.");
}
else{
state.Mobile.SendMessage( "Illegal option selected");
}
}
}
}

View File

@@ -0,0 +1,27 @@
LIARS DICE for Ultima Online
Copyright: Bobby Kramer 2011, http://www.panthar.net
Released under GPL V3.
Includes disconnect protection, turn timers, and a monetary punishment to any player who leaves on his turn,
or 1 player before his turn. This will make sense once you understand how the game works.
What this script does, is it allows the server admin (and maybe GM) to create an item called a "LiarsDice".
INSTALL:
Extract the zip file into /scripts/ inside your RunUO directory.
ONCE YOU HAVE LAIRS DICE INSTALLED/WORKING ON SERVER:
To add this item, log into your RunUO server, type [add LiarsDice into UO client.
Once you have created a LiarsDice Constructable item, that item and any copys of that object you make will all link players to the same LIARS DICE GAME.
TO PLAY THE GAME, SIMPLY DOUBLE CLICK THE DICE TO JOIN THAT GAME. YOU MUST HAVE AT LEAST 2 PLAYERS TO PLAY.
Basically, if you look at LiarsDice.cs, it will become quickly apperant how to customize the settings for the game.
IF you want MORE THAN ONE GAME with different SETTINGS on EACH game:
Copy LiarsDice.cs to a new file, rename the file/constructor/class to the new name of the Item, and set the settings for
that game using LiarsDice.cs as an example. Now when you create/double click your new item, it will display a DIFFERENT Liars Dice Game window.

Some files were not shown because too many files have changed in this diff Show More