From 875b76634a15c0903049eba20b0cb8ced988dbb3 Mon Sep 17 00:00:00 2001 From: Filip Maj Date: Sun, 25 Jun 2017 14:25:54 -0400 Subject: [PATCH] Implemented more of the Guildleve Director. Correct script is now autoloaded based on leveplate. Players are now added to the contentgroup on leve start. Moved animation and stuff to C# side of things. Cleaned up code. --- .../FFXIVClassic Map Server.csproj | 1 + FFXIVClassic Map Server/WorldManager.cs | 64 +++++++++++-- FFXIVClassic Map Server/actors/area/Area.cs | 50 +++++++++- .../actors/chara/Character.cs | 12 +-- .../actors/chara/player/Player.cs | 18 +++- .../actors/director/Director.cs | 34 +++++-- .../actors/director/GuildleveDirector.cs | 95 ++++++++++++++++++- .../actors/group/ContentGroup.cs | 44 ++++----- .../actors/group/GLContentGroup.cs | 29 ++++++ 9 files changed, 292 insertions(+), 55 deletions(-) create mode 100644 FFXIVClassic Map Server/actors/group/GLContentGroup.cs 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; + } + } +}