fix(content): Converts mahjong packets (#402)
- [X] Converts mahjong packets
This commit is contained in:
parent
f4dd7c8e7f
commit
ca196e4729
7 changed files with 436 additions and 51 deletions
|
|
@ -83,7 +83,7 @@ namespace Server.Engines.Mahjong
|
|||
|
||||
if (Players.IsInGamePlayer(Players.DealerPosition))
|
||||
{
|
||||
Players.Dealer.Send(new MahjongGeneralInfo(this));
|
||||
Players.Dealer.NetState.SendMahjongGeneralInfo(this);
|
||||
}
|
||||
|
||||
Players.SendTilesPacket(false, true);
|
||||
|
|
|
|||
271
Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs
Normal file
271
Projects/UOContent/Items/Games/Mahjong/MahjongPackets.cs
Normal file
|
|
@ -0,0 +1,271 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright (C) 2019-2021 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: MahjongPackets.cs *
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.IO;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.Mahjong
|
||||
{
|
||||
public static class MahjongPackets
|
||||
{
|
||||
public const int MahjongGeneralInfoPacketLength = 25;
|
||||
public const int MahjongRelievePacketLength = 9;
|
||||
|
||||
public static void SendMahjongJoinGame(this NetState ns, Serial game)
|
||||
{
|
||||
if (ns == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var writer = new SpanWriter(stackalloc byte[9]);
|
||||
writer.Write((byte)0xDA); // Packet ID
|
||||
writer.Write((ushort)9);
|
||||
writer.Write(game);
|
||||
writer.Write((ushort)0x19); // Command
|
||||
|
||||
ns.Send(writer.Span);
|
||||
}
|
||||
|
||||
public static void SendMahjongPlayersInfo(this NetState ns, MahjongGame game, Mobile to)
|
||||
{
|
||||
if (ns == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var maxLength = 11 + game.Players.Seats * 45;
|
||||
var writer = new SpanWriter(stackalloc byte[maxLength]);
|
||||
writer.Write((byte)0xDA); // Packet ID
|
||||
writer.Seek(2, SeekOrigin.Current);
|
||||
writer.Write(game.Serial);
|
||||
writer.Write((ushort)0x02); // Command
|
||||
|
||||
writer.Seek(2, SeekOrigin.Current); // Seats
|
||||
|
||||
var players = game.Players;
|
||||
var count = 0;
|
||||
|
||||
for (var i = 0; i < players.Seats; i++)
|
||||
{
|
||||
var m = players.GetPlayer(i);
|
||||
|
||||
if (m == null && !game.ShowScores)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
writer.Write(m?.Serial ?? Serial.Zero);
|
||||
writer.Write(m != null && players.DealerPosition == i ? (byte)0x1 : (byte)0x2);
|
||||
writer.Write((byte)i);
|
||||
|
||||
if (game.ShowScores || m == to)
|
||||
{
|
||||
writer.Write(players.GetScore(i));
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
writer.Write((short)0);
|
||||
writer.Write((byte)0);
|
||||
|
||||
writer.Write(players.IsPublic(i));
|
||||
writer.WriteAscii(m?.Name ?? "", 30);
|
||||
|
||||
writer.Write(m == null || !players.IsInGamePlayer(i));
|
||||
count++;
|
||||
}
|
||||
|
||||
writer.Seek(9, SeekOrigin.Begin);
|
||||
writer.Write((ushort)count);
|
||||
writer.WritePacketLength();
|
||||
|
||||
ns.Send(writer.Span);
|
||||
}
|
||||
|
||||
public static void SendMahjongTileInfo(this NetState ns, MahjongTile tile, Mobile to)
|
||||
{
|
||||
if (ns == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var game = tile.Game;
|
||||
var players = game.Players;
|
||||
|
||||
var writer = new SpanWriter(stackalloc byte[18]);
|
||||
writer.Write((byte)0xDA); // Packet ID
|
||||
writer.Write((ushort)18);
|
||||
writer.Write(game.Serial);
|
||||
writer.Write((ushort)0x03); // Command
|
||||
|
||||
writer.Write((byte)tile.Number);
|
||||
|
||||
if (tile.Flipped)
|
||||
{
|
||||
var hand = tile.Dimensions.GetHandArea();
|
||||
|
||||
if (hand < 0 || players.IsPublic(hand) || players.GetPlayer(hand) == to ||
|
||||
game.SpectatorVision && players.IsSpectator(to))
|
||||
{
|
||||
writer.Write((byte)tile.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write((byte)0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write((byte)0);
|
||||
}
|
||||
|
||||
writer.Write((short)tile.Position.Y);
|
||||
writer.Write((short)tile.Position.X);
|
||||
writer.Write((byte)tile.StackLevel);
|
||||
writer.Write((byte)tile.Direction);
|
||||
writer.Write((byte)(tile.Flipped ? 0x10 : 0x0));
|
||||
|
||||
ns.Send(writer.Span);
|
||||
}
|
||||
|
||||
public static void SendMahjongTilesInfo(this NetState ns, MahjongGame game, Mobile to)
|
||||
{
|
||||
if (ns == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var tiles = game.Tiles;
|
||||
var players = game.Players;
|
||||
|
||||
var length = 11 + tiles.Length * 9;
|
||||
var writer = new SpanWriter(stackalloc byte[length]);
|
||||
writer.Write((byte)0xDA); // Packet ID
|
||||
writer.Write((ushort)length);
|
||||
writer.Write(game.Serial);
|
||||
writer.Write((ushort)0x04); // Command
|
||||
|
||||
writer.Write((short)tiles.Length);
|
||||
|
||||
foreach (var tile in tiles)
|
||||
{
|
||||
writer.Write((byte)tile.Number);
|
||||
|
||||
if (tile.Flipped)
|
||||
{
|
||||
var hand = tile.Dimensions.GetHandArea();
|
||||
|
||||
if (hand < 0 || players.IsPublic(hand) || players.GetPlayer(hand) == to ||
|
||||
game.SpectatorVision && players.IsSpectator(to))
|
||||
{
|
||||
writer.Write((byte)tile.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write((byte)0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write((byte)0);
|
||||
}
|
||||
|
||||
writer.Write((short)tile.Position.Y);
|
||||
writer.Write((short)tile.Position.X);
|
||||
writer.Write((byte)tile.StackLevel);
|
||||
writer.Write((byte)tile.Direction);
|
||||
|
||||
writer.Write((byte)(tile.Flipped ? 0x10 : 0x0));
|
||||
}
|
||||
|
||||
ns.Send(writer.Span);
|
||||
}
|
||||
|
||||
public static void SendMahjongGeneralInfo(this NetState ns, MahjongGame game)
|
||||
{
|
||||
if (ns == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Span<byte> buffer = stackalloc byte[MahjongGeneralInfoPacketLength].InitializePacket();
|
||||
CreateMahjongGeneralInfo(buffer, game);
|
||||
|
||||
ns.Send(buffer);
|
||||
}
|
||||
|
||||
public static void CreateMahjongGeneralInfo(Span<byte> buffer, MahjongGame game)
|
||||
{
|
||||
if (buffer[0] != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var writer = new SpanWriter(buffer);
|
||||
writer.Write((byte)0xDA); // Packet ID
|
||||
writer.Write((ushort)MahjongGeneralInfoPacketLength);
|
||||
writer.Write(game.Serial);
|
||||
writer.Write((ushort)0x05); // Command
|
||||
|
||||
writer.Write((short)0);
|
||||
writer.Write((byte)0);
|
||||
|
||||
writer.Write((byte)((game.ShowScores ? 0x1 : 0x0) | (game.SpectatorVision ? 0x2 : 0x0)));
|
||||
|
||||
writer.Write((byte)game.Dices.First);
|
||||
writer.Write((byte)game.Dices.Second);
|
||||
|
||||
writer.Write((byte)game.DealerIndicator.Wind);
|
||||
writer.Write((short)game.DealerIndicator.Position.Y);
|
||||
writer.Write((short)game.DealerIndicator.Position.X);
|
||||
writer.Write((byte)game.DealerIndicator.Direction);
|
||||
|
||||
writer.Write((short)game.WallBreakIndicator.Position.Y);
|
||||
writer.Write((short)game.WallBreakIndicator.Position.X);
|
||||
}
|
||||
|
||||
public static void SendMahjongRelieve(this NetState ns, Serial game)
|
||||
{
|
||||
if (ns == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Span<byte> buffer = stackalloc byte[MahjongRelievePacketLength].InitializePacket();
|
||||
CreateMahjongRelieve(buffer, game);
|
||||
|
||||
ns.Send(buffer);
|
||||
}
|
||||
|
||||
public static void CreateMahjongRelieve(Span<byte> buffer, Serial game)
|
||||
{
|
||||
if (buffer[0] != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var writer = new SpanWriter(buffer);
|
||||
writer.Write((byte)0xDA); // Packet ID
|
||||
writer.Write((ushort)MahjongRelievePacketLength);
|
||||
writer.Write(game);
|
||||
writer.Write((ushort)0x1A); // Command
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.Mahjong
|
||||
{
|
||||
|
|
@ -171,6 +173,8 @@ namespace Server.Engines.Mahjong
|
|||
{
|
||||
var removed = false;
|
||||
|
||||
Span<byte> relievePacket = stackalloc byte[MahjongPackets.MahjongRelievePacketLength].InitializePacket();
|
||||
|
||||
for (var i = 0; i < m_Players.Length; i++)
|
||||
{
|
||||
var player = m_Players[i];
|
||||
|
|
@ -205,7 +209,8 @@ namespace Server.Engines.Mahjong
|
|||
{
|
||||
m_InGame[i] = false;
|
||||
|
||||
player.Send(new MahjongRelieve(Game));
|
||||
MahjongPackets.CreateMahjongRelieve(relievePacket, Game.Serial);
|
||||
player.NetState?.Send(relievePacket);
|
||||
|
||||
SendPlayerExitMessage(player);
|
||||
UpdateDealer(true);
|
||||
|
|
@ -228,7 +233,8 @@ namespace Server.Engines.Mahjong
|
|||
{
|
||||
m_Spectators.RemoveAt(i);
|
||||
|
||||
mobile.Send(new MahjongRelieve(Game));
|
||||
MahjongPackets.CreateMahjongRelieve(relievePacket, Game.Serial);
|
||||
mobile.NetState?.Send(relievePacket);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -335,13 +341,13 @@ namespace Server.Engines.Mahjong
|
|||
|
||||
if (sendJoinGame)
|
||||
{
|
||||
player.Send(new MahjongJoinGame(Game));
|
||||
player.NetState.SendMahjongJoinGame(Game.Serial);
|
||||
}
|
||||
|
||||
SendPlayersPacket(true, true);
|
||||
|
||||
player.Send(new MahjongGeneralInfo(Game));
|
||||
player.Send(new MahjongTilesInfo(Game, player));
|
||||
player.NetState.SendMahjongGeneralInfo(Game);
|
||||
player.NetState.SendMahjongTilesInfo(Game, player);
|
||||
|
||||
if (DealerPosition == index)
|
||||
{
|
||||
|
|
@ -360,10 +366,10 @@ namespace Server.Engines.Mahjong
|
|||
m_Spectators.Add(mobile);
|
||||
}
|
||||
|
||||
mobile.Send(new MahjongJoinGame(Game));
|
||||
mobile.Send(new MahjongPlayersInfo(Game, mobile));
|
||||
mobile.Send(new MahjongGeneralInfo(Game));
|
||||
mobile.Send(new MahjongTilesInfo(Game, mobile));
|
||||
mobile.NetState.SendMahjongJoinGame(Game.Serial);
|
||||
mobile.NetState.SendMahjongPlayersInfo(Game, mobile);
|
||||
mobile.NetState.SendMahjongGeneralInfo(Game);
|
||||
mobile.NetState.SendMahjongTilesInfo(Game, mobile);
|
||||
}
|
||||
|
||||
public void Join(Mobile mobile)
|
||||
|
|
@ -373,19 +379,18 @@ namespace Server.Engines.Mahjong
|
|||
if (index >= 0)
|
||||
{
|
||||
AddPlayer(mobile, index, true);
|
||||
return;
|
||||
}
|
||||
|
||||
var nextSeat = GetNextSeat();
|
||||
|
||||
if (nextSeat >= 0)
|
||||
{
|
||||
AddPlayer(mobile, nextSeat, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
var nextSeat = GetNextSeat();
|
||||
|
||||
if (nextSeat >= 0)
|
||||
{
|
||||
AddPlayer(mobile, nextSeat, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddSpectator(mobile);
|
||||
}
|
||||
AddSpectator(mobile);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -438,14 +443,12 @@ namespace Server.Engines.Mahjong
|
|||
}
|
||||
else
|
||||
{
|
||||
from.Send(new MahjongPlayersInfo(Game, from));
|
||||
to.Send(new MahjongPlayersInfo(Game, to));
|
||||
from.NetState.SendMahjongPlayersInfo(Game, from);
|
||||
to.NetState.SendMahjongPlayersInfo(Game, to);
|
||||
}
|
||||
|
||||
SendLocalizedMessage(
|
||||
1062774,
|
||||
$"{from.Name}\t{to.Name}\t{amount}"
|
||||
); // ~1_giver~ gives ~2_receiver~ ~3_number~ points.
|
||||
// ~1_giver~ gives ~2_receiver~ ~3_number~ points.
|
||||
SendLocalizedMessage(1062774, $"{from.Name}\t{to.Name}\t{amount}");
|
||||
}
|
||||
|
||||
public void OpenSeat(int index)
|
||||
|
|
@ -458,7 +461,7 @@ namespace Server.Engines.Mahjong
|
|||
|
||||
if (m_InGame[index])
|
||||
{
|
||||
player.Send(new MahjongRelieve(Game));
|
||||
player.NetState.SendMahjongRelieve(Game.Serial);
|
||||
}
|
||||
|
||||
m_Players[index] = null;
|
||||
|
|
@ -488,10 +491,10 @@ namespace Server.Engines.Mahjong
|
|||
|
||||
if (IsInGamePlayer(oldDealer))
|
||||
{
|
||||
m_Players[oldDealer].Send(new MahjongPlayersInfo(Game, m_Players[oldDealer]));
|
||||
m_Players[oldDealer].NetState.SendMahjongPlayersInfo(Game, m_Players[oldDealer]);
|
||||
}
|
||||
|
||||
to.Send(new MahjongPlayersInfo(Game, to));
|
||||
to.NetState.SendMahjongPlayersInfo(Game, to);
|
||||
|
||||
SendDealerChangedMessage();
|
||||
}
|
||||
|
|
@ -513,7 +516,7 @@ namespace Server.Engines.Mahjong
|
|||
{
|
||||
foreach (var mobile in GetInGameMobiles(players, spectators))
|
||||
{
|
||||
mobile.Send(new MahjongPlayersInfo(Game, mobile));
|
||||
mobile.NetState.SendMahjongPlayersInfo(Game, mobile);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -526,23 +529,20 @@ namespace Server.Engines.Mahjong
|
|||
return;
|
||||
}
|
||||
|
||||
var generalInfo = new MahjongGeneralInfo(Game);
|
||||
|
||||
generalInfo.Acquire();
|
||||
Span<byte> generalInfo = stackalloc byte[MahjongPackets.MahjongGeneralInfoPacketLength].InitializePacket();
|
||||
|
||||
foreach (var mobile in mobiles)
|
||||
{
|
||||
mobile.Send(generalInfo);
|
||||
MahjongPackets.CreateMahjongGeneralInfo(generalInfo, Game);
|
||||
mobile.NetState?.Send(generalInfo);
|
||||
}
|
||||
|
||||
generalInfo.Release();
|
||||
}
|
||||
|
||||
public void SendTilesPacket(bool players, bool spectators)
|
||||
{
|
||||
foreach (var mobile in GetInGameMobiles(players, spectators))
|
||||
{
|
||||
mobile.Send(new MahjongTilesInfo(Game, mobile));
|
||||
mobile.NetState.SendMahjongTilesInfo(Game, mobile);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -550,7 +550,7 @@ namespace Server.Engines.Mahjong
|
|||
{
|
||||
foreach (var mobile in GetInGameMobiles(players, spectators))
|
||||
{
|
||||
mobile.Send(new MahjongTileInfo(tile, mobile));
|
||||
mobile.NetState.SendMahjongTileInfo(tile, mobile);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -563,16 +563,13 @@ namespace Server.Engines.Mahjong
|
|||
return;
|
||||
}
|
||||
|
||||
var relieve = new MahjongRelieve(Game);
|
||||
|
||||
relieve.Acquire();
|
||||
Span<byte> relievePacket = stackalloc byte[MahjongPackets.MahjongRelievePacketLength].InitializePacket();
|
||||
|
||||
foreach (var mobile in mobiles)
|
||||
{
|
||||
mobile.Send(relieve);
|
||||
MahjongPackets.CreateMahjongRelieve(relievePacket, Game.Serial);
|
||||
mobile.NetState?.Send(relievePacket);
|
||||
}
|
||||
|
||||
relieve.Release();
|
||||
}
|
||||
|
||||
public void SendLocalizedMessage(int number)
|
||||
|
|
|
|||
|
|
@ -1,221 +0,0 @@
|
|||
using System.IO;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.Mahjong
|
||||
{
|
||||
public sealed class MahjongJoinGame : Packet
|
||||
{
|
||||
public MahjongJoinGame(MahjongGame game) : base(0xDA)
|
||||
{
|
||||
EnsureCapacity(9);
|
||||
|
||||
Stream.Write(game.Serial);
|
||||
Stream.Write((byte)0);
|
||||
Stream.Write((byte)0x19);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class MahjongPlayersInfo : Packet
|
||||
{
|
||||
public MahjongPlayersInfo(MahjongGame game, Mobile to) : base(0xDA)
|
||||
{
|
||||
var players = game.Players;
|
||||
|
||||
EnsureCapacity(11 + 45 * players.Seats);
|
||||
|
||||
Stream.Write(game.Serial);
|
||||
Stream.Write((byte)0);
|
||||
Stream.Write((byte)0x2);
|
||||
|
||||
Stream.Write((byte)0);
|
||||
Stream.Write((byte)players.Seats);
|
||||
|
||||
var n = 0;
|
||||
for (var i = 0; i < players.Seats; i++)
|
||||
{
|
||||
var mobile = players.GetPlayer(i);
|
||||
|
||||
if (mobile != null)
|
||||
{
|
||||
Stream.Write(mobile.Serial);
|
||||
Stream.Write(players.DealerPosition == i ? (byte)0x1 : (byte)0x2);
|
||||
Stream.Write((byte)i);
|
||||
|
||||
if (game.ShowScores || mobile == to)
|
||||
{
|
||||
Stream.Write(players.GetScore(i));
|
||||
}
|
||||
else
|
||||
{
|
||||
Stream.Write(0);
|
||||
}
|
||||
|
||||
Stream.Write((short)0);
|
||||
Stream.Write((byte)0);
|
||||
|
||||
Stream.Write(players.IsPublic(i));
|
||||
|
||||
Stream.WriteAsciiFixed(mobile.Name, 30);
|
||||
Stream.Write(!players.IsInGamePlayer(i));
|
||||
|
||||
n++;
|
||||
}
|
||||
else if (game.ShowScores)
|
||||
{
|
||||
Stream.Write(0);
|
||||
Stream.Write((byte)0x2);
|
||||
Stream.Write((byte)i);
|
||||
|
||||
Stream.Write(players.GetScore(i));
|
||||
|
||||
Stream.Write((short)0);
|
||||
Stream.Write((byte)0);
|
||||
|
||||
Stream.Write(players.IsPublic(i));
|
||||
|
||||
Stream.WriteAsciiFixed("", 30);
|
||||
Stream.Write(true);
|
||||
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
if (n != players.Seats)
|
||||
{
|
||||
Stream.Seek(10, SeekOrigin.Begin);
|
||||
Stream.Write((byte)n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class MahjongGeneralInfo : Packet
|
||||
{
|
||||
public MahjongGeneralInfo(MahjongGame game) : base(0xDA)
|
||||
{
|
||||
EnsureCapacity(13);
|
||||
|
||||
Stream.Write(game.Serial);
|
||||
Stream.Write((byte)0);
|
||||
Stream.Write((byte)0x5);
|
||||
|
||||
Stream.Write((short)0);
|
||||
Stream.Write((byte)0);
|
||||
|
||||
Stream.Write((byte)((game.ShowScores ? 0x1 : 0x0) | (game.SpectatorVision ? 0x2 : 0x0)));
|
||||
|
||||
Stream.Write((byte)game.Dices.First);
|
||||
Stream.Write((byte)game.Dices.Second);
|
||||
|
||||
Stream.Write((byte)game.DealerIndicator.Wind);
|
||||
Stream.Write((short)game.DealerIndicator.Position.Y);
|
||||
Stream.Write((short)game.DealerIndicator.Position.X);
|
||||
Stream.Write((byte)game.DealerIndicator.Direction);
|
||||
|
||||
Stream.Write((short)game.WallBreakIndicator.Position.Y);
|
||||
Stream.Write((short)game.WallBreakIndicator.Position.X);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class MahjongTilesInfo : Packet
|
||||
{
|
||||
public MahjongTilesInfo(MahjongGame game, Mobile to) : base(0xDA)
|
||||
{
|
||||
var tiles = game.Tiles;
|
||||
var players = game.Players;
|
||||
|
||||
EnsureCapacity(11 + 9 * tiles.Length);
|
||||
|
||||
Stream.Write(game.Serial);
|
||||
Stream.Write((byte)0);
|
||||
Stream.Write((byte)0x4);
|
||||
|
||||
Stream.Write((short)tiles.Length);
|
||||
|
||||
foreach (var tile in tiles)
|
||||
{
|
||||
Stream.Write((byte)tile.Number);
|
||||
|
||||
if (tile.Flipped)
|
||||
{
|
||||
var hand = tile.Dimensions.GetHandArea();
|
||||
|
||||
if (hand < 0 || players.IsPublic(hand) || players.GetPlayer(hand) == to ||
|
||||
game.SpectatorVision && players.IsSpectator(to))
|
||||
{
|
||||
Stream.Write((byte)tile.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
Stream.Write((byte)0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Stream.Write((byte)0);
|
||||
}
|
||||
|
||||
Stream.Write((short)tile.Position.Y);
|
||||
Stream.Write((short)tile.Position.X);
|
||||
Stream.Write((byte)tile.StackLevel);
|
||||
Stream.Write((byte)tile.Direction);
|
||||
|
||||
Stream.Write(tile.Flipped ? (byte)0x10 : (byte)0x0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class MahjongTileInfo : Packet
|
||||
{
|
||||
public MahjongTileInfo(MahjongTile tile, Mobile to) : base(0xDA)
|
||||
{
|
||||
var game = tile.Game;
|
||||
var players = game.Players;
|
||||
|
||||
EnsureCapacity(18);
|
||||
|
||||
Stream.Write(tile.Game.Serial);
|
||||
Stream.Write((byte)0);
|
||||
Stream.Write((byte)0x3);
|
||||
|
||||
Stream.Write((byte)tile.Number);
|
||||
|
||||
if (tile.Flipped)
|
||||
{
|
||||
var hand = tile.Dimensions.GetHandArea();
|
||||
|
||||
if (hand < 0 || players.IsPublic(hand) || players.GetPlayer(hand) == to ||
|
||||
game.SpectatorVision && players.IsSpectator(to))
|
||||
{
|
||||
Stream.Write((byte)tile.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
Stream.Write((byte)0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Stream.Write((byte)0);
|
||||
}
|
||||
|
||||
Stream.Write((short)tile.Position.Y);
|
||||
Stream.Write((short)tile.Position.X);
|
||||
Stream.Write((byte)tile.StackLevel);
|
||||
Stream.Write((byte)tile.Direction);
|
||||
|
||||
Stream.Write(tile.Flipped ? (byte)0x10 : (byte)0x0);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class MahjongRelieve : Packet
|
||||
{
|
||||
public MahjongRelieve(MahjongGame game) : base(0xDA)
|
||||
{
|
||||
EnsureCapacity(9);
|
||||
|
||||
Stream.Write(game.Serial);
|
||||
Stream.Write((byte)0);
|
||||
Stream.Write((byte)0x1A);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue