aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/world/master/2023_01_12_37_world_2023_01_09_00_world.sql34
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp74
-rw-r--r--src/server/game/Entities/Creature/CreatureData.h7
-rw-r--r--src/server/game/Entities/Unit/UnitDefines.h14
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp82
5 files changed, 142 insertions, 69 deletions
diff --git a/sql/updates/world/master/2023_01_12_37_world_2023_01_09_00_world.sql b/sql/updates/world/master/2023_01_12_37_world_2023_01_09_00_world.sql
new file mode 100644
index 00000000000..c58503cbc0c
--- /dev/null
+++ b/sql/updates/world/master/2023_01_12_37_world_2023_01_09_00_world.sql
@@ -0,0 +1,34 @@
+ALTER TABLE `creature_template_addon`
+ ADD COLUMN `StandState` TINYINT UNSIGNED DEFAULT 0 NOT NULL AFTER `MountCreatureID`,
+ ADD COLUMN `AnimTier` TINYINT UNSIGNED DEFAULT 0 NOT NULL AFTER `StandState`,
+ ADD COLUMN `VisFlags` TINYINT UNSIGNED DEFAULT 0 NOT NULL AFTER `AnimTier`,
+ ADD COLUMN `SheathState` TINYINT UNSIGNED DEFAULT 1 NOT NULL AFTER `VisFlags`,
+ ADD COLUMN `PvPFlags` TINYINT UNSIGNED DEFAULT 0 NOT NULL AFTER `SheathState`;
+
+UPDATE `creature_template_addon` SET `StandState`=`bytes1` & 0xFF;
+UPDATE `creature_template_addon` SET `AnimTier`=(`bytes1` >> 24) & 0xFF;
+UPDATE `creature_template_addon` SET `VisFlags`=(`bytes1` >> 16) & 0xFF;
+UPDATE `creature_template_addon` SET `SheathState`=`bytes2` & 0xFF;
+UPDATE `creature_template_addon` SET `PvPFlags`=(`bytes2` >> 8) & 0xFF;
+
+ALTER TABLE `creature_addon`
+ ADD COLUMN `StandState` TINYINT UNSIGNED DEFAULT 0 NOT NULL AFTER `MountCreatureID`,
+ ADD COLUMN `AnimTier` TINYINT UNSIGNED DEFAULT 0 NOT NULL AFTER `StandState`,
+ ADD COLUMN `VisFlags` TINYINT UNSIGNED DEFAULT 0 NOT NULL AFTER `AnimTier`,
+ ADD COLUMN `SheathState` TINYINT UNSIGNED DEFAULT 1 NOT NULL AFTER `VisFlags`,
+ ADD COLUMN `PvPFlags` TINYINT UNSIGNED DEFAULT 0 NOT NULL AFTER `SheathState`;
+
+UPDATE `creature_addon` SET `StandState`=`bytes1` & 0xFF;
+UPDATE `creature_addon` SET `AnimTier`=(`bytes1` >> 24) & 0xFF;
+UPDATE `creature_addon` SET `VisFlags`=(`bytes1` >> 16) & 0xFF;
+UPDATE `creature_addon` SET `SheathState`=`bytes2` & 0xFF;
+UPDATE `creature_addon` SET `PvPFlags`=(`bytes2` >> 8) & 0xFF;
+
+-- Conversion done, drop old columns
+ALTER TABLE `creature_template_addon`
+ DROP COLUMN `bytes1`,
+ DROP COLUMN `bytes2`;
+
+ALTER TABLE `creature_addon`
+ DROP COLUMN `bytes1`,
+ DROP COLUMN `bytes2`;
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 57ff7b1a0a7..aace76abc41 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -2630,64 +2630,50 @@ CreatureAddon const* Creature::GetCreatureAddon() const
//creature_addon table
bool Creature::LoadCreaturesAddon()
{
- CreatureAddon const* cainfo = GetCreatureAddon();
- if (!cainfo)
+ CreatureAddon const* creatureAddon = GetCreatureAddon();
+ if (!creatureAddon)
return false;
- if (cainfo->mount != 0)
- Mount(cainfo->mount);
+ if (creatureAddon->mount != 0)
+ Mount(creatureAddon->mount);
- if (cainfo->bytes1 != 0)
- {
- // 0 StandState
- // 1 FreeTalentPoints Pet only, so always 0 for default creature
- // 2 StandFlags
- // 3 StandMiscFlags
+ SetStandState(UnitStandStateType(creatureAddon->standState));
+ ReplaceAllVisFlags(UnitVisFlags(creatureAddon->visFlags));
+ SetAnimTier(AnimTier(creatureAddon->animTier), false);
- SetStandState(UnitStandStateType(cainfo->bytes1 & 0xFF));
- ReplaceAllVisFlags(UnitVisFlags((cainfo->bytes1 >> 16) & 0xFF));
- SetAnimTier(AnimTier((cainfo->bytes1 >> 24) & 0xFF), false);
+ //! Suspected correlation between UNIT_FIELD_BYTES_1, offset 3, value 0x2:
+ //! If no inhabittype_fly (if no MovementFlag_DisableGravity or MovementFlag_CanFly flag found in sniffs)
+ //! Check using InhabitType as movement flags are assigned dynamically
+ //! basing on whether the creature is in air or not
+ //! Set MovementFlag_Hover. Otherwise do nothing.
+ if (CanHover())
+ AddUnitMovementFlag(MOVEMENTFLAG_HOVER);
- //! Suspected correlation between UNIT_FIELD_BYTES_1, offset 3, value 0x2:
- //! If no inhabittype_fly (if no MovementFlag_DisableGravity or MovementFlag_CanFly flag found in sniffs)
- //! Check using InhabitType as movement flags are assigned dynamically
- //! basing on whether the creature is in air or not
- //! Set MovementFlag_Hover. Otherwise do nothing.
- if (CanHover())
- AddUnitMovementFlag(MOVEMENTFLAG_HOVER);
- }
+ SetSheath(SheathState(creatureAddon->sheathState));
+ ReplaceAllPvpFlags(UnitPVPStateFlags(creatureAddon->pvpFlags));
- if (cainfo->bytes2 != 0)
- {
- // 0 SheathState
- // 1 PvpFlags
- // 2 PetFlags Pet only, so always 0 for default creature
- // 3 ShapeshiftForm Must be determined/set by shapeshift spell/aura
-
- SetSheath(SheathState(cainfo->bytes2 & 0xFF));
- ReplaceAllPvpFlags(UnitPVPStateFlags((cainfo->bytes2 >> 8) & 0xFF));
- ReplaceAllPetFlags(UNIT_PET_FLAG_NONE);
- SetShapeshiftForm(FORM_NONE);
- }
+ // These fields must only be handled by core internals and must not be modified via scripts/DB dat
+ ReplaceAllPetFlags(UNIT_PET_FLAG_NONE);
+ SetShapeshiftForm(FORM_NONE);
- if (cainfo->emote != 0)
- SetEmoteState(Emote(cainfo->emote));
+ if (creatureAddon->emote != 0)
+ SetEmoteState(Emote(creatureAddon->emote));
- SetAIAnimKitId(cainfo->aiAnimKit);
- SetMovementAnimKitId(cainfo->movementAnimKit);
- SetMeleeAnimKitId(cainfo->meleeAnimKit);
+ SetAIAnimKitId(creatureAddon->aiAnimKit);
+ SetMovementAnimKitId(creatureAddon->movementAnimKit);
+ SetMeleeAnimKitId(creatureAddon->meleeAnimKit);
// Check if visibility distance different
- if (cainfo->visibilityDistanceType != VisibilityDistanceType::Normal)
- SetVisibilityDistanceOverride(cainfo->visibilityDistanceType);
+ if (creatureAddon->visibilityDistanceType != VisibilityDistanceType::Normal)
+ SetVisibilityDistanceOverride(creatureAddon->visibilityDistanceType);
// Load Path
- if (cainfo->path_id != 0)
- _waypointPathId = cainfo->path_id;
+ if (creatureAddon->path_id != 0)
+ _waypointPathId = creatureAddon->path_id;
- if (!cainfo->auras.empty())
+ if (!creatureAddon->auras.empty())
{
- for (std::vector<uint32>::const_iterator itr = cainfo->auras.begin(); itr != cainfo->auras.end(); ++itr)
+ for (std::vector<uint32>::const_iterator itr = creatureAddon->auras.begin(); itr != creatureAddon->auras.end(); ++itr)
{
SpellInfo const* AdditionalSpellInfo = sSpellMgr->GetSpellInfo(*itr, GetMap()->GetDifficultyID());
if (!AdditionalSpellInfo)
diff --git a/src/server/game/Entities/Creature/CreatureData.h b/src/server/game/Entities/Creature/CreatureData.h
index 45ded7b5011..09b758d7af3 100644
--- a/src/server/game/Entities/Creature/CreatureData.h
+++ b/src/server/game/Entities/Creature/CreatureData.h
@@ -645,8 +645,11 @@ struct CreatureAddon
{
uint32 path_id;
uint32 mount;
- uint32 bytes1;
- uint32 bytes2;
+ uint8 standState;
+ uint8 animTier;
+ uint8 sheathState;
+ uint8 pvpFlags;
+ uint8 visFlags;
uint32 emote;
uint16 aiAnimKit;
uint16 movementAnimKit;
diff --git a/src/server/game/Entities/Unit/UnitDefines.h b/src/server/game/Entities/Unit/UnitDefines.h
index 93adec7dd4b..759f3070458 100644
--- a/src/server/game/Entities/Unit/UnitDefines.h
+++ b/src/server/game/Entities/Unit/UnitDefines.h
@@ -43,7 +43,9 @@ enum UnitStandStateType : uint8
UNIT_STAND_STATE_SIT_HIGH_CHAIR = 6,
UNIT_STAND_STATE_DEAD = 7,
UNIT_STAND_STATE_KNEEL = 8,
- UNIT_STAND_STATE_SUBMERGED = 9
+ UNIT_STAND_STATE_SUBMERGED = 9,
+
+ MAX_UNIT_STAND_STATE
};
// byte flag value (UNIT_FIELD_BYTES_1, 2)
@@ -64,7 +66,9 @@ enum class AnimTier : uint8
Swim = 1, // falls back to ground tier animations, not handled by the client, should never appear in sniffs, will prevent tier change animations from playing correctly if used
Hover = 2, // plays flying tier animations or falls back to ground tier animations, automatically enables hover clientside when entering visibility with this value
Fly = 3, // plays flying tier animations
- Submerged = 4
+ Submerged = 4,
+
+ Max
};
// low byte (0 from 0..3) of UNIT_FIELD_BYTES_2
@@ -72,10 +76,10 @@ enum SheathState : uint8
{
SHEATH_STATE_UNARMED = 0, // non prepared weapon
SHEATH_STATE_MELEE = 1, // prepared melee weapon
- SHEATH_STATE_RANGED = 2 // prepared ranged weapon
-};
+ SHEATH_STATE_RANGED = 2, // prepared ranged weapon
-#define MAX_SHEATH_STATE 3
+ MAX_SHEATH_STATE
+};
// byte (1 from 0..3) of UNIT_FIELD_BYTES_2
enum UnitPVPStateFlags : uint8
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 432addd74a7..bf6bb94889b 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -715,8 +715,8 @@ void ObjectMgr::LoadCreatureTemplateAddons()
{
uint32 oldMSTime = getMSTime();
- // 0 1 2 3 4 5 6 7 8 9 10
- QueryResult result = WorldDatabase.Query("SELECT entry, path_id, mount, bytes1, bytes2, emote, aiAnimKit, movementAnimKit, meleeAnimKit, visibilityDistanceType, auras FROM creature_template_addon");
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12
+ QueryResult result = WorldDatabase.Query("SELECT entry, path_id, mount, StandState, AnimTier, VisFlags, SheathState, PvPFlags, emote, aiAnimKit, movementAnimKit, meleeAnimKit, visibilityDistanceType, auras FROM creature_template_addon");
if (!result)
{
@@ -741,13 +741,16 @@ void ObjectMgr::LoadCreatureTemplateAddons()
creatureAddon.path_id = fields[1].GetUInt32();
creatureAddon.mount = fields[2].GetUInt32();
- creatureAddon.bytes1 = fields[3].GetUInt32();
- creatureAddon.bytes2 = fields[4].GetUInt32();
- creatureAddon.emote = fields[5].GetUInt32();
- creatureAddon.aiAnimKit = fields[6].GetUInt16();
- creatureAddon.movementAnimKit = fields[7].GetUInt16();
- creatureAddon.meleeAnimKit = fields[8].GetUInt16();
- creatureAddon.visibilityDistanceType = VisibilityDistanceType(fields[9].GetUInt8());
+ creatureAddon.standState = fields[3].GetUInt8();
+ creatureAddon.animTier = fields[4].GetUInt8();
+ creatureAddon.visFlags = fields[5].GetUInt8();
+ creatureAddon.sheathState = fields[6].GetUInt8();
+ creatureAddon.pvpFlags = fields[7].GetUInt8();
+ creatureAddon.emote = fields[8].GetUInt32();
+ creatureAddon.aiAnimKit = fields[9].GetUInt16();
+ creatureAddon.movementAnimKit = fields[10].GetUInt16();
+ creatureAddon.meleeAnimKit = fields[11].GetUInt16();
+ creatureAddon.visibilityDistanceType = VisibilityDistanceType(fields[12].GetUInt8());
for (std::string_view aura : Trinity::Tokenize(fields[10].GetStringView(), ' ', false))
{
@@ -788,6 +791,26 @@ void ObjectMgr::LoadCreatureTemplateAddons()
}
}
+ if (creatureAddon.standState >= MAX_UNIT_STAND_STATE)
+ {
+ TC_LOG_ERROR("sql.sql", "Creature (Entry: {}) has invalid unit stand state ({}) defined in `creature_addon`. Truncated to 0.", entry, creatureAddon.standState);
+ creatureAddon.standState = 0;
+ }
+
+ if (AnimTier(creatureAddon.animTier) >= AnimTier::Max)
+ {
+ TC_LOG_ERROR("sql.sql", "Creature (Entry: {}) has invalid animation tier ({}) defined in `creature_addon`. Truncated to 0.", entry, creatureAddon.animTier);
+ creatureAddon.animTier = 0;
+ }
+
+ if (creatureAddon.sheathState >= MAX_SHEATH_STATE)
+ {
+ TC_LOG_ERROR("sql.sql", "Creature (Entry: {}) has invalid sheath state ({}) defined in `creature_addon`. Truncated to 0.", entry, creatureAddon.sheathState);
+ creatureAddon.sheathState = 0;
+ }
+
+ // PvPFlags don't need any checking for the time being since they cover the entire range of a byte
+
if (!sEmotesStore.LookupEntry(creatureAddon.emote))
{
TC_LOG_ERROR("sql.sql", "Creature (Entry: {}) has invalid emote ({}) defined in `creature_template_addon`.", entry, creatureAddon.emote);
@@ -1277,8 +1300,8 @@ void ObjectMgr::LoadCreatureAddons()
{
uint32 oldMSTime = getMSTime();
- // 0 1 2 3 4 5 6 7 8 9 10
- QueryResult result = WorldDatabase.Query("SELECT guid, path_id, mount, bytes1, bytes2, emote, aiAnimKit, movementAnimKit, meleeAnimKit, visibilityDistanceType, auras FROM creature_addon");
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12
+ QueryResult result = WorldDatabase.Query("SELECT guid, path_id, mount, StandState, AnimTier, VisFlags, SheathState, PvPFlags, emote, aiAnimKit, movementAnimKit, meleeAnimKit, visibilityDistanceType, auras FROM creature_addon");
if (!result)
{
@@ -1310,13 +1333,16 @@ void ObjectMgr::LoadCreatureAddons()
}
creatureAddon.mount = fields[2].GetUInt32();
- creatureAddon.bytes1 = fields[3].GetUInt32();
- creatureAddon.bytes2 = fields[4].GetUInt32();
- creatureAddon.emote = fields[5].GetUInt32();
- creatureAddon.aiAnimKit = fields[6].GetUInt16();
- creatureAddon.movementAnimKit = fields[7].GetUInt16();
- creatureAddon.meleeAnimKit = fields[8].GetUInt16();
- creatureAddon.visibilityDistanceType = VisibilityDistanceType(fields[9].GetUInt8());
+ creatureAddon.standState = fields[3].GetUInt8();
+ creatureAddon.animTier = fields[4].GetUInt8();
+ creatureAddon.visFlags = fields[5].GetUInt8();
+ creatureAddon.sheathState = fields[6].GetUInt8();
+ creatureAddon.pvpFlags = fields[7].GetUInt8();
+ creatureAddon.emote = fields[8].GetUInt32();
+ creatureAddon.aiAnimKit = fields[9].GetUInt16();
+ creatureAddon.movementAnimKit = fields[10].GetUInt16();
+ creatureAddon.meleeAnimKit = fields[11].GetUInt16();
+ creatureAddon.visibilityDistanceType = VisibilityDistanceType(fields[12].GetUInt8());
for (std::string_view aura : Trinity::Tokenize(fields[10].GetStringView(), ' ', false))
{
@@ -1357,6 +1383,26 @@ void ObjectMgr::LoadCreatureAddons()
}
}
+ if (creatureAddon.standState >= MAX_UNIT_STAND_STATE)
+ {
+ TC_LOG_ERROR("sql.sql", "Creature (GUID: {}) has invalid unit stand state ({}) defined in `creature_addon`. Truncated to 0.", guid, creatureAddon.standState);
+ creatureAddon.standState = 0;
+ }
+
+ if (AnimTier(creatureAddon.animTier) >= AnimTier::Max)
+ {
+ TC_LOG_ERROR("sql.sql", "Creature (GUID: {}) has invalid animation tier ({}) defined in `creature_addon`. Truncated to 0.", guid, creatureAddon.animTier);
+ creatureAddon.animTier = 0;
+ }
+
+ if (creatureAddon.sheathState >= MAX_SHEATH_STATE)
+ {
+ TC_LOG_ERROR("sql.sql", "Creature (GUID: {}) has invalid sheath state ({}) defined in `creature_addon`. Truncated to 0.", guid, creatureAddon.sheathState);
+ creatureAddon.sheathState = 0;
+ }
+
+ // PvPFlags don't need any checking for the time being since they cover the entire range of a byte
+
if (!sEmotesStore.LookupEntry(creatureAddon.emote))
{
TC_LOG_ERROR("sql.sql", "Creature (GUID: {}) has invalid emote ({}) defined in `creature_addon`.", guid, creatureAddon.emote);