diff --git a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj
index eee44060..7e0ff280 100644
--- a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj
+++ b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj
@@ -70,6 +70,8 @@
+
+
@@ -172,6 +174,7 @@
+
diff --git a/FFXIVClassic Map Server/actors/EventList.cs b/FFXIVClassic Map Server/actors/EventList.cs
index b1559522..7b7630c1 100644
--- a/FFXIVClassic Map Server/actors/EventList.cs
+++ b/FFXIVClassic Map Server/actors/EventList.cs
@@ -27,6 +27,13 @@ namespace FFXIVClassic_Map_Server.actors
public byte unknown1;
public byte unknown2;
public string conditionName;
+
+ public NoticeEventCondition(string name, byte unk1, byte unk2)
+ {
+ conditionName = name;
+ unknown1 = unk1;
+ unknown2 = unk2;
+ }
}
public class EmoteEventCondition
diff --git a/FFXIVClassic Map Server/actors/chara/player/Player.cs b/FFXIVClassic Map Server/actors/chara/player/Player.cs
index 7617882c..8385f922 100644
--- a/FFXIVClassic Map Server/actors/chara/player/Player.cs
+++ b/FFXIVClassic Map Server/actors/chara/player/Player.cs
@@ -3,6 +3,7 @@ using FFXIVClassic_Lobby_Server.common;
using FFXIVClassic_Lobby_Server.packets;
using FFXIVClassic_Map_Server.actors.area;
using FFXIVClassic_Map_Server.actors.chara.player;
+using FFXIVClassic_Map_Server.actors.director;
using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.dataobjects.chara;
using FFXIVClassic_Map_Server.lua;
@@ -122,6 +123,8 @@ namespace FFXIVClassic_Map_Server.Actors
public Quest[] questScenario = new Quest[16];
public Quest[] questGuildleve = new Quest[8];
+ public Director currentDirector;
+
public PlayerWork playerWork = new PlayerWork();
public ConnectedPlayer playerSession;
@@ -518,10 +521,18 @@ namespace FFXIVClassic_Map_Server.Actors
BasePacket areaMasterSpawn = zone.getSpawnPackets(actorId);
BasePacket debugSpawn = world.GetDebugActor().getSpawnPackets(actorId);
BasePacket worldMasterSpawn = world.GetActor().getSpawnPackets(actorId);
+ BasePacket directorSpawn = null;
+
+ if (currentDirector != null)
+ directorSpawn = currentDirector.getSpawnPackets(actorId);
+
playerSession.queuePacket(areaMasterSpawn);
playerSession.queuePacket(debugSpawn);
playerSession.queuePacket(worldMasterSpawn);
+ // if (directorSpawn != null)
+ // queuePacket(directorSpawn);
+
#region hardcode
BasePacket reply10 = new BasePacket("./packets/login/login10.bin"); //Item Storage, Inn Door created
BasePacket reply11 = new BasePacket("./packets/login/login11.bin"); //NPC Create ??? Final init
@@ -950,6 +961,44 @@ namespace FFXIVClassic_Map_Server.Actors
return equipment;
}
+ public Quest getQuest(uint id)
+ {
+ for (int i = 0; i < questScenario.Length; i++)
+ {
+ if (questScenario[i] != null && questScenario[i].actorId == (0xA0F00000 | id))
+ return questScenario[i];
+ }
+
+ return null;
+ }
+
+ public bool hasQuest(uint id)
+ {
+ for (int i = 0; i < questScenario.Length; i++)
+ {
+ if (questScenario[i] != null && questScenario[i].actorId == (0xA0F00000 | id))
+ return true;
+ }
+
+ return false;
+ }
+
+ public void setDirector(string directorType)
+ {
+ if (directorType.Equals("openingDirector"))
+ {
+ currentDirector = new OpeningDirector(0x5FF80004);
+ }
+
+ queuePacket(RemoveActorPacket.buildPacket(actorId, 0x5FF80004));
+ queuePacket(currentDirector.getSpawnPackets(actorId));
+ }
+
+ public Director getDirector()
+ {
+ return currentDirector;
+ }
+
public void examinePlayer(Actor examinee)
{
Player toBeExamined;
@@ -971,6 +1020,14 @@ namespace FFXIVClassic_Map_Server.Actors
queuePacket(spacket);
}
+ public void kickEvent(Actor actor, string conditionName, params object[] parameters)
+ {
+ List lParams = LuaUtils.createLuaParamList(parameters);
+ SubPacket spacket = KickEventPacket.buildPacket(actorId, actor.actorId, conditionName, lParams);
+ spacket.debugPrintSubPacket();
+ queuePacket(spacket);
+ }
+
public void runEventFunction(string functionName, params object[] parameters)
{
List lParams = LuaUtils.createLuaParamList(parameters);
diff --git a/FFXIVClassic Map Server/actors/director/Director.cs b/FFXIVClassic Map Server/actors/director/Director.cs
new file mode 100644
index 00000000..baf9080c
--- /dev/null
+++ b/FFXIVClassic Map Server/actors/director/Director.cs
@@ -0,0 +1,17 @@
+using FFXIVClassic_Map_Server.Actors;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace FFXIVClassic_Map_Server.actors.director
+{
+ class Director : Actor
+ {
+ public Director(uint id) : base(id)
+ {
+
+ }
+ }
+}
diff --git a/FFXIVClassic Map Server/actors/director/OpeningDirector.cs b/FFXIVClassic Map Server/actors/director/OpeningDirector.cs
new file mode 100644
index 00000000..c1fa0592
--- /dev/null
+++ b/FFXIVClassic Map Server/actors/director/OpeningDirector.cs
@@ -0,0 +1,39 @@
+using FFXIVClassic_Lobby_Server.packets;
+using FFXIVClassic_Map_Server.lua;
+using FFXIVClassic_Map_Server.packets.send.actor;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace FFXIVClassic_Map_Server.actors.director
+{
+ class OpeningDirector : Director
+ {
+ public OpeningDirector(uint id) : base(id)
+ {
+ this.displayNameId = 0;
+ this.customDisplayName = "openingDire_ocn0Btl02_0h";
+
+ this.actorName = "openingDire_ocn0Btl02_0h@0C100";
+ this.className = "OpeningDirector";
+
+ this.eventConditions = new EventList();
+
+ List noticeEventList = new List();
+
+ noticeEventList.Add(new EventList.NoticeEventCondition("noticeEvent", 0xE, 0x0));
+ noticeEventList.Add(new EventList.NoticeEventCondition("noticeRequest", 0x0, 0x1));
+
+ this.eventConditions.noticeEventConditions = noticeEventList;
+ }
+
+ public override SubPacket createScriptBindPacket(uint playerActorId)
+ {
+ List lParams;
+ lParams = LuaUtils.createLuaParamList("/Director/OpeningDirector", false, false, false, false, 0x13881);
+ return ActorInstantiatePacket.buildPacket(actorId, playerActorId, actorName, className, lParams);
+ }
+ }
+}
diff --git a/FFXIVClassic Map Server/actors/director/WeatherDirector.cs b/FFXIVClassic Map Server/actors/director/WeatherDirector.cs
index 060a3c24..658776de 100644
--- a/FFXIVClassic Map Server/actors/director/WeatherDirector.cs
+++ b/FFXIVClassic Map Server/actors/director/WeatherDirector.cs
@@ -1,4 +1,5 @@
using FFXIVClassic_Lobby_Server.packets;
+using FFXIVClassic_Map_Server.actors.director;
using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.packets.send.actor;
@@ -10,12 +11,12 @@ using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.Actors
{
- class WeatherDirector : Actor
+ class WeatherDirector : Director
{
private uint weatherId;
public WeatherDirector(uint weatherId)
- : base(0x5FF80002)
+ : base(0x5FF80003)
{
this.weatherId = weatherId;
diff --git a/FFXIVClassic Map Server/packets/send/events/KickEventPacket.cs b/FFXIVClassic Map Server/packets/send/events/KickEventPacket.cs
new file mode 100644
index 00000000..677a6253
--- /dev/null
+++ b/FFXIVClassic Map Server/packets/send/events/KickEventPacket.cs
@@ -0,0 +1,39 @@
+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.events
+{
+ class KickEventPacket
+ {
+ public const ushort OPCODE = 0x012F;
+ public const uint PACKET_SIZE = 0x90;
+
+ public static SubPacket buildPacket(uint playerActorId, uint targetActorId, string conditionName, List luaParams)
+ {
+ byte[] data = new byte[PACKET_SIZE - 0x20];
+
+ using (MemoryStream mem = new MemoryStream(data))
+ {
+ using (BinaryWriter binWriter = new BinaryWriter(mem))
+ {
+ binWriter.Write((UInt32)playerActorId);
+ binWriter.Write((UInt32)targetActorId);
+ binWriter.Write((UInt32)0);
+ binWriter.Write((UInt32)0);
+ binWriter.Write(Encoding.ASCII.GetBytes(conditionName), 0, Encoding.ASCII.GetByteCount(conditionName) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(conditionName));
+
+ LuaUtils.writeLuaParams(binWriter, luaParams);
+ }
+ }
+
+ return new SubPacket(OPCODE, playerActorId, playerActorId, data);
+ }
+ }
+
+}