diff --git a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj
index 5f77be8f..b9bbe097 100644
--- a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj
+++ b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj
@@ -90,6 +90,7 @@
+
diff --git a/FFXIVClassic Map Server/WorldManager.cs b/FFXIVClassic Map Server/WorldManager.cs
index f6cd0e17..dcf02d29 100644
--- a/FFXIVClassic Map Server/WorldManager.cs
+++ b/FFXIVClassic Map Server/WorldManager.cs
@@ -600,7 +600,7 @@ namespace FFXIVClassic_Map_Server
if (player.currentContentGroup != null)
{
player.currentContentGroup.RemoveMember(player.actorId);
- player.SetCurrentContentGroup(null, player);
+ player.SetCurrentContentGroup(null);
if (oldZone is PrivateAreaContent)
((PrivateAreaContent)oldZone).CheckDestroy();
@@ -762,11 +762,6 @@ namespace FFXIVClassic_Map_Server
}
- public ContentGroup CreateContentGroup(Director director)
- {
- return CreateContentGroup(director, null);
- }
-
public ContentGroup CreateContentGroup(Director director, params Actor[] actors)
{
if (director == null)
@@ -795,6 +790,62 @@ namespace FFXIVClassic_Map_Server
}
}
+ public ContentGroup CreateContentGroup(Director director, List actors)
+ {
+ if (director == null)
+ return null;
+
+ lock (groupLock)
+ {
+ uint[] initialMembers = null;
+
+ if (actors != null)
+ {
+ initialMembers = new uint[actors.Count];
+ for (int i = 0; i < actors.Count; i++)
+ initialMembers[i] = actors[i].actorId;
+ }
+
+ groupIndexId = groupIndexId | 0x3000000000000000;
+
+ ContentGroup contentGroup = new ContentGroup(groupIndexId, director, initialMembers);
+ mContentGroups.Add(groupIndexId, contentGroup);
+ groupIndexId++;
+ if (initialMembers != null && initialMembers.Length != 0)
+ contentGroup.SendAll();
+
+ return contentGroup;
+ }
+ }
+
+ public ContentGroup CreateGLContentGroup(Director director, List actors)
+ {
+ if (director == null)
+ return null;
+
+ lock (groupLock)
+ {
+ uint[] initialMembers = null;
+
+ if (actors != null)
+ {
+ initialMembers = new uint[actors.Count];
+ for (int i = 0; i < actors.Count; i++)
+ initialMembers[i] = actors[i].actorId;
+ }
+
+ groupIndexId = groupIndexId | 0x2000000000000000;
+
+ GLContentGroup contentGroup = new GLContentGroup(groupIndexId, director, initialMembers);
+ mContentGroups.Add(groupIndexId, contentGroup);
+ groupIndexId++;
+ if (initialMembers != null && initialMembers.Length != 0)
+ contentGroup.SendAll();
+
+ return contentGroup;
+ }
+ }
+
public void DeleteContentGroup(ulong groupId)
{
lock (groupLock)
@@ -802,7 +853,6 @@ namespace FFXIVClassic_Map_Server
if (mContentGroups.ContainsKey(groupId) && mContentGroups[groupId] is ContentGroup)
{
ContentGroup group = (ContentGroup)mContentGroups[groupId];
- group.SendDeletePackets();
mContentGroups.Remove(groupId);
}
}
diff --git a/FFXIVClassic Map Server/actors/area/Area.cs b/FFXIVClassic Map Server/actors/area/Area.cs
index fec0e1c6..8bf5a2d9 100644
--- a/FFXIVClassic Map Server/actors/area/Area.cs
+++ b/FFXIVClassic Map Server/actors/area/Area.cs
@@ -368,6 +368,12 @@ namespace FFXIVClassic_Map_Server.Actors
}
}
+ public void BroadcastPacketsAroundActor(Actor actor, List packets)
+ {
+ foreach (SubPacket packet in packets)
+ BroadcastPacketAroundActor(actor, packet);
+ }
+
public void BroadcastPacketAroundActor(Actor actor, SubPacket packet)
{
if (isIsolated)
@@ -501,11 +507,48 @@ namespace FFXIVClassic_Map_Server.Actors
}
}
- public Director CreateGuildleveDirector(string path, uint glid, params object[] args)
+ public Director CreateGuildleveDirector(uint glid, byte difficulty, Player owner, params object[] args)
{
+ String directorScriptPath = "";
+
+ uint type = Server.GetGuildleveGamedata(glid).plateId;
+
+ if (glid == 10801 || glid == 12401 || glid == 11601)
+ directorScriptPath = "Guildleve/PrivateGLBattleTutorial";
+ else
+ {
+ switch (type)
+ {
+ case 20021:
+ directorScriptPath = "Guildleve/PrivateGLBattleSweepNormal";
+ break;
+ case 20022:
+ directorScriptPath = "Guildleve/PrivateGLBattleChaseNormal";
+ break;
+ case 20023:
+ directorScriptPath = "Guildleve/PrivateGLBattleOrbNormal";
+ break;
+ case 20024:
+ directorScriptPath = "Guildleve/PrivateGLBattleHuntNormal";
+ break;
+ case 20025:
+ directorScriptPath = "Guildleve/PrivateGLBattleGatherNormal";
+ break;
+ case 20026:
+ directorScriptPath = "Guildleve/PrivateGLBattleRoundNormal";
+ break;
+ case 20027:
+ directorScriptPath = "Guildleve/PrivateGLBattleSurviveNormal";
+ break;
+ case 20028:
+ directorScriptPath = "Guildleve/PrivateGLBattleDetectNormal";
+ break;
+ }
+ }
+
lock (directorLock)
{
- GuildleveDirector director = new GuildleveDirector(directorIdCount, this, path, glid, args);
+ GuildleveDirector director = new GuildleveDirector(directorIdCount, this, directorScriptPath, glid, difficulty, owner, args);
currentDirectors.Add(directorIdCount, director);
directorIdCount++;
return director;
@@ -518,7 +561,8 @@ namespace FFXIVClassic_Map_Server.Actors
{
if (currentDirectors.ContainsKey(id))
{
- currentDirectors[id].RemoveMembers();
+ if (!currentDirectors[id].IsDeleted())
+ currentDirectors[id].EndDirector();
currentDirectors.Remove(id);
}
}
diff --git a/FFXIVClassic Map Server/actors/chara/Character.cs b/FFXIVClassic Map Server/actors/chara/Character.cs
index 849f7b81..66b54804 100644
--- a/FFXIVClassic Map Server/actors/chara/Character.cs
+++ b/FFXIVClassic Map Server/actors/chara/Character.cs
@@ -89,7 +89,7 @@ namespace FFXIVClassic_Map_Server.Actors
player.QueuePacket(SetActorQuestGraphicPacket.BuildPacket(player.actorId, actorId, graphicNum));
}
- public void SetCurrentContentGroup(ContentGroup group, Player player = null)
+ public void SetCurrentContentGroup(ContentGroup group)
{
if (group != null)
charaWork.currentContentGroup = group.GetTypeId();
@@ -98,12 +98,10 @@ namespace FFXIVClassic_Map_Server.Actors
currentContentGroup = group;
- if (player != null)
- {
- ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("charaWork/currentContentGroup", this, actorId);
- propPacketUtil.AddProperty("charaWork.currentContentGroup");
- player.QueuePackets(propPacketUtil.Done());
- }
+ ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("charaWork/currentContentGroup", this, actorId);
+ propPacketUtil.AddProperty("charaWork.currentContentGroup");
+ zone.BroadcastPacketsAroundActor(this, propPacketUtil.Done());
+
}
public void PlayAnimation(uint animId)
diff --git a/FFXIVClassic Map Server/actors/chara/player/Player.cs b/FFXIVClassic Map Server/actors/chara/player/Player.cs
index 10a23f9f..0c4d12a2 100644
--- a/FFXIVClassic Map Server/actors/chara/player/Player.cs
+++ b/FFXIVClassic Map Server/actors/chara/player/Player.cs
@@ -795,7 +795,7 @@ namespace FFXIVClassic_Map_Server.Actors
QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, actorId, textIdOwner.actorId, textId, log, LuaUtils.CreateLuaParamList(msgParams)));
}
- public void SendGameMessage(Actor textIdOwner, ushort textId, byte log, string customSender, params object[] msgParams)
+ public void SendGameMessageCustomSender(Actor textIdOwner, ushort textId, byte log, string customSender, params object[] msgParams)
{
if (msgParams == null || msgParams.Length == 0)
QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, actorId, textIdOwner.actorId, textId, customSender, log));
@@ -803,7 +803,7 @@ namespace FFXIVClassic_Map_Server.Actors
QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, actorId, textIdOwner.actorId, textId, customSender, log, LuaUtils.CreateLuaParamList(msgParams)));
}
- public void SendGameMessage(Actor textIdOwner, ushort textId, byte log, uint displayId, params object[] msgParams)
+ public void SendGameMessageDisplayIDSender(Actor textIdOwner, ushort textId, byte log, uint displayId, params object[] msgParams)
{
if (msgParams == null || msgParams.Length == 0)
QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, actorId, textIdOwner.actorId, textId, displayId, log));
@@ -1433,13 +1433,25 @@ namespace FFXIVClassic_Map_Server.Actors
public void RemoveDirector(Director director)
{
- if (!ownedDirectors.Contains(director))
+ if (ownedDirectors.Contains(director))
{
+ QueuePacket(RemoveActorPacket.BuildPacket(actorId, director.actorId));
ownedDirectors.Remove(director);
director.RemoveMember(this);
}
}
+ public Director GetGuildleveDirector()
+ {
+ foreach (Director d in ownedDirectors)
+ {
+ if (d is GuildleveDirector)
+ return d;
+ }
+
+ return null;
+ }
+
public Director GetDirector(string directorName)
{
foreach (Director d in ownedDirectors)
diff --git a/FFXIVClassic Map Server/actors/director/Director.cs b/FFXIVClassic Map Server/actors/director/Director.cs
index 047fbc26..5203ad9f 100644
--- a/FFXIVClassic Map Server/actors/director/Director.cs
+++ b/FFXIVClassic Map Server/actors/director/Director.cs
@@ -17,6 +17,7 @@ namespace FFXIVClassic_Map_Server.actors.director
private string directorScriptPath;
private List members = new List();
private bool isCreated = false;
+ private bool isDeleted = false;
private Script directorScript;
private Coroutine currentCoroutine;
@@ -26,6 +27,7 @@ namespace FFXIVClassic_Map_Server.actors.director
{
directorId = id;
this.zone = zone;
+ this.zoneId = zone.actorId;
directorScriptPath = directorPath;
LoadLuaScript();
@@ -111,10 +113,25 @@ namespace FFXIVClassic_Map_Server.actors.director
}
}
+ if (this is GuildleveDirector)
+ ((GuildleveDirector)this).LoadGuildleve();
- StartCoroutine("mainLoop", this);
+ StartCoroutine("main", this);
}
+ public void EndDirector()
+ {
+ if (this is GuildleveDirector)
+ ((GuildleveDirector)this).EndGuildleveDirector();
+
+ List players = GetPlayerMembers();
+ foreach (Actor player in players)
+ ((Player)player).RemoveDirector(this);
+ members.Clear();
+ isDeleted = true;
+ Server.GetWorldManager().GetZone(zoneId).DeleteDirector(actorId);
+ }
+
public void AddMember(Actor actor)
{
if (!members.Contains(actor))
@@ -124,15 +141,7 @@ namespace FFXIVClassic_Map_Server.actors.director
public void RemoveMember(Actor actor)
{
if (members.Contains(actor))
- members.Remove(actor);
- if (members.Count == 0)
- Server.GetWorldManager().GetZone(zoneId).DeleteDirector(actorId);
- }
-
- public void RemoveMembers()
- {
- members.Clear();
- Server.GetWorldManager().GetZone(zoneId).DeleteDirector(actorId);
+ members.Remove(actor);
}
public List GetMembers()
@@ -155,6 +164,11 @@ namespace FFXIVClassic_Map_Server.actors.director
return isCreated;
}
+ public bool IsDeleted()
+ {
+ return isDeleted;
+ }
+
public void GenerateActorName(int actorNumber)
{
//Format Class Name
diff --git a/FFXIVClassic Map Server/actors/director/GuildleveDirector.cs b/FFXIVClassic Map Server/actors/director/GuildleveDirector.cs
index 58a0e8cc..7289e353 100644
--- a/FFXIVClassic Map Server/actors/director/GuildleveDirector.cs
+++ b/FFXIVClassic Map Server/actors/director/GuildleveDirector.cs
@@ -1,5 +1,7 @@
using FFXIVClassic.Common;
+using FFXIVClassic_Map_Server.actors.area;
using FFXIVClassic_Map_Server.actors.director.Work;
+using FFXIVClassic_Map_Server.actors.group;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.utils;
@@ -14,14 +16,20 @@ namespace FFXIVClassic_Map_Server.actors.director
class GuildleveDirector : Director
{
public uint guildleveId;
+ public Player guildleveOwner;
+ public byte selectedDifficulty;
+ public ContentGroup contentGroup;
+
public GuildleveData guildleveData;
public GuildleveWork guildleveWork = new GuildleveWork();
- public GuildleveDirector(uint id, Area zone, string directorPath, uint guildleveId, params object[] args)
+ public GuildleveDirector(uint id, Area zone, string directorPath, uint guildleveId, byte selectedDifficulty, Player guildleveOwner, params object[] args)
: base(id, zone, directorPath, args)
{
this.guildleveId = guildleveId;
+ this.selectedDifficulty = selectedDifficulty;
this.guildleveData = Server.GetGuildleveGamedata(guildleveId);
+ this.guildleveOwner = guildleveOwner;
guildleveWork.aimNum[0] = guildleveData.aimNum[0];
guildleveWork.aimNum[1] = guildleveData.aimNum[1];
@@ -38,18 +46,50 @@ namespace FFXIVClassic_Map_Server.actors.director
guildleveWork.uiState[3] = 1;
guildleveWork.aimNumNow[0] = guildleveWork.aimNumNow[1] = guildleveWork.aimNumNow[2] = guildleveWork.aimNumNow[3] = 0;
+
+ LoadGuildleve();
+ }
+
+ public void LoadGuildleve()
+ {
+ contentGroup = Server.GetWorldManager().CreateGLContentGroup(this, GetMembers());
}
public void StartGuildleve()
{
+ foreach (Actor p in GetPlayerMembers())
+ {
+ Player player = (Player) p;
+
+ //Set music
+ if (guildleveData.location == 1)
+ player.ChangeMusic(22);
+ else if (guildleveData.location == 2)
+ player.ChangeMusic(14);
+ else if (guildleveData.location == 3)
+ player.ChangeMusic(26);
+ else if (guildleveData.location == 4)
+ player.ChangeMusic(16);
+
+ //Show Start Messages
+ player.SendGameMessage(Server.GetWorldManager().GetActor(), 50022, 0x20, guildleveId, selectedDifficulty);
+ player.SendDataPacket("attention", Server.GetWorldManager().GetActor(), "", 50022, guildleveId, selectedDifficulty);
+ player.SendGameMessage(Server.GetWorldManager().GetActor(), 50026, 0x20, (object)(int)guildleveData.timeLimit);
+ }
+
guildleveWork.startTime = Utils.UnixTimeStampUTC();
ActorPropertyPacketUtil propertyBuilder = new ActorPropertyPacketUtil("guildleveWork/start", this, actorId);
propertyBuilder.AddProperty("guildleveWork.startTime");
SendPacketsToPlayers(propertyBuilder.Done());
}
- public void EndGuildleve()
+ public void EndGuildleve(bool wasCompleted)
{
+ if (wasCompleted)
+ {
+
+ }
+
guildleveWork.startTime = 0;
guildleveWork.signal = -1;
ActorPropertyPacketUtil propertyBuilder = new ActorPropertyPacketUtil("guildleveWork/signal", this, actorId);
@@ -57,7 +97,31 @@ namespace FFXIVClassic_Map_Server.actors.director
propertyBuilder.NewTarget("guildleveWork/start");
propertyBuilder.AddProperty("guildleveWork.startTime");
SendPacketsToPlayers(propertyBuilder.Done());
+
}
+
+ public void AbandonGuildleve()
+ {
+ foreach (Actor p in GetPlayerMembers())
+ {
+ Player player = (Player)p;
+ player.SendGameMessage(Server.GetWorldManager().GetActor(), 50147, 0x20, (object)guildleveId);
+ }
+
+ EndGuildleve(false);
+ EndDirector();
+ }
+
+ //Delete ContentGroup, change music back
+ public void EndGuildleveDirector()
+ {
+ contentGroup.DeleteGroup();
+ foreach (Actor p in GetPlayerMembers())
+ {
+ Player player = (Player)p;
+ player.ChangeMusic(player.GetZone().bgmDay);
+ }
+ }
public void SyncAllInfo()
{
@@ -95,6 +159,7 @@ namespace FFXIVClassic_Map_Server.actors.director
public void UpdateAimNumNow(int index, sbyte value)
{
+ guildleveWork.aimNumNow[index] = value;
ActorPropertyPacketUtil propertyBuilder = new ActorPropertyPacketUtil("guildleveWork/infoVariable", this, actorId);
propertyBuilder.AddProperty(String.Format("guildleveWork.aimNumNow[{0}]", index));
SendPacketsToPlayers(propertyBuilder.Done());
@@ -102,6 +167,7 @@ namespace FFXIVClassic_Map_Server.actors.director
public void UpdateUiState(int index, sbyte value)
{
+ guildleveWork.uiState[index] = value;
ActorPropertyPacketUtil propertyBuilder = new ActorPropertyPacketUtil("guildleveWork/infoVariable", this, actorId);
propertyBuilder.AddProperty(String.Format("guildleveWork.uiState[{0}]", index));
SendPacketsToPlayers(propertyBuilder.Done());
@@ -128,5 +194,30 @@ namespace FFXIVClassic_Map_Server.actors.director
}
}
+ public static uint GlBorderIconIDToAnimID(uint iconId)
+ {
+ return iconId - 20000;
+ }
+
+ public static uint GlPlateIconIDToAnimID(uint iconId)
+ {
+ return iconId - 20020;
+ }
+
+ public static uint GetGLStartAnimationFromSheet(uint border, uint plate, bool isBoost)
+ {
+ return GetGLStartAnimation(GlBorderIconIDToAnimID(border), GlPlateIconIDToAnimID(plate), isBoost);
+ }
+
+ public static uint GetGLStartAnimation(uint border, uint plate, bool isBoost)
+ {
+ uint borderBits = border;
+ uint plateBits = plate << 7;
+
+ uint boostBits = isBoost ? (uint)0x8000 : (uint) 0;
+
+ return 0x0B000000 | boostBits | plateBits | borderBits;
+ }
+
}
}
diff --git a/FFXIVClassic Map Server/actors/group/ContentGroup.cs b/FFXIVClassic Map Server/actors/group/ContentGroup.cs
index 2cabe0f9..5c866d87 100644
--- a/FFXIVClassic Map Server/actors/group/ContentGroup.cs
+++ b/FFXIVClassic Map Server/actors/group/ContentGroup.cs
@@ -25,7 +25,13 @@ namespace FFXIVClassic_Map_Server.actors.group
if (initialMembers != null)
{
for (int i = 0; i < initialMembers.Length; i++)
+ {
+ Session s = Server.GetServer().GetSession(initialMembers[i]);
+ if (s != null)
+ s.GetActor().SetCurrentContentGroup(this);
+
members.Add(initialMembers[i]);
+ }
}
this.director = director;
@@ -38,11 +44,10 @@ namespace FFXIVClassic_Map_Server.actors.group
return;
members.Add(actor.actorId);
- if (actor is Character)
- {
- ((Character)actor).SetCurrentContentGroup(this);
- SendCurrentContentSync(actor);
- }
+
+ if (actor is Character)
+ ((Character)actor).SetCurrentContentGroup(this);
+
SendGroupPacketsAll(members);
}
@@ -110,20 +115,6 @@ namespace FFXIVClassic_Map_Server.actors.group
}
- public void SendCurrentContentSync(Actor currentContentChanged)
- {
- foreach (uint memberId in members)
- {
- Session session = Server.GetServer().GetSession(memberId);
- if (session != null)
- {
- ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("charaWork/currentContentGroup", currentContentChanged, session.id);
- propPacketUtil.AddProperty("charaWork.currentContentGroup");
- session.GetActor().QueuePackets(propPacketUtil.Done());
- }
- }
- }
-
public override uint GetTypeId()
{
return Group.ContentGroup_SimpleContentGroup24B;
@@ -135,12 +126,19 @@ namespace FFXIVClassic_Map_Server.actors.group
SendGroupPacketsAll(members);
}
- public void DeleteAll()
+ public void DeleteGroup()
{
- SendDeletePackets(members);
+ SendDeletePackets();
+ for (int i = 0; i < members.Count; i++)
+ {
+ Session s = Server.GetServer().GetSession(members[i]);
+ if (s != null)
+ s.GetActor().SetCurrentContentGroup(null);
+ members.Remove(members[i]);
+ }
+ Server.GetWorldManager().DeleteContentGroup(groupIndex);
}
-
public void CheckDestroy()
{
bool foundSession = false;
@@ -155,7 +153,7 @@ namespace FFXIVClassic_Map_Server.actors.group
}
if (!foundSession)
- Server.GetWorldManager().DeleteContentGroup(groupIndex);
+ DeleteGroup();
}
}
diff --git a/FFXIVClassic Map Server/actors/group/GLContentGroup.cs b/FFXIVClassic Map Server/actors/group/GLContentGroup.cs
new file mode 100644
index 00000000..ada138f3
--- /dev/null
+++ b/FFXIVClassic Map Server/actors/group/GLContentGroup.cs
@@ -0,0 +1,29 @@
+using FFXIVClassic.Common;
+using FFXIVClassic_Map_Server.actors.director;
+using FFXIVClassic_Map_Server.actors.group.Work;
+using FFXIVClassic_Map_Server.Actors;
+using FFXIVClassic_Map_Server.dataobjects;
+using FFXIVClassic_Map_Server.packets.send.group;
+using FFXIVClassic_Map_Server.packets.send.groups;
+using FFXIVClassic_Map_Server.utils;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace FFXIVClassic_Map_Server.actors.group
+{
+ class GLContentGroup : ContentGroup
+ {
+ public GLContentGroup(ulong groupIndex, Director director, uint[] initialMembers)
+ : base(groupIndex, director, initialMembers)
+ {
+ }
+
+ public override uint GetTypeId()
+ {
+ return Group.ContentGroup_GuildleveGroup;
+ }
+ }
+}