Core/Creature: Added possibility to give creatures multiple gossip menu ids and control them via conditions (#28159)
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
--
|
||||
DROP TABLE IF EXISTS `creature_template_gossip`;
|
||||
CREATE TABLE `creature_template_gossip` (
|
||||
`CreatureID` int UNSIGNED NOT NULL,
|
||||
`MenuID` int UNSIGNED NOT NULL,
|
||||
`VerifiedBuild` int NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`CreatureID`, `MenuID`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
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`;
|
||||
@@ -77,7 +77,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, help FROM command", CONNECTION_SYNCH);
|
||||
PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, name, femaleName, subname, TitleAlt, IconName, gossip_menu_id, HealthScalingExpansion, RequiredExpansion, VignetteID, faction, npcflag, speed_walk, speed_run, scale, `rank`, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, unit_flags3, dynamicflags, family, trainer_class, type, type_flags, type_flags2, lootid, pickpocketloot, skinloot, VehicleId, mingold, maxgold, AIName, MovementType, ctm.Ground, ctm.Swim, ctm.Flight, ctm.Rooted, ctm.Chase, ctm.Random, ctm.InteractionPauseTimer, HoverHeight, HealthModifier, HealthModifierExtra, ManaModifier, ManaModifierExtra, ArmorModifier, DamageModifier, ExperienceModifier, RacialLeader, movementId, CreatureDifficultyID, WidgetSetID, WidgetSetUnitConditionID, RegenHealth, mechanic_immune_mask, spell_school_immune_mask, flags_extra, ScriptName, StringId FROM creature_template ct LEFT JOIN creature_template_movement ctm ON ct.entry = ctm.CreatureId WHERE entry = ? OR 1 = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, name, femaleName, subname, TitleAlt, IconName, HealthScalingExpansion, RequiredExpansion, VignetteID, faction, npcflag, speed_walk, speed_run, scale, `rank`, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, unit_flags3, dynamicflags, family, trainer_class, type, type_flags, type_flags2, lootid, pickpocketloot, skinloot, VehicleId, mingold, maxgold, AIName, MovementType, ctm.Ground, ctm.Swim, ctm.Flight, ctm.Rooted, ctm.Chase, ctm.Random, ctm.InteractionPauseTimer, HoverHeight, HealthModifier, HealthModifierExtra, ManaModifier, ManaModifierExtra, ArmorModifier, DamageModifier, ExperienceModifier, RacialLeader, movementId, CreatureDifficultyID, WidgetSetID, WidgetSetUnitConditionID, RegenHealth, mechanic_immune_mask, spell_school_immune_mask, flags_extra, ScriptName, StringId FROM creature_template ct LEFT JOIN creature_template_movement ctm ON ct.entry = ctm.CreatureId WHERE entry = ? OR 1 = ?", 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);
|
||||
|
||||
@@ -1530,12 +1530,10 @@ 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", "{} GossipMenu {} not found.", cond->ToString(), cond->SourceGroup);
|
||||
|
||||
@@ -294,7 +294,7 @@ Creature::Creature(bool isWorldObject) : Unit(isWorldObject), MapObject(), m_Pla
|
||||
m_defaultMovementType(IDLE_MOTION_TYPE), m_spawnId(UI64LIT(0)), m_equipmentId(0), m_originalEquipmentId(0), m_AlreadyCallAssistance(false), m_AlreadySearchedAssistance(false), 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),
|
||||
m_formation(nullptr), m_triggerJustAppeared(true), m_respawnCompatibilityMode(false), _lastDamagedTime(0),
|
||||
_regenerateHealth(true), _isMissingCanSwimFlagOutOfCombat(false)
|
||||
_regenerateHealth(true), _isMissingCanSwimFlagOutOfCombat(false), _gossipMenuId(0)
|
||||
{
|
||||
m_regenTimer = CREATURE_REGEN_INTERVAL;
|
||||
|
||||
@@ -3525,13 +3525,10 @@ void Creature::ExitVehicle(Position const* /*exitPosition*/)
|
||||
|
||||
uint32 Creature::GetGossipMenuId() const
|
||||
{
|
||||
if (_gossipMenuId)
|
||||
return *_gossipMenuId;
|
||||
|
||||
return GetCreatureTemplate()->GossipMenuId;
|
||||
return _gossipMenuId;
|
||||
}
|
||||
|
||||
void Creature::SetGossipMenuId(Optional<uint32> gossipMenuId)
|
||||
void Creature::SetGossipMenuId(uint32 gossipMenuId)
|
||||
{
|
||||
_gossipMenuId = gossipMenuId;
|
||||
}
|
||||
|
||||
@@ -413,7 +413,7 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
|
||||
bool HasFlag(CreatureStaticFlags8 flag) const { return _staticFlags.HasFlag(flag); }
|
||||
|
||||
uint32 GetGossipMenuId() const;
|
||||
void SetGossipMenuId(Optional<uint32> gossipMenuId);
|
||||
void SetGossipMenuId(uint32 gossipMenuId);
|
||||
|
||||
uint32 GetTrainerId() const;
|
||||
void SetTrainerId(Optional<uint32> trainerId);
|
||||
@@ -507,7 +507,7 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
|
||||
|
||||
bool _isMissingCanSwimFlagOutOfCombat;
|
||||
|
||||
Optional<uint32> _gossipMenuId;
|
||||
uint32 _gossipMenuId;
|
||||
Optional<uint32> _trainerId;
|
||||
};
|
||||
|
||||
|
||||
@@ -478,7 +478,7 @@ struct TC_GAME_API CreatureTemplate
|
||||
std::string SubName;
|
||||
std::string TitleAlt;
|
||||
std::string IconName;
|
||||
uint32 GossipMenuId;
|
||||
std::vector<uint32> GossipMenuIds;
|
||||
std::unordered_map<Difficulty, CreatureLevelScaling> scalingStore;
|
||||
int32 HealthScalingExpansion;
|
||||
uint32 RequiredExpansion;
|
||||
|
||||
@@ -14233,7 +14233,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)
|
||||
@@ -14247,6 +14247,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;
|
||||
}
|
||||
@@ -14254,12 +14258,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()->GetGossipMenuId();
|
||||
{
|
||||
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:
|
||||
|
||||
@@ -1542,7 +1542,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 ***/
|
||||
|
||||
@@ -352,21 +352,21 @@ void ObjectMgr::LoadCreatureTemplates()
|
||||
|
||||
// 0 1 2 3 4 5 6 7 8
|
||||
// "SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, name, femaleName, subname, "
|
||||
// 9 10 11 12 13 14
|
||||
// "TitleAlt, IconName, gossip_menu_id, HealthScalingExpansion, RequiredExpansion, VignetteID, "
|
||||
// 15 16 17 18 19 20 21 22 23 24 25
|
||||
// 9 10 11 12 13
|
||||
// "TitleAlt, IconName, HealthScalingExpansion, RequiredExpansion, VignetteID, "
|
||||
// 14 15 16 17 18 19 20 21 22 23 24
|
||||
// "faction, npcflag, speed_walk, speed_run, scale, `rank`, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, "
|
||||
// 26 27 28 29 30 31 32 33
|
||||
// 25 26 27 28 29 30 31 32
|
||||
// "unit_class, unit_flags, unit_flags2, unit_flags3, dynamicflags, family, trainer_class, type, "
|
||||
// 34 35 36 37 38 39 40 41 42 43
|
||||
// 33 34 35 36 37 38 39 40 41 42
|
||||
// "type_flags, type_flags2, lootid, pickpocketloot, skinloot, VehicleId, mingold, maxgold, AIName, MovementType, "
|
||||
// 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
|
||||
// 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
|
||||
// "ctm.Ground, ctm.Swim, ctm.Flight, ctm.Rooted, ctm.Chase, ctm.Random, ctm.InteractionPauseTimer, HoverHeight, HealthModifier, HealthModifierExtra, ManaModifier, ManaModifierExtra, ArmorModifier, DamageModifier, ExperienceModifier, "
|
||||
// 59 60 61 62 63 64
|
||||
// 58 59 60 61 62 63
|
||||
// "RacialLeader, movementId, CreatureDifficultyID, WidgetSetID, WidgetSetUnitConditionID, RegenHealth, "
|
||||
// 65 66 67
|
||||
// 64 65 66
|
||||
// "mechanic_immune_mask, spell_school_immune_mask, flags_extra, "
|
||||
// 68 69
|
||||
// 67 68
|
||||
// "ScriptName, StringId FROM creature_template WHERE entry = ? OR 1 = ?");
|
||||
|
||||
WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_CREATURE_TEMPLATE);
|
||||
@@ -420,34 +420,33 @@ void ObjectMgr::LoadCreatureTemplate(Field* fields)
|
||||
creatureTemplate.SubName = fields[8].GetString();
|
||||
creatureTemplate.TitleAlt = fields[9].GetString();
|
||||
creatureTemplate.IconName = fields[10].GetString();
|
||||
creatureTemplate.GossipMenuId = fields[11].GetUInt32();
|
||||
creatureTemplate.HealthScalingExpansion = fields[12].GetInt32();
|
||||
creatureTemplate.RequiredExpansion = fields[13].GetUInt32();
|
||||
creatureTemplate.VignetteID = fields[14].GetUInt32();
|
||||
creatureTemplate.faction = fields[15].GetUInt16();
|
||||
creatureTemplate.npcflag = fields[16].GetUInt64();
|
||||
creatureTemplate.speed_walk = fields[17].GetFloat();
|
||||
creatureTemplate.speed_run = fields[18].GetFloat();
|
||||
creatureTemplate.scale = fields[19].GetFloat();
|
||||
creatureTemplate.rank = uint32(fields[20].GetUInt8());
|
||||
creatureTemplate.dmgschool = uint32(fields[21].GetInt8());
|
||||
creatureTemplate.BaseAttackTime = fields[22].GetUInt32();
|
||||
creatureTemplate.RangeAttackTime = fields[23].GetUInt32();
|
||||
creatureTemplate.BaseVariance = fields[24].GetFloat();
|
||||
creatureTemplate.RangeVariance = fields[25].GetFloat();
|
||||
creatureTemplate.unit_class = uint32(fields[26].GetUInt8());
|
||||
creatureTemplate.unit_flags = fields[27].GetUInt32();
|
||||
creatureTemplate.unit_flags2 = fields[28].GetUInt32();
|
||||
creatureTemplate.unit_flags3 = fields[29].GetUInt32();
|
||||
creatureTemplate.dynamicflags = fields[30].GetUInt32();
|
||||
creatureTemplate.family = CreatureFamily(fields[31].GetInt32());
|
||||
creatureTemplate.trainer_class = uint32(fields[32].GetUInt8());
|
||||
creatureTemplate.type = uint32(fields[33].GetUInt8());
|
||||
creatureTemplate.type_flags = fields[34].GetUInt32();
|
||||
creatureTemplate.type_flags2 = fields[35].GetUInt32();
|
||||
creatureTemplate.lootid = fields[36].GetUInt32();
|
||||
creatureTemplate.pickpocketLootId = fields[37].GetUInt32();
|
||||
creatureTemplate.SkinLootId = fields[38].GetUInt32();
|
||||
creatureTemplate.HealthScalingExpansion = fields[11].GetInt32();
|
||||
creatureTemplate.RequiredExpansion = fields[12].GetUInt32();
|
||||
creatureTemplate.VignetteID = fields[13].GetUInt32();
|
||||
creatureTemplate.faction = fields[14].GetUInt16();
|
||||
creatureTemplate.npcflag = fields[15].GetUInt64();
|
||||
creatureTemplate.speed_walk = fields[16].GetFloat();
|
||||
creatureTemplate.speed_run = fields[17].GetFloat();
|
||||
creatureTemplate.scale = fields[18].GetFloat();
|
||||
creatureTemplate.rank = uint32(fields[19].GetUInt8());
|
||||
creatureTemplate.dmgschool = uint32(fields[20].GetInt8());
|
||||
creatureTemplate.BaseAttackTime = fields[21].GetUInt32();
|
||||
creatureTemplate.RangeAttackTime = fields[22].GetUInt32();
|
||||
creatureTemplate.BaseVariance = fields[23].GetFloat();
|
||||
creatureTemplate.RangeVariance = fields[24].GetFloat();
|
||||
creatureTemplate.unit_class = uint32(fields[25].GetUInt8());
|
||||
creatureTemplate.unit_flags = fields[26].GetUInt32();
|
||||
creatureTemplate.unit_flags2 = fields[27].GetUInt32();
|
||||
creatureTemplate.unit_flags3 = fields[28].GetUInt32();
|
||||
creatureTemplate.dynamicflags = fields[29].GetUInt32();
|
||||
creatureTemplate.family = CreatureFamily(fields[30].GetInt32());
|
||||
creatureTemplate.trainer_class = uint32(fields[31].GetUInt8());
|
||||
creatureTemplate.type = uint32(fields[32].GetUInt8());
|
||||
creatureTemplate.type_flags = fields[33].GetUInt32();
|
||||
creatureTemplate.type_flags2 = fields[34].GetUInt32();
|
||||
creatureTemplate.lootid = fields[35].GetUInt32();
|
||||
creatureTemplate.pickpocketLootId = fields[36].GetUInt32();
|
||||
creatureTemplate.SkinLootId = fields[37].GetUInt32();
|
||||
|
||||
for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
|
||||
creatureTemplate.resistance[i] = 0;
|
||||
@@ -455,51 +454,97 @@ void ObjectMgr::LoadCreatureTemplate(Field* fields)
|
||||
for (uint8 i = 0; i < MAX_CREATURE_SPELLS; ++i)
|
||||
creatureTemplate.spells[i] = 0;
|
||||
|
||||
creatureTemplate.VehicleId = fields[39].GetUInt32();
|
||||
creatureTemplate.mingold = fields[40].GetUInt32();
|
||||
creatureTemplate.maxgold = fields[41].GetUInt32();
|
||||
creatureTemplate.AIName = fields[42].GetString();
|
||||
creatureTemplate.MovementType = uint32(fields[43].GetUInt8());
|
||||
creatureTemplate.VehicleId = fields[38].GetUInt32();
|
||||
creatureTemplate.mingold = fields[39].GetUInt32();
|
||||
creatureTemplate.maxgold = fields[40].GetUInt32();
|
||||
creatureTemplate.AIName = fields[41].GetString();
|
||||
creatureTemplate.MovementType = uint32(fields[42].GetUInt8());
|
||||
if (!fields[43].IsNull())
|
||||
creatureTemplate.Movement.Ground = static_cast<CreatureGroundMovementType>(fields[43].GetUInt8());
|
||||
|
||||
if (!fields[44].IsNull())
|
||||
creatureTemplate.Movement.Ground = static_cast<CreatureGroundMovementType>(fields[44].GetUInt8());
|
||||
creatureTemplate.Movement.Swim = fields[44].GetBool();
|
||||
|
||||
if (!fields[45].IsNull())
|
||||
creatureTemplate.Movement.Swim = fields[45].GetBool();
|
||||
creatureTemplate.Movement.Flight = static_cast<CreatureFlightMovementType>(fields[45].GetUInt8());
|
||||
|
||||
if (!fields[46].IsNull())
|
||||
creatureTemplate.Movement.Flight = static_cast<CreatureFlightMovementType>(fields[46].GetUInt8());
|
||||
creatureTemplate.Movement.Rooted = fields[46].GetBool();
|
||||
|
||||
if (!fields[47].IsNull())
|
||||
creatureTemplate.Movement.Rooted = fields[47].GetBool();
|
||||
creatureTemplate.Movement.Chase = static_cast<CreatureChaseMovementType>(fields[47].GetUInt8());
|
||||
|
||||
if (!fields[48].IsNull())
|
||||
creatureTemplate.Movement.Chase = static_cast<CreatureChaseMovementType>(fields[48].GetUInt8());
|
||||
creatureTemplate.Movement.Random = static_cast<CreatureRandomMovementType>(fields[48].GetUInt8());
|
||||
|
||||
if (!fields[49].IsNull())
|
||||
creatureTemplate.Movement.Random = static_cast<CreatureRandomMovementType>(fields[49].GetUInt8());
|
||||
creatureTemplate.Movement.InteractionPauseTimer = fields[49].GetUInt32();
|
||||
|
||||
if (!fields[50].IsNull())
|
||||
creatureTemplate.Movement.InteractionPauseTimer = fields[50].GetUInt32();
|
||||
creatureTemplate.HoverHeight = fields[50].GetFloat();
|
||||
creatureTemplate.ModHealth = fields[51].GetFloat();
|
||||
creatureTemplate.ModHealthExtra = fields[52].GetFloat();
|
||||
creatureTemplate.ModMana = fields[53].GetFloat();
|
||||
creatureTemplate.ModManaExtra = fields[54].GetFloat();
|
||||
creatureTemplate.ModArmor = fields[55].GetFloat();
|
||||
creatureTemplate.ModDamage = fields[56].GetFloat();
|
||||
creatureTemplate.ModExperience = fields[57].GetFloat();
|
||||
creatureTemplate.RacialLeader = fields[58].GetBool();
|
||||
creatureTemplate.movementId = fields[59].GetUInt32();
|
||||
creatureTemplate.CreatureDifficultyID = fields[60].GetInt32();
|
||||
creatureTemplate.WidgetSetID = fields[61].GetInt32();
|
||||
creatureTemplate.WidgetSetUnitConditionID = fields[62].GetInt32();
|
||||
creatureTemplate.RegenHealth = fields[63].GetBool();
|
||||
creatureTemplate.MechanicImmuneMask = fields[64].GetUInt64();
|
||||
creatureTemplate.SpellSchoolImmuneMask = fields[65].GetUInt32();
|
||||
creatureTemplate.flags_extra = fields[66].GetUInt32();
|
||||
creatureTemplate.ScriptID = GetScriptId(fields[67].GetString());
|
||||
creatureTemplate.StringId = fields[68].GetString();
|
||||
}
|
||||
|
||||
creatureTemplate.HoverHeight = fields[51].GetFloat();
|
||||
creatureTemplate.ModHealth = fields[52].GetFloat();
|
||||
creatureTemplate.ModHealthExtra = fields[53].GetFloat();
|
||||
creatureTemplate.ModMana = fields[54].GetFloat();
|
||||
creatureTemplate.ModManaExtra = fields[55].GetFloat();
|
||||
creatureTemplate.ModArmor = fields[56].GetFloat();
|
||||
creatureTemplate.ModDamage = fields[57].GetFloat();
|
||||
creatureTemplate.ModExperience = fields[58].GetFloat();
|
||||
creatureTemplate.RacialLeader = fields[59].GetBool();
|
||||
creatureTemplate.movementId = fields[60].GetUInt32();
|
||||
creatureTemplate.CreatureDifficultyID = fields[61].GetInt32();
|
||||
creatureTemplate.WidgetSetID = fields[62].GetInt32();
|
||||
creatureTemplate.WidgetSetUnitConditionID = fields[63].GetInt32();
|
||||
creatureTemplate.RegenHealth = fields[64].GetBool();
|
||||
creatureTemplate.MechanicImmuneMask = fields[65].GetUInt64();
|
||||
creatureTemplate.SpellSchoolImmuneMask = fields[66].GetUInt32();
|
||||
creatureTemplate.flags_extra = fields[67].GetUInt32();
|
||||
creatureTemplate.ScriptID = GetScriptId(fields[68].GetString());
|
||||
creatureTemplate.StringId = fields[69].GetString();
|
||||
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::LoadCreatureTemplateResistances()
|
||||
@@ -1243,9 +1288,9 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo)
|
||||
|
||||
const_cast<CreatureTemplate*>(cInfo)->ModDamage *= Creature::_GetDamageMod(cInfo->rank);
|
||||
|
||||
if (cInfo->GossipMenuId && !(cInfo->npcflag & UNIT_NPC_FLAG_GOSSIP))
|
||||
TC_LOG_INFO("sql.sql", "Creature (Entry: {}) has assigned gossip menu {}, but npcflag does not include UNIT_NPC_FLAG_GOSSIP.", cInfo->Entry, cInfo->GossipMenuId);
|
||||
else if (!cInfo->GossipMenuId && cInfo->npcflag & UNIT_NPC_FLAG_GOSSIP)
|
||||
if (!cInfo->GossipMenuIds.empty() && !(cInfo->npcflag & UNIT_NPC_FLAG_GOSSIP))
|
||||
TC_LOG_INFO("sql.sql", "Creature (Entry: {}) 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: {}) has npcflag UNIT_NPC_FLAG_GOSSIP, but gossip menu is unassigned.", cInfo->Entry);
|
||||
}
|
||||
|
||||
|
||||
@@ -1326,6 +1326,7 @@ class TC_GAME_API ObjectMgr
|
||||
void LoadCreatureTemplates();
|
||||
void LoadCreatureTemplateAddons();
|
||||
void LoadCreatureTemplate(Field* fields);
|
||||
void LoadCreatureTemplateGossip();
|
||||
void LoadCreatureTemplateResistances();
|
||||
void LoadCreatureTemplateSpells();
|
||||
void LoadCreatureTemplateModels();
|
||||
|
||||
@@ -183,7 +183,7 @@ void WorldSession::HandleGossipHelloOpcode(WorldPackets::NPC::Hello& packet)
|
||||
if (!unit->AI()->OnGossipHello(_player))
|
||||
{
|
||||
// _player->TalkedToCreature(unit->GetEntry(), unit->GetGUID());
|
||||
_player->PrepareGossipMenu(unit, unit->GetGossipMenuId(), true);
|
||||
_player->PrepareGossipMenu(unit, _player->GetGossipMenuForSource(unit), true);
|
||||
_player->SendPreparedGossip(unit);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ void WorldSession::HandleQuestgiverHelloOpcode(WorldPackets::Quest::QuestGiverHe
|
||||
if (creature->AI()->OnGossipHello(_player))
|
||||
return;
|
||||
|
||||
_player->PrepareGossipMenu(creature, creature->GetGossipMenuId(), true);
|
||||
_player->PrepareGossipMenu(creature, _player->GetGossipMenuForSource(creature), true);
|
||||
_player->SendPreparedGossip(creature);
|
||||
}
|
||||
|
||||
|
||||
@@ -2256,6 +2256,9 @@ void World::SetInitialWorldSettings()
|
||||
TC_LOG_INFO("server.loading", "Loading Gossip menu addon...");
|
||||
sObjectMgr->LoadGossipMenuAddon();
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -678,7 +678,7 @@ public:
|
||||
|
||||
bool OnGossipHello(Player* player) override
|
||||
{
|
||||
uint32 gossipMenuId = Player::GetDefaultGossipMenuForSource(me);
|
||||
uint32 gossipMenuId = player->GetGossipMenuForSource(me);
|
||||
InitGossipMenuFor(player, gossipMenuId);
|
||||
if (player->GetQuestStatus(QUEST_DEATH_CHALLENGE) == QUEST_STATUS_INCOMPLETE && me->IsFullHealth())
|
||||
{
|
||||
@@ -688,7 +688,7 @@ public:
|
||||
if (player->IsInCombat() || me->IsInCombat())
|
||||
return true;
|
||||
|
||||
AddGossipItemFor(player, gossipMenuId, 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;
|
||||
|
||||
@@ -130,7 +130,7 @@ public:
|
||||
|
||||
bool OnGossipHello(Player* player) override
|
||||
{
|
||||
uint32 gossipMenuId = Player::GetDefaultGossipMenuForSource(me);
|
||||
uint32 gossipMenuId = player->GetGossipMenuForSource(me);
|
||||
InitGossipMenuFor(player, gossipMenuId);
|
||||
if (instance->GetData(TYPE_FREE_NPC) != DONE && instance->GetData(TYPE_RETHILGORE) == DONE)
|
||||
AddGossipItemFor(player, gossipMenuId, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
|
||||
@@ -69,7 +69,9 @@ enum Points
|
||||
|
||||
enum Misc
|
||||
{
|
||||
ITEM_VIRTUAL_ITEM = 5301
|
||||
ITEM_VIRTUAL_ITEM = 5301,
|
||||
|
||||
GOSSIP_MENU_START_INTRO = 12797,
|
||||
};
|
||||
|
||||
Position const VoljinIntroWaypoint[4] =
|
||||
@@ -104,7 +106,7 @@ class npc_voljin_zulaman : public CreatureScript
|
||||
if (_instance->GetData(DATA_ZULAMAN_STATE) != NOT_STARTED)
|
||||
return true;
|
||||
|
||||
if (me->GetGossipMenuId() == menuId && !gossipListId)
|
||||
if (menuId == GOSSIP_MENU_START_INTRO && !gossipListId)
|
||||
{
|
||||
_events.Reset();
|
||||
me->SetMountDisplayId(0);
|
||||
|
||||
@@ -104,6 +104,11 @@ enum Points
|
||||
MAX_BRANN_WAYPOINTS_INTRO = 17
|
||||
};
|
||||
|
||||
enum GossipMenuIds
|
||||
{
|
||||
GOSSIP_MENU_START_INTRO = 11339,
|
||||
};
|
||||
|
||||
Position const AnraphetActivatePos = {-193.656f, 366.689f, 75.91001f, 3.138207f};
|
||||
|
||||
Position const BrannIntroWaypoint[MAX_BRANN_WAYPOINTS_INTRO] =
|
||||
@@ -331,12 +336,12 @@ class npc_brann_bronzebeard_anraphet : public CreatureScript
|
||||
{
|
||||
npc_brann_bronzebeard_anraphetAI(Creature* creature) : CreatureAI(creature), _currentPoint(0), _instance(creature->GetInstanceScript()) { }
|
||||
|
||||
bool OnGossipSelect(Player* /*player*/, uint32 sender, uint32 action) override
|
||||
bool OnGossipSelect(Player* /*player*/, uint32 menuId, uint32 action) override
|
||||
{
|
||||
if (_instance->GetBossState(DATA_VAULT_OF_LIGHTS) == DONE)
|
||||
return true;
|
||||
|
||||
if (me->GetGossipMenuId() == sender && !action)
|
||||
if (menuId == GOSSIP_MENU_START_INTRO && !action)
|
||||
{
|
||||
_instance->SetBossState(DATA_VAULT_OF_LIGHTS, IN_PROGRESS);
|
||||
_currentPoint = 0;
|
||||
|
||||
@@ -364,7 +364,9 @@ enum MiscData
|
||||
enum Misc
|
||||
{
|
||||
DATA_PLAGUE_STACK = 70337,
|
||||
DATA_VILE = 45814622
|
||||
DATA_VILE = 45814622,
|
||||
|
||||
GOSSIP_MENU_START_INTRO = 10993
|
||||
};
|
||||
|
||||
class NecroticPlagueTargetCheck
|
||||
@@ -1193,7 +1195,7 @@ struct npc_tirion_fordring_tft : public ScriptedAI
|
||||
|
||||
bool OnGossipSelect(Player* /*player*/, uint32 menuId, uint32 gossipListId) override
|
||||
{
|
||||
if (me->GetGossipMenuId() == menuId && !gossipListId)
|
||||
if (menuId == GOSSIP_MENU_START_INTRO && !gossipListId)
|
||||
{
|
||||
_events.SetPhase(PHASE_INTRO);
|
||||
me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
|
||||
|
||||
Reference in New Issue
Block a user