diff --git a/FFXIVClassic Map Server/Database.cs b/FFXIVClassic Map Server/Database.cs index c4858f73..33091cb6 100644 --- a/FFXIVClassic Map Server/Database.cs +++ b/FFXIVClassic Map Server/Database.cs @@ -391,6 +391,79 @@ namespace FFXIVClassic_Map_Server } } + public static void SaveGuildleve(Player player, uint glId, int slot) + { + string query; + MySqlCommand cmd; + + using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD))) + { + try + { + conn.Open(); + + query = @" + INSERT INTO characters_quest_guildleve_regional + (characterId, slot, guildleveId, abandoned, completed) + VALUES + (@charaId, @slot, @guildleveId, @abandoned, @completed) + ON DUPLICATE KEY UPDATE + guildleveId = @guildleveId, abandoned = @abandoned, completed = @completed + "; + + cmd = new MySqlCommand(query, conn); + cmd.Parameters.AddWithValue("@charaId", player.actorId); + cmd.Parameters.AddWithValue("@slot", slot); + cmd.Parameters.AddWithValue("@guildleveId", glId); + cmd.Parameters.AddWithValue("@abandoned", 0); + cmd.Parameters.AddWithValue("@completed", 0); + + cmd.ExecuteNonQuery(); + } + catch (MySqlException e) + { + Program.Log.Error(e.ToString()); + } + finally + { + conn.Dispose(); + } + } + } + + public static void RemoveGuildleve(Player player, uint glId) + { + string query; + MySqlCommand cmd; + + using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD))) + { + try + { + conn.Open(); + + query = @" + DELETE FROM characters_quest_guildleve_regional + WHERE characterId = @charaId and guildleveId = @guildleveId + "; + + cmd = new MySqlCommand(query, conn); + cmd.Parameters.AddWithValue("@charaId", player.actorId); + cmd.Parameters.AddWithValue("@guildleveId", glId); + + cmd.ExecuteNonQuery(); + } + catch (MySqlException e) + { + Program.Log.Error(e.ToString()); + } + finally + { + conn.Dispose(); + } + } + } + public static void RemoveQuest(Player player, uint questId) { string query; diff --git a/FFXIVClassic Map Server/actors/chara/player/Player.cs b/FFXIVClassic Map Server/actors/chara/player/Player.cs index c6ebafd6..3e700d63 100644 --- a/FFXIVClassic Map Server/actors/chara/player/Player.cs +++ b/FFXIVClassic Map Server/actors/chara/player/Player.cs @@ -126,7 +126,7 @@ namespace FFXIVClassic_Map_Server.Actors //Quest Actors (MUST MATCH playerWork.questScenario/questGuildleve) public Quest[] questScenario = new Quest[16]; - public Quest[] questGuildleve = new Quest[8]; + public uint[] questGuildleve = new uint[8]; //Aetheryte public uint homepoint = 0; @@ -1090,6 +1090,17 @@ namespace FFXIVClassic_Map_Server.Actors return -1; } + public int GetFreeGuildleveSlot() + { + for (int i = 0; i < questGuildleve.Length; i++) + { + if (questGuildleve[i] == 0) + return i; + } + + return -1; + } + //For Lua calls, cause MoonSharp goes retard with uint public void AddQuest(int id, bool isSilent = false) { @@ -1117,6 +1128,37 @@ namespace FFXIVClassic_Map_Server.Actors } //For Lua calls, cause MoonSharp goes retard with uint + public void AddGuildleve(uint id) + { + int freeSlot = GetFreeGuildleveSlot(); + + if (freeSlot == -1) + return; + + playerWork.questScenario[freeSlot] = id; + questGuildleve[freeSlot] = id; + Database.SaveGuildleve(this, id, freeSlot); + SendGuildleveClientUpdate(freeSlot); + } + + public void RemoveGuildleve(uint id) + { + if (HasGuildleve(id)) + { + for (int i = 0; i < questGuildleve.Length; i++) + { + if (questGuildleve[i] != null && questGuildleve[i] == id) + { + Database.RemoveGuildleve(this, id); + questGuildleve[i] = 0; + playerWork.questGuildleve[i] = 0; + SendGuildleveClientUpdate(i); + break; + } + } + } + } + public void AddQuest(uint id, bool isSilent = false) { Actor actor = Server.GetStaticActors((0xA0F00000 | id)); @@ -1290,6 +1332,17 @@ namespace FFXIVClassic_Map_Server.Actors return false; } + public bool HasGuildleve(uint id) + { + for (int i = 0; i < questGuildleve.Length; i++) + { + if (questGuildleve[i] != null && questGuildleve[i] == id) + return true; + } + + return false; + } + public int GetQuestSlot(uint id) { for (int i = 0; i < questScenario.Length; i++) @@ -1349,19 +1402,32 @@ namespace FFXIVClassic_Map_Server.Actors QueuePackets(propPacketUtil.Done()); } + private void SendGuildleveClientUpdate(int slot) + { + ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("playerWork/journal", this, actorId); + propPacketUtil.AddProperty(String.Format("playerWork.questGuildleve[{0}]", slot)); + QueuePackets(propPacketUtil.Done()); + } + public void SetLoginDirector(Director director) { if (ownedDirectors.Contains(director)) loginInitDirector = director; } - public void AddDirector(Director director) + public void AddDirector(Director director, bool spawnImmediatly = false) { if (!ownedDirectors.Contains(director)) { ownedDirectors.Add(director); director.AddChild(this); - //QueuePacket(director.GetSetEventStatusPackets(actorId)); + + if (spawnImmediatly) + { + director.GetSpawnPackets(actorId).DebugPrintPacket(); + QueuePacket(director.GetSpawnPackets(actorId)); + QueuePacket(director.GetInitPackets(actorId)); + } } } diff --git a/FFXIVClassic Map Server/actors/director/Director.cs b/FFXIVClassic Map Server/actors/director/Director.cs index 0d26358b..6db051b4 100644 --- a/FFXIVClassic Map Server/actors/director/Director.cs +++ b/FFXIVClassic Map Server/actors/director/Director.cs @@ -30,7 +30,8 @@ namespace FFXIVClassic_Map_Server.actors.director eventConditions = new EventList(); eventConditions.noticeEventConditions = new List(); eventConditions.noticeEventConditions.Add(new EventList.NoticeEventCondition("noticeEvent", 0xE,0x0)); - eventConditions.noticeEventConditions.Add(new EventList.NoticeEventCondition("noticeRequest",0x0,0x1)); + eventConditions.noticeEventConditions.Add(new EventList.NoticeEventCondition("noticeRequest", 0x0, 0x1)); + eventConditions.noticeEventConditions.Add(new EventList.NoticeEventCondition("reqForChild", 0x0, 0x1)); } public override SubPacket CreateScriptBindPacket(uint playerActorId) @@ -42,7 +43,10 @@ namespace FFXIVClassic_Map_Server.actors.director actualLParams.Insert(3, new LuaParam(4, 4)); actualLParams.Insert(4, new LuaParam(4, 4)); actualLParams.Insert(5, new LuaParam(4, 4)); - actualLParams.Insert(6, new LuaParam(0, (int)0x13883)); + + List lparams = LuaEngine.GetInstance().CallLuaFunctionForReturn(null, this, "init", false); + for (int i = 1; i < lparams.Count; i++) + actualLParams.Add(lparams[i]); return ActorInstantiatePacket.BuildPacket(actorId, playerActorId, actorName, className, actualLParams); } @@ -82,7 +86,7 @@ namespace FFXIVClassic_Map_Server.actors.director { List lparams = LuaEngine.GetInstance().CallLuaFunctionForReturn(null, this, "init", false); - if (lparams.Count == 1 && lparams[0].value is string) + if (lparams.Count >= 1 && lparams[0].value is string) { classPath = (string)lparams[0].value; className = classPath.Substring(classPath.LastIndexOf("/") + 1);