fix: Codegens mahjong (#1070)
This commit is contained in:
parent
800f864335
commit
6edccfe2aa
15 changed files with 1272 additions and 1122 deletions
|
|
@ -1,69 +1,62 @@
|
||||||
namespace Server.Engines.Mahjong
|
using ModernUO.Serialization;
|
||||||
|
|
||||||
|
namespace Server.Engines.Mahjong;
|
||||||
|
|
||||||
|
[SerializationGenerator(1, false)]
|
||||||
|
public partial class MahjongDealerIndicator
|
||||||
{
|
{
|
||||||
public class MahjongDealerIndicator
|
[DirtyTrackingEntity]
|
||||||
|
private readonly MahjongGame _game;
|
||||||
|
|
||||||
|
[SerializableField(0, setter: "private")]
|
||||||
|
private Point2D _position;
|
||||||
|
|
||||||
|
[SerializableField(1, setter: "private")]
|
||||||
|
private MahjongPieceDirection _direction;
|
||||||
|
|
||||||
|
[SerializableField(2, setter: "private")]
|
||||||
|
private MahjongWind _wind;
|
||||||
|
|
||||||
|
public MahjongDealerIndicator(MahjongGame game)
|
||||||
{
|
{
|
||||||
public MahjongDealerIndicator(MahjongGame game, Point2D position, MahjongPieceDirection direction, MahjongWind wind)
|
_game = game;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MahjongDealerIndicator(MahjongGame game, Point2D position, MahjongPieceDirection direction, MahjongWind wind)
|
||||||
|
{
|
||||||
|
_game = game;
|
||||||
|
_position = position;
|
||||||
|
_direction = direction;
|
||||||
|
_wind = wind;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MahjongPieceDim Dimensions => GetDimensions(_position, _direction);
|
||||||
|
|
||||||
|
public static MahjongPieceDim GetDimensions(Point2D position, MahjongPieceDirection direction) =>
|
||||||
|
direction is MahjongPieceDirection.Up or MahjongPieceDirection.Down
|
||||||
|
? new MahjongPieceDim(position, 40, 20)
|
||||||
|
: new MahjongPieceDim(position, 20, 40);
|
||||||
|
|
||||||
|
public void Move(Point2D position, MahjongPieceDirection direction, MahjongWind wind)
|
||||||
|
{
|
||||||
|
var dim = GetDimensions(position, direction);
|
||||||
|
|
||||||
|
if (!dim.IsValid())
|
||||||
{
|
{
|
||||||
Game = game;
|
return;
|
||||||
Position = position;
|
|
||||||
Direction = direction;
|
|
||||||
Wind = wind;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public MahjongDealerIndicator(MahjongGame game, IGenericReader reader)
|
_position = position;
|
||||||
{
|
_direction = direction;
|
||||||
Game = game;
|
_wind = wind;
|
||||||
|
|
||||||
var version = reader.ReadInt();
|
_game.Players.SendGeneralPacket(true, true);
|
||||||
|
}
|
||||||
|
|
||||||
Position = reader.ReadPoint2D();
|
private void Deserialize(IGenericReader reader, int version)
|
||||||
Direction = (MahjongPieceDirection)reader.ReadInt();
|
{
|
||||||
Wind = (MahjongWind)reader.ReadInt();
|
_position = reader.ReadPoint2D();
|
||||||
}
|
_direction = (MahjongPieceDirection)reader.ReadInt();
|
||||||
|
_wind = (MahjongWind)reader.ReadInt();
|
||||||
public MahjongGame Game { get; }
|
|
||||||
|
|
||||||
public Point2D Position { get; private set; }
|
|
||||||
|
|
||||||
public MahjongPieceDirection Direction { get; private set; }
|
|
||||||
|
|
||||||
public MahjongWind Wind { get; private set; }
|
|
||||||
|
|
||||||
public MahjongPieceDim Dimensions => GetDimensions(Position, Direction);
|
|
||||||
|
|
||||||
public static MahjongPieceDim GetDimensions(Point2D position, MahjongPieceDirection direction)
|
|
||||||
{
|
|
||||||
if (direction is MahjongPieceDirection.Up or MahjongPieceDirection.Down)
|
|
||||||
{
|
|
||||||
return new MahjongPieceDim(position, 40, 20);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new MahjongPieceDim(position, 20, 40);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Move(Point2D position, MahjongPieceDirection direction, MahjongWind wind)
|
|
||||||
{
|
|
||||||
var dim = GetDimensions(position, direction);
|
|
||||||
|
|
||||||
if (!dim.IsValid())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Position = position;
|
|
||||||
Direction = direction;
|
|
||||||
Wind = wind;
|
|
||||||
|
|
||||||
Game.Players.SendGeneralPacket(true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Save(IGenericWriter writer)
|
|
||||||
{
|
|
||||||
writer.Write(0); // version
|
|
||||||
|
|
||||||
writer.Write(Position);
|
|
||||||
writer.Write((int)Direction);
|
|
||||||
writer.Write((int)Wind);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,52 +1,37 @@
|
||||||
namespace Server.Engines.Mahjong
|
using ModernUO.Serialization;
|
||||||
|
|
||||||
|
namespace Server.Engines.Mahjong;
|
||||||
|
|
||||||
|
[SerializationGenerator(0, false)]
|
||||||
|
public partial class MahjongDices
|
||||||
{
|
{
|
||||||
public class MahjongDices
|
[DirtyTrackingEntity]
|
||||||
|
private readonly MahjongGame _game;
|
||||||
|
|
||||||
|
[SerializableField(0, setter: "private")]
|
||||||
|
private int _first;
|
||||||
|
|
||||||
|
[SerializableField(1, setter: "private")]
|
||||||
|
private int _second;
|
||||||
|
|
||||||
|
public MahjongDices(MahjongGame game)
|
||||||
{
|
{
|
||||||
public MahjongDices(MahjongGame game)
|
_game = game;
|
||||||
|
_first = Utility.Random(1, 6);
|
||||||
|
_second = Utility.Random(1, 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RollDices(Mobile from)
|
||||||
|
{
|
||||||
|
_first = Utility.Random(1, 6);
|
||||||
|
_second = Utility.Random(1, 6);
|
||||||
|
|
||||||
|
_game.Players.SendGeneralPacket(true, true);
|
||||||
|
|
||||||
|
if (from != null)
|
||||||
{
|
{
|
||||||
Game = game;
|
// ~1_name~ rolls the dice and gets a ~2_number~ and a ~3_number~!
|
||||||
First = Utility.Random(1, 6);
|
_game.Players.SendLocalizedMessage(1062695, $"{from.Name}\t{_first}\t{_second}");
|
||||||
Second = Utility.Random(1, 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MahjongDices(MahjongGame game, IGenericReader reader)
|
|
||||||
{
|
|
||||||
Game = game;
|
|
||||||
|
|
||||||
var version = reader.ReadInt();
|
|
||||||
|
|
||||||
First = reader.ReadInt();
|
|
||||||
Second = reader.ReadInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
public MahjongGame Game { get; }
|
|
||||||
|
|
||||||
public int First { get; private set; }
|
|
||||||
|
|
||||||
public int Second { get; private set; }
|
|
||||||
|
|
||||||
public void RollDices(Mobile from)
|
|
||||||
{
|
|
||||||
First = Utility.Random(1, 6);
|
|
||||||
Second = Utility.Random(1, 6);
|
|
||||||
|
|
||||||
Game.Players.SendGeneralPacket(true, true);
|
|
||||||
|
|
||||||
if (from != null)
|
|
||||||
{
|
|
||||||
Game.Players.SendLocalizedMessage(
|
|
||||||
1062695,
|
|
||||||
$"{from.Name}\t{First}\t{Second}"
|
|
||||||
); // ~1_name~ rolls the dice and gets a ~2_number~ and a ~3_number~!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Save(IGenericWriter writer)
|
|
||||||
{
|
|
||||||
writer.Write(0); // version
|
|
||||||
|
|
||||||
writer.Write(First);
|
|
||||||
writer.Write(Second);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,56 +1,55 @@
|
||||||
namespace Server.Engines.Mahjong
|
namespace Server.Engines.Mahjong;
|
||||||
|
|
||||||
|
public enum MahjongPieceDirection
|
||||||
{
|
{
|
||||||
public enum MahjongPieceDirection
|
Up,
|
||||||
{
|
Left,
|
||||||
Up,
|
Down,
|
||||||
Left,
|
Right
|
||||||
Down,
|
}
|
||||||
Right
|
|
||||||
}
|
public enum MahjongWind
|
||||||
|
{
|
||||||
public enum MahjongWind
|
North,
|
||||||
{
|
East,
|
||||||
North,
|
South,
|
||||||
East,
|
West
|
||||||
South,
|
}
|
||||||
West
|
|
||||||
}
|
public enum MahjongTileType
|
||||||
|
{
|
||||||
public enum MahjongTileType
|
Dagger1 = 1,
|
||||||
{
|
Dagger2,
|
||||||
Dagger1 = 1,
|
Dagger3,
|
||||||
Dagger2,
|
Dagger4,
|
||||||
Dagger3,
|
Dagger5,
|
||||||
Dagger4,
|
Dagger6,
|
||||||
Dagger5,
|
Dagger7,
|
||||||
Dagger6,
|
Dagger8,
|
||||||
Dagger7,
|
Dagger9,
|
||||||
Dagger8,
|
Gem1,
|
||||||
Dagger9,
|
Gem2,
|
||||||
Gem1,
|
Gem3,
|
||||||
Gem2,
|
Gem4,
|
||||||
Gem3,
|
Gem5,
|
||||||
Gem4,
|
Gem6,
|
||||||
Gem5,
|
Gem7,
|
||||||
Gem6,
|
Gem8,
|
||||||
Gem7,
|
Gem9,
|
||||||
Gem8,
|
Number1,
|
||||||
Gem9,
|
Number2,
|
||||||
Number1,
|
Number3,
|
||||||
Number2,
|
Number4,
|
||||||
Number3,
|
Number5,
|
||||||
Number4,
|
Number6,
|
||||||
Number5,
|
Number7,
|
||||||
Number6,
|
Number8,
|
||||||
Number7,
|
Number9,
|
||||||
Number8,
|
North,
|
||||||
Number9,
|
East,
|
||||||
North,
|
South,
|
||||||
East,
|
West,
|
||||||
South,
|
Green,
|
||||||
West,
|
Red,
|
||||||
Green,
|
White
|
||||||
Red,
|
|
||||||
White
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,347 +1,316 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using ModernUO.Serialization;
|
||||||
using Server.ContextMenus;
|
using Server.ContextMenus;
|
||||||
using Server.Gumps;
|
using Server.Gumps;
|
||||||
using Server.Multis;
|
using Server.Multis;
|
||||||
|
|
||||||
namespace Server.Engines.Mahjong
|
namespace Server.Engines.Mahjong;
|
||||||
|
|
||||||
|
[SerializationGenerator(1, false)]
|
||||||
|
public partial class MahjongGame : Item, ISecurable
|
||||||
{
|
{
|
||||||
public class MahjongGame : Item, ISecurable
|
public const int MaxPlayers = 4;
|
||||||
|
public const int BaseScore = 30000;
|
||||||
|
|
||||||
|
[SerializableField(0)]
|
||||||
|
[SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")]
|
||||||
|
private SecureLevel _level;
|
||||||
|
|
||||||
|
[SerializableField(1, setter: "private")]
|
||||||
|
private MahjongTile[] _tiles;
|
||||||
|
|
||||||
|
[SerializableField(2, setter: "private")]
|
||||||
|
private MahjongDealerIndicator _dealerIndicator;
|
||||||
|
|
||||||
|
[SerializableField(3, setter: "private")]
|
||||||
|
private MahjongWallBreakIndicator _wallBreakIndicator;
|
||||||
|
|
||||||
|
[SerializableField(4, setter: "private")]
|
||||||
|
private MahjongDices _dices;
|
||||||
|
|
||||||
|
[SerializableField(5, setter: "private")]
|
||||||
|
private MahjongPlayers _players;
|
||||||
|
|
||||||
|
// Field 6
|
||||||
|
private bool _showScores;
|
||||||
|
|
||||||
|
// Field 7
|
||||||
|
private bool _spectatorVision;
|
||||||
|
|
||||||
|
private DateTime _lastReset;
|
||||||
|
|
||||||
|
[Constructible]
|
||||||
|
public MahjongGame() : base(0xFAA)
|
||||||
{
|
{
|
||||||
public const int MaxPlayers = 4;
|
Weight = 5.0;
|
||||||
public const int BaseScore = 30000;
|
|
||||||
private DateTime m_LastReset;
|
|
||||||
|
|
||||||
private bool m_ShowScores;
|
BuildWalls();
|
||||||
private bool m_SpectatorVision;
|
_dealerIndicator =
|
||||||
|
new MahjongDealerIndicator(this, new Point2D(300, 300), MahjongPieceDirection.Up, MahjongWind.North);
|
||||||
|
_wallBreakIndicator = new MahjongWallBreakIndicator(this, new Point2D(335, 335));
|
||||||
|
_dices = new MahjongDices(this);
|
||||||
|
_players = new MahjongPlayers(this, MaxPlayers, BaseScore);
|
||||||
|
_lastReset = Core.Now;
|
||||||
|
_level = SecureLevel.CoOwners;
|
||||||
|
}
|
||||||
|
|
||||||
[Constructible]
|
[CommandProperty(AccessLevel.GameMaster)]
|
||||||
public MahjongGame() : base(0xFAA)
|
[SerializableField(6)]
|
||||||
|
public bool ShowScores
|
||||||
|
{
|
||||||
|
get => _showScores;
|
||||||
|
set
|
||||||
{
|
{
|
||||||
Weight = 5.0;
|
if (_showScores == value)
|
||||||
|
|
||||||
BuildWalls();
|
|
||||||
DealerIndicator =
|
|
||||||
new MahjongDealerIndicator(this, new Point2D(300, 300), MahjongPieceDirection.Up, MahjongWind.North);
|
|
||||||
WallBreakIndicator = new MahjongWallBreakIndicator(this, new Point2D(335, 335));
|
|
||||||
Dices = new MahjongDices(this);
|
|
||||||
Players = new MahjongPlayers(this, MaxPlayers, BaseScore);
|
|
||||||
m_LastReset = Core.Now;
|
|
||||||
Level = SecureLevel.CoOwners;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MahjongGame(Serial serial) : base(serial)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public MahjongTile[] Tiles { get; private set; }
|
|
||||||
|
|
||||||
public MahjongDealerIndicator DealerIndicator { get; private set; }
|
|
||||||
|
|
||||||
public MahjongWallBreakIndicator WallBreakIndicator { get; private set; }
|
|
||||||
|
|
||||||
public MahjongDices Dices { get; private set; }
|
|
||||||
|
|
||||||
public MahjongPlayers Players { get; private set; }
|
|
||||||
|
|
||||||
[CommandProperty(AccessLevel.GameMaster)]
|
|
||||||
public bool ShowScores
|
|
||||||
{
|
|
||||||
get => m_ShowScores;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (m_ShowScores == value)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_ShowScores = value;
|
|
||||||
|
|
||||||
if (value)
|
|
||||||
{
|
|
||||||
Players.SendPlayersPacket(true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
Players.SendGeneralPacket(true, true);
|
|
||||||
|
|
||||||
Players.SendLocalizedMessage(value ? 1062777 : 1062778); // The dealer has enabled/disabled score display.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[CommandProperty(AccessLevel.GameMaster)]
|
|
||||||
public bool SpectatorVision
|
|
||||||
{
|
|
||||||
get => m_SpectatorVision;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (m_SpectatorVision == value)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_SpectatorVision = value;
|
|
||||||
|
|
||||||
if (Players.IsInGamePlayer(Players.DealerPosition))
|
|
||||||
{
|
|
||||||
Players.Dealer.NetState.SendMahjongGeneralInfo(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
Players.SendTilesPacket(false, true);
|
|
||||||
|
|
||||||
Players.SendLocalizedMessage(value ? 1062715 : 1062716); // The dealer has enabled/disabled Spectator Vision.
|
|
||||||
|
|
||||||
InvalidateProperties();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[CommandProperty(AccessLevel.GameMaster)]
|
|
||||||
public SecureLevel Level { get; set; }
|
|
||||||
|
|
||||||
private void BuildHorizontalWall(
|
|
||||||
ref int index, int x, int y, int stackLevel, MahjongPieceDirection direction,
|
|
||||||
MahjongTileTypeGenerator typeGenerator
|
|
||||||
)
|
|
||||||
{
|
|
||||||
for (var i = 0; i < 17; i++)
|
|
||||||
{
|
|
||||||
var position = new Point2D(x + i * 20, y);
|
|
||||||
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 (var i = 0; i < 17; i++)
|
|
||||||
{
|
|
||||||
var position = new Point2D(x, y + i * 20);
|
|
||||||
Tiles[index + i] = new MahjongTile(
|
|
||||||
this,
|
|
||||||
index + i,
|
|
||||||
typeGenerator.Next(),
|
|
||||||
position,
|
|
||||||
stackLevel,
|
|
||||||
direction,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
index += 17;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void BuildWalls()
|
|
||||||
{
|
|
||||||
Tiles = new MahjongTile[136];
|
|
||||||
|
|
||||||
var typeGenerator = new MahjongTileTypeGenerator();
|
|
||||||
|
|
||||||
var 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(IPropertyList 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<ContextMenuEntry> list)
|
|
||||||
{
|
|
||||||
base.GetContextMenuEntries(from, list);
|
|
||||||
|
|
||||||
Players.CheckPlayers();
|
|
||||||
|
|
||||||
if (from.Alive && IsAccessibleTo(from) && Players.GetInGameMobiles(true, false).Count == 0)
|
|
||||||
{
|
|
||||||
list.Add(new ResetGameEntry(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
SetSecureLevelEntry.AddTo(from, this, list);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnDoubleClick(Mobile from)
|
|
||||||
{
|
|
||||||
Players.CheckPlayers();
|
|
||||||
|
|
||||||
Players.Join(from);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ResetGame(Mobile from)
|
|
||||||
{
|
|
||||||
if (Core.Now - m_LastReset < TimeSpan.FromSeconds(5.0))
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_LastReset = Core.Now;
|
_showScores = value;
|
||||||
|
|
||||||
if (from != null)
|
if (value)
|
||||||
{
|
{
|
||||||
Players.SendLocalizedMessage(1062771, from.Name); // ~1_name~ has reset the game.
|
_players.SendPlayersPacket(true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Players.SendRelievePacket(true, true);
|
_players.SendGeneralPacket(true, true);
|
||||||
|
_players.SendLocalizedMessage(value ? 1062777 : 1062778); // The dealer has enabled/disabled score display.
|
||||||
BuildWalls();
|
this.MarkDirty();
|
||||||
DealerIndicator =
|
|
||||||
new MahjongDealerIndicator(this, new Point2D(300, 300), MahjongPieceDirection.Up, MahjongWind.North);
|
|
||||||
WallBreakIndicator = new MahjongWallBreakIndicator(this, new Point2D(335, 335));
|
|
||||||
Players = new MahjongPlayers(this, MaxPlayers, BaseScore);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void ResetWalls(Mobile from)
|
[CommandProperty(AccessLevel.GameMaster)]
|
||||||
|
[SerializableField(7)]
|
||||||
|
public bool SpectatorVision
|
||||||
|
{
|
||||||
|
get => _spectatorVision;
|
||||||
|
set
|
||||||
{
|
{
|
||||||
if (Core.Now - m_LastReset < TimeSpan.FromSeconds(5.0))
|
if (_spectatorVision == value)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_LastReset = Core.Now;
|
_spectatorVision = value;
|
||||||
|
|
||||||
BuildWalls();
|
if (_players.IsInGamePlayer(_players.DealerPosition))
|
||||||
|
|
||||||
Players.SendTilesPacket(true, true);
|
|
||||||
|
|
||||||
if (from != null)
|
|
||||||
{
|
{
|
||||||
Players.SendLocalizedMessage(1062696); // The dealer rebuilds the wall.
|
_players.Dealer.NetState.SendMahjongGeneralInfo(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
_players.SendTilesPacket(false, true);
|
||||||
|
_players.SendLocalizedMessage(value ? 1062715 : 1062716); // The dealer has enabled/disabled Spectator Vision.
|
||||||
|
InvalidateProperties();
|
||||||
|
this.MarkDirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BuildHorizontalWall(
|
||||||
|
ref int index, int x, int y, int stackLevel, MahjongPieceDirection direction,
|
||||||
|
MahjongTileTypeGenerator typeGenerator
|
||||||
|
)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < 17; i++)
|
||||||
|
{
|
||||||
|
var position = new Point2D(x + i * 20, y);
|
||||||
|
Tiles[index + i] = new MahjongTile(
|
||||||
|
this,
|
||||||
|
index + i,
|
||||||
|
typeGenerator.Next(),
|
||||||
|
position,
|
||||||
|
stackLevel,
|
||||||
|
direction,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
index += 17;
|
||||||
|
this.MarkDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BuildVerticalWall(
|
||||||
|
ref int index, int x, int y, int stackLevel, MahjongPieceDirection direction,
|
||||||
|
MahjongTileTypeGenerator typeGenerator
|
||||||
|
)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < 17; i++)
|
||||||
|
{
|
||||||
|
var position = new Point2D(x, y + i * 20);
|
||||||
|
Tiles[index + i] = new MahjongTile(
|
||||||
|
this,
|
||||||
|
index + i,
|
||||||
|
typeGenerator.Next(),
|
||||||
|
position,
|
||||||
|
stackLevel,
|
||||||
|
direction,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
index += 17;
|
||||||
|
this.MarkDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BuildWalls()
|
||||||
|
{
|
||||||
|
Tiles = new MahjongTile[136];
|
||||||
|
|
||||||
|
var typeGenerator = new MahjongTileTypeGenerator();
|
||||||
|
|
||||||
|
var 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(IPropertyList list)
|
||||||
|
{
|
||||||
|
base.GetProperties(list);
|
||||||
|
|
||||||
|
if (_spectatorVision)
|
||||||
|
{
|
||||||
|
list.Add(1062717); // Spectator Vision Enabled
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
list.Add(1062718); // Spectator Vision Disabled
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
|
||||||
|
{
|
||||||
|
base.GetContextMenuEntries(from, list);
|
||||||
|
|
||||||
|
_players.CheckPlayers();
|
||||||
|
|
||||||
|
if (from.Alive && IsAccessibleTo(from) && _players.GetInGameMobiles(true, false).Count == 0)
|
||||||
|
{
|
||||||
|
list.Add(new ResetGameEntry(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
SetSecureLevelEntry.AddTo(from, this, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnDoubleClick(Mobile from)
|
||||||
|
{
|
||||||
|
_players.CheckPlayers();
|
||||||
|
_players.Join(from);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResetGame(Mobile from)
|
||||||
|
{
|
||||||
|
if (Core.Now - _lastReset < TimeSpan.FromSeconds(5.0))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_lastReset = Core.Now;
|
||||||
|
|
||||||
|
if (from != null)
|
||||||
|
{
|
||||||
|
_players.SendLocalizedMessage(1062771, from.Name); // ~1_name~ has reset the game.
|
||||||
|
}
|
||||||
|
|
||||||
|
_players.SendRelievePacket(true, true);
|
||||||
|
|
||||||
|
BuildWalls();
|
||||||
|
DealerIndicator =
|
||||||
|
new MahjongDealerIndicator(this, new Point2D(300, 300), MahjongPieceDirection.Up, MahjongWind.North);
|
||||||
|
WallBreakIndicator = new MahjongWallBreakIndicator(this, new Point2D(335, 335));
|
||||||
|
Players = new MahjongPlayers(this, MaxPlayers, BaseScore);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResetWalls(Mobile from)
|
||||||
|
{
|
||||||
|
if (Core.Now - _lastReset < TimeSpan.FromSeconds(5.0))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_lastReset = Core.Now;
|
||||||
|
|
||||||
|
BuildWalls();
|
||||||
|
|
||||||
|
_players.SendTilesPacket(true, true);
|
||||||
|
|
||||||
|
if (from != null)
|
||||||
|
{
|
||||||
|
_players.SendLocalizedMessage(1062696); // The dealer rebuilds the wall.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetStackLevel(MahjongPieceDim dim)
|
||||||
|
{
|
||||||
|
var level = -1;
|
||||||
|
foreach (var tile in _tiles)
|
||||||
|
{
|
||||||
|
if (tile.StackLevel > level && dim.IsOverlapping(tile.Dimensions))
|
||||||
|
{
|
||||||
|
level = tile.StackLevel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetStackLevel(MahjongPieceDim dim)
|
return level;
|
||||||
{
|
}
|
||||||
var level = -1;
|
|
||||||
foreach (var tile in Tiles)
|
|
||||||
{
|
|
||||||
if (tile.StackLevel > level && dim.IsOverlapping(tile.Dimensions))
|
|
||||||
{
|
|
||||||
level = tile.StackLevel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return level;
|
private void Deserialize(IGenericReader reader, int number)
|
||||||
|
{
|
||||||
|
_level = (SecureLevel)reader.ReadInt();
|
||||||
|
var length = reader.ReadInt();
|
||||||
|
_tiles = new MahjongTile[length];
|
||||||
|
|
||||||
|
for (var i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
var tile = _tiles[i] = new MahjongTile(this);
|
||||||
|
tile.Deserialize(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Serialize(IGenericWriter writer)
|
_dealerIndicator = new MahjongDealerIndicator(this);
|
||||||
|
_dealerIndicator.Deserialize(reader);
|
||||||
|
|
||||||
|
_wallBreakIndicator = new MahjongWallBreakIndicator(this);
|
||||||
|
_wallBreakIndicator.Deserialize(reader);
|
||||||
|
|
||||||
|
_dices = new MahjongDices(this);
|
||||||
|
_dices.Deserialize(reader);
|
||||||
|
|
||||||
|
_players = new MahjongPlayers(this);
|
||||||
|
_players.Deserialize(reader);
|
||||||
|
|
||||||
|
_showScores = reader.ReadBool();
|
||||||
|
_spectatorVision = reader.ReadBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
[AfterDeserialization]
|
||||||
|
private void AfterDeserialization()
|
||||||
|
{
|
||||||
|
_lastReset = Core.Now;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ResetGameEntry : ContextMenuEntry
|
||||||
|
{
|
||||||
|
private readonly MahjongGame _game;
|
||||||
|
|
||||||
|
public ResetGameEntry(MahjongGame game) : base(6162) => _game = game;
|
||||||
|
|
||||||
|
public override void OnClick()
|
||||||
{
|
{
|
||||||
base.Serialize(writer);
|
var from = Owner.From;
|
||||||
|
|
||||||
writer.Write(1); // version
|
if (from.CheckAlive() && !_game.Deleted && _game.IsAccessibleTo(from) &&
|
||||||
|
_game.Players.GetInGameMobiles(true, false).Count == 0)
|
||||||
writer.Write((int)Level);
|
|
||||||
|
|
||||||
writer.Write(Tiles.Length);
|
|
||||||
|
|
||||||
for (var i = 0; i < Tiles.Length; i++)
|
|
||||||
{
|
{
|
||||||
Tiles[i].Save(writer);
|
_game.ResetGame(from);
|
||||||
}
|
|
||||||
|
|
||||||
DealerIndicator.Save(writer);
|
|
||||||
|
|
||||||
WallBreakIndicator.Save(writer);
|
|
||||||
|
|
||||||
Dices.Save(writer);
|
|
||||||
|
|
||||||
Players.Save(writer);
|
|
||||||
|
|
||||||
writer.Write(m_ShowScores);
|
|
||||||
writer.Write(m_SpectatorVision);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Deserialize(IGenericReader reader)
|
|
||||||
{
|
|
||||||
base.Deserialize(reader);
|
|
||||||
|
|
||||||
var version = reader.ReadInt();
|
|
||||||
|
|
||||||
switch (version)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
Level = (SecureLevel)reader.ReadInt();
|
|
||||||
|
|
||||||
goto case 0;
|
|
||||||
}
|
|
||||||
case 0:
|
|
||||||
{
|
|
||||||
if (version < 1)
|
|
||||||
{
|
|
||||||
Level = SecureLevel.CoOwners;
|
|
||||||
}
|
|
||||||
|
|
||||||
var length = reader.ReadInt();
|
|
||||||
Tiles = new MahjongTile[length];
|
|
||||||
|
|
||||||
for (var i = 0; i < length; i++)
|
|
||||||
{
|
|
||||||
Tiles[i] = new MahjongTile(this, reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
DealerIndicator = new MahjongDealerIndicator(this, reader);
|
|
||||||
|
|
||||||
WallBreakIndicator = new MahjongWallBreakIndicator(this, reader);
|
|
||||||
|
|
||||||
Dices = new MahjongDices(this, reader);
|
|
||||||
|
|
||||||
Players = new MahjongPlayers(this, reader);
|
|
||||||
|
|
||||||
m_ShowScores = reader.ReadBool();
|
|
||||||
m_SpectatorVision = reader.ReadBool();
|
|
||||||
|
|
||||||
m_LastReset = Core.Now;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ResetGameEntry : ContextMenuEntry
|
|
||||||
{
|
|
||||||
private readonly MahjongGame m_Game;
|
|
||||||
|
|
||||||
public ResetGameEntry(MahjongGame game) : base(6162) => m_Game = game;
|
|
||||||
|
|
||||||
public override void OnClick()
|
|
||||||
{
|
|
||||||
var 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,50 +1,49 @@
|
||||||
namespace Server.Engines.Mahjong
|
namespace Server.Engines.Mahjong;
|
||||||
|
|
||||||
|
public struct MahjongPieceDim
|
||||||
{
|
{
|
||||||
public struct MahjongPieceDim
|
public Point2D Position { get; }
|
||||||
|
|
||||||
|
public int Width { get; }
|
||||||
|
|
||||||
|
public int Height { get; }
|
||||||
|
|
||||||
|
public MahjongPieceDim(Point2D position, int width, int height)
|
||||||
{
|
{
|
||||||
public Point2D Position { get; }
|
Position = position;
|
||||||
|
Width = width;
|
||||||
|
Height = height;
|
||||||
|
}
|
||||||
|
|
||||||
public int Width { get; }
|
public bool IsValid() =>
|
||||||
|
Position.X >= 0 && Position.Y >= 0 && Position.X + Width <= 670 && Position.Y + Height <= 670;
|
||||||
|
|
||||||
public int Height { get; }
|
public bool IsOverlapping(MahjongPieceDim dim) =>
|
||||||
|
Position.X < dim.Position.X + dim.Width && Position.Y < dim.Position.Y + dim.Height &&
|
||||||
|
Position.X + Width > dim.Position.X && Position.Y + Height > dim.Position.Y;
|
||||||
|
|
||||||
public MahjongPieceDim(Point2D position, int width, int height)
|
public int GetHandArea()
|
||||||
|
{
|
||||||
|
if (Position.X + Width > 150 && Position.X < 520 && Position.Y < 35)
|
||||||
{
|
{
|
||||||
Position = position;
|
return 0;
|
||||||
Width = width;
|
|
||||||
Height = height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsValid() =>
|
if (Position.X + Width > 635 && Position.Y + Height > 150 && Position.Y < 520)
|
||||||
Position.X >= 0 && Position.Y >= 0 && Position.X + Width <= 670 && Position.Y + Height <= 670;
|
|
||||||
|
|
||||||
public bool IsOverlapping(MahjongPieceDim dim) =>
|
|
||||||
Position.X < dim.Position.X + dim.Width && Position.Y < dim.Position.Y + dim.Height &&
|
|
||||||
Position.X + Width > dim.Position.X && Position.Y + Height > dim.Position.Y;
|
|
||||||
|
|
||||||
public int GetHandArea()
|
|
||||||
{
|
{
|
||||||
if (Position.X + Width > 150 && Position.X < 520 && Position.Y < 35)
|
return 1;
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Position.X + Width > 635 && Position.Y + Height > 150 && Position.Y < 520)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Position.X + Width > 150 && Position.X < 520 && Position.Y + Height > 635)
|
|
||||||
{
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Position.X < 35 && Position.Y + Height > 150 && Position.Y < 520)
|
|
||||||
{
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Position.X + Width > 150 && Position.X < 520 && Position.Y + Height > 635)
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Position.X < 35 && Position.Y + Height > 150 && Position.Y < 520)
|
||||||
|
{
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,95 +1,86 @@
|
||||||
namespace Server.Engines.Mahjong
|
using ModernUO.Serialization;
|
||||||
|
|
||||||
|
namespace Server.Engines.Mahjong;
|
||||||
|
|
||||||
|
[SerializationGenerator(1, false)]
|
||||||
|
public partial class MahjongTile
|
||||||
{
|
{
|
||||||
public class MahjongTile
|
[DirtyTrackingEntity]
|
||||||
|
private readonly MahjongGame _game;
|
||||||
|
|
||||||
|
[SerializableField(0, setter: "private")]
|
||||||
|
private int _number;
|
||||||
|
|
||||||
|
[SerializableField(1, setter: "private")]
|
||||||
|
private MahjongTileType _value;
|
||||||
|
|
||||||
|
[SerializableField(2, setter: "private")]
|
||||||
|
private Point2D _position;
|
||||||
|
|
||||||
|
[SerializableField(3, setter: "private")]
|
||||||
|
private int _stackLevel;
|
||||||
|
|
||||||
|
[SerializableField(4, setter: "private")]
|
||||||
|
private MahjongPieceDirection _direction;
|
||||||
|
|
||||||
|
[SerializableField(5, setter: "private")]
|
||||||
|
private bool _flipped;
|
||||||
|
|
||||||
|
public MahjongTile(MahjongGame game) => _game = game;
|
||||||
|
|
||||||
|
public MahjongTile(
|
||||||
|
MahjongGame game, int number, MahjongTileType value, Point2D position, int stackLevel,
|
||||||
|
MahjongPieceDirection direction, bool flipped
|
||||||
|
)
|
||||||
{
|
{
|
||||||
protected Point2D m_Position;
|
_game = game;
|
||||||
|
_number = number;
|
||||||
|
_value = value;
|
||||||
|
_position = position;
|
||||||
|
_stackLevel = stackLevel;
|
||||||
|
_direction = direction;
|
||||||
|
_flipped = flipped;
|
||||||
|
}
|
||||||
|
|
||||||
public MahjongTile(
|
public MahjongGame Game => _game;
|
||||||
MahjongGame game, int number, MahjongTileType value, Point2D position, int stackLevel,
|
|
||||||
MahjongPieceDirection direction, bool flipped
|
private void Deserialize(IGenericReader reader, int version)
|
||||||
)
|
{
|
||||||
|
_number = reader.ReadInt();
|
||||||
|
_value = (MahjongTileType)reader.ReadInt();
|
||||||
|
_position = reader.ReadPoint2D();
|
||||||
|
_stackLevel = reader.ReadInt();
|
||||||
|
_direction = (MahjongPieceDirection)reader.ReadInt();
|
||||||
|
_flipped = reader.ReadBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MahjongPieceDim Dimensions => GetDimensions(_position, _direction);
|
||||||
|
|
||||||
|
public bool IsMovable => _game.GetStackLevel(Dimensions) <= _stackLevel;
|
||||||
|
|
||||||
|
public static MahjongPieceDim GetDimensions(Point2D position, MahjongPieceDirection direction) =>
|
||||||
|
direction is MahjongPieceDirection.Up or MahjongPieceDirection.Down
|
||||||
|
? new MahjongPieceDim(position, 20, 30)
|
||||||
|
: new MahjongPieceDim(position, 30, 20);
|
||||||
|
|
||||||
|
public void Move(Point2D position, MahjongPieceDirection direction, bool flip, int validHandArea)
|
||||||
|
{
|
||||||
|
var dim = GetDimensions(position, direction);
|
||||||
|
var curHandArea = Dimensions.GetHandArea();
|
||||||
|
var newHandArea = dim.GetHandArea();
|
||||||
|
|
||||||
|
if (!IsMovable || !dim.IsValid() || validHandArea >= 0 &&
|
||||||
|
(curHandArea >= 0 && curHandArea != validHandArea || newHandArea >= 0 && newHandArea != validHandArea))
|
||||||
{
|
{
|
||||||
Game = game;
|
return;
|
||||||
Number = number;
|
|
||||||
Value = value;
|
|
||||||
m_Position = position;
|
|
||||||
StackLevel = stackLevel;
|
|
||||||
Direction = direction;
|
|
||||||
Flipped = flipped;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public MahjongTile(MahjongGame game, IGenericReader reader)
|
Position = position;
|
||||||
{
|
Direction = direction;
|
||||||
Game = game;
|
StackLevel = -1; // Avoid self interference
|
||||||
|
StackLevel = _game.GetStackLevel(dim) + 1;
|
||||||
|
Flipped = flip;
|
||||||
|
|
||||||
var version = reader.ReadInt();
|
_game.Players.SendTilePacket(this, true, true);
|
||||||
|
|
||||||
Number = reader.ReadInt();
|
|
||||||
Value = (MahjongTileType)reader.ReadInt();
|
|
||||||
m_Position = reader.ReadPoint2D();
|
|
||||||
StackLevel = reader.ReadInt();
|
|
||||||
Direction = (MahjongPieceDirection)reader.ReadInt();
|
|
||||||
Flipped = reader.ReadBool();
|
|
||||||
}
|
|
||||||
|
|
||||||
public MahjongGame Game { get; }
|
|
||||||
|
|
||||||
public int Number { get; }
|
|
||||||
|
|
||||||
public MahjongTileType Value { get; }
|
|
||||||
|
|
||||||
public Point2D Position => m_Position;
|
|
||||||
public int StackLevel { get; private set; }
|
|
||||||
|
|
||||||
public MahjongPieceDirection Direction { get; private set; }
|
|
||||||
|
|
||||||
public bool Flipped { get; private set; }
|
|
||||||
|
|
||||||
public MahjongPieceDim Dimensions => GetDimensions(m_Position, Direction);
|
|
||||||
|
|
||||||
public bool IsMovable => Game.GetStackLevel(Dimensions) <= StackLevel;
|
|
||||||
|
|
||||||
public static MahjongPieceDim GetDimensions(Point2D position, MahjongPieceDirection direction)
|
|
||||||
{
|
|
||||||
if (direction is MahjongPieceDirection.Up or MahjongPieceDirection.Down)
|
|
||||||
{
|
|
||||||
return new MahjongPieceDim(position, 20, 30);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new MahjongPieceDim(position, 30, 20);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Move(Point2D position, MahjongPieceDirection direction, bool flip, int validHandArea)
|
|
||||||
{
|
|
||||||
var dim = GetDimensions(position, direction);
|
|
||||||
var curHandArea = Dimensions.GetHandArea();
|
|
||||||
var newHandArea = dim.GetHandArea();
|
|
||||||
|
|
||||||
if (!IsMovable || !dim.IsValid() || validHandArea >= 0 &&
|
|
||||||
(curHandArea >= 0 && curHandArea != validHandArea || newHandArea >= 0 && newHandArea != validHandArea))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Position = position;
|
|
||||||
Direction = direction;
|
|
||||||
StackLevel = -1; // Avoid self interference
|
|
||||||
StackLevel = Game.GetStackLevel(dim) + 1;
|
|
||||||
Flipped = flip;
|
|
||||||
|
|
||||||
Game.Players.SendTilePacket(this, true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Save(IGenericWriter writer)
|
|
||||||
{
|
|
||||||
writer.Write(0); // version
|
|
||||||
|
|
||||||
writer.Write(Number);
|
|
||||||
writer.Write((int)Value);
|
|
||||||
writer.Write(m_Position);
|
|
||||||
writer.Write(StackLevel);
|
|
||||||
writer.Write((int)Direction);
|
|
||||||
writer.Write(Flipped);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,31 +1,28 @@
|
||||||
using System.Collections.Generic;
|
namespace Server.Engines.Mahjong;
|
||||||
|
|
||||||
namespace Server.Engines.Mahjong
|
public class MahjongTileTypeGenerator
|
||||||
{
|
{
|
||||||
public class MahjongTileTypeGenerator
|
private MahjongTileType[] _leftTileTypes;
|
||||||
|
private int _nextTile;
|
||||||
|
|
||||||
|
public MahjongTileTypeGenerator()
|
||||||
{
|
{
|
||||||
public MahjongTileTypeGenerator()
|
_leftTileTypes = new MahjongTileType[136];
|
||||||
{
|
|
||||||
LeftTileTypes = new List<MahjongTileType>(136);
|
|
||||||
|
|
||||||
for (var i = 1; i <= 34; i++)
|
for (int i = 1, j = 0; i <= 34; i++)
|
||||||
{
|
{
|
||||||
var tile = (MahjongTileType)i;
|
var tile = (MahjongTileType)i;
|
||||||
LeftTileTypes.Add(tile);
|
_leftTileTypes[j++] = tile;
|
||||||
LeftTileTypes.Add(tile);
|
_leftTileTypes[j++] = tile;
|
||||||
LeftTileTypes.Add(tile);
|
_leftTileTypes[j++] = tile;
|
||||||
LeftTileTypes.Add(tile);
|
_leftTileTypes[j++] = tile;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<MahjongTileType> LeftTileTypes { get; }
|
_leftTileTypes.Shuffle();
|
||||||
|
_leftTileTypes.Shuffle();
|
||||||
public MahjongTileType Next()
|
_leftTileTypes.Shuffle();
|
||||||
{
|
_leftTileTypes.Shuffle();
|
||||||
var next = LeftTileTypes.RandomElement();
|
|
||||||
LeftTileTypes.Remove(next);
|
|
||||||
|
|
||||||
return next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MahjongTileType Next() => _leftTileTypes[_nextTile++];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,49 +1,39 @@
|
||||||
namespace Server.Engines.Mahjong
|
using ModernUO.Serialization;
|
||||||
|
|
||||||
|
namespace Server.Engines.Mahjong;
|
||||||
|
|
||||||
|
[SerializationGenerator(0, false)]
|
||||||
|
public partial class MahjongWallBreakIndicator
|
||||||
{
|
{
|
||||||
public class MahjongWallBreakIndicator
|
[DirtyTrackingEntity]
|
||||||
|
private readonly MahjongGame _game;
|
||||||
|
|
||||||
|
[SerializableField(0, setter: "private")]
|
||||||
|
private Point2D _position;
|
||||||
|
|
||||||
|
public MahjongWallBreakIndicator(MahjongGame game) => _game = game;
|
||||||
|
|
||||||
|
public MahjongWallBreakIndicator(MahjongGame game, Point2D position)
|
||||||
{
|
{
|
||||||
public MahjongWallBreakIndicator(MahjongGame game, Point2D position)
|
_game = game;
|
||||||
|
_position = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MahjongPieceDim Dimensions => GetDimensions(_position);
|
||||||
|
|
||||||
|
public static MahjongPieceDim GetDimensions(Point2D position) => new(position, 20, 20);
|
||||||
|
|
||||||
|
public void Move(Point2D position)
|
||||||
|
{
|
||||||
|
var dim = GetDimensions(position);
|
||||||
|
|
||||||
|
if (!dim.IsValid())
|
||||||
{
|
{
|
||||||
Game = game;
|
return;
|
||||||
Position = position;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public MahjongWallBreakIndicator(MahjongGame game, IGenericReader reader)
|
_position = position;
|
||||||
{
|
|
||||||
Game = game;
|
|
||||||
|
|
||||||
var version = reader.ReadInt();
|
_game.Players.SendGeneralPacket(true, true);
|
||||||
|
|
||||||
Position = reader.ReadPoint2D();
|
|
||||||
}
|
|
||||||
|
|
||||||
public MahjongGame Game { get; }
|
|
||||||
|
|
||||||
public Point2D Position { get; private set; }
|
|
||||||
|
|
||||||
public MahjongPieceDim Dimensions => GetDimensions(Position);
|
|
||||||
|
|
||||||
public static MahjongPieceDim GetDimensions(Point2D position) => new(position, 20, 20);
|
|
||||||
|
|
||||||
public void Move(Point2D position)
|
|
||||||
{
|
|
||||||
var dim = GetDimensions(position);
|
|
||||||
|
|
||||||
if (!dim.IsValid())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Position = position;
|
|
||||||
|
|
||||||
Game.Players.SendGeneralPacket(true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Save(IGenericWriter writer)
|
|
||||||
{
|
|
||||||
writer.Write(0); // version
|
|
||||||
|
|
||||||
writer.Write(Position);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"type": "Server.Engines.Mahjong.MahjongDealerIndicator",
|
||||||
|
"properties": [
|
||||||
|
{
|
||||||
|
"name": "Position",
|
||||||
|
"type": "Server.Point2D",
|
||||||
|
"rule": "PrimitiveUOTypeMigrationRule",
|
||||||
|
"ruleArguments": [
|
||||||
|
"Point2D"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Direction",
|
||||||
|
"type": "Server.Engines.Mahjong.MahjongPieceDirection",
|
||||||
|
"rule": "EnumMigrationRule"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Wind",
|
||||||
|
"type": "Server.Engines.Mahjong.MahjongWind",
|
||||||
|
"rule": "EnumMigrationRule"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"version": 0,
|
||||||
|
"type": "Server.Engines.Mahjong.MahjongDices",
|
||||||
|
"properties": [
|
||||||
|
{
|
||||||
|
"name": "First",
|
||||||
|
"type": "int",
|
||||||
|
"rule": "PrimitiveTypeMigrationRule",
|
||||||
|
"ruleArguments": [
|
||||||
|
""
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Second",
|
||||||
|
"type": "int",
|
||||||
|
"rule": "PrimitiveTypeMigrationRule",
|
||||||
|
"ruleArguments": [
|
||||||
|
""
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"type": "Server.Engines.Mahjong.MahjongGame",
|
||||||
|
"properties": [
|
||||||
|
{
|
||||||
|
"name": "Level",
|
||||||
|
"type": "Server.Multis.SecureLevel",
|
||||||
|
"rule": "EnumMigrationRule"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Tiles",
|
||||||
|
"type": "Server.Engines.Mahjong.MahjongTile[]",
|
||||||
|
"rule": "ArrayMigrationRule",
|
||||||
|
"ruleArguments": [
|
||||||
|
"Server.Engines.Mahjong.MahjongTile",
|
||||||
|
"RawSerializableMigrationRule",
|
||||||
|
"DeserializationRequiresParent"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "DealerIndicator",
|
||||||
|
"type": "Server.Engines.Mahjong.MahjongDealerIndicator",
|
||||||
|
"rule": "RawSerializableMigrationRule",
|
||||||
|
"ruleArguments": [
|
||||||
|
"DeserializationRequiresParent"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "WallBreakIndicator",
|
||||||
|
"type": "Server.Engines.Mahjong.MahjongWallBreakIndicator",
|
||||||
|
"rule": "RawSerializableMigrationRule",
|
||||||
|
"ruleArguments": [
|
||||||
|
"DeserializationRequiresParent"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Dices",
|
||||||
|
"type": "Server.Engines.Mahjong.MahjongDices",
|
||||||
|
"rule": "RawSerializableMigrationRule",
|
||||||
|
"ruleArguments": [
|
||||||
|
"DeserializationRequiresParent"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Players",
|
||||||
|
"type": "Server.Engines.Mahjong.MahjongPlayers",
|
||||||
|
"rule": "RawSerializableMigrationRule",
|
||||||
|
"ruleArguments": [
|
||||||
|
"DeserializationRequiresParent"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ShowScores",
|
||||||
|
"type": "bool",
|
||||||
|
"rule": "PrimitiveTypeMigrationRule",
|
||||||
|
"ruleArguments": [
|
||||||
|
""
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SpectatorVision",
|
||||||
|
"type": "bool",
|
||||||
|
"rule": "PrimitiveTypeMigrationRule",
|
||||||
|
"ruleArguments": [
|
||||||
|
""
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"type": "Server.Engines.Mahjong.MahjongPlayers",
|
||||||
|
"properties": [
|
||||||
|
{
|
||||||
|
"name": "Players",
|
||||||
|
"type": "Server.Mobile[]",
|
||||||
|
"rule": "ArrayMigrationRule",
|
||||||
|
"ruleArguments": [
|
||||||
|
"Server.Mobile",
|
||||||
|
"SerializableInterfaceMigrationRule"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "InGame",
|
||||||
|
"type": "bool[]",
|
||||||
|
"rule": "ArrayMigrationRule",
|
||||||
|
"ruleArguments": [
|
||||||
|
"bool",
|
||||||
|
"PrimitiveTypeMigrationRule",
|
||||||
|
""
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "PublicHand",
|
||||||
|
"type": "bool[]",
|
||||||
|
"rule": "ArrayMigrationRule",
|
||||||
|
"ruleArguments": [
|
||||||
|
"bool",
|
||||||
|
"PrimitiveTypeMigrationRule",
|
||||||
|
""
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Scores",
|
||||||
|
"type": "int[]",
|
||||||
|
"rule": "ArrayMigrationRule",
|
||||||
|
"ruleArguments": [
|
||||||
|
"int",
|
||||||
|
"PrimitiveTypeMigrationRule",
|
||||||
|
""
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "DealerPosition",
|
||||||
|
"type": "int",
|
||||||
|
"rule": "PrimitiveTypeMigrationRule",
|
||||||
|
"ruleArguments": [
|
||||||
|
""
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"type": "Server.Engines.Mahjong.MahjongTile",
|
||||||
|
"properties": [
|
||||||
|
{
|
||||||
|
"name": "Number",
|
||||||
|
"type": "int",
|
||||||
|
"rule": "PrimitiveTypeMigrationRule",
|
||||||
|
"ruleArguments": [
|
||||||
|
""
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Value",
|
||||||
|
"type": "Server.Engines.Mahjong.MahjongTileType",
|
||||||
|
"rule": "EnumMigrationRule"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Position",
|
||||||
|
"type": "Server.Point2D",
|
||||||
|
"rule": "PrimitiveUOTypeMigrationRule",
|
||||||
|
"ruleArguments": [
|
||||||
|
"Point2D"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "StackLevel",
|
||||||
|
"type": "int",
|
||||||
|
"rule": "PrimitiveTypeMigrationRule",
|
||||||
|
"ruleArguments": [
|
||||||
|
""
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Direction",
|
||||||
|
"type": "Server.Engines.Mahjong.MahjongPieceDirection",
|
||||||
|
"rule": "EnumMigrationRule"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Flipped",
|
||||||
|
"type": "bool",
|
||||||
|
"rule": "PrimitiveTypeMigrationRule",
|
||||||
|
"ruleArguments": [
|
||||||
|
""
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"version": 0,
|
||||||
|
"type": "Server.Engines.Mahjong.MahjongWallBreakIndicator",
|
||||||
|
"properties": [
|
||||||
|
{
|
||||||
|
"name": "Position",
|
||||||
|
"type": "Server.Point2D",
|
||||||
|
"rule": "PrimitiveUOTypeMigrationRule",
|
||||||
|
"ruleArguments": [
|
||||||
|
"Point2D"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue