From 45333097dfe69303588c604b5afc379701290bf5 Mon Sep 17 00:00:00 2001 From: hondacrx Date: Mon, 1 Jan 2018 12:18:52 -0500 Subject: [PATCH] Core/Quests: Implemented player choices --- Source/Framework/Constants/AccountConst.cs | 1 + .../Framework/Constants/Spells/SpellConst.cs | 2 +- Source/Game/Entities/Player/Player.cs | 34 ++ Source/Game/Globals/ObjectManager.cs | 369 ++++++++++++++---- Source/Game/Handlers/QuestHandler.cs | 6 + Source/Game/Network/Packets/QuestPackets.cs | 85 ++++ Source/Game/Scripting/CoreScripts.cs | 3 + Source/Game/Scripting/ScriptManager.cs | 4 + Source/Game/Server/WorldManager.cs | 6 + Source/Game/Spells/SpellEffects.cs | 12 + Source/Game/Text/CreatureTextManager.cs | 10 +- 11 files changed, 441 insertions(+), 91 deletions(-) diff --git a/Source/Framework/Constants/AccountConst.cs b/Source/Framework/Constants/AccountConst.cs index 0692b0cd6..80354f352 100644 --- a/Source/Framework/Constants/AccountConst.cs +++ b/Source/Framework/Constants/AccountConst.cs @@ -773,6 +773,7 @@ namespace Framework.Constants CommandListSpawnpoints = 866, // Reserved CommandReloadQuestGreetingLocale = 867, // Reserved CommandModifyPower = 868, + CommandDebugSendPlayerChoice = 869, // Custom Permissions 1000+ Max diff --git a/Source/Framework/Constants/Spells/SpellConst.cs b/Source/Framework/Constants/Spells/SpellConst.cs index 768b3cf51..8339607d9 100644 --- a/Source/Framework/Constants/Spells/SpellConst.cs +++ b/Source/Framework/Constants/Spells/SpellConst.cs @@ -1989,7 +1989,7 @@ namespace Framework.Constants Unk202 = 202, Unk203 = 203, ChangeBattlepetQuality = 204, - LaunchQuestTask = 205, + LaunchQuestChoice = 205, AlterItem = 206, Unk207 = 207, Unk208 = 208, diff --git a/Source/Game/Entities/Player/Player.cs b/Source/Game/Entities/Player/Player.cs index 7c54b3aae..52a65dd25 100644 --- a/Source/Game/Entities/Player/Player.cs +++ b/Source/Game/Entities/Player/Player.cs @@ -4994,6 +4994,40 @@ namespace Game.Entities SendMessageToSet(updateCollisionHeight, false); } + public void SendPlayerChoice(ObjectGuid sender, uint choiceID) + { + PlayerChoice playerChoice = Global.ObjectMgr.GetPlayerChoice((int)choiceID); + if (playerChoice == null) + return; + + PlayerChoice localizedPlayerChoice = playerChoice; + + LocaleConstant locale = GetSession().GetSessionDbLocaleIndex(); + if (locale != LocaleConstant.enUS) + { + PlayerChoiceLocale playerChoiceLocale = Global.ObjectMgr.GetPlayerChoiceLocale((uint)localizedPlayerChoice.ChoiceId); + if (playerChoiceLocale != null) + ObjectManager.GetLocaleString(playerChoiceLocale.Question, locale, ref localizedPlayerChoice.Question); + + foreach (var playerChoiceResponse in localizedPlayerChoice.Responses) + { + PlayerChoiceResponseLocale playerChoiceResponseLocale = Global.ObjectMgr.GetPlayerChoiceResponseLocale((uint)localizedPlayerChoice.ChoiceId, (uint)playerChoiceResponse.Value.ResponseID); + if (playerChoiceResponseLocale != null) + { + ObjectManager.GetLocaleString(playerChoiceResponseLocale.Header, locale, ref playerChoiceResponse.Value.Header); + ObjectManager.GetLocaleString(playerChoiceResponseLocale.Answer, locale, ref playerChoiceResponse.Value.Answer); + ObjectManager.GetLocaleString(playerChoiceResponseLocale.Description, locale, ref playerChoiceResponse.Value.Description); + ObjectManager.GetLocaleString(playerChoiceResponseLocale.Confirmation, locale, ref playerChoiceResponse.Value.Confirmation); + } + } + } + + DisplayPlayerChoice displayPlayerChoice = new DisplayPlayerChoice(); + displayPlayerChoice.Choice = localizedPlayerChoice; + displayPlayerChoice.SenderGUID = sender; + SendPacket(displayPlayerChoice); + } + public float GetCollisionHeight(bool mounted) { if (mounted) diff --git a/Source/Game/Globals/ObjectManager.cs b/Source/Game/Globals/ObjectManager.cs index 36b529375..b1a3ea791 100644 --- a/Source/Game/Globals/ObjectManager.cs +++ b/Source/Game/Globals/ObjectManager.cs @@ -32,6 +32,7 @@ using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Linq; using System.Runtime.InteropServices; +using Framework.Dynamic; namespace Game { @@ -587,6 +588,18 @@ namespace Game return (Expansion)_classExpansionRequirementStorage[(byte)class_]; return Expansion.Classic; } + public PlayerChoice GetPlayerChoice(int choiceId) + { + return _playerChoiceContainer.LookupByKey(choiceId); + } + public PlayerChoiceLocale GetPlayerChoiceLocale(uint ChoiceID) + { + return _playerChoiceLocaleContainer.LookupByKey(ChoiceID); + } + public PlayerChoiceResponseLocale GetPlayerChoiceResponseLocale(uint ChoiceID, uint ResponseID) + { + return _playerChoiceResponseLocaleContainer.LookupByKey(Tuple.Create(ChoiceID, ResponseID)); + } //Gossip public void LoadGossipMenu() @@ -7678,23 +7691,18 @@ namespace Game { uint id = result.Read(0); string localeName = result.Read(1); - string name = result.Read(2); - string nameAlt = result.Read(3); - string title = result.Read(4); - string titleAlt = result.Read(5); - - if (!_creatureLocaleStorage.ContainsKey(id)) - _creatureLocaleStorage[id] = new CreatureLocale(); - LocaleConstant locale = localeName.ToEnum(); if (locale == LocaleConstant.enUS) continue; + if (!_creatureLocaleStorage.ContainsKey(id)) + _creatureLocaleStorage[id] = new CreatureLocale(); + CreatureLocale data = _creatureLocaleStorage[id]; - AddLocaleString(name, locale, data.Name); - AddLocaleString(nameAlt, locale, data.NameAlt); - AddLocaleString(title, locale, data.Title); - AddLocaleString(titleAlt, locale, data.TitleAlt); + AddLocaleString(result.Read(2), locale, data.Name); + AddLocaleString(result.Read(3), locale, data.NameAlt); + AddLocaleString(result.Read(4), locale, data.Title); + AddLocaleString(result.Read(5), locale, data.TitleAlt); } while (result.NextRow()); } @@ -7713,22 +7721,17 @@ namespace Game { uint id = result.Read(0); string localeName = result.Read(1); - - string name = result.Read(2); - string castBarCaption = result.Read(3); - string unk1 = result.Read(4); + LocaleConstant locale = localeName.ToEnum(); + if (locale == LocaleConstant.enUS) + continue; if (!_gameObjectLocaleStorage.ContainsKey(id)) _gameObjectLocaleStorage[id] = new GameObjectLocale(); GameObjectLocale data = _gameObjectLocaleStorage[id]; - LocaleConstant locale = localeName.ToEnum(); - if (locale == LocaleConstant.enUS) - continue; - - AddLocaleString(name, locale, data.Name); - AddLocaleString(castBarCaption, locale, data.CastBarCaption); - AddLocaleString(unk1, locale, data.Unk1); + AddLocaleString(result.Read(2), locale, data.Name); + AddLocaleString(result.Read(3), locale, data.CastBarCaption); + AddLocaleString(result.Read(4), locale, data.Unk1); } while (result.NextRow()); @@ -7749,34 +7752,23 @@ namespace Game { uint id = result.Read(0); string localeName = result.Read(1); - - string logTitle = result.Read(2); - string logDescription = result.Read(3); - string questDescription = result.Read(4); - string areaDescription = result.Read(5); - string portraitGiverText = result.Read(6); - string portraitGiverName = result.Read(7); - string portraitTurnInText = result.Read(8); - string portraitTurnInName = result.Read(9); - string questCompletionLog = result.Read(10); + LocaleConstant locale = localeName.ToEnum(); + if (locale == LocaleConstant.enUS) + continue; if (!_questTemplateLocaleStorage.ContainsKey(id)) _questTemplateLocaleStorage[id] = new QuestTemplateLocale(); QuestTemplateLocale data = _questTemplateLocaleStorage[id]; - LocaleConstant locale = localeName.ToEnum(); - if (locale == LocaleConstant.enUS) - continue; - - AddLocaleString(logTitle, locale, data.LogTitle); - AddLocaleString(logDescription, locale, data.LogDescription); - AddLocaleString(questDescription, locale, data.QuestDescription); - AddLocaleString(areaDescription, locale, data.AreaDescription); - AddLocaleString(portraitGiverText, locale, data.PortraitGiverText); - AddLocaleString(portraitGiverName, locale, data.PortraitGiverName); - AddLocaleString(portraitTurnInText, locale, data.PortraitTurnInText); - AddLocaleString(portraitTurnInName, locale, data.PortraitTurnInName); - AddLocaleString(questCompletionLog, locale, data.QuestCompletionLog); + AddLocaleString(result.Read(2), locale, data.LogTitle); + AddLocaleString(result.Read(3), locale, data.LogDescription); + AddLocaleString(result.Read(4), locale, data.QuestDescription); + AddLocaleString(result.Read(5), locale, data.AreaDescription); + AddLocaleString(result.Read(6), locale, data.PortraitGiverText); + AddLocaleString(result.Read(7), locale, data.PortraitGiverName); + AddLocaleString(result.Read(8), locale, data.PortraitTurnInText); + AddLocaleString(result.Read(9), locale, data.PortraitTurnInName); + AddLocaleString(result.Read(10), locale, data.QuestCompletionLog); } while (result.NextRow()); Log.outInfo(LogFilter.ServerLoading, "Loaded {0} Quest Tempalate locale strings in {1} ms", _questTemplateLocaleStorage.Count, Time.GetMSTimeDiffToNow(oldMSTime)); @@ -7795,18 +7787,15 @@ namespace Game { uint id = result.Read(0); string localeName = result.Read(1); - - string Description = result.Read(2); + LocaleConstant locale = localeName.ToEnum(); + if (locale == LocaleConstant.enUS) + continue; if (!_questObjectivesLocaleStorage.ContainsKey(id)) _questObjectivesLocaleStorage[id] = new QuestObjectivesLocale(); QuestObjectivesLocale data = _questObjectivesLocaleStorage[id]; - LocaleConstant locale = localeName.ToEnum(); - if (locale == LocaleConstant.enUS) - continue; - - AddLocaleString(Description, locale, data.Description); + AddLocaleString(result.Read(2), locale, data.Description); } while (result.NextRow()); @@ -7826,18 +7815,15 @@ namespace Game { uint id = result.Read(0); string localeName = result.Read(1); - - string RewardText = result.Read(2); + LocaleConstant locale = localeName.ToEnum(); + if (locale == LocaleConstant.enUS) + continue; if (!_questOfferRewardLocaleStorage.ContainsKey(id)) _questOfferRewardLocaleStorage[id] = new QuestOfferRewardLocale(); QuestOfferRewardLocale data = _questOfferRewardLocaleStorage[id]; - LocaleConstant locale = localeName.ToEnum(); - if (locale == LocaleConstant.enUS) - continue; - - AddLocaleString(RewardText, locale, data.RewardText); + AddLocaleString(result.Read(2), locale, data.RewardText); } while (result.NextRow()); Log.outInfo(LogFilter.ServerLoading, "Loaded {0} Quest Offer Reward locale strings in {1} ms", _questOfferRewardLocaleStorage.Count, Time.GetMSTimeDiffToNow(oldMSTime)); @@ -7856,17 +7842,15 @@ namespace Game { uint id = result.Read(0); string localeName = result.Read(1); - string completionText = result.Read(2); + LocaleConstant locale = localeName.ToEnum(); + if (locale == LocaleConstant.enUS) + continue; if (!_questRequestItemsLocaleStorage.ContainsKey(id)) _questRequestItemsLocaleStorage[id] = new QuestRequestItemsLocale(); QuestRequestItemsLocale data = _questRequestItemsLocaleStorage[id]; - LocaleConstant locale = localeName.ToEnum(); - if (locale == LocaleConstant.enUS) - continue; - - AddLocaleString(completionText, locale, data.CompletionText); + AddLocaleString(result.Read(2), locale, data.CompletionText); } while (result.NextRow()); Log.outInfo(LogFilter.ServerLoading, "Loaded {0} Quest Request Items locale strings in {1} ms", _questRequestItemsLocaleStorage.Count, Time.GetMSTimeDiffToNow(oldMSTime)); @@ -7887,16 +7871,14 @@ namespace Game ushort menuId = result.Read(0); ushort optionId = result.Read(1); string localeName = result.Read(2); - string optionText = result.Read(3); - string boxText = result.Read(4); - GossipMenuItemsLocale data = new GossipMenuItemsLocale(); LocaleConstant locale = localeName.ToEnum(); if (locale == LocaleConstant.enUS) continue; - AddLocaleString(optionText, locale, data.OptionText); - AddLocaleString(boxText, locale, data.BoxText); + GossipMenuItemsLocale data = new GossipMenuItemsLocale(); + AddLocaleString(result.Read(3), locale, data.OptionText); + AddLocaleString(result.Read(4), locale, data.BoxText); _gossipMenuItemsLocaleStorage[MathFunctions.MakePair32(menuId, optionId)] = data; } @@ -7919,17 +7901,15 @@ namespace Game { uint id = result.Read(0); string localeName = result.Read(1); - string text = result.Read(2); + LocaleConstant locale = localeName.ToEnum(); + if (locale == LocaleConstant.enUS) + continue; if (!_pageTextLocaleStorage.ContainsKey(id)) _pageTextLocaleStorage[id] = new PageTextLocale(); PageTextLocale data = _pageTextLocaleStorage[id]; - LocaleConstant locale = localeName.ToEnum(); - if (locale == LocaleConstant.enUS) - continue; - - AddLocaleString(text, locale, data.Text); + AddLocaleString(result.Read(2), locale, data.Text); } while (result.NextRow()); Log.outInfo(LogFilter.ServerLoading, "Loaded {0} PageText locale strings in {1} ms", _pageTextLocaleStorage.Count, Time.GetMSTimeDiffToNow(oldMSTime)); @@ -7949,18 +7929,15 @@ namespace Game { uint id = result.Read(0); string localeName = result.Read(1); - string name = result.Read(2); + LocaleConstant locale = localeName.ToEnum(); + if (locale == LocaleConstant.enUS) + continue; if (!_pointOfInterestLocaleStorage.ContainsKey(id)) _pointOfInterestLocaleStorage[id] = new PointOfInterestLocale(); PointOfInterestLocale data = _pointOfInterestLocaleStorage[id]; - - LocaleConstant locale = localeName.ToEnum(); - if (locale == LocaleConstant.enUS) - continue; - - AddLocaleString(name, locale, data.Name); + AddLocaleString(result.Read(2), locale, data.Name); } while (result.NextRow()); } @@ -8666,6 +8643,177 @@ namespace Game Log.outInfo(LogFilter.ServerLoading, "Loaded {0} scene templates in {1} ms.", count, Time.GetMSTimeDiffToNow(oldMSTime)); } + public void LoadPlayerChoices() + { + uint oldMSTime = Time.GetMSTime(); + _playerChoiceContainer.Clear(); + + SQLResult choiceResult = DB.World.Query("SELECT ChoiceID, Question FROM playerchoice"); + if (choiceResult.IsEmpty()) + { + Log.outInfo(LogFilter.ServerLoading, "Loaded 0 player choices. DB table `playerchoice` is empty."); + return; + } + + uint responseCount = 0; + uint rewardCount = 0; + + do + { + int choiceId = choiceResult.Read(0); + + PlayerChoice choice = new PlayerChoice(); + choice.ChoiceId = choiceId; + choice.Question = choiceResult.Read(1); + _playerChoiceContainer[choiceId] = choice; + + } while (choiceResult.NextRow()); + + Log.outInfo(LogFilter.ServerLoading, $"Loaded {_playerChoiceContainer.Count} player choices in {Time.GetMSTimeDiffToNow(oldMSTime)} ms."); + + SQLResult responses = DB.World.Query("SELECT ChoiceID, ResponseID, ChoiceArtFileID, Header, Answer, Description, Confirmation FROM playerchoice_response"); + if (!responses.IsEmpty()) + { + do + { + ++responseCount; + + int choiceId = responses.Read(0); + int ResponseID = responses.Read(1); + + if (!_playerChoiceContainer.ContainsKey(choiceId)) + { + Log.outError(LogFilter.Sql, "Table `playerchoice_response` has nonexistent choiceId: {choiceId} (ResponseID : {ResponseID}), skipped"); + continue; + } + + PlayerChoice choice = _playerChoiceContainer[choiceId]; + PlayerChoiceResponse response = new PlayerChoiceResponse(); + + response.ResponseID = ResponseID; + response.ChoiceArtFileID = responses.Read(2); + response.Header = responses.Read(3); + response.Answer = responses.Read(4); + response.Description = responses.Read(5); + response.Confirmation = responses.Read(6); + + choice.Responses[ResponseID] = response; + } while (responses.NextRow()); + + Log.outInfo(LogFilter.ServerLoading, $"Loaded {responseCount} player choices response in {Time.GetMSTimeDiffToNow(oldMSTime)} ms."); + } + else + { + Log.outInfo(LogFilter.ServerLoading, "Loaded 0 player choices responses. DB table `playerchoice_response` is empty."); + } + + SQLResult rewards = DB.World.Query("SELECT ChoiceID, ResponseID, TitleID, PackageID, SkillLineID, SkillPointCount, ArenaPointCount, HonorPointCount, Money, Xp FROM playerchoice_response_reward"); + if (!rewards.IsEmpty()) + { + do + { + ++rewardCount; + + int choiceId = rewards.Read(0); + int ResponseID = rewards.Read(1); + + if (!_playerChoiceContainer.ContainsKey(choiceId)) + { + Log.outError(LogFilter.Sql, "Table `playerchoice_response_reward` has nonexistent choiceId: {choiceId} (ResponseID : {ResponseID}), skipped"); + continue; + } + + PlayerChoice choice = _playerChoiceContainer[choiceId]; + + if (!choice.Responses.ContainsKey(ResponseID)) + { + Log.outError(LogFilter.Sql, $"Table `playerchoice_response_reward` has nonexistent ResponseID: {ResponseID} for choiceId {choiceId}, skipped"); + continue; + } + + PlayerChoiceResponse response = choice.Responses[ResponseID]; + + PlayerChoiceResponseReward reward = new PlayerChoiceResponseReward(); + + reward.TitleID = rewards.Read(2); + reward.PackageID = rewards.Read(3); + reward.SkillLineID = rewards.Read(4); + reward.SkillPointCount = rewards.Read(5); + reward.ArenaPointCount = rewards.Read(6); + reward.HonorPointCount = rewards.Read(7); + reward.Money = rewards.Read(8); + reward.Xp = rewards.Read(9); + + response.Reward.Set(reward); + + } while (rewards.NextRow()); + + Log.outInfo(LogFilter.ServerLoading, $"Loaded {rewardCount} player choices reward in {Time.GetMSTimeDiffToNow(oldMSTime)} ms."); + } + else + { + Log.outInfo(LogFilter.ServerLoading, "Loaded 0 player choices responses reward. DB table `playerchoice_response_reward` is empty."); + } + } + public void LoadPlayerChoicesLocale() + { + uint oldMSTime = Time.GetMSTime(); + + // need for reload case + _playerChoiceLocaleContainer.Clear(); + _playerChoiceResponseLocaleContainer.Clear(); + + // 0 1 2 + SQLResult result = DB.World.Query("SELECT ChoiceID, locale, Question FROM playerchoice_locale"); + if (!result.IsEmpty()) + { + do + { + uint ChoiceID = result.Read(0); + string localeName = result.Read(1); + LocaleConstant locale = localeName.ToEnum(); + if (locale == LocaleConstant.enUS) + continue; + + if (!_playerChoiceLocaleContainer.ContainsKey(ChoiceID)) + _playerChoiceLocaleContainer[ChoiceID] = new PlayerChoiceLocale(); + + PlayerChoiceLocale data = _playerChoiceLocaleContainer[ChoiceID]; + AddLocaleString(result.Read(2), locale, data.Question); + } while (result.NextRow()); + + Log.outInfo(LogFilter.ServerLoading, $"Loaded {_playerChoiceLocaleContainer.Count} Player Choice locale strings in {Time.GetMSTimeDiffToNow(oldMSTime)} ms"); + } + + oldMSTime = Time.GetMSTime(); + + // 0 1 2 3 4 5 6 + result = DB.World.Query("SELECT ChoiceID, ResponseID, locale, Header, Answer, Description, Confirmation FROM playerchoice_response_locale"); + if (!result.IsEmpty()) + { + do + { + uint ChoiceID = result.Read(0); + uint ResponseID = result.Read(1); + string localeName = result.Read(2); + LocaleConstant locale = localeName.ToEnum(); + if (locale == LocaleConstant.enUS) + continue; + + Tuple pair = Tuple.Create(ChoiceID, ResponseID); + if (_playerChoiceResponseLocaleContainer.ContainsKey(pair)) + _playerChoiceResponseLocaleContainer[pair] = new PlayerChoiceResponseLocale(); + + PlayerChoiceResponseLocale data = _playerChoiceResponseLocaleContainer[pair]; + AddLocaleString(result.Read(3), locale, data.Header); + AddLocaleString(result.Read(4), locale, data.Answer); + AddLocaleString(result.Read(5), locale, data.Description); + AddLocaleString(result.Read(6), locale, data.Confirmation); + } while (result.NextRow()); + + Log.outInfo(LogFilter.ServerLoading, $"Loaded {_playerChoiceResponseLocaleContainer} Player Choice Response locale strings in {Time.GetMSTimeDiffToNow(oldMSTime)} ms"); + } + } public MailLevelReward GetMailLevelReward(uint level, uint raceMask) { @@ -9169,6 +9317,7 @@ namespace Game Dictionary _repSpilloverTemplateStorage = new Dictionary(); MultiMap _mailLevelRewardStorage = new MultiMap(); MultiMap, TempSummonData> _tempSummonDataStorage = new MultiMap, TempSummonData>(); + Dictionary _playerChoiceContainer; Dictionary _pageTextStorage = new Dictionary(); List _reservedNamesStorage = new List(); Dictionary _sceneTemplateStorage = new Dictionary(); @@ -9278,6 +9427,8 @@ namespace Game Dictionary _gossipMenuItemsLocaleStorage = new Dictionary(); Dictionary _pageTextLocaleStorage = new Dictionary(); Dictionary _pointOfInterestLocaleStorage = new Dictionary(); + Dictionary _playerChoiceLocaleContainer = new Dictionary(); + Dictionary, PlayerChoiceResponseLocale> _playerChoiceResponseLocaleContainer = new Dictionary, PlayerChoiceResponseLocale>(); List _tavernAreaTriggerStorage = new List(); Dictionary _areaTriggerStorage = new Dictionary(); @@ -10054,4 +10205,54 @@ namespace Game public StringArray OptionText = new StringArray((int)LocaleConstant.Total); public StringArray BoxText = new StringArray((int)LocaleConstant.Total); } + + public class PlayerChoiceLocale + { + public StringArray Question = new StringArray((int)LocaleConstant.Total); + } + + public class PlayerChoiceResponseLocale + { + public StringArray Header = new StringArray((int)LocaleConstant.Total); + public StringArray Answer = new StringArray((int)LocaleConstant.Total); + public StringArray Description = new StringArray((int)LocaleConstant.Total); + public StringArray Confirmation = new StringArray((int)LocaleConstant.Total); + } + + public class PlayerChoiceResponseReward + { + public int TitleID; + public int PackageID; + public int SkillLineID; + public uint SkillPointCount; + public uint ArenaPointCount; + public uint HonorPointCount; + public ulong Money; + public uint Xp; + + //std::vector Items; + //std::vector Currency; + //std::vector Faction; + //std::vector ItemChoice; + } + + public class PlayerChoiceResponse + { + public int ResponseID; + public int ChoiceArtFileID; + + public string Header; + public string Answer; + public string Description; + public string Confirmation; + + public Optional Reward; + } + + public class PlayerChoice + { + public int ChoiceId; + public string Question; + public Dictionary Responses = new Dictionary(); + } } diff --git a/Source/Game/Handlers/QuestHandler.cs b/Source/Game/Handlers/QuestHandler.cs index 8087d9c1b..5f3dff43d 100644 --- a/Source/Game/Handlers/QuestHandler.cs +++ b/Source/Game/Handlers/QuestHandler.cs @@ -648,5 +648,11 @@ namespace Game SendPacket(response); } + + [WorldPacketHandler(ClientOpcodes.ChoiceResponse)] + void HandlePlayerChoiceResponse(PlayerChoiceResponsePkt packet) + { + Global.ScriptMgr.OnPlayerChoiceResponse(GetPlayer(), (uint)packet.ChoiceID, (uint)packet.ResponseID); + } } } diff --git a/Source/Game/Network/Packets/QuestPackets.cs b/Source/Game/Network/Packets/QuestPackets.cs index 82e047309..8a78abc09 100644 --- a/Source/Game/Network/Packets/QuestPackets.cs +++ b/Source/Game/Network/Packets/QuestPackets.cs @@ -816,6 +816,91 @@ namespace Game.Network.Packets List WorldQuestUpdates = new List(); } + class DisplayPlayerChoice : ServerPacket + { + public DisplayPlayerChoice() : base(ServerOpcodes.DisplayPlayerChoice) { } + + public override void Write() + { + _worldPacket.WriteInt32(Choice.ChoiceId); + _worldPacket.WriteUInt32(Choice.Responses.Count); + _worldPacket.WritePackedGuid(SenderGUID); + _worldPacket.WriteBits(Choice.Question.Length, 8); + _worldPacket.WriteBit(CloseChoiceFrame); + _worldPacket.FlushBits(); + + foreach (var response in Choice.Responses.Values) + { + _worldPacket.WriteInt32(response.ResponseID); + _worldPacket.WriteInt32(response.ChoiceArtFileID); + + _worldPacket.WriteBits(response.Answer.Length, 9); + _worldPacket.WriteBits(response.Header.Length, 9); + _worldPacket.WriteBits(response.Description.Length, 11); + _worldPacket.WriteBits(response.Confirmation.Length, 7); + + _worldPacket.WriteBit(response.Reward.HasValue); + _worldPacket.FlushBits(); + + if (response.Reward.HasValue) + { + var reward = response.Reward.Value; + + _worldPacket.WriteInt32(reward.TitleID); + _worldPacket.WriteInt32(reward.PackageID); + _worldPacket.WriteInt32(reward.SkillLineID); + _worldPacket.WriteUInt32(reward.SkillPointCount); + _worldPacket.WriteUInt32(reward.ArenaPointCount); + _worldPacket.WriteUInt32(reward.HonorPointCount); + _worldPacket.WriteUInt64(reward.Money); + _worldPacket.WriteUInt32(reward.Xp); + + _worldPacket.WriteUInt32(0); // itemCount + _worldPacket.WriteUInt32(0); // currencyCount + _worldPacket.WriteUInt32(0); // factionCount + _worldPacket.WriteUInt32(0); // itemChoiceCount + + /*for (var i = 0u; i < itemCount; ++i) + ReadPlayerChoiceResponseRewardEntry(packet, "Item", i); + + for (var i = 0u; i < currencyCount; ++i) + ReadPlayerChoiceResponseRewardEntry(packet, "Currency", i); + + for (var i = 0u; i < factionCount; ++i) + ReadPlayerChoiceResponseRewardEntry(packet, "Faction", i); + + for (var i = 0u; i < itemChoiceCount; ++i) + ReadPlayerChoiceResponseRewardEntry(packet, "ItemChoice", i);*/ + } + + _worldPacket.WriteString(response.Answer); + _worldPacket.WriteString(response.Header); + _worldPacket.WriteString(response.Description); + _worldPacket.WriteString(response.Confirmation); + } + + _worldPacket.WriteString(Choice.Question); + } + + public ObjectGuid SenderGUID; + public PlayerChoice Choice; + public bool CloseChoiceFrame; + } + + class PlayerChoiceResponsePkt : ClientPacket + { + public PlayerChoiceResponsePkt(WorldPacket packet) : base(packet) { } + + public override void Read() + { + ChoiceID = _worldPacket.ReadInt32(); + ResponseID = _worldPacket.ReadInt32(); + } + + public int ChoiceID; + public int ResponseID; + } + //Structs public class QuestGiverInfo { diff --git a/Source/Game/Scripting/CoreScripts.cs b/Source/Game/Scripting/CoreScripts.cs index 0627a41db..5d3ff585f 100644 --- a/Source/Game/Scripting/CoreScripts.cs +++ b/Source/Game/Scripting/CoreScripts.cs @@ -655,6 +655,9 @@ namespace Game.Scripting // Called when a player completes a movie public virtual void OnMovieComplete(Player player, uint movieId) { } + + // Called when a player choose a response from a PlayerChoice + public virtual void OnPlayerChoiceResponse(Player player, uint choiceID, uint responseID) { } } public class GuildScript : ScriptObject diff --git a/Source/Game/Scripting/ScriptManager.cs b/Source/Game/Scripting/ScriptManager.cs index eea1fb908..e01262d04 100644 --- a/Source/Game/Scripting/ScriptManager.cs +++ b/Source/Game/Scripting/ScriptManager.cs @@ -1175,6 +1175,10 @@ namespace Game.Scripting { ForEach(p => p.OnMovieComplete(player, movieId)); } + public void OnPlayerChoiceResponse(Player player, uint choiceID, uint responseID) + { + ForEach(p => p.OnPlayerChoiceResponse(player, choiceID, responseID)); + } // GuildScript public void OnGuildAddMember(Guild guild, Player player, byte plRank) diff --git a/Source/Game/Server/WorldManager.cs b/Source/Game/Server/WorldManager.cs index c63acd85a..4c35b1ffd 100644 --- a/Source/Game/Server/WorldManager.cs +++ b/Source/Game/Server/WorldManager.cs @@ -625,6 +625,12 @@ namespace Game Log.outInfo(LogFilter.ServerLoading, "Loading Scenes Templates..."); Global.ObjectMgr.LoadSceneTemplates(); + Log.outInfo(LogFilter.ServerLoading, "Loading Player Choices..."); + Global.ObjectMgr.LoadPlayerChoices(); + + Log.outInfo(LogFilter.ServerLoading, "Loading Player Choices Locales..."); + Global.ObjectMgr.LoadPlayerChoicesLocale(); + CharacterDatabaseCleaner.CleanDatabase(); Log.outInfo(LogFilter.ServerLoading, "Loading the max pet number..."); diff --git a/Source/Game/Spells/SpellEffects.cs b/Source/Game/Spells/SpellEffects.cs index 303b7b6cd..c59461bfd 100644 --- a/Source/Game/Spells/SpellEffects.cs +++ b/Source/Game/Spells/SpellEffects.cs @@ -5593,6 +5593,18 @@ namespace Game.Spells plr.GetSession().GetBattlePetMgr().UnlockSlot(0); } + [SpellEffectHandler(SpellEffectName.LaunchQuestChoice)] + void EffectLaunchQuestChoice(uint effIndex) + { + if (effectHandleMode != SpellEffectHandleMode.HitTarget) + return; + + if (!unitTarget || !unitTarget.IsPlayer()) + return; + + unitTarget.ToPlayer().SendPlayerChoice(GetCaster().GetGUID(), (uint)GetEffect(effIndex).MiscValue); + } + [SpellEffectHandler(SpellEffectName.UncageBattlepet)] void EffectUncageBattlePet(uint effIndex) { diff --git a/Source/Game/Text/CreatureTextManager.cs b/Source/Game/Text/CreatureTextManager.cs index 5577d3a15..19bc1d8ef 100644 --- a/Source/Game/Text/CreatureTextManager.cs +++ b/Source/Game/Text/CreatureTextManager.cs @@ -142,18 +142,16 @@ namespace Game uint groupId = result.Read(1); uint id = result.Read(2); string localeName = result.Read(3); - string text = result.Read(4); + LocaleConstant locale = localeName.ToEnum(); + if (locale == LocaleConstant.enUS) + continue; var key = new CreatureTextId(creatureId, groupId, id); if (!mLocaleTextMap.ContainsKey(key)) mLocaleTextMap[key] = new CreatureTextLocale(); - LocaleConstant locale = localeName.ToEnum(); - if (locale == LocaleConstant.enUS) - continue; - CreatureTextLocale data = mLocaleTextMap[key]; - ObjectManager.AddLocaleString(text, locale, data.Text); + ObjectManager.AddLocaleString(result.Read(4), locale, data.Text); } while (result.NextRow());