Core/Garrisons: Implement SMSG_GARRISON_OPEN_TALENT_NPC opcode
Port From (https://github.com/TrinityCore/TrinityCore/commit/4772c4817f1b34553f1c697e2aedc0372af9aea2)
This commit is contained in:
@@ -78,7 +78,7 @@ namespace Framework.Constants
|
|||||||
GarrisonTradeskill = 29, /*NYI*/ // White chat bubble
|
GarrisonTradeskill = 29, /*NYI*/ // White chat bubble
|
||||||
GarrisonRecruitment = 30, /*NYI*/ // White chat bubble
|
GarrisonRecruitment = 30, /*NYI*/ // White chat bubble
|
||||||
AdventureMap = 31, /*NYI*/ // White chat bubble
|
AdventureMap = 31, /*NYI*/ // White chat bubble
|
||||||
GarrisonTalent = 32, /*NYI*/ // White chat bubble
|
GarrisonTalent = 32, // White chat bubble
|
||||||
ContributionCollector = 33, /*NYI*/ // White chat bubble
|
ContributionCollector = 33, /*NYI*/ // White chat bubble
|
||||||
Transmogrify = 34, // Purple helm
|
Transmogrify = 34, // Purple helm
|
||||||
AzeriteRespec = 35, /*NYI*/ // White chat bubble
|
AzeriteRespec = 35, /*NYI*/ // White chat bubble
|
||||||
|
|||||||
@@ -497,6 +497,11 @@ namespace Framework.Database
|
|||||||
PrepareStatement(HotfixStatements.SEL_GARR_SITE_LEVEL_PLOT_INST, "SELECT ID, UiMarkerPosX, UiMarkerPosY, GarrSiteLevelID, GarrPlotInstanceID, UiMarkerSize" +
|
PrepareStatement(HotfixStatements.SEL_GARR_SITE_LEVEL_PLOT_INST, "SELECT ID, UiMarkerPosX, UiMarkerPosY, GarrSiteLevelID, GarrPlotInstanceID, UiMarkerSize" +
|
||||||
" FROM garr_site_level_plot_inst");
|
" FROM garr_site_level_plot_inst");
|
||||||
|
|
||||||
|
// GarrTalentTree.db2
|
||||||
|
PrepareStatement(HotfixStatements.SEL_GARR_TALENT_TREE, "SELECT ID, Name, GarrTypeID, ClassID, MaxTiers, UiOrder, Flags, UiTextureKitID, " +
|
||||||
|
"GarrTalentTreeType, PlayerConditionID, FeatureTypeIndex, FeatureSubtypeIndex, CurrencyID FROM garr_talent_tree");
|
||||||
|
PrepareStatement(HotfixStatements.SEL_GARR_TALENT_TREE_LOCALE, "SELECT ID, Name_lang FROM garr_talent_tree_locale WHERE locale = ?");
|
||||||
|
|
||||||
// GemProperties.db2
|
// GemProperties.db2
|
||||||
PrepareStatement(HotfixStatements.SEL_GEM_PROPERTIES, "SELECT ID, EnchantId, Type FROM gem_properties");
|
PrepareStatement(HotfixStatements.SEL_GEM_PROPERTIES, "SELECT ID, EnchantId, Type FROM gem_properties");
|
||||||
|
|
||||||
@@ -1533,6 +1538,9 @@ namespace Framework.Database
|
|||||||
|
|
||||||
SEL_GARR_SITE_LEVEL_PLOT_INST,
|
SEL_GARR_SITE_LEVEL_PLOT_INST,
|
||||||
|
|
||||||
|
SEL_GARR_TALENT_TREE,
|
||||||
|
SEL_GARR_TALENT_TREE_LOCALE,
|
||||||
|
|
||||||
SEL_GEM_PROPERTIES,
|
SEL_GEM_PROPERTIES,
|
||||||
|
|
||||||
SEL_GLOBAL_CURVE,
|
SEL_GLOBAL_CURVE,
|
||||||
|
|||||||
@@ -158,6 +158,7 @@ namespace Game.DataStorage
|
|||||||
GarrPlotInstanceStorage = ReadDB2<GarrPlotInstanceRecord>("GarrPlotInstance.db2", HotfixStatements.SEL_GARR_PLOT_INSTANCE);
|
GarrPlotInstanceStorage = ReadDB2<GarrPlotInstanceRecord>("GarrPlotInstance.db2", HotfixStatements.SEL_GARR_PLOT_INSTANCE);
|
||||||
GarrSiteLevelStorage = ReadDB2<GarrSiteLevelRecord>("GarrSiteLevel.db2", HotfixStatements.SEL_GARR_SITE_LEVEL);
|
GarrSiteLevelStorage = ReadDB2<GarrSiteLevelRecord>("GarrSiteLevel.db2", HotfixStatements.SEL_GARR_SITE_LEVEL);
|
||||||
GarrSiteLevelPlotInstStorage = ReadDB2<GarrSiteLevelPlotInstRecord>("GarrSiteLevelPlotInst.db2", HotfixStatements.SEL_GARR_SITE_LEVEL_PLOT_INST);
|
GarrSiteLevelPlotInstStorage = ReadDB2<GarrSiteLevelPlotInstRecord>("GarrSiteLevelPlotInst.db2", HotfixStatements.SEL_GARR_SITE_LEVEL_PLOT_INST);
|
||||||
|
GarrTalentTreeStorage = ReadDB2<GarrTalentTreeRecord>("GarrTalentTree.db2", HotfixStatements.SEL_GARR_TALENT_TREE, HotfixStatements.SEL_GARR_TALENT_TREE_LOCALE);
|
||||||
GemPropertiesStorage = ReadDB2<GemPropertiesRecord>("GemProperties.db2", HotfixStatements.SEL_GEM_PROPERTIES);
|
GemPropertiesStorage = ReadDB2<GemPropertiesRecord>("GemProperties.db2", HotfixStatements.SEL_GEM_PROPERTIES);
|
||||||
GlobalCurveStorage = ReadDB2<GlobalCurveRecord>("GlobalCurve.db2", HotfixStatements.SEL_GLOBAL_CURVE);
|
GlobalCurveStorage = ReadDB2<GlobalCurveRecord>("GlobalCurve.db2", HotfixStatements.SEL_GLOBAL_CURVE);
|
||||||
GlyphBindableSpellStorage = ReadDB2<GlyphBindableSpellRecord>("GlyphBindableSpell.db2", HotfixStatements.SEL_GLYPH_BINDABLE_SPELL);
|
GlyphBindableSpellStorage = ReadDB2<GlyphBindableSpellRecord>("GlyphBindableSpell.db2", HotfixStatements.SEL_GLYPH_BINDABLE_SPELL);
|
||||||
@@ -555,6 +556,7 @@ namespace Game.DataStorage
|
|||||||
public static DB6Storage<GarrPlotInstanceRecord> GarrPlotInstanceStorage;
|
public static DB6Storage<GarrPlotInstanceRecord> GarrPlotInstanceStorage;
|
||||||
public static DB6Storage<GarrSiteLevelRecord> GarrSiteLevelStorage;
|
public static DB6Storage<GarrSiteLevelRecord> GarrSiteLevelStorage;
|
||||||
public static DB6Storage<GarrSiteLevelPlotInstRecord> GarrSiteLevelPlotInstStorage;
|
public static DB6Storage<GarrSiteLevelPlotInstRecord> GarrSiteLevelPlotInstStorage;
|
||||||
|
public static DB6Storage<GarrTalentTreeRecord> GarrTalentTreeStorage;
|
||||||
public static DB6Storage<GemPropertiesRecord> GemPropertiesStorage;
|
public static DB6Storage<GemPropertiesRecord> GemPropertiesStorage;
|
||||||
public static DB6Storage<GlobalCurveRecord> GlobalCurveStorage;
|
public static DB6Storage<GlobalCurveRecord> GlobalCurveStorage;
|
||||||
public static DB6Storage<GlyphBindableSpellRecord> GlyphBindableSpellStorage;
|
public static DB6Storage<GlyphBindableSpellRecord> GlyphBindableSpellStorage;
|
||||||
|
|||||||
@@ -258,6 +258,23 @@ namespace Game.DataStorage
|
|||||||
public byte UiMarkerSize;
|
public byte UiMarkerSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public sealed class GarrTalentTreeRecord
|
||||||
|
{
|
||||||
|
public uint Id;
|
||||||
|
public string Name;
|
||||||
|
public byte GarrTypeID;
|
||||||
|
public int ClassID;
|
||||||
|
public sbyte MaxTiers;
|
||||||
|
public sbyte UiOrder;
|
||||||
|
public int Flags;
|
||||||
|
public ushort UiTextureKitID;
|
||||||
|
public int GarrTalentTreeType;
|
||||||
|
public int PlayerConditionID;
|
||||||
|
public sbyte FeatureTypeIndex;
|
||||||
|
public sbyte FeatureSubtypeIndex;
|
||||||
|
public int CurrencyID;
|
||||||
|
}
|
||||||
|
|
||||||
public sealed class GemPropertiesRecord
|
public sealed class GemPropertiesRecord
|
||||||
{
|
{
|
||||||
public uint Id;
|
public uint Id;
|
||||||
|
|||||||
@@ -746,6 +746,11 @@ namespace Game.Misc
|
|||||||
public int FriendshipFactionID;
|
public int FriendshipFactionID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class GossipMenuItemAddon
|
||||||
|
{
|
||||||
|
public int? GarrTalentTreeID;
|
||||||
|
}
|
||||||
|
|
||||||
public class PointOfInterest
|
public class PointOfInterest
|
||||||
{
|
{
|
||||||
public uint Id;
|
public uint Id;
|
||||||
|
|||||||
@@ -3111,5 +3111,14 @@ namespace Game.Entities
|
|||||||
|
|
||||||
SendPacket(displayToast);
|
SendPacket(displayToast);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SendGarrisonOpenTalentNpc(ObjectGuid guid, int garrTalentTreeId, int friendshipFactionId)
|
||||||
|
{
|
||||||
|
GarrisonOpenTalentNpc openTalentNpc = new();
|
||||||
|
openTalentNpc.NpcGUID = guid;
|
||||||
|
openTalentNpc.GarrTalentTreeID = garrTalentTreeId;
|
||||||
|
openTalentNpc.FriendshipFactionID = friendshipFactionId;
|
||||||
|
SendPacket(openTalentNpc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2612,6 +2612,13 @@ namespace Game.Entities
|
|||||||
PlayerTalkClass.SendCloseGossip();
|
PlayerTalkClass.SendCloseGossip();
|
||||||
SendRespecWipeConfirm(guid, 0, SpecResetType.Glyphs);
|
SendRespecWipeConfirm(guid, 0, SpecResetType.Glyphs);
|
||||||
break;
|
break;
|
||||||
|
case GossipOptionNpc.GarrisonTalent:
|
||||||
|
{
|
||||||
|
GossipMenuAddon addon = Global.ObjectMgr.GetGossipMenuAddon(menuId);
|
||||||
|
GossipMenuItemAddon itemAddon = Global.ObjectMgr.GetGossipMenuItemAddon(menuId, gossipListId);
|
||||||
|
SendGarrisonOpenTalentNpc(guid, itemAddon != null ? itemAddon.GarrTalentTreeID.GetValueOrDefault(0) : 0, addon != null ? addon.FriendshipFactionID : 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case GossipOptionNpc.Transmogrify:
|
case GossipOptionNpc.Transmogrify:
|
||||||
GetSession().SendOpenTransmogrifier(guid);
|
GetSession().SendOpenTransmogrifier(guid);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -661,7 +661,7 @@ namespace Game
|
|||||||
|
|
||||||
Log.outInfo(LogFilter.ServerLoading, $"Loaded {gossipMenuItemsStorage.Count} gossip_menu_option entries in {Time.GetMSTimeDiffToNow(oldMSTime)} ms");
|
Log.outInfo(LogFilter.ServerLoading, $"Loaded {gossipMenuItemsStorage.Count} gossip_menu_option entries in {Time.GetMSTimeDiffToNow(oldMSTime)} ms");
|
||||||
}
|
}
|
||||||
public void LoadGossipMenuFriendshipFactions()
|
public void LoadGossipMenuAddon()
|
||||||
{
|
{
|
||||||
uint oldMSTime = Time.GetMSTime();
|
uint oldMSTime = Time.GetMSTime();
|
||||||
|
|
||||||
@@ -701,6 +701,42 @@ namespace Game
|
|||||||
|
|
||||||
Log.outInfo(LogFilter.ServerLoading, $"Loaded {_gossipMenuAddonStorage.Count} gossip_menu_addon IDs in {Time.GetMSTimeDiffToNow(oldMSTime)} ms");
|
Log.outInfo(LogFilter.ServerLoading, $"Loaded {_gossipMenuAddonStorage.Count} gossip_menu_addon IDs in {Time.GetMSTimeDiffToNow(oldMSTime)} ms");
|
||||||
}
|
}
|
||||||
|
public void LoadGossipMenuItemAddon()
|
||||||
|
{
|
||||||
|
uint oldMSTime = Time.GetMSTime();
|
||||||
|
|
||||||
|
_gossipMenuItemAddonStorage.Clear();
|
||||||
|
|
||||||
|
// 0 1 2
|
||||||
|
SQLResult result = DB.World.Query("SELECT MenuID, OptionId, GarrTalentTreeID FROM gossip_menu_option_addon");
|
||||||
|
if (result.IsEmpty())
|
||||||
|
{
|
||||||
|
Log.outInfo(LogFilter.ServerLoading, "Loaded 0 gossip_menu_option_addon IDs. DB table `gossip_menu_option_addon` is empty!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
uint menuId = result.Read<uint>(0);
|
||||||
|
uint optionId = result.Read<uint>(1);
|
||||||
|
GossipMenuItemAddon addon = new();
|
||||||
|
if (!result.IsNull(2))
|
||||||
|
{
|
||||||
|
addon.GarrTalentTreeID = result.Read<int>(2);
|
||||||
|
|
||||||
|
if (!CliDB.GarrTalentTreeStorage.ContainsKey(addon.GarrTalentTreeID.Value))
|
||||||
|
{
|
||||||
|
Log.outError(LogFilter.Sql, $"Table gossip_menu_option_addon: MenuID {menuId} OptionID {optionId} is using non-existing GarrTalentTree {addon.GarrTalentTreeID.Value}");
|
||||||
|
addon.GarrTalentTreeID = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_gossipMenuItemAddonStorage[Tuple.Create(menuId, optionId)] = addon;
|
||||||
|
|
||||||
|
} while (result.NextRow());
|
||||||
|
|
||||||
|
Log.outInfo(LogFilter.ServerLoading, $"Loaded {_gossipMenuItemAddonStorage.Count} gossip_menu_option_addon IDs in {Time.GetMSTimeDiffToNow(oldMSTime)} ms");
|
||||||
|
}
|
||||||
|
|
||||||
public void LoadPointsOfInterest()
|
public void LoadPointsOfInterest()
|
||||||
{
|
{
|
||||||
@@ -756,6 +792,10 @@ namespace Game
|
|||||||
{
|
{
|
||||||
return _gossipMenuAddonStorage.LookupByKey(menuId);
|
return _gossipMenuAddonStorage.LookupByKey(menuId);
|
||||||
}
|
}
|
||||||
|
public GossipMenuItemAddon GetGossipMenuItemAddon(uint menuId, uint optionId)
|
||||||
|
{
|
||||||
|
return _gossipMenuItemAddonStorage.LookupByKey(Tuple.Create(menuId, optionId));
|
||||||
|
}
|
||||||
public PointOfInterest GetPointOfInterest(uint id)
|
public PointOfInterest GetPointOfInterest(uint id)
|
||||||
{
|
{
|
||||||
return pointsOfInterestStorage.LookupByKey(id);
|
return pointsOfInterestStorage.LookupByKey(id);
|
||||||
@@ -10863,6 +10903,7 @@ namespace Game
|
|||||||
MultiMap<uint, GossipMenus> gossipMenusStorage = new();
|
MultiMap<uint, GossipMenus> gossipMenusStorage = new();
|
||||||
MultiMap<uint, GossipMenuItems> gossipMenuItemsStorage = new();
|
MultiMap<uint, GossipMenuItems> gossipMenuItemsStorage = new();
|
||||||
Dictionary<uint, GossipMenuAddon> _gossipMenuAddonStorage = new();
|
Dictionary<uint, GossipMenuAddon> _gossipMenuAddonStorage = new();
|
||||||
|
Dictionary<Tuple<uint, uint>, GossipMenuItemAddon> _gossipMenuItemAddonStorage = new();
|
||||||
Dictionary<uint, PointOfInterest> pointsOfInterestStorage = new();
|
Dictionary<uint, PointOfInterest> pointsOfInterestStorage = new();
|
||||||
|
|
||||||
//Creature
|
//Creature
|
||||||
|
|||||||
@@ -317,6 +317,22 @@ namespace Game.Networking.Packets
|
|||||||
public uint GarrPlotInstanceID;
|
public uint GarrPlotInstanceID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class GarrisonOpenTalentNpc : ServerPacket
|
||||||
|
{
|
||||||
|
public GarrisonOpenTalentNpc() : base(ServerOpcodes.GarrisonOpenTalentNpc, ConnectionType.Instance) { }
|
||||||
|
|
||||||
|
public override void Write()
|
||||||
|
{
|
||||||
|
_worldPacket.WritePackedGuid(NpcGUID);
|
||||||
|
_worldPacket.WriteInt32(GarrTalentTreeID);
|
||||||
|
_worldPacket.WriteInt32(FriendshipFactionID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObjectGuid NpcGUID;
|
||||||
|
public int GarrTalentTreeID;
|
||||||
|
public int FriendshipFactionID; // Always 0 except on The Deaths of Chromie Scenario
|
||||||
|
}
|
||||||
|
|
||||||
//Structs
|
//Structs
|
||||||
public struct GarrisonPlotInfo
|
public struct GarrisonPlotInfo
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -887,8 +887,11 @@ namespace Game
|
|||||||
Log.outInfo(LogFilter.ServerLoading, "Loading Gossip menu options...");
|
Log.outInfo(LogFilter.ServerLoading, "Loading Gossip menu options...");
|
||||||
Global.ObjectMgr.LoadGossipMenuItems();
|
Global.ObjectMgr.LoadGossipMenuItems();
|
||||||
|
|
||||||
Log.outInfo(LogFilter.ServerLoading, "Loading Gossip menu friendship factions...");
|
Log.outInfo(LogFilter.ServerLoading, "Loading Gossip menu addon...");
|
||||||
Global.ObjectMgr.LoadGossipMenuFriendshipFactions();
|
Global.ObjectMgr.LoadGossipMenuAddon();
|
||||||
|
|
||||||
|
Log.outInfo(LogFilter.ServerLoading, "Loading Gossip menu item addon...");
|
||||||
|
Global.ObjectMgr.LoadGossipMenuItemAddon();
|
||||||
|
|
||||||
Log.outInfo(LogFilter.ServerLoading, "Loading Creature trainers...");
|
Log.outInfo(LogFilter.ServerLoading, "Loading Creature trainers...");
|
||||||
Global.ObjectMgr.LoadCreatureTrainers(); // must be after LoadGossipMenuItems
|
Global.ObjectMgr.LoadCreatureTrainers(); // must be after LoadGossipMenuItems
|
||||||
|
|||||||
Reference in New Issue
Block a user