Core/Creature: Add support for multiple gossip menu IDs (#472)
* Core/Creature: Add support for multiple gossip menu IDs Adds support for assigning multiple gossip menu IDs to creatures and controlling them through conditions. Cherry-picked and adapted from: https://github.com/TrinityCore/TrinityCore/commit/36044a9470e9c39a71916e908ab6cf4f95677793 Also disables StormLib automatic static linking. StormLib fix suggested by @brian8544 on Discord. * merge prep --------- Co-authored-by: Ovahlord <18347559+Ovahlord@users.noreply.github.com>
This commit is contained in:
1 parent
30aab19ce5
commit
9da95e6cc9
15 files changed
+199
-96
No files matched your search
@@ -0,0 +1,14 @@
|
||||
--
|
||||
CREATE TABLE `creature_template_gossip` (
|
||||
`CreatureID` INT(10) UNSIGNED NOT NULL,
|
||||
`MenuID` INT(10) UNSIGNED NOT NULL,
|
||||
`VerifiedBuild` INT(11) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`CreatureID`, `MenuID`) USING BTREE
|
||||
)
|
||||
COLLATE='utf8mb4_unicode_ci'
|
||||
ENGINE=InnoDB
|
||||
;
|
||||
|
||||
INSERT INTO `creature_template_gossip` SELECT `entry`, `gossip_menu_id`, `VerifiedBuild` FROM `creature_template` WHERE `gossip_menu_id` <> 0;
|
||||
|
||||
ALTER TABLE `creature_template` DROP COLUMN `gossip_menu_id`;
|
||||
@@ -76,7 +76,7 @@ void WorldDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(WORLD_SEL_WAYPOINT_SCRIPT_ID_BY_GUID, "SELECT id FROM waypoint_scripts WHERE guid = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(WORLD_DEL_CREATURE, "DELETE FROM creature WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(WORLD_SEL_COMMANDS, "SELECT name, permission, help FROM command", CONNECTION_SYNCH);
|
||||
PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, femaleName, subname, IconName, gossip_menu_id, minlevel, maxlevel, HealthScalingExpansion, exp_unk, faction, npcflag, speed_walk, speed_run, scale, `rank`, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, family, trainer_class, type, type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, ctm.HoverInitiallyEnabled, ctm.GravityInitiallyDisabled, ctm.Random, ctm.InteractionPauseTimer, HoverHeight, HealthModifier, HealthModifierExtra, ManaModifier, ManaModifierExtra, ArmorModifier, DamageModifier, ExperienceModifier, RacialLeader, movementId, RegenHealth, mechanic_immune_mask, spell_school_immune_mask, flags_extra, StaticFlags, StaticFlags2, StaticFlags3, StaticFlags4, StaticFlags5, ScriptName FROM creature_template ct LEFT JOIN creature_template_movement ctm ON ct.entry = ctm.CreatureId WHERE entry = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, femaleName, subname, IconName, minlevel, maxlevel, HealthScalingExpansion, exp_unk, faction, npcflag, speed_walk, speed_run, scale, `rank`, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, family, trainer_class, type, type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, ctm.HoverInitiallyEnabled, ctm.GravityInitiallyDisabled, ctm.Random, ctm.InteractionPauseTimer, HoverHeight, HealthModifier, HealthModifierExtra, ManaModifier, ManaModifierExtra, ArmorModifier, DamageModifier, ExperienceModifier, RacialLeader, movementId, RegenHealth, mechanic_immune_mask, spell_school_immune_mask, flags_extra, StaticFlags, StaticFlags2, StaticFlags3, StaticFlags4, StaticFlags5, ScriptName FROM creature_template ct LEFT JOIN creature_template_movement ctm ON ct.entry = ctm.CreatureId WHERE entry = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(WORLD_SEL_WAYPOINT_SCRIPT_BY_ID, "SELECT guid, delay, command, datalong, datalong2, dataint, x, y, z, o FROM waypoint_scripts WHERE id = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(WORLD_SEL_CREATURE_BY_ID, "SELECT guid FROM creature WHERE id = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(WORLD_SEL_GAMEOBJECT_NEAREST, "SELECT guid, id, position_x, position_y, position_z, map, (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) AS order_ FROM gameobject WHERE map = ? AND (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) <= ? ORDER BY order_", CONNECTION_SYNCH);
|
||||
|
||||
@@ -1401,12 +1401,11 @@ bool ConditionMgr::addToGossipMenus(Condition* cond) const
|
||||
{
|
||||
for (GossipMenusContainer::iterator itr = pMenuBounds.first; itr != pMenuBounds.second; ++itr)
|
||||
{
|
||||
if ((*itr).second.MenuID == cond->SourceGroup && (*itr).second.TextID == uint32(cond->SourceEntry))
|
||||
{
|
||||
(*itr).second.Conditions.push_back(cond);
|
||||
return true;
|
||||
}
|
||||
if (itr->second.MenuID == cond->SourceGroup && (itr->second.TextID == uint32(cond->SourceEntry) || cond->SourceEntry == 0))
|
||||
itr->second.Conditions.push_back(cond);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TC_LOG_ERROR("sql.sql", "%s GossipMenu %u not found.", cond->ToString().c_str(), cond->SourceGroup);
|
||||
|
||||
@@ -280,7 +280,7 @@ m_respawnDelay(300), m_corpseDelay(60), m_wanderDistance(0.0f), m_boundaryCheckT
|
||||
m_defaultMovementType(IDLE_MOTION_TYPE), m_spawnId(0), m_equipmentId(0), m_originalEquipmentId(0), m_AlreadyCallAssistance(false),
|
||||
m_AlreadySearchedAssistance(false), m_regenHealth(true), m_cannotReachTarget(false), m_cannotReachTimer(0), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),
|
||||
m_originalEntry(0), m_homePosition(), m_transportHomePosition(), m_creatureInfo(nullptr), m_creatureData(nullptr), _waypointPathId(0), _currentWaypointNodeInfo(0, 0), _cyclicSplinePathId(0),
|
||||
m_formation(nullptr), m_triggerJustAppeared(true), m_respawnCompatibilityMode(false), _lastDamagedTime(0), _isMissingSwimmingFlagOutOfCombat(false), _noNpcDamageBelowPctHealth(0.f)
|
||||
m_formation(nullptr), m_triggerJustAppeared(true), m_respawnCompatibilityMode(false), _lastDamagedTime(0), _isMissingSwimmingFlagOutOfCombat(false), _noNpcDamageBelowPctHealth(0.f), _gossipMenuId(0)
|
||||
{
|
||||
m_valuesCount = UNIT_END;
|
||||
|
||||
@@ -1241,6 +1241,16 @@ Group* Creature::GetLootRecipientGroup() const
|
||||
return sGroupMgr->GetGroupByGUID(m_lootRecipientGroup);
|
||||
}
|
||||
|
||||
uint32 Creature::GetGossipMenuId() const
|
||||
{
|
||||
return _gossipMenuId;
|
||||
}
|
||||
|
||||
void Creature::SetGossipMenuId(uint32 gossipMenuID)
|
||||
{
|
||||
_gossipMenuId = gossipMenuID;
|
||||
}
|
||||
|
||||
void Creature::SetLootRecipient(Unit* unit, bool withGroup)
|
||||
{
|
||||
// set the player whose group should receive the right
|
||||
|
||||
@@ -411,6 +411,9 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
|
||||
bool HasStaticFlag(CreatureStaticFlags4 flag) const { return _staticFlags.HasFlag(flag); }
|
||||
bool HasStaticFlag(CreatureStaticFlags5 flag) const { return _staticFlags.HasFlag(flag); }
|
||||
|
||||
uint32 GetGossipMenuId() const;
|
||||
void SetGossipMenuId(uint32 gossipMenuId);
|
||||
|
||||
CreatureMovementInfo const& GetCreatureMovementInfo() const { return _creatureMovementInfo; }
|
||||
|
||||
// Sets the the max health percentage threshold at which uncontrolled/unowned creatures can no longer deal damage to the creature
|
||||
@@ -508,6 +511,8 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
|
||||
|
||||
Optional<uint32> _defaultMountDisplayIdOverride;
|
||||
float _noNpcDamageBelowPctHealth;
|
||||
|
||||
uint32 _gossipMenuId;
|
||||
};
|
||||
|
||||
class TC_GAME_API AssistDelayEvent : public BasicEvent
|
||||
|
||||
@@ -365,7 +365,7 @@ struct TC_GAME_API CreatureTemplate
|
||||
std::string FemaleName;
|
||||
std::string Title;
|
||||
std::string IconName;
|
||||
uint32 GossipMenuId;
|
||||
std::vector<uint32> GossipMenuIds;
|
||||
uint8 minlevel;
|
||||
uint8 maxlevel;
|
||||
int32 HealthScalingExpansion;
|
||||
|
||||
@@ -13385,7 +13385,7 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId /*= 0*/, bool
|
||||
GossipMenuItemsMapBounds menuItemBounds = sObjectMgr->GetGossipMenuItemsMapBounds(menuId);
|
||||
|
||||
// if default menuId and no menu options exist for this, use options from default options
|
||||
if (menuItemBounds.first == menuItemBounds.second && menuId == GetDefaultGossipMenuForSource(source))
|
||||
if (menuItemBounds.first == menuItemBounds.second && menuId == GetGossipMenuForSource(source))
|
||||
menuItemBounds = sObjectMgr->GetGossipMenuItemsMapBounds(0);
|
||||
|
||||
uint32 npcflags = 0;
|
||||
@@ -13701,7 +13701,7 @@ uint32 Player::GetGossipTextId(WorldObject* source)
|
||||
if (!source)
|
||||
return DEFAULT_GOSSIP_MESSAGE;
|
||||
|
||||
return GetGossipTextId(GetDefaultGossipMenuForSource(source), source);
|
||||
return GetGossipTextId(GetGossipMenuForSource(source), source);
|
||||
}
|
||||
|
||||
uint32 Player::GetGossipTextId(uint32 menuId, WorldObject* source)
|
||||
@@ -13715,6 +13715,10 @@ uint32 Player::GetGossipTextId(uint32 menuId, WorldObject* source)
|
||||
|
||||
for (GossipMenusContainer::const_iterator itr = menuBounds.first; itr != menuBounds.second; ++itr)
|
||||
{
|
||||
// continue if only checks menuid instead of text
|
||||
if (!itr->second.TextID)
|
||||
continue;
|
||||
|
||||
if (sConditionMgr->IsObjectMeetToConditions(this, source, itr->second.Conditions))
|
||||
textId = itr->second.TextID;
|
||||
}
|
||||
@@ -13722,12 +13726,33 @@ uint32 Player::GetGossipTextId(uint32 menuId, WorldObject* source)
|
||||
return textId;
|
||||
}
|
||||
|
||||
uint32 Player::GetDefaultGossipMenuForSource(WorldObject* source)
|
||||
uint32 Player::GetGossipMenuForSource(WorldObject* source)
|
||||
{
|
||||
switch (source->GetTypeId())
|
||||
{
|
||||
case TYPEID_UNIT:
|
||||
return source->ToCreature()->GetCreatureTemplate()->GossipMenuId;
|
||||
{
|
||||
uint32 menuIdToShow = source->ToCreature()->GetGossipMenuId();
|
||||
|
||||
// if menu id is set by script
|
||||
if (menuIdToShow)
|
||||
return menuIdToShow;
|
||||
|
||||
// otherwise pick from db based on conditions
|
||||
for (uint32 menuId : source->ToCreature()->GetCreatureTemplate()->GossipMenuIds)
|
||||
{
|
||||
GossipMenusMapBounds menuBounds = sObjectMgr->GetGossipMenusMapBounds(menuId);
|
||||
|
||||
for (GossipMenusContainer::const_iterator itr = menuBounds.first; itr != menuBounds.second; ++itr)
|
||||
{
|
||||
if (!sConditionMgr->IsObjectMeetToConditions(this, source, itr->second.Conditions))
|
||||
continue;
|
||||
|
||||
menuIdToShow = menuId;
|
||||
}
|
||||
}
|
||||
return menuIdToShow;
|
||||
}
|
||||
case TYPEID_GAMEOBJECT:
|
||||
return source->ToGameObject()->GetGOInfo()->GetGossipMenuId();
|
||||
default:
|
||||
|
||||
@@ -1296,7 +1296,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
|
||||
|
||||
uint32 GetGossipTextId(uint32 menuId, WorldObject* source);
|
||||
uint32 GetGossipTextId(WorldObject* source);
|
||||
static uint32 GetDefaultGossipMenuForSource(WorldObject* source);
|
||||
uint32 GetGossipMenuForSource(WorldObject* source);
|
||||
|
||||
/*********************************************************/
|
||||
/*** QUEST SYSTEM ***/
|
||||
|
||||
@@ -413,21 +413,21 @@ void ObjectMgr::LoadCreatureTemplates()
|
||||
{
|
||||
uint32 oldMSTime = getMSTime();
|
||||
|
||||
// 0 1 2 3 4 5 6 7 8
|
||||
// 0 1 2 3 4 5 6 7 8
|
||||
QueryResult result = WorldDatabase.Query("SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, "
|
||||
// 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
||||
"modelid4, name, femaleName, subname, IconName, gossip_menu_id, minlevel, maxlevel, HealthScalingExpansion, exp_unk, faction, npcflag, speed_walk, speed_run, "
|
||||
// 23 24 25 26 27 28 29 30 31 32
|
||||
// 9 10 11 12 13 14 15 16 17 18 19 20 21
|
||||
"modelid4, name, femaleName, subname, IconName, minlevel, maxlevel, HealthScalingExpansion, exp_unk, faction, npcflag, speed_walk, speed_run, "
|
||||
// 22 23 24 25 26 27 28 29 30 31
|
||||
"scale, `rank`, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, "
|
||||
// 33 34 35 36 37 38 39 40 41 42 43 44 45 46
|
||||
// 32 33 34 35 36 37 38 39 40 41 42 43 44 45
|
||||
"family, trainer_class, type, type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, "
|
||||
// 47 48 49 50 51 52 53 54 55 56 57 58 59 60
|
||||
// 46 47 48 49 50 51 52 53 54 55 56 57 58 59
|
||||
"spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, "
|
||||
// 61 62 63 64 65 66 67 68 69
|
||||
// 60 61 62 63 64 65 66 67 68
|
||||
"ctm.HoverInitiallyEnabled, ctm.GravityInitiallyDisabled, ctm.Random, ctm.InteractionPauseTimer, HoverHeight, HealthModifier, HealthModifierExtra, ManaModifier, ManaModifierExtra, "
|
||||
// 70 71 72 73 74 75 76 77
|
||||
// 69 70 71 72 73 74 75 76
|
||||
"ArmorModifier, DamageModifier, ExperienceModifier, RacialLeader, movementId, RegenHealth, mechanic_immune_mask, spell_school_immune_mask, "
|
||||
// 78 79 80 81 82 83 84
|
||||
// 77 78 79 80 81 82 83
|
||||
"flags_extra, StaticFlags, StaticFlags2, StaticFlags3, StaticFlags4, StaticFlags5, ScriptName FROM creature_template ct LEFT JOIN creature_template_movement ctm ON ct.entry = ctm.CreatureId");
|
||||
|
||||
if (!result)
|
||||
@@ -468,84 +468,77 @@ void ObjectMgr::LoadCreatureTemplate(Field* fields)
|
||||
for (uint8 i = 0; i < MAX_KILL_CREDIT; ++i)
|
||||
creatureTemplate.KillCredit[i] = fields[4 + i].GetUInt32();
|
||||
|
||||
//creatureTemplate.Modelid1 = fields[6].GetUInt32();
|
||||
//creatureTemplate.Modelid2 = fields[7].GetUInt32();
|
||||
//creatureTemplate.Modelid3 = fields[8].GetUInt32();
|
||||
//creatureTemplate.Modelid4 = fields[9].GetUInt32();
|
||||
creatureTemplate.Name = fields[10].GetString();
|
||||
creatureTemplate.FemaleName = fields[11].GetString();
|
||||
creatureTemplate.Title = fields[12].GetString();
|
||||
creatureTemplate.IconName = fields[13].GetString();
|
||||
creatureTemplate.GossipMenuId = fields[14].GetUInt32();
|
||||
creatureTemplate.minlevel = fields[15].GetUInt8();
|
||||
creatureTemplate.maxlevel = fields[16].GetUInt8();
|
||||
creatureTemplate.HealthScalingExpansion = fields[17].GetInt32();
|
||||
creatureTemplate.expansionUnknown = uint32(fields[18].GetUInt16());
|
||||
creatureTemplate.faction = uint32(fields[19].GetUInt16());
|
||||
creatureTemplate.npcflag = fields[20].GetUInt32();
|
||||
creatureTemplate.speed_walk = fields[21].GetFloat();
|
||||
creatureTemplate.speed_run = fields[22].GetFloat();
|
||||
creatureTemplate.scale = fields[23].GetFloat();
|
||||
creatureTemplate.rank = uint32(fields[24].GetUInt8());
|
||||
creatureTemplate.dmgschool = uint32(fields[25].GetInt8());
|
||||
creatureTemplate.BaseAttackTime = fields[26].GetUInt32();
|
||||
creatureTemplate.RangeAttackTime = fields[27].GetUInt32();
|
||||
creatureTemplate.BaseVariance = fields[28].GetFloat();
|
||||
creatureTemplate.RangeVariance = fields[29].GetFloat();
|
||||
creatureTemplate.unit_class = uint32(fields[30].GetUInt8());
|
||||
creatureTemplate.unit_flags = fields[31].GetUInt32();
|
||||
creatureTemplate.unit_flags2 = fields[32].GetUInt32();
|
||||
creatureTemplate.family = CreatureFamily(uint32(fields[33].GetUInt8()));
|
||||
creatureTemplate.trainer_class = fields[34].GetUInt32();
|
||||
creatureTemplate.type = uint32(fields[35].GetUInt8());
|
||||
creatureTemplate.type_flags = fields[36].GetUInt32();
|
||||
creatureTemplate.type_flags2 = fields[37].GetUInt32();
|
||||
creatureTemplate.lootid = fields[38].GetUInt32();
|
||||
creatureTemplate.pickpocketLootId = fields[39].GetUInt32();
|
||||
creatureTemplate.SkinLootId = fields[40].GetUInt32();
|
||||
creatureTemplate.Name = fields[10].GetString();
|
||||
creatureTemplate.FemaleName = fields[11].GetString();
|
||||
creatureTemplate.Title = fields[12].GetString();
|
||||
creatureTemplate.IconName = fields[13].GetString();
|
||||
creatureTemplate.minlevel = fields[14].GetUInt8();
|
||||
creatureTemplate.maxlevel = fields[15].GetUInt8();
|
||||
creatureTemplate.HealthScalingExpansion = fields[16].GetInt32();
|
||||
creatureTemplate.expansionUnknown = uint32(fields[17].GetInt16());
|
||||
creatureTemplate.faction = uint32(fields[18].GetUInt16());
|
||||
creatureTemplate.npcflag = fields[19].GetUInt32();
|
||||
creatureTemplate.speed_walk = fields[20].GetFloat();
|
||||
creatureTemplate.speed_run = fields[21].GetFloat();
|
||||
creatureTemplate.scale = fields[22].GetFloat();
|
||||
creatureTemplate.rank = uint32(fields[23].GetUInt8());
|
||||
creatureTemplate.dmgschool = uint32(fields[24].GetInt8());
|
||||
creatureTemplate.BaseAttackTime = fields[25].GetUInt32();
|
||||
creatureTemplate.RangeAttackTime = fields[26].GetUInt32();
|
||||
creatureTemplate.BaseVariance = fields[27].GetFloat();
|
||||
creatureTemplate.RangeVariance = fields[28].GetFloat();
|
||||
creatureTemplate.unit_class = uint32(fields[29].GetUInt8());
|
||||
creatureTemplate.unit_flags = fields[30].GetUInt32();
|
||||
creatureTemplate.unit_flags2 = fields[31].GetUInt32();
|
||||
creatureTemplate.family = CreatureFamily(uint32(fields[32].GetUInt8()));
|
||||
creatureTemplate.trainer_class = fields[33].GetUInt32();
|
||||
creatureTemplate.type = uint32(fields[34].GetUInt8());
|
||||
creatureTemplate.type_flags = fields[35].GetUInt32();
|
||||
creatureTemplate.type_flags2 = fields[36].GetUInt32();
|
||||
creatureTemplate.lootid = fields[37].GetUInt32();
|
||||
creatureTemplate.pickpocketLootId = fields[38].GetUInt32();
|
||||
creatureTemplate.SkinLootId = fields[39].GetUInt32();
|
||||
|
||||
for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
|
||||
creatureTemplate.resistance[i] = fields[41 + i - 1].GetInt16();
|
||||
creatureTemplate.resistance[i] = fields[40 + i - 1].GetInt16();
|
||||
|
||||
for (uint8 i = 0; i < MAX_CREATURE_SPELLS; ++i)
|
||||
creatureTemplate.spells[i] = fields[47 + i].GetUInt32();
|
||||
creatureTemplate.spells[i] = fields[46 + i].GetUInt32();
|
||||
|
||||
creatureTemplate.PetSpellDataId = fields[54].GetUInt32();
|
||||
creatureTemplate.VehicleId = fields[55].GetUInt32();
|
||||
creatureTemplate.mingold = fields[56].GetUInt32();
|
||||
creatureTemplate.maxgold = fields[57].GetUInt32();
|
||||
creatureTemplate.AIName = fields[58].GetString();
|
||||
creatureTemplate.MovementType = uint32(fields[59].GetUInt8());
|
||||
if (!fields[60].IsNull())
|
||||
creatureTemplate.Movement.HoverInitiallyEnabled = fields[60].GetBool();
|
||||
|
||||
creatureTemplate.PetSpellDataId = fields[55].GetUInt32();
|
||||
creatureTemplate.VehicleId = fields[56].GetUInt32();
|
||||
creatureTemplate.mingold = fields[57].GetUInt32();
|
||||
creatureTemplate.maxgold = fields[58].GetUInt32();
|
||||
creatureTemplate.AIName = fields[59].GetString();
|
||||
creatureTemplate.MovementType = uint32(fields[60].GetUInt8());
|
||||
if (!fields[61].IsNull())
|
||||
creatureTemplate.Movement.HoverInitiallyEnabled = fields[61].GetBool();
|
||||
|
||||
creatureTemplate.Movement.GravityInitiallyDisabled = fields[61].GetBool();
|
||||
if (!fields[62].IsNull())
|
||||
creatureTemplate.Movement.GravityInitiallyDisabled = fields[62].GetBool();
|
||||
creatureTemplate.Movement.Random = static_cast<CreatureRandomMovementType>(fields[62].GetUInt8());
|
||||
|
||||
if (!fields[63].IsNull())
|
||||
creatureTemplate.Movement.Random = static_cast<CreatureRandomMovementType>(fields[63].GetUInt8());
|
||||
creatureTemplate.Movement.InteractionPauseTimer = fields[63].GetUInt32();
|
||||
creatureTemplate.HoverHeight = fields[64].GetFloat();
|
||||
creatureTemplate.ModHealth = fields[65].GetFloat();
|
||||
creatureTemplate.ModHealthExtra = fields[66].GetFloat();
|
||||
creatureTemplate.ModMana = fields[67].GetFloat();
|
||||
creatureTemplate.ModManaExtra = fields[68].GetFloat();
|
||||
creatureTemplate.ModArmor = fields[69].GetFloat();
|
||||
creatureTemplate.ModDamage = fields[70].GetFloat();
|
||||
creatureTemplate.ModExperience = fields[71].GetFloat();
|
||||
|
||||
if (!fields[64].IsNull())
|
||||
creatureTemplate.Movement.InteractionPauseTimer = fields[64].GetUInt32();
|
||||
|
||||
creatureTemplate.HoverHeight = fields[65].GetFloat();
|
||||
creatureTemplate.ModHealth = fields[66].GetFloat();
|
||||
creatureTemplate.ModHealthExtra = fields[67].GetFloat();
|
||||
creatureTemplate.ModMana = fields[68].GetFloat();
|
||||
creatureTemplate.ModManaExtra = fields[69].GetFloat();
|
||||
creatureTemplate.ModArmor = fields[70].GetFloat();
|
||||
creatureTemplate.ModDamage = fields[71].GetFloat();
|
||||
creatureTemplate.ModExperience = fields[72].GetFloat();
|
||||
|
||||
creatureTemplate.RacialLeader = fields[73].GetBool();
|
||||
creatureTemplate.movementId = fields[74].GetUInt32();
|
||||
creatureTemplate.RegenHealth = fields[75].GetBool();
|
||||
creatureTemplate.MechanicImmuneMask = fields[76].GetUInt32();
|
||||
creatureTemplate.SpellSchoolImmuneMask = fields[77].GetUInt32();
|
||||
creatureTemplate.flags_extra = fields[78].GetUInt32();
|
||||
creatureTemplate.StaticFlags = CreatureStaticFlagsHolder(CreatureStaticFlags(fields[79].GetUInt32()), CreatureStaticFlags2(fields[80].GetUInt32()),
|
||||
CreatureStaticFlags3(fields[81].GetUInt32()), CreatureStaticFlags4(fields[82].GetUInt32()), CreatureStaticFlags5(fields[83].GetUInt32()));
|
||||
creatureTemplate.ScriptID = GetScriptId(fields[84].GetCString());
|
||||
creatureTemplate.RacialLeader = fields[72].GetBool();
|
||||
creatureTemplate.movementId = fields[73].GetUInt32();
|
||||
creatureTemplate.RegenHealth = fields[74].GetBool();
|
||||
creatureTemplate.MechanicImmuneMask = fields[75].GetUInt32();
|
||||
creatureTemplate.SpellSchoolImmuneMask = fields[76].GetUInt32();
|
||||
creatureTemplate.flags_extra = fields[77].GetUInt32();
|
||||
creatureTemplate.StaticFlags = CreatureStaticFlagsHolder(CreatureStaticFlags(fields[78].GetUInt32()), CreatureStaticFlags2(fields[79].GetUInt32()),
|
||||
CreatureStaticFlags3(fields[80].GetUInt32()), CreatureStaticFlags4(fields[81].GetUInt32()), CreatureStaticFlags5(fields[82].GetUInt32()));
|
||||
creatureTemplate.ScriptID = GetScriptId(fields[83].GetCString());
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadCreatureTemplateModels()
|
||||
@@ -603,6 +596,52 @@ void ObjectMgr::LoadCreatureTemplateModels()
|
||||
TC_LOG_INFO("server.loading", ">> Loaded %u creature template models in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadCreatureTemplateGossip()
|
||||
{
|
||||
uint32 oldMSTime = getMSTime();
|
||||
|
||||
// 0 1
|
||||
QueryResult result = WorldDatabase.Query("SELECT CreatureID, MenuID FROM creature_template_gossip");
|
||||
|
||||
if (!result)
|
||||
{
|
||||
TC_LOG_INFO("server.loading", ">> Loaded 0 creature template gossip definitions. DB table `creature_template_gossip` is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 count = 0;
|
||||
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
|
||||
uint32 creatureID = fields[0].GetUInt32();
|
||||
uint32 menuID = fields[1].GetUInt32();
|
||||
|
||||
CreatureTemplateContainer::iterator itr = _creatureTemplateStore.find(creatureID);
|
||||
if (itr == _creatureTemplateStore.end())
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "creature_template_gossip has gossip definitions for creature %u but this creature doesn't exist", creatureID);
|
||||
continue;
|
||||
}
|
||||
|
||||
GossipMenusMapBounds menuBounds = sObjectMgr->GetGossipMenusMapBounds(menuID);
|
||||
if (menuBounds.first == menuBounds.second)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "creature_template_gossip has gossip definitions for menu id %u but this menu doesn't exist", menuID);
|
||||
continue;
|
||||
}
|
||||
|
||||
CreatureTemplate& creatureTemplate = itr->second;
|
||||
creatureTemplate.GossipMenuIds.push_back(menuID);
|
||||
|
||||
++count;
|
||||
|
||||
} while (result->NextRow());
|
||||
|
||||
TC_LOG_INFO("server.loading", ">> Loaded %u creature template gossip menus in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadCreatureTemplateAddons()
|
||||
{
|
||||
uint32 oldMSTime = getMSTime();
|
||||
@@ -1129,6 +1168,11 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo)
|
||||
}
|
||||
|
||||
const_cast<CreatureTemplate*>(cInfo)->ModDamage *= Creature::_GetDamageMod(cInfo->rank);
|
||||
|
||||
if (!cInfo->GossipMenuIds.empty() && !(cInfo->npcflag & UNIT_NPC_FLAG_GOSSIP))
|
||||
TC_LOG_INFO("sql.sql", "Creature (Entry: %u) has assigned gossip menu, but npcflag does not include UNIT_NPC_FLAG_GOSSIP.", cInfo->Entry);
|
||||
else if (cInfo->GossipMenuIds.empty() && cInfo->npcflag & UNIT_NPC_FLAG_GOSSIP)
|
||||
TC_LOG_INFO("sql.sql", "Creature (Entry: %u) has npcflag UNIT_NPC_FLAG_GOSSIP, but gossip menu is unassigned.", cInfo->Entry);
|
||||
}
|
||||
|
||||
void ObjectMgr::CheckCreatureMovement(char const* table, uint64 id, CreatureMovementData& creatureMovement)
|
||||
|
||||
@@ -1176,6 +1176,7 @@ class TC_GAME_API ObjectMgr
|
||||
void LoadCreatureSparringTemplate();
|
||||
void LoadCreatureTemplate(Field* fields);
|
||||
void LoadCreatureTemplateModels();
|
||||
void LoadCreatureTemplateGossip();
|
||||
void CheckCreatureTemplate(CreatureTemplate const* cInfo);
|
||||
void CheckCreatureMovement(char const* table, uint64 id, CreatureMovementData& creatureMovement);
|
||||
void LoadGameObjectQuestItems();
|
||||
|
||||
@@ -201,7 +201,7 @@ void WorldSession::HandleGossipHelloOpcode(WorldPackets::NPC::Hello& packet)
|
||||
if (!unit->AI()->GossipHello(_player))
|
||||
{
|
||||
// _player->TalkedToCreature(unit->GetEntry(), unit->GetGUID());
|
||||
_player->PrepareGossipMenu(unit, unit->GetCreatureTemplate()->GossipMenuId, true);
|
||||
_player->PrepareGossipMenu(unit, _player->GetGossipMenuForSource(unit), true);
|
||||
|
||||
// If npc is a flightmaster who is a quest giver do not send the gossip if there is no quest
|
||||
if (unit->IsTaxi() && (unit->IsQuestGiver() || unit->IsGossip()))
|
||||
|
||||
@@ -98,7 +98,7 @@ void WorldSession::HandleQuestgiverHelloOpcode(WorldPackets::Quest::QuestGiverHe
|
||||
if (creature->AI()->GossipHello(_player))
|
||||
return;
|
||||
|
||||
_player->PrepareGossipMenu(creature, creature->GetCreatureTemplate()->GossipMenuId, true);
|
||||
_player->PrepareGossipMenu(creature, _player->GetGossipMenuForSource(creature), true);
|
||||
_player->SendPreparedGossip(creature);
|
||||
}
|
||||
|
||||
@@ -227,7 +227,7 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPackets::Quest::QuestG
|
||||
auto launchGossip = [&](WorldObject* worldObject)
|
||||
{
|
||||
_player->PlayerTalkClass->ClearMenus();
|
||||
_player->PrepareGossipMenu(worldObject, _player->GetDefaultGossipMenuForSource(worldObject), true);
|
||||
_player->PrepareGossipMenu(worldObject, _player->GetGossipMenuForSource(worldObject), true);
|
||||
_player->SendPreparedGossip(worldObject);
|
||||
};
|
||||
|
||||
|
||||
@@ -2143,6 +2143,9 @@ void World::SetInitialWorldSettings()
|
||||
TC_LOG_INFO("server.loading", "Loading Gossip menu options...");
|
||||
sObjectMgr->LoadGossipMenuItems();
|
||||
|
||||
TC_LOG_INFO("server.loading", "Loading Creature Template Gossip...");
|
||||
sObjectMgr->LoadCreatureTemplateGossip();
|
||||
|
||||
TC_LOG_INFO("server.loading", "Loading Creature trainers...");
|
||||
sObjectMgr->LoadCreatureTrainers(); // must be after LoadGossipMenuItems
|
||||
|
||||
|
||||
@@ -650,7 +650,7 @@ public:
|
||||
if (player->IsInCombat() || me->IsInCombat())
|
||||
return true;
|
||||
|
||||
AddGossipItemFor(player, Player::GetDefaultGossipMenuForSource(me), 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
|
||||
AddGossipItemFor(player, player->GetGossipMenuForSource(me), 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
|
||||
SendGossipMenuFor(player, player->GetGossipTextId(me), me->GetGUID());
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -366,7 +366,9 @@ enum MiscData
|
||||
enum Misc
|
||||
{
|
||||
DATA_PLAGUE_STACK = 70337,
|
||||
DATA_VILE = 45814622
|
||||
DATA_VILE = 45814622,
|
||||
|
||||
GOSSIP_MENU_START_INTRO = 10993
|
||||
};
|
||||
|
||||
class NecroticPlagueTargetCheck
|
||||
@@ -1206,7 +1208,7 @@ class npc_tirion_fordring_tft : public CreatureScript
|
||||
|
||||
bool GossipSelect(Player* /*player*/, uint32 menuId, uint32 gossipListId) override
|
||||
{
|
||||
if (me->GetCreatureTemplate()->GossipMenuId == menuId && !gossipListId)
|
||||
if (menuId == GOSSIP_MENU_START_INTRO && !gossipListId)
|
||||
{
|
||||
_events.SetPhase(PHASE_INTRO);
|
||||
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||
|
||||
Reference in new issue
Block a user