diff --git a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj
index a1e692a2..6b81af4d 100644
--- a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj
+++ b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj
@@ -147,6 +147,7 @@
+
diff --git a/FFXIVClassic Map Server/actors/Actor.cs b/FFXIVClassic Map Server/actors/Actor.cs
index b56f0dfc..b71b618c 100644
--- a/FFXIVClassic Map Server/actors/Actor.cs
+++ b/FFXIVClassic Map Server/actors/Actor.cs
@@ -29,6 +29,7 @@ namespace FFXIVClassic_Map_Server.Actors
public float positionX, positionY, positionZ, rotation;
public float oldPositionX, oldPositionY, oldPositionZ, oldRotation;
public ushort moveState, oldMoveState;
+ public float[] moveSpeeds = new float[5];
public uint zoneId;
public Zone zone = null;
@@ -52,6 +53,11 @@ namespace FFXIVClassic_Map_Server.Actors
this.actorName = actorName;
this.className = className;
this.classParams = classParams;
+
+ this.moveSpeeds[0] = SetActorSpeedPacket.DEFAULT_STOP;
+ this.moveSpeeds[1] = SetActorSpeedPacket.DEFAULT_WALK;
+ this.moveSpeeds[2] = SetActorSpeedPacket.DEFAULT_RUN;
+ this.moveSpeeds[3] = SetActorSpeedPacket.DEFAULT_RUN;
}
public SubPacket createAddActorPacket(uint playerActorId, byte val)
@@ -220,6 +226,30 @@ namespace FFXIVClassic_Map_Server.Actors
return classParams;
}
+ public void changeState(ushort newState)
+ {
+ currentMainState = newState;
+ SubPacket changeStatePacket = SetActorStatePacket.buildPacket(actorId, actorId, newState, currentSubState);
+ zone.broadcastPacketAroundActor(this, changeStatePacket);
+ }
+
+ public void changeSpeed(int type, float value)
+ {
+ moveSpeeds[type] = value;
+ SubPacket changeSpeedPacket = SetActorSpeedPacket.buildPacket(actorId, actorId, moveSpeeds[0], moveSpeeds[1], moveSpeeds[2]);
+ zone.broadcastPacketAroundActor(this, changeSpeedPacket);
+ }
+
+ public void changeSpeed(float speedStop, float speedWalk, float speedRun)
+ {
+ moveSpeeds[0] = speedStop;
+ moveSpeeds[1] = speedWalk;
+ moveSpeeds[2] = speedRun;
+ moveSpeeds[3] = speedRun;
+ SubPacket changeSpeedPacket = SetActorSpeedPacket.buildPacket(actorId, actorId, moveSpeeds[0], moveSpeeds[1], moveSpeeds[2]);
+ zone.broadcastPacketAroundActor(this, changeSpeedPacket);
+ }
+
}
}
diff --git a/FFXIVClassic Map Server/actors/area/Zone.cs b/FFXIVClassic Map Server/actors/area/Zone.cs
index c984468a..147e9cb2 100644
--- a/FFXIVClassic Map Server/actors/area/Zone.cs
+++ b/FFXIVClassic Map Server/actors/area/Zone.cs
@@ -289,5 +289,22 @@ namespace FFXIVClassic_Map_Server.Actors
}
}
+ public void broadcastPacketAroundActor(Actor actor, SubPacket packet)
+ {
+ if (zone != null)
+ {
+ List aroundActor = getActorsAroundActor(actor, 50);
+ foreach (Actor a in aroundActor)
+ {
+ if (a is Player)
+ {
+ SubPacket clonedPacket = new SubPacket(packet, actor.actorId);
+ Player p = (Player)a;
+ p.queuePacket(clonedPacket);
+ }
+ }
+ }
+ }
+
}
}
diff --git a/FFXIVClassic Map Server/actors/chara/player/Player.cs b/FFXIVClassic Map Server/actors/chara/player/Player.cs
index 25df3340..c909a770 100644
--- a/FFXIVClassic Map Server/actors/chara/player/Player.cs
+++ b/FFXIVClassic Map Server/actors/chara/player/Player.cs
@@ -598,7 +598,7 @@ namespace FFXIVClassic_Map_Server.Actors
{
playerSession.queuePacket(packet, true, false);
}
-
+
public void sendMessage(uint logType, string sender, string message)
{
queuePacket(SendMessagePacket.buildPacket(actorId, actorId, logType, sender, message));
@@ -614,6 +614,32 @@ namespace FFXIVClassic_Map_Server.Actors
queuePacket(QuitPacket.buildPacket(actorId));
}
+ public void changeMusic(ushort musicId)
+ {
+ queuePacket(SetMusicPacket.buildPacket(actorId, musicId, 1));
+ }
+
+ public void sendChocoboAppearance()
+ {
+ queuePacket(SetCurrentMountChocoboPacket.buildPacket(actorId, chocoboAppearance));
+ }
+
+ public void sendGoobbueAppearance()
+ {
+ queuePacket(SetCurrentMountGoobbuePacket.buildPacket(actorId, 1));
+ }
+
+ public void sendWorldMessage(ushort worldMasterId, params object[] msgParams)
+ {
+ //queuePacket(WorldMasterPacket.buildPacket());
+ }
+
+ public void broadcastWorldMessage(ushort worldMasterId, params object[] msgParams)
+ {
+ //SubPacket worldMasterMessage =
+ //zone.broadcastPacketAroundActor(this, worldMasterMessage);
+ }
+
public void runEventFunction(string functionName, params object[] parameters)
{
List lParams = LuaUtils.createLuaParamList(parameters);
diff --git a/FFXIVClassic Map Server/packets/SubPacket.cs b/FFXIVClassic Map Server/packets/SubPacket.cs
index 8ef5c83d..87231156 100644
--- a/FFXIVClassic Map Server/packets/SubPacket.cs
+++ b/FFXIVClassic Map Server/packets/SubPacket.cs
@@ -95,6 +95,17 @@ namespace FFXIVClassic_Lobby_Server.packets
header.subpacketSize = (ushort)(SUBPACKET_SIZE + GAMEMESSAGE_SIZE + data.Length);
}
+ public SubPacket(SubPacket original, uint newTargetId)
+ {
+ this.header = new SubPacketHeader();
+ this.gameMessage = original.gameMessage;
+ header.subpacketSize = original.header.subpacketSize;
+ header.type = original.header.type;
+ header.sourceId = original.header.sourceId;
+ header.targetId = newTargetId;
+ data = original.data;
+ }
+
public byte[] getHeaderBytes()
{
int size = Marshal.SizeOf(header);
diff --git a/FFXIVClassic Map Server/packets/send/Actor/SetActorSpeedPacket.cs b/FFXIVClassic Map Server/packets/send/Actor/SetActorSpeedPacket.cs
index 2fed0ebc..a1f388c7 100644
--- a/FFXIVClassic Map Server/packets/send/Actor/SetActorSpeedPacket.cs
+++ b/FFXIVClassic Map Server/packets/send/Actor/SetActorSpeedPacket.cs
@@ -13,9 +13,9 @@ namespace FFXIVClassic_Map_Server.packets.send.actor
public const ushort OPCODE = 0x00D0;
public const uint PACKET_SIZE = 0xA8;
- public const ushort DEFAULT_STOP = 0x0000;
- public const ushort DEFAULT_WALK = 0x4000;
- public const ushort DEFAULT_RUN = 0x40A0;
+ public const float DEFAULT_STOP = 0.0f;
+ public const float DEFAULT_WALK = 2.0f;
+ public const float DEFAULT_RUN = 5.0f;
public static SubPacket buildPacket(uint playerActorID, uint targetActorID)
{
@@ -25,20 +25,16 @@ namespace FFXIVClassic_Map_Server.packets.send.actor
{
using (BinaryWriter binWriter = new BinaryWriter(mem))
{
- binWriter.Write((UInt16)00);
- binWriter.Write((UInt16)DEFAULT_STOP);
+ binWriter.Write((Single)DEFAULT_STOP);
binWriter.Write((UInt32)0);
- binWriter.Write((UInt16)00);
- binWriter.Write((UInt16)DEFAULT_WALK);
+ binWriter.Write((Single)DEFAULT_WALK);
binWriter.Write((UInt32)1);
- binWriter.Write((UInt16)00);
- binWriter.Write((UInt16)DEFAULT_RUN);
+ binWriter.Write((Single)DEFAULT_RUN);
binWriter.Write((UInt32)2);
- binWriter.Write((UInt16)00);
- binWriter.Write((UInt16)DEFAULT_RUN);
+ binWriter.Write((Single)DEFAULT_RUN);
binWriter.Write((UInt32)3);
binWriter.BaseStream.Seek(0x80, SeekOrigin.Begin);
@@ -50,7 +46,7 @@ namespace FFXIVClassic_Map_Server.packets.send.actor
return new SubPacket(OPCODE, playerActorID, targetActorID, data);
}
- public static SubPacket buildPacket(uint playerActorID, uint targetActorID, ushort stopSpeed, ushort walkSpeed, ushort runSpeed)
+ public static SubPacket buildPacket(uint playerActorID, uint targetActorID, float stopSpeed, float walkSpeed, float runSpeed)
{
byte[] data = new byte[PACKET_SIZE - 0x20];
@@ -58,20 +54,17 @@ namespace FFXIVClassic_Map_Server.packets.send.actor
{
using (BinaryWriter binWriter = new BinaryWriter(mem))
{
- binWriter.Write((UInt16)00);
- binWriter.Write((UInt16)stopSpeed);
+ binWriter.Write((Single)stopSpeed);
binWriter.Write((UInt32)0);
- binWriter.Write((UInt16)00);
- binWriter.Write((UInt16)walkSpeed);
+ binWriter.Write((Single)walkSpeed);
binWriter.Write((UInt32)1);
binWriter.Write((UInt16)00);
- binWriter.Write((UInt16)runSpeed);
+ binWriter.Write((Single)runSpeed);
binWriter.Write((UInt32)2);
-
- binWriter.Write((UInt16)00);
- binWriter.Write((UInt16)runSpeed);
+
+ binWriter.Write((Single)runSpeed);
binWriter.Write((UInt32)3);
binWriter.BaseStream.Seek(0x90, SeekOrigin.Begin);
diff --git a/FFXIVClassic Map Server/packets/send/GameMessagePacket.cs b/FFXIVClassic Map Server/packets/send/GameMessagePacket.cs
new file mode 100644
index 00000000..ba05abad
--- /dev/null
+++ b/FFXIVClassic Map Server/packets/send/GameMessagePacket.cs
@@ -0,0 +1,346 @@
+using FFXIVClassic_Lobby_Server.packets;
+using FFXIVClassic_Map_Server.lua;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace FFXIVClassic_Map_Server.packets.send
+{
+ class GameMessagePacket
+ {
+ public const ushort OPCODE_GAMEMESSAGE_WITH_ACTOR1 = 0x157;
+ public const ushort OPCODE_GAMEMESSAGE_WITH_ACTOR2 = 0x158;
+ public const ushort OPCODE_GAMEMESSAGE_WITH_ACTOR3 = 0x159;
+ public const ushort OPCODE_GAMEMESSAGE_WITH_ACTOR4 = 0x15a;
+ public const ushort OPCODE_GAMEMESSAGE_WITH_ACTOR5 = 0x15b;
+
+ public const ushort OPCODE_GAMEMESSAGE_WITH_CUSTOM_SENDER1 = 0x15c;
+ public const ushort OPCODE_GAMEMESSAGE_WITH_CUSTOM_SENDER2 = 0x15d;
+ public const ushort OPCODE_GAMEMESSAGE_WITH_CUSTOM_SENDER3 = 0x15e;
+ public const ushort OPCODE_GAMEMESSAGE_WITH_CUSTOM_SENDER4 = 0x15f;
+ public const ushort OPCODE_GAMEMESSAGE_WITH_CUSTOM_SENDER5 = 0x160;
+
+ public const ushort OPCODE_GAMEMESSAGE_WITH_DISPID_SENDER1 = 0x161;
+ public const ushort OPCODE_GAMEMESSAGE_WITH_DISPID_SENDER2 = 0x162;
+ public const ushort OPCODE_GAMEMESSAGE_WITH_DISPID_SENDER3 = 0x163;
+ public const ushort OPCODE_GAMEMESSAGE_WITH_DISPID_SENDER4 = 0x164;
+ public const ushort OPCODE_GAMEMESSAGE_WITH_DISPID_SENDER5 = 0x165;
+
+ public const ushort OPCODE_GAMEMESSAGE_WITHOUT_ACTOR1 = 0x166;
+ public const ushort OPCODE_GAMEMESSAGE_WITHOUT_ACTOR2 = 0x167;
+ public const ushort OPCODE_GAMEMESSAGE_WITHOUT_ACTOR3 = 0x168;
+ public const ushort OPCODE_GAMEMESSAGE_WITHOUT_ACTOR4 = 0x169;
+ public const ushort OPCODE_GAMEMESSAGE_WITHOUT_ACTOR5 = 0x16a;
+
+ public const ushort SIZE_GAMEMESSAGE_WITH_ACTOR1 = 0x30;
+ public const ushort SIZE_GAMEMESSAGE_WITH_ACTOR2 = 0x38;
+ public const ushort SIZE_GAMEMESSAGE_WITH_ACTOR3 = 0x40;
+ public const ushort SIZE_GAMEMESSAGE_WITH_ACTOR4 = 0x50;
+ public const ushort SIZE_GAMEMESSAGE_WITH_ACTOR5 = 0x70;
+
+ public const ushort SIZE_GAMEMESSAGE_WITH_CUSTOM_SENDER1 = 0x48;
+ public const ushort SIZE_GAMEMESSAGE_WITH_CUSTOM_SENDER2 = 0x58;
+ public const ushort SIZE_GAMEMESSAGE_WITH_CUSTOM_SENDER3 = 0x68;
+ public const ushort SIZE_GAMEMESSAGE_WITH_CUSTOM_SENDER4 = 0x78;
+ public const ushort SIZE_GAMEMESSAGE_WITH_CUSTOM_SENDER5 = 0x98;
+
+ public const ushort SIZE_GAMEMESSAGE_WITH_DISPID_SENDER1 = 0x30;
+ public const ushort SIZE_GAMEMESSAGE_WITH_DISPID_SENDER2 = 0x38;
+ public const ushort SIZE_GAMEMESSAGE_WITH_DISPID_SENDER3 = 0x40;
+ public const ushort SIZE_GAMEMESSAGE_WITH_DISPID_SENDER4 = 0x50;
+ public const ushort SIZE_GAMEMESSAGE_WITH_DISPID_SENDER5 = 0x60;
+
+ public const ushort SIZE_GAMEMESSAGE_WITHOUT_ACTOR1 = 0x28;
+ public const ushort SIZE_GAMEMESSAGE_WITHOUT_ACTOR2 = 0x38;
+ public const ushort SIZE_GAMEMESSAGE_WITHOUT_ACTOR3 = 0x38;
+ public const ushort SIZE_GAMEMESSAGE_WITHOUT_ACTOR4 = 0x48;
+ public const ushort SIZE_GAMEMESSAGE_WITHOUT_ACTOR5 = 0x68;
+
+ public static SubPacket buildPacket(uint sourceId, uint targetId, uint actorId, uint textOwnerActorId, ushort textId, byte log)
+ {
+ byte[] data = new byte[SIZE_GAMEMESSAGE_WITH_ACTOR1 - 0x20];
+
+ using (MemoryStream mem = new MemoryStream(data))
+ {
+ using (BinaryWriter binWriter = new BinaryWriter(mem))
+ {
+ binWriter.Write((UInt32)actorId);
+ binWriter.Write((UInt32)textOwnerActorId);
+ binWriter.Write((UInt16)textId);
+ binWriter.Write((UInt16)log);
+ }
+ }
+
+ return new SubPacket(OPCODE_GAMEMESSAGE_WITH_ACTOR1, sourceId, targetId, data);
+ }
+
+ public static SubPacket buildPacket(uint sourceId, uint targetId, uint actorId, uint textOwnerActorId, ushort textId, byte log, List lParams)
+ {
+ int lParamsSize = findSizeOfParams(lParams);
+ byte[] data;
+ ushort opcode;
+
+ if (lParamsSize <= 0x8)
+ {
+ data = new byte[SIZE_GAMEMESSAGE_WITH_ACTOR2 - 0x20];
+ opcode = OPCODE_GAMEMESSAGE_WITH_ACTOR2;
+ }
+ else if (lParamsSize <= 0x10)
+ {
+ data = new byte[SIZE_GAMEMESSAGE_WITH_ACTOR3 - 0x20];
+ opcode = OPCODE_GAMEMESSAGE_WITH_ACTOR3;
+ }
+ else if (lParamsSize <= 0x20)
+ {
+ data = new byte[SIZE_GAMEMESSAGE_WITH_ACTOR4 - 0x20];
+ opcode = OPCODE_GAMEMESSAGE_WITH_ACTOR4;
+ }
+ else
+ {
+ data = new byte[SIZE_GAMEMESSAGE_WITH_ACTOR5 - 0x20];
+ opcode = OPCODE_GAMEMESSAGE_WITH_ACTOR5;
+ }
+
+ using (MemoryStream mem = new MemoryStream(data))
+ {
+ using (BinaryWriter binWriter = new BinaryWriter(mem))
+ {
+ binWriter.Write((UInt32)actorId);
+ binWriter.Write((UInt32)textOwnerActorId);
+ binWriter.Write((UInt16)textId);
+ binWriter.Write((UInt16)log);
+ LuaUtils.writeLuaParams(binWriter, lParams);
+
+ if (lParamsSize <= 0x14-12)
+ {
+ binWriter.Seek(0x14, SeekOrigin.Begin);
+ binWriter.Write((UInt32)8);
+ }
+ }
+ }
+
+ return new SubPacket(opcode, sourceId, targetId, data);
+ }
+
+ public static SubPacket buildPacket(uint sourceId, uint targetId, uint textOwnerActorId, ushort textId, string sender, byte log)
+ {
+ byte[] data = new byte[SIZE_GAMEMESSAGE_WITH_CUSTOM_SENDER1 - 0x20];
+
+ using (MemoryStream mem = new MemoryStream(data))
+ {
+ using (BinaryWriter binWriter = new BinaryWriter(mem))
+ {
+ binWriter.Write((UInt32)textOwnerActorId);
+ binWriter.Write((UInt16)textId);
+ binWriter.Write((UInt16)log);
+ binWriter.Write(Encoding.ASCII.GetBytes(sender), 0, Encoding.ASCII.GetByteCount(sender) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(sender));
+ }
+ }
+
+ return new SubPacket(OPCODE_GAMEMESSAGE_WITH_CUSTOM_SENDER1, sourceId, targetId, data);
+ }
+
+ public static SubPacket buildPacket(uint sourceId, uint targetId, uint textOwnerActorId, ushort textId, string sender, byte log, List lParams)
+ {
+ int lParamsSize = findSizeOfParams(lParams);
+ byte[] data;
+ ushort opcode;
+
+ if (lParamsSize <= 0x8)
+ {
+ data = new byte[SIZE_GAMEMESSAGE_WITH_CUSTOM_SENDER2 - 0x20];
+ opcode = OPCODE_GAMEMESSAGE_WITH_CUSTOM_SENDER2;
+ }
+ else if (lParamsSize <= 0x10)
+ {
+ data = new byte[SIZE_GAMEMESSAGE_WITH_CUSTOM_SENDER3 - 0x20];
+ opcode = OPCODE_GAMEMESSAGE_WITH_CUSTOM_SENDER3;
+ }
+ else if (lParamsSize <= 0x20)
+ {
+ data = new byte[SIZE_GAMEMESSAGE_WITH_CUSTOM_SENDER4 - 0x20];
+ opcode = OPCODE_GAMEMESSAGE_WITH_CUSTOM_SENDER4;
+ }
+ else
+ {
+ data = new byte[SIZE_GAMEMESSAGE_WITH_CUSTOM_SENDER5 - 0x20];
+ opcode = OPCODE_GAMEMESSAGE_WITH_CUSTOM_SENDER5;
+ }
+
+ using (MemoryStream mem = new MemoryStream(data))
+ {
+ using (BinaryWriter binWriter = new BinaryWriter(mem))
+ {
+ binWriter.Write((UInt32)textOwnerActorId);
+ binWriter.Write((UInt16)textId);
+ binWriter.Write((UInt16)log);
+ binWriter.Write(Encoding.ASCII.GetBytes(sender), 0, Encoding.ASCII.GetByteCount(sender) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(sender));
+ LuaUtils.writeLuaParams(binWriter, lParams);
+
+ if (lParamsSize <= 0x14 - 12)
+ {
+ binWriter.Seek(0x30, SeekOrigin.Begin);
+ binWriter.Write((UInt32)8);
+ }
+ }
+ }
+
+ return new SubPacket(opcode, sourceId, targetId, data);
+ }
+
+ public static SubPacket buildPacket(uint sourceId, uint targetId, uint textOwnerActorId, ushort textId, uint senderDisplayNameId, byte log)
+ {
+ byte[] data = new byte[SIZE_GAMEMESSAGE_WITH_DISPID_SENDER1 - 0x20];
+
+ using (MemoryStream mem = new MemoryStream(data))
+ {
+ using (BinaryWriter binWriter = new BinaryWriter(mem))
+ {
+ binWriter.Write((UInt32)senderDisplayNameId);
+ binWriter.Write((UInt32)textOwnerActorId);
+ binWriter.Write((UInt16)textId);
+ binWriter.Write((UInt16)log);
+ }
+ }
+
+ return new SubPacket(OPCODE_GAMEMESSAGE_WITH_DISPID_SENDER1, sourceId, targetId, data);
+ }
+
+ public static SubPacket buildPacket(uint sourceId, uint targetId, uint textOwnerActorId, ushort textId, uint senderDisplayNameId, byte log, List lParams)
+ {
+ int lParamsSize = findSizeOfParams(lParams);
+ byte[] data;
+ ushort opcode;
+
+ if (lParamsSize <= 0x8)
+ {
+ data = new byte[SIZE_GAMEMESSAGE_WITH_DISPID_SENDER2 - 0x20];
+ opcode = OPCODE_GAMEMESSAGE_WITH_DISPID_SENDER2;
+ }
+ else if (lParamsSize <= 0x10)
+ {
+ data = new byte[SIZE_GAMEMESSAGE_WITH_DISPID_SENDER3 - 0x20];
+ opcode = OPCODE_GAMEMESSAGE_WITH_DISPID_SENDER3;
+ }
+ else if (lParamsSize <= 0x20)
+ {
+ data = new byte[SIZE_GAMEMESSAGE_WITH_DISPID_SENDER4 - 0x20];
+ opcode = OPCODE_GAMEMESSAGE_WITH_DISPID_SENDER4;
+ }
+ else
+ {
+ data = new byte[SIZE_GAMEMESSAGE_WITH_DISPID_SENDER5 - 0x20];
+ opcode = OPCODE_GAMEMESSAGE_WITH_DISPID_SENDER5;
+ }
+
+ using (MemoryStream mem = new MemoryStream(data))
+ {
+ using (BinaryWriter binWriter = new BinaryWriter(mem))
+ {
+ binWriter.Write((UInt32)senderDisplayNameId);
+ binWriter.Write((UInt32)textOwnerActorId);
+ binWriter.Write((UInt16)textId);
+ binWriter.Write((UInt16)log);
+ LuaUtils.writeLuaParams(binWriter, lParams);
+
+ if (lParamsSize <= 0x14 - 12)
+ {
+ binWriter.Seek(0x14, SeekOrigin.Begin);
+ binWriter.Write((UInt32)8);
+ }
+ }
+ }
+
+ return new SubPacket(opcode, sourceId, targetId, data);
+ }
+
+ public static SubPacket buildPacket(uint sourceId, uint targetId, uint textOwnerActorId, ushort textId, byte log)
+ {
+ byte[] data = new byte[SIZE_GAMEMESSAGE_WITHOUT_ACTOR1 - 0x20];
+
+ using (MemoryStream mem = new MemoryStream(data))
+ {
+ using (BinaryWriter binWriter = new BinaryWriter(mem))
+ {
+ binWriter.Write((UInt32)textOwnerActorId);
+ binWriter.Write((UInt16)textId);
+ binWriter.Write((UInt16)log);
+ }
+ }
+
+ return new SubPacket(OPCODE_GAMEMESSAGE_WITHOUT_ACTOR1, sourceId, targetId, data);
+ }
+
+ public static SubPacket buildPacket(uint sourceId, uint targetId, uint textOwnerActorId, ushort textId, byte log, List lParams)
+ {
+ int lParamsSize = findSizeOfParams(lParams);
+ byte[] data;
+ ushort opcode;
+
+ if (lParamsSize <= 0x8)
+ {
+ data = new byte[SIZE_GAMEMESSAGE_WITHOUT_ACTOR2 - 0x20];
+ opcode = OPCODE_GAMEMESSAGE_WITHOUT_ACTOR2;
+ }
+ else if (lParamsSize <= 0x10)
+ {
+ data = new byte[SIZE_GAMEMESSAGE_WITHOUT_ACTOR3 - 0x20];
+ opcode = OPCODE_GAMEMESSAGE_WITHOUT_ACTOR3;
+ }
+ else if (lParamsSize <= 0x20)
+ {
+ data = new byte[SIZE_GAMEMESSAGE_WITHOUT_ACTOR4 - 0x20];
+ opcode = OPCODE_GAMEMESSAGE_WITHOUT_ACTOR4;
+ }
+ else
+ {
+ data = new byte[SIZE_GAMEMESSAGE_WITHOUT_ACTOR5 - 0x20];
+ opcode = OPCODE_GAMEMESSAGE_WITHOUT_ACTOR5;
+ }
+
+ using (MemoryStream mem = new MemoryStream(data))
+ {
+ using (BinaryWriter binWriter = new BinaryWriter(mem))
+ {
+ binWriter.Write((UInt32)textOwnerActorId);
+ binWriter.Write((UInt16)textId);
+ binWriter.Write((UInt16)log);
+ LuaUtils.writeLuaParams(binWriter, lParams);
+
+ if (lParamsSize <= 0x14 - 12)
+ {
+ binWriter.Seek(0x30, SeekOrigin.Begin);
+ binWriter.Write((UInt32)8);
+ }
+ }
+ }
+
+ return new SubPacket(opcode, sourceId, targetId, data);
+ }
+
+ private static int findSizeOfParams(List lParams)
+ {
+ int total = 0;
+ foreach (LuaParam l in lParams)
+ {
+ switch (l.typeID)
+ {
+ case 0:
+ case 1:
+ case 6:
+ total += 5;
+ break;
+ case 3:
+ case 4:
+ case 5:
+ total += 1;
+ break;
+ }
+ }
+ return total + 1;
+ }
+ }
+}