diff options
-rw-r--r-- | sql/updates/world/master/2022_03_05_91_world_2021_01_22_01_world.sql | 16 | ||||
-rw-r--r-- | src/server/database/Database/Implementation/WorldDatabase.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/Creature.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/CreatureData.h | 6 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 77 | ||||
-rw-r--r-- | src/server/game/Handlers/BattleGroundHandler.cpp | 3 | ||||
-rw-r--r-- | src/server/game/Handlers/ItemHandler.cpp | 3 | ||||
-rw-r--r-- | src/server/game/Handlers/NPCHandler.cpp | 3 | ||||
-rw-r--r-- | src/server/game/Handlers/QuestHandler.cpp | 3 |
9 files changed, 83 insertions, 34 deletions
diff --git a/sql/updates/world/master/2022_03_05_91_world_2021_01_22_01_world.sql b/sql/updates/world/master/2022_03_05_91_world_2021_01_22_01_world.sql new file mode 100644 index 00000000000..7b6a52d70ae --- /dev/null +++ b/sql/updates/world/master/2022_03_05_91_world_2021_01_22_01_world.sql @@ -0,0 +1,16 @@ +-- +ALTER TABLE `creature_template_movement` CHANGE `Ground` `Ground` TINYINT(3) UNSIGNED DEFAULT NULL NULL; +ALTER TABLE `creature_template_movement` CHANGE `Swim` `Swim` TINYINT(3) UNSIGNED DEFAULT NULL NULL; +ALTER TABLE `creature_template_movement` CHANGE `Flight` `Flight` TINYINT(3) UNSIGNED DEFAULT NULL NULL; +ALTER TABLE `creature_template_movement` CHANGE `Rooted` `Rooted` TINYINT(3) UNSIGNED DEFAULT NULL NULL; +ALTER TABLE `creature_template_movement` CHANGE `Chase` `Chase` TINYINT(3) UNSIGNED DEFAULT NULL NULL; +ALTER TABLE `creature_template_movement` CHANGE `Random` `Random` TINYINT(3) UNSIGNED DEFAULT NULL NULL; +ALTER TABLE `creature_template_movement` ADD COLUMN `InteractionPauseTimer` INT(10) UNSIGNED DEFAULT NULL NULL COMMENT 'Time (in milliseconds) during which creature will not move after interaction with player' AFTER `Random`; + +ALTER TABLE `creature_movement_override` CHANGE `Ground` `Ground` TINYINT(3) UNSIGNED DEFAULT NULL NULL; +ALTER TABLE `creature_movement_override` CHANGE `Swim` `Swim` TINYINT(3) UNSIGNED DEFAULT NULL NULL; +ALTER TABLE `creature_movement_override` CHANGE `Flight` `Flight` TINYINT(3) UNSIGNED DEFAULT NULL NULL; +ALTER TABLE `creature_movement_override` CHANGE `Rooted` `Rooted` TINYINT(3) UNSIGNED DEFAULT NULL NULL; +ALTER TABLE `creature_movement_override` CHANGE `Chase` `Chase` TINYINT(3) UNSIGNED DEFAULT NULL NULL; +ALTER TABLE `creature_movement_override` CHANGE `Random` `Random` TINYINT(3) UNSIGNED DEFAULT NULL NULL; +ALTER TABLE `creature_movement_override` ADD COLUMN `InteractionPauseTimer` INT(10) UNSIGNED DEFAULT NULL NULL COMMENT 'Time (in milliseconds) during which creature will not move after interaction with player' AFTER `Random`; diff --git a/src/server/database/Database/Implementation/WorldDatabase.cpp b/src/server/database/Database/Implementation/WorldDatabase.cpp index 3c87a79111e..b7bd1fb0991 100644 --- a/src/server/database/Database/Implementation/WorldDatabase.cpp +++ b/src/server/database/Database/Implementation/WorldDatabase.cpp @@ -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, minlevel, maxlevel, 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, HoverHeight, HealthModifier, HealthModifierExtra, ManaModifier, ManaModifierExtra, ArmorModifier, DamageModifier, ExperienceModifier, RacialLeader, movementId, CreatureDifficultyID, WidgetSetID, WidgetSetUnitConditionID, RegenHealth, mechanic_immune_mask, spell_school_immune_mask, flags_extra, ScriptName 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, gossip_menu_id, minlevel, maxlevel, 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 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); diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index f33ed67c810..d6df4e1be9c 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -55,6 +55,9 @@ #include <G3D/g3dmath.h> #include <sstream> +CreatureMovementData::CreatureMovementData() : Ground(CreatureGroundMovementType::Run), Flight(CreatureFlightMovementType::None), Swim(true), Rooted(false), Chase(CreatureChaseMovementType::Run), +Random(CreatureRandomMovementType::Walk), InteractionPauseTimer(sWorld->getIntConfig(CONFIG_CREATURE_STOP_FOR_PLAYER)) { } + std::string CreatureMovementData::ToString() const { char const* const GroundStates[] = { "None", "Run", "Hover" }; @@ -71,6 +74,7 @@ std::string CreatureMovementData::ToString() const << ", Random: " << RandomStates[AsUnderlyingType(Random)]; if (Rooted) str << ", Rooted"; + str << ", InteractionPauseTimer: " << InteractionPauseTimer; return str.str(); } diff --git a/src/server/game/Entities/Creature/CreatureData.h b/src/server/game/Entities/Creature/CreatureData.h index afaa9851274..1497295a0d4 100644 --- a/src/server/game/Entities/Creature/CreatureData.h +++ b/src/server/game/Entities/Creature/CreatureData.h @@ -337,8 +337,7 @@ enum class CreatureRandomMovementType : uint8 struct TC_GAME_API CreatureMovementData { - CreatureMovementData() : Ground(CreatureGroundMovementType::Run), Flight(CreatureFlightMovementType::None), Swim(true), Rooted(false), Chase(CreatureChaseMovementType::Run), - Random(CreatureRandomMovementType::Walk) { } + CreatureMovementData(); CreatureGroundMovementType Ground; CreatureFlightMovementType Flight; @@ -346,6 +345,7 @@ struct TC_GAME_API CreatureMovementData bool Rooted; CreatureChaseMovementType Chase; CreatureRandomMovementType Random; + uint32 InteractionPauseTimer; bool IsGroundAllowed() const { return Ground != CreatureGroundMovementType::None; } bool IsSwimAllowed() const { return Swim; } @@ -355,6 +355,8 @@ struct TC_GAME_API CreatureMovementData CreatureChaseMovementType GetChase() const { return Chase; } CreatureRandomMovementType GetRandom() const { return Random; } + uint32 GetInteractionPauseTimer() const { return InteractionPauseTimer; } + std::string ToString() const; }; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index bb31ea2dcb2..8aafd9306b6 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -358,8 +358,8 @@ void ObjectMgr::LoadCreatureTemplates() // "unit_class, unit_flags, unit_flags2, unit_flags3, dynamicflags, family, trainer_class, type, " // 36 37 38 39 40 41 42 43 44 45 // "type_flags, type_flags2, lootid, pickpocketloot, skinloot, VehicleId, mingold, maxgold, AIName, MovementType, " - // 46 47 48 49 50 51 52 53 54 55 56 57 58 59 - // "ctm.Ground, ctm.Swim, ctm.Flight, ctm.Rooted, ctm.Chase, ctm.Random, HoverHeight, HealthModifier, HealthModifierExtra, ManaModifier, ManaModifierExtra, ArmorModifier, DamageModifier, ExperienceModifier, " + // 46 47 48 49 50 51 52 53 54 55 56 57 58 59 + // "ctm.Ground, ctm.Swim, ctm.Flight, ctm.Rooted, ctm.Chase, ctm.Random, ctm.InteractionPauseTimer, HoverHeight, HealthModifier, HealthModifierExtra, ManaModifier, ManaModifierExtra, ArmorModifier, DamageModifier, ExperienceModifier, " // 60 61 62 63 64 65 // "RacialLeader, movementId, CreatureDifficultyID, WidgetSetID, WidgetSetUnitConditionID, RegenHealth, " // 66 67 68 @@ -476,24 +476,27 @@ void ObjectMgr::LoadCreatureTemplate(Field* fields) if (!fields[51].IsNull()) creatureTemplate.Movement.Random = static_cast<CreatureRandomMovementType>(fields[51].GetUInt8()); - creatureTemplate.HoverHeight = fields[52].GetFloat(); - creatureTemplate.ModHealth = fields[53].GetFloat(); - creatureTemplate.ModHealthExtra = fields[54].GetFloat(); - creatureTemplate.ModMana = fields[55].GetFloat(); - creatureTemplate.ModManaExtra = fields[56].GetFloat(); - creatureTemplate.ModArmor = fields[57].GetFloat(); - creatureTemplate.ModDamage = fields[58].GetFloat(); - creatureTemplate.ModExperience = fields[59].GetFloat(); - creatureTemplate.RacialLeader = fields[60].GetBool(); - creatureTemplate.movementId = fields[61].GetUInt32(); - creatureTemplate.CreatureDifficultyID = fields[62].GetInt32(); - creatureTemplate.WidgetSetID = fields[63].GetInt32(); - creatureTemplate.WidgetSetUnitConditionID = fields[64].GetInt32(); - creatureTemplate.RegenHealth = fields[65].GetBool(); - creatureTemplate.MechanicImmuneMask = fields[66].GetUInt32(); - creatureTemplate.SpellSchoolImmuneMask = fields[67].GetUInt32(); - creatureTemplate.flags_extra = fields[68].GetUInt32(); - creatureTemplate.ScriptID = GetScriptId(fields[69].GetString()); + if (!fields[52].IsNull()) + creatureTemplate.Movement.InteractionPauseTimer = fields[52].GetUInt32(); + + creatureTemplate.HoverHeight = fields[53].GetFloat(); + creatureTemplate.ModHealth = fields[54].GetFloat(); + creatureTemplate.ModHealthExtra = fields[55].GetFloat(); + creatureTemplate.ModMana = fields[56].GetFloat(); + creatureTemplate.ModManaExtra = fields[57].GetFloat(); + creatureTemplate.ModArmor = fields[58].GetFloat(); + creatureTemplate.ModDamage = fields[59].GetFloat(); + creatureTemplate.ModExperience = fields[50].GetFloat(); + creatureTemplate.RacialLeader = fields[61].GetBool(); + creatureTemplate.movementId = fields[62].GetUInt32(); + creatureTemplate.CreatureDifficultyID = fields[63].GetInt32(); + creatureTemplate.WidgetSetID = fields[64].GetInt32(); + creatureTemplate.WidgetSetUnitConditionID = fields[65].GetInt32(); + creatureTemplate.RegenHealth = fields[66].GetBool(); + creatureTemplate.MechanicImmuneMask = fields[67].GetUInt32(); + creatureTemplate.SpellSchoolImmuneMask = fields[68].GetUInt32(); + creatureTemplate.flags_extra = fields[69].GetUInt32(); + creatureTemplate.ScriptID = GetScriptId(fields[70].GetString()); } void ObjectMgr::LoadCreatureTemplateResistances() @@ -1527,7 +1530,19 @@ void ObjectMgr::LoadCreatureMovementOverrides() _creatureMovementOverrides.clear(); - QueryResult result = WorldDatabase.Query("SELECT SpawnId, Ground, Swim, Flight, Rooted, Chase, Random from creature_movement_override"); + // Load the data from creature_movement_override and if NULL fallback to creature_template_movement + QueryResult result = WorldDatabase.Query( + "SELECT cmo.SpawnId," + "COALESCE(cmo.Ground, ctm.Ground)," + "COALESCE(cmo.Swim, ctm.Swim)," + "COALESCE(cmo.Flight, ctm.Flight)," + "COALESCE(cmo.Rooted, ctm.Rooted)," + "COALESCE(cmo.Chase, ctm.Chase)," + "COALESCE(cmo.Random, ctm.Random)," + "COALESCE(cmo.InteractionPauseTimer, ctm.InteractionPauseTimer) " + "FROM creature_movement_override AS cmo " + "LEFT JOIN creature AS c ON c.guid = cmo.SpawnId " + "LEFT JOIN creature_template_movement AS ctm ON ctm.CreatureId = c.id"); if (!result) { @@ -1546,12 +1561,20 @@ void ObjectMgr::LoadCreatureMovementOverrides() } CreatureMovementData& movement = _creatureMovementOverrides[spawnId]; - movement.Ground = static_cast<CreatureGroundMovementType>(fields[1].GetUInt8()); - movement.Swim = fields[2].GetBool(); - movement.Flight = static_cast<CreatureFlightMovementType>(fields[3].GetUInt8()); - movement.Rooted = fields[4].GetBool(); - movement.Chase = static_cast<CreatureChaseMovementType>(fields[5].GetUInt8()); - movement.Random = static_cast<CreatureRandomMovementType>(fields[6].GetUInt8()); + if (!fields[1].IsNull()) + movement.Ground = static_cast<CreatureGroundMovementType>(fields[1].GetUInt8()); + if (!fields[2].IsNull()) + movement.Swim = fields[2].GetBool(); + if (!fields[3].IsNull()) + movement.Flight = static_cast<CreatureFlightMovementType>(fields[3].GetUInt8()); + if (!fields[4].IsNull()) + movement.Rooted = fields[4].GetBool(); + if (!fields[5].IsNull()) + movement.Chase = static_cast<CreatureChaseMovementType>(fields[5].GetUInt8()); + if (!fields[6].IsNull()) + movement.Random = static_cast<CreatureRandomMovementType>(fields[6].GetUInt8()); + if (!fields[7].IsNull()) + movement.InteractionPauseTimer = fields[7].GetUInt32(); CheckCreatureMovement("creature_movement_override", spawnId, movement); } diff --git a/src/server/game/Handlers/BattleGroundHandler.cpp b/src/server/game/Handlers/BattleGroundHandler.cpp index 605c2785dea..7928905cebf 100644 --- a/src/server/game/Handlers/BattleGroundHandler.cpp +++ b/src/server/game/Handlers/BattleGroundHandler.cpp @@ -44,7 +44,8 @@ void WorldSession::HandleBattlemasterHelloOpcode(WorldPackets::NPC::Hello& hello return; // Stop the npc if moving - unit->PauseMovement(sWorld->getIntConfig(CONFIG_CREATURE_STOP_FOR_PLAYER)); + if (uint32 pause = unit->GetMovementTemplate().GetInteractionPauseTimer()) + unit->PauseMovement(pause); unit->SetHomePosition(unit->GetPosition()); BattlegroundTypeId bgTypeId = sBattlegroundMgr->GetBattleMasterBG(unit->GetEntry()); diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index 696eb7290fa..c7762fe397c 100644 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -606,7 +606,8 @@ void WorldSession::SendListInventory(ObjectGuid vendorGuid) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); // Stop the npc if moving - vendor->PauseMovement(sWorld->getIntConfig(CONFIG_CREATURE_STOP_FOR_PLAYER)); + if (uint32 pause = vendor->GetMovementTemplate().GetInteractionPauseTimer()) + vendor->PauseMovement(pause); vendor->SetHomePosition(vendor->GetPosition()); VendorItemData const* vendorItems = vendor->GetVendorItems(); diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp index 5496515cc09..4366175f1b7 100644 --- a/src/server/game/Handlers/NPCHandler.cpp +++ b/src/server/game/Handlers/NPCHandler.cpp @@ -161,7 +161,8 @@ void WorldSession::HandleGossipHelloOpcode(WorldPackets::NPC::Hello& packet) GetPlayer()->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::Interacting); // Stop the npc if moving - unit->PauseMovement(sWorld->getIntConfig(CONFIG_CREATURE_STOP_FOR_PLAYER)); + if (uint32 pause = unit->GetMovementTemplate().GetInteractionPauseTimer()) + unit->PauseMovement(pause); unit->SetHomePosition(unit->GetPosition()); // If spiritguide, no need for gossip menu, just put player into resurrect queue diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index 90260a8b593..4683c3a177c 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -90,7 +90,8 @@ void WorldSession::HandleQuestgiverHelloOpcode(WorldPackets::Quest::QuestGiverHe GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); // Stop the npc if moving - creature->PauseMovement(sWorld->getIntConfig(CONFIG_CREATURE_STOP_FOR_PLAYER)); + if (uint32 pause = creature->GetMovementTemplate().GetInteractionPauseTimer()) + creature->PauseMovement(pause); creature->SetHomePosition(creature->GetPosition()); _player->PlayerTalkClass->ClearMenus(); |