diff --git a/data/sql/updates/pending_db_world/rev_1652621127582675200.sql b/data/sql/updates/pending_db_world/rev_1652621127582675200.sql new file mode 100644 index 000000000..a95dc6d3d --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1652621127582675200.sql @@ -0,0 +1,26 @@ +-- +DROP TABLE IF EXISTS `creaturedisplayinfoextra_dbc`; +CREATE TABLE `creaturedisplayinfoextra_dbc` +( `ID` INT UNSIGNED NOT NULL DEFAULT '0', +`DisplayRaceID` INT UNSIGNED NOT NULL DEFAULT '0', +`DisplaySexID` INT UNSIGNED NOT NULL DEFAULT '0', +`SkinID` INT UNSIGNED NOT NULL DEFAULT '0', +`FaceID` INT UNSIGNED NOT NULL DEFAULT '0', +`HairStyleID` INT UNSIGNED NOT NULL DEFAULT '0', +`HairColorID` INT UNSIGNED NOT NULL DEFAULT '0', +`FacialHairID` INT UNSIGNED NOT NULL DEFAULT '0', +`NPCItemDisplay1` INT UNSIGNED NOT NULL DEFAULT '0', +`NPCItemDisplay2` INT UNSIGNED NOT NULL DEFAULT '0', +`NPCItemDisplay3` INT UNSIGNED NOT NULL DEFAULT '0', +`NPCItemDisplay4` INT UNSIGNED NOT NULL DEFAULT '0', +`NPCItemDisplay5` INT UNSIGNED NOT NULL DEFAULT '0', +`NPCItemDisplay6` INT UNSIGNED NOT NULL DEFAULT '0', +`NPCItemDisplay7` INT UNSIGNED NOT NULL DEFAULT '0', +`NPCItemDisplay8` INT UNSIGNED NOT NULL DEFAULT '0', +`NPCItemDisplay9` INT UNSIGNED NOT NULL DEFAULT '0', +`NPCItemDisplay10` INT UNSIGNED NOT NULL DEFAULT '0', +`NPCItemDisplay11` INT UNSIGNED NOT NULL DEFAULT '0', +`Flags` INT UNSIGNED NOT NULL DEFAULT '0', +`BakeName` VARCHAR(100) NOT NULL, +PRIMARY KEY (`ID`) ) +ENGINE=MYISAM CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index b9ff31654..c396c3c1e 100644 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -56,6 +56,7 @@ DBCStorage sChrRacesStore(ChrRacesEntryfmt); DBCStorage sCinematicCameraStore(CinematicCameraEntryfmt); DBCStorage sCinematicSequencesStore(CinematicSequencesEntryfmt); DBCStorage sCreatureDisplayInfoStore(CreatureDisplayInfofmt); +DBCStorage sCreatureDisplayInfoExtraStore(CreatureDisplayInfoExtrafmt); DBCStorage sCreatureFamilyStore(CreatureFamilyfmt); DBCStorage sCreatureModelDataStore(CreatureModelDatafmt); DBCStorage sCreatureSpellDataStore(CreatureSpellDatafmt); @@ -279,6 +280,7 @@ void LoadDBCStores(const std::string& dataPath) LOAD_DBC(sCinematicCameraStore, "CinematicCamera.dbc", "cinematiccamera_dbc"); LOAD_DBC(sCinematicSequencesStore, "CinematicSequences.dbc", "cinematicsequences_dbc"); LOAD_DBC(sCreatureDisplayInfoStore, "CreatureDisplayInfo.dbc", "creaturedisplayinfo_dbc"); + LOAD_DBC(sCreatureDisplayInfoExtraStore, "CreatureDisplayInfoExtra.dbc", "creaturedisplayinfoextra_dbc"); LOAD_DBC(sCreatureFamilyStore, "CreatureFamily.dbc", "creaturefamily_dbc"); LOAD_DBC(sCreatureModelDataStore, "CreatureModelData.dbc", "creaturemodeldata_dbc"); LOAD_DBC(sCreatureSpellDataStore, "CreatureSpellData.dbc", "creaturespelldata_dbc"); diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h index 046071e06..cd122c788 100644 --- a/src/server/game/DataStores/DBCStores.h +++ b/src/server/game/DataStores/DBCStores.h @@ -90,6 +90,7 @@ extern DBCStorage sChrRacesStore; extern DBCStorage sCinematicCameraStore; extern DBCStorage sCinematicSequencesStore; extern DBCStorage sCreatureDisplayInfoStore; +extern DBCStorage sCreatureDisplayInfoExtraStore; extern DBCStorage sCreatureFamilyStore; extern DBCStorage sCreatureModelDataStore; extern DBCStorage sCreatureSpellDataStore; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index aa6f0891a..1595ddcb4 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -20669,3 +20669,58 @@ bool Unit::CanRestoreMana(SpellInfo const* spellInfo) const return false; } + +bool Unit::IsInDisallowedMountForm() const +{ + if (SpellInfo const* transformSpellInfo = sSpellMgr->GetSpellInfo(getTransForm())) + { + if (transformSpellInfo->HasAttribute(SPELL_ATTR0_ALLOW_WHILE_MOUNTED)) + { + return false; + } + } + + if (ShapeshiftForm form = GetShapeshiftForm()) + { + SpellShapeshiftEntry const* shapeshift = sSpellShapeshiftStore.LookupEntry(form); + if (!shapeshift) + { + return true; + } + + if (!(shapeshift->flags1 & 0x1)) + { + return true; + } + } + + if (GetDisplayId() == GetNativeDisplayId()) + { + return false; + } + + CreatureDisplayInfoEntry const* display = sCreatureDisplayInfoStore.LookupEntry(GetDisplayId()); + if (!display) + { + return true; + } + + CreatureDisplayInfoExtraEntry const* displayExtra = sCreatureDisplayInfoExtraStore.LookupEntry(display->ExtendedDisplayInfoID); + if (!displayExtra) + { + return true; + } + + CreatureModelDataEntry const* model = sCreatureModelDataStore.LookupEntry(display->ModelId); + ChrRacesEntry const* race = sChrRacesStore.LookupEntry(displayExtra->DisplayRaceID); + + if (model && !(model->HasFlag(CREATURE_MODEL_DATA_FLAGS_CAN_MOUNT))) + { + if (race && !(race->HasFlag(CHRRACES_FLAGS_CAN_MOUNT))) + { + return true; + } + } + + return false; +} diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 02f2943ff..55b133428 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -2034,18 +2034,13 @@ public: SetByteValue(UNIT_FIELD_BYTES_2, 3, form); } - [[nodiscard]] inline bool IsInFeralForm() const + [[nodiscard]] bool IsInFeralForm() const { ShapeshiftForm form = GetShapeshiftForm(); return form == FORM_CAT || form == FORM_BEAR || form == FORM_DIREBEAR || form == FORM_GHOSTWOLF; // Xinef: added shamans Ghost Wolf, should behave exactly like druid forms } - [[nodiscard]] inline bool IsInDisallowedMountForm() const - { - ShapeshiftForm form = GetShapeshiftForm(); - return form != FORM_NONE && form != FORM_BATTLESTANCE && form != FORM_BERSERKERSTANCE && form != FORM_DEFENSIVESTANCE && - form != FORM_SHADOW && form != FORM_STEALTH && form != FORM_UNDEAD; - } + [[nodiscard]] bool IsInDisallowedMountForm() const; float m_modMeleeHitChance; float m_modRangedHitChance; @@ -2127,7 +2122,7 @@ public: void AddInterruptMask(uint32 mask) { m_interruptMask |= mask; } void UpdateInterruptMask(); - uint32 GetDisplayId() { return GetUInt32Value(UNIT_FIELD_DISPLAYID); } + [[nodiscard]] uint32 GetDisplayId() const { return GetUInt32Value(UNIT_FIELD_DISPLAYID); } virtual void SetDisplayId(uint32 modelId); [[nodiscard]] uint32 GetNativeDisplayId() const { return GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID); } void RestoreDisplayId(); diff --git a/src/server/shared/DataStores/DBCStructure.h b/src/server/shared/DataStores/DBCStructure.h index 63a5a1075..7ee64900e 100644 --- a/src/server/shared/DataStores/DBCStructure.h +++ b/src/server/shared/DataStores/DBCStructure.h @@ -667,10 +667,17 @@ struct ChrClassesEntry uint32 expansion; // 59 (0 - original race, 1 - tbc addon, ...) }; +enum ChrRacesFlags +{ + CHRRACES_FLAGS_NOT_PLAYABLE = 0x01, + CHRRACES_FLAGS_BARE_FEET = 0x02, + CHRRACES_FLAGS_CAN_MOUNT = 0x04 +}; + struct ChrRacesEntry { uint32 RaceID; // 0 - // 1 unused + uint32 Flags; // 1 uint32 FactionID; // 2 facton template id // 3 unused uint32 model_m; // 4 @@ -688,6 +695,8 @@ struct ChrRacesEntry // 64 string flags, unused // 65-67 unused uint32 expansion; // 68 (0 - original race, 1 - tbc addon, ...) + + inline bool HasFlag(ChrRacesFlags flag) const { return (Flags & flag) != 0; } }; struct CinematicCameraEntry @@ -712,7 +721,7 @@ struct CreatureDisplayInfoEntry uint32 Displayid; // 0 m_ID uint32 ModelId; // 1 m_modelID // 2 m_soundID - // 3 m_extendedDisplayInfoID + uint32 ExtendedDisplayInfoID; // 3 float scale; // 4 m_creatureModelScale // 5 m_creatureModelAlpha // 6-8 m_textureVariation[3] @@ -725,6 +734,21 @@ struct CreatureDisplayInfoEntry // 15 m_objectEffectPackageID }; +struct CreatureDisplayInfoExtraEntry +{ + //uint32 ID; // 0 + uint32 DisplayRaceID; // 1 + uint32 DisplaySexID; // 2 + //uint32 SkinID; // 3 + //uint32 FaceID; // 4 + //uint32 HairStyleID; // 5 + //uint32 HairColorID; // 6 + //uint32 FacialHairID; // 7 + //uint32 NPCItemDisplay[11]; // 8-18 + //uint32 Flags; // 19 + //char const* BakeName; // 20 +}; + struct CreatureFamilyEntry { uint32 ID; // 0 m_ID @@ -741,11 +765,16 @@ struct CreatureFamilyEntry // 27 m_iconFile }; +enum CreatureModelDataFlags +{ + CREATURE_MODEL_DATA_FLAGS_CAN_MOUNT = 0x00000080 +}; + struct CreatureModelDataEntry { uint32 Id; - //uint32 Flags; - //char const* ModelPath[16] + uint32 Flags; + //char const* ModelPath //uint32 Unk1; float Scale; // Used in calculation of unit collision data //int32 Unk2 @@ -761,6 +790,8 @@ struct CreatureModelDataEntry float CollisionHeight; float MountHeight; // Used in calculation of unit collision data when mounted //float Unks[11] + + inline bool HasFlag(CreatureModelDataFlags flag) const { return (Flags & flag) != 0; } }; #define MAX_CREATURE_SPELL_DATA_SLOT 4 diff --git a/src/server/shared/DataStores/DBCfmt.h b/src/server/shared/DataStores/DBCfmt.h index 0cf21d8b3..7dc5867da 100644 --- a/src/server/shared/DataStores/DBCfmt.h +++ b/src/server/shared/DataStores/DBCfmt.h @@ -32,12 +32,13 @@ char constexpr CharStartOutfitEntryfmt[] = "dbbbXiiiiiiiiiiiiiiiiiiiiiiiixxxxxxx char constexpr CharTitlesEntryfmt[] = "nxssssssssssssssssxssssssssssssssssxi"; char constexpr ChatChannelsEntryfmt[] = "nixssssssssssssssssxxxxxxxxxxxxxxxxxx"; // ChatChannelsEntryfmt, index not used (more compact store) char constexpr ChrClassesEntryfmt[] = "nxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixii"; -char constexpr ChrRacesEntryfmt[] = "nxixiixixxxxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi"; +char constexpr ChrRacesEntryfmt[] = "niixiixixxxxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi"; char constexpr CinematicCameraEntryfmt[] = "nsiffff"; char constexpr CinematicSequencesEntryfmt[] = "nxixxxxxxx"; -char constexpr CreatureDisplayInfofmt[] = "nixxfxxxxxxxxxxx"; +char constexpr CreatureDisplayInfofmt[] = "nixifxxxxxxxxxxx"; +char constexpr CreatureDisplayInfoExtrafmt[] = "diixxxxxxxxxxxxxxxxxx"; char constexpr CreatureFamilyfmt[] = "nfifiiiiixssssssssssssssssxx"; -char constexpr CreatureModelDatafmt[] = "nxxxfxxxxxxxxxfffxxxxxxxxxxx"; +char constexpr CreatureModelDatafmt[] = "nixxfxxxxxxxxxfffxxxxxxxxxxx"; char constexpr CreatureSpellDatafmt[] = "niiiixxxx"; char constexpr CreatureTypefmt[] = "nxxxxxxxxxxxxxxxxxx"; char constexpr CurrencyTypesfmt[] = "xnxi";