using System; using System.Collections; using System.Collections.Generic; using Server; using Server.Gumps; using Server.Multis; using Server.ContextMenus; namespace Server.Engines.Mahjong { public class MahjongGame : Item, ISecurable { public const int MaxPlayers = 4; public const int BaseScore = 30000; private MahjongTile[] m_Tiles; private MahjongDealerIndicator m_DealerIndicator; private MahjongWallBreakIndicator m_WallBreakIndicator; private MahjongDices m_Dices; private MahjongPlayers m_Players; private bool m_ShowScores; private bool m_SpectatorVision; private DateTime m_LastReset; public MahjongTile[] Tiles { get { return m_Tiles; } } public MahjongDealerIndicator DealerIndicator { get { return m_DealerIndicator; } } public MahjongWallBreakIndicator WallBreakIndicator { get { return m_WallBreakIndicator; } } public MahjongDices Dices { get { return m_Dices; } } public MahjongPlayers Players { get { return m_Players; } } private SecureLevel m_Level; [CommandProperty( AccessLevel.GameMaster )] public SecureLevel Level { get{ return m_Level; } set{ m_Level = value; } } [CommandProperty( AccessLevel.GameMaster )] public bool ShowScores { get { return m_ShowScores; } set { if ( m_ShowScores == value ) return; m_ShowScores = value; if ( value ) m_Players.SendPlayersPacket( true, true ); m_Players.SendGeneralPacket( true, true ); m_Players.SendLocalizedMessage( value ? 1062777 : 1062778 ); // The dealer has enabled/disabled score display. } } [CommandProperty( AccessLevel.GameMaster )] public bool SpectatorVision { get { return m_SpectatorVision; } set { if ( m_SpectatorVision == value ) return; m_SpectatorVision = value; if ( m_Players.IsInGamePlayer( m_Players.DealerPosition ) ) m_Players.Dealer.Send( new MahjongGeneralInfo( this ) ); m_Players.SendTilesPacket( false, true ); m_Players.SendLocalizedMessage( value ? 1062715 : 1062716 ); // The dealer has enabled/disabled Spectator Vision. InvalidateProperties(); } } [Constructable] public MahjongGame() : base( 0xFAA ) { Weight = 5.0; BuildWalls(); m_DealerIndicator = new MahjongDealerIndicator( this, new Point2D( 300, 300 ), MahjongPieceDirection.Up, MahjongWind.North ); m_WallBreakIndicator = new MahjongWallBreakIndicator( this, new Point2D( 335, 335 ) ); m_Dices = new MahjongDices( this ); m_Players = new MahjongPlayers( this, MaxPlayers, BaseScore ); m_LastReset = DateTime.Now; m_Level = SecureLevel.CoOwners; } public MahjongGame( Serial serial ) : base( serial ) { } private void BuildHorizontalWall( ref int index, int x, int y, int stackLevel, MahjongPieceDirection direction, MahjongTileTypeGenerator typeGenerator ) { for ( int i = 0; i < 17; i++ ) { Point2D position = new Point2D( x + i*20, y ); m_Tiles[index + i] = new MahjongTile( this, index + i, typeGenerator.Next(), position, stackLevel, direction, false ); } index += 17; } private void BuildVerticalWall( ref int index, int x, int y, int stackLevel, MahjongPieceDirection direction, MahjongTileTypeGenerator typeGenerator ) { for ( int i = 0; i < 17; i++ ) { Point2D position = new Point2D( x, y + i*20 ); m_Tiles[index + i] = new MahjongTile( this, index + i, typeGenerator.Next(), position, stackLevel, direction, false ); } index += 17; } private void BuildWalls() { m_Tiles = new MahjongTile[17 * 8]; MahjongTileTypeGenerator typeGenerator = new MahjongTileTypeGenerator( 4 ); int i = 0; BuildHorizontalWall( ref i, 165, 110, 0, MahjongPieceDirection.Up, typeGenerator ); BuildHorizontalWall( ref i, 165, 115, 1, MahjongPieceDirection.Up, typeGenerator ); BuildVerticalWall( ref i, 530, 165, 0, MahjongPieceDirection.Left, typeGenerator ); BuildVerticalWall( ref i, 525, 165, 1, MahjongPieceDirection.Left, typeGenerator ); BuildHorizontalWall( ref i, 165, 530, 0, MahjongPieceDirection.Down, typeGenerator ); BuildHorizontalWall( ref i, 165, 525, 1, MahjongPieceDirection.Down, typeGenerator ); BuildVerticalWall( ref i, 110, 165, 0, MahjongPieceDirection.Right, typeGenerator ); BuildVerticalWall( ref i, 115, 165, 1, MahjongPieceDirection.Right, typeGenerator ); } public override void GetProperties( ObjectPropertyList list ) { base.GetProperties( list ); if ( m_SpectatorVision ) list.Add( 1062717 ); // Spectator Vision Enabled else list.Add( 1062718 ); // Spectator Vision Disabled } public override void GetContextMenuEntries( Mobile from, List list ) { base.GetContextMenuEntries( from, list ); m_Players.CheckPlayers(); if ( from.Alive && IsAccessibleTo( from ) && m_Players.GetInGameMobiles( true, false ).Count == 0 ) list.Add( new ResetGameEntry( this ) ); SetSecureLevelEntry.AddTo( from, this, list ); } private class ResetGameEntry : ContextMenuEntry { private MahjongGame m_Game; public ResetGameEntry( MahjongGame game ) : base( 6162 ) { m_Game = game; } public override void OnClick() { Mobile from = Owner.From; if ( from.CheckAlive() && !m_Game.Deleted && m_Game.IsAccessibleTo( from ) && m_Game.Players.GetInGameMobiles( true, false ).Count == 0 ) m_Game.ResetGame( from ); } } public override void OnDoubleClick( Mobile from ) { m_Players.CheckPlayers(); m_Players.Join( from ); } public void ResetGame( Mobile from ) { if ( DateTime.Now - m_LastReset < TimeSpan.FromSeconds( 5.0 ) ) return; m_LastReset = DateTime.Now; if ( from != null ) m_Players.SendLocalizedMessage( 1062771, from.Name ); // ~1_name~ has reset the game. m_Players.SendRelievePacket( true, true ); BuildWalls(); m_DealerIndicator = new MahjongDealerIndicator( this, new Point2D( 300, 300 ), MahjongPieceDirection.Up, MahjongWind.North ); m_WallBreakIndicator = new MahjongWallBreakIndicator( this, new Point2D( 335, 335 ) ); m_Players = new MahjongPlayers( this, MaxPlayers, BaseScore ); } public void ResetWalls( Mobile from ) { if ( DateTime.Now - m_LastReset < TimeSpan.FromSeconds( 5.0 ) ) return; m_LastReset = DateTime.Now; BuildWalls(); m_Players.SendTilesPacket( true, true ); if ( from != null ) m_Players.SendLocalizedMessage( 1062696 ); // The dealer rebuilds the wall. } public int GetStackLevel( MahjongPieceDim dim ) { int level = -1; foreach ( MahjongTile tile in m_Tiles ) { if ( tile.StackLevel > level && dim.IsOverlapping( tile.Dimensions ) ) level = tile.StackLevel; } return level; } public override void Serialize( GenericWriter writer ) { base.Serialize( writer ); writer.Write( (int) 1 ); // version writer.Write( (int) m_Level ); writer.Write( m_Tiles.Length ); for ( int i = 0; i < m_Tiles.Length; i++ ) m_Tiles[i].Save( writer ); m_DealerIndicator.Save( writer ); m_WallBreakIndicator.Save( writer ); m_Dices.Save( writer ); m_Players.Save( writer ); writer.Write( m_ShowScores ); writer.Write( m_SpectatorVision ); } public override void Deserialize( GenericReader reader ) { base.Deserialize( reader ); int version = reader.ReadInt(); switch ( version ) { case 1: { m_Level = (SecureLevel)reader.ReadInt(); goto case 0; } case 0: { if ( version < 1 ) m_Level = SecureLevel.CoOwners; int length = reader.ReadInt(); m_Tiles = new MahjongTile[length]; for ( int i = 0; i < length; i++ ) m_Tiles[i] = new MahjongTile( this, reader ); m_DealerIndicator = new MahjongDealerIndicator( this, reader ); m_WallBreakIndicator = new MahjongWallBreakIndicator( this, reader ); m_Dices = new MahjongDices( this, reader ); m_Players = new MahjongPlayers( this, reader ); m_ShowScores = reader.ReadBool(); m_SpectatorVision = reader.ReadBool(); m_LastReset = DateTime.Now; break; } } } } }