diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 3072e7ca5..98d62de98 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -9,6 +9,7 @@ #include "Cell.h" #include "Common.h" +#include "CreatureData.h" #include "DatabaseEnv.h" #include "ItemTemplate.h" #include "LootMgr.h" @@ -25,406 +26,6 @@ class Player; class WorldSession; class CreatureGroup; -enum CreatureFlagsExtra : uint32 -{ - // TODO: Implement missing flags from TC in places that custom flags from xinef&pussywizzard use flag values. - CREATURE_FLAG_EXTRA_INSTANCE_BIND = 0x00000001, // creature kill bind instance with killer and killer's group - CREATURE_FLAG_EXTRA_CIVILIAN = 0x00000002, // not aggro (ignore faction/reputation hostility) - CREATURE_FLAG_EXTRA_NO_PARRY = 0x00000004, // creature can't parry - CREATURE_FLAG_EXTRA_NO_PARRY_HASTEN = 0x00000008, // creature can't counter-attack at parry - CREATURE_FLAG_EXTRA_NO_BLOCK = 0x00000010, // creature can't block - CREATURE_FLAG_EXTRA_NO_CRUSHING_BLOWS = 0x00000020, // creature can't do crush attacks - CREATURE_FLAG_EXTRA_NO_XP = 0x00000040, // creature kill does not provide XP - CREATURE_FLAG_EXTRA_TRIGGER = 0x00000080, // trigger creature - CREATURE_FLAG_EXTRA_NO_TAUNT = 0x00000100, // creature is immune to taunt auras and 'attack me' effects - CREATURE_FLAG_EXTRA_UNUSED_10 = 0x00000200, // TODO: Implement CREATURE_FLAG_EXTRA_NO_MOVE_FLAGS_UPDATE (creature won't update movement flags) - CREATURE_FLAG_EXTRA_GHOST_VISIBILITY = 0x00000400, // creature will only be visible to dead players - CREATURE_FLAG_EXTRA_UNUSED_12 = 0x00000800, // TODO: Implement CREATURE_FLAG_EXTRA_USE_OFFHAND_ATTACK (creature will use offhand attacks) - CREATURE_FLAG_EXTRA_NO_SELL_VENDOR = 0x00001000, // players can't sell items to this vendor - CREATURE_FLAG_EXTRA_IGNORE_COMBAT = 0x00002000, - CREATURE_FLAG_EXTRA_WORLDEVENT = 0x00004000, // custom flag for world event creatures (left room for merging) - CREATURE_FLAG_EXTRA_GUARD = 0x00008000, // Creature is guard - CREATURE_FLAG_EXTRA_IGNORE_FEIGN_DEATH = 0x00010000, // creature ignores feign death - CREATURE_FLAG_EXTRA_NO_CRIT = 0x00020000, // creature can't do critical strikes - CREATURE_FLAG_EXTRA_NO_SKILL_GAINS = 0x00040000, // creature won't increase weapon skills - CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS = 0x00080000, // Taunt is subject to diminishing returns on this creature - CREATURE_FLAG_EXTRA_ALL_DIMINISH = 0x00100000, // creature is subject to all diminishing returns as players are - CREATURE_FLAG_EXTRA_UNUSED_22 = 0x00200000, - CREATURE_FLAG_EXTRA_AVOID_AOE = 0x00400000, // pussywizard: ignored by aoe attacks (for icc blood prince council npc - Dark Nucleus) - CREATURE_FLAG_EXTRA_NO_DODGE = 0x00800000, // xinef: target cannot dodge - CREATURE_FLAG_EXTRA_UNUSED_25 = 0x01000000, - CREATURE_FLAG_EXTRA_UNUSED_26 = 0x02000000, - CREATURE_FLAG_EXTRA_UNUSED_27 = 0x04000000, - CREATURE_FLAG_EXTRA_UNUSED_28 = 0x08000000, - CREATURE_FLAG_EXTRA_DUNGEON_BOSS = 0x10000000, // creature is a dungeon boss (SET DYNAMICALLY, DO NOT ADD IN DB) - CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING = 0x20000000, // creature ignore pathfinding - CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK = 0x40000000, // creature is immune to knockback effects - CREATURE_FLAG_EXTRA_UNUSED_32 = 0x80000000, - - // Masks - CREATURE_FLAG_EXTRA_UNUSED = (CREATURE_FLAG_EXTRA_UNUSED_10 | CREATURE_FLAG_EXTRA_UNUSED_12 | - CREATURE_FLAG_EXTRA_UNUSED_22 | CREATURE_FLAG_EXTRA_UNUSED_25 | CREATURE_FLAG_EXTRA_UNUSED_26 | - CREATURE_FLAG_EXTRA_UNUSED_27 | CREATURE_FLAG_EXTRA_UNUSED_28 | CREATURE_FLAG_EXTRA_UNUSED_32), - CREATURE_FLAG_EXTRA_DB_ALLOWED = (0xFFFFFFFF & ~(CREATURE_FLAG_EXTRA_UNUSED | CREATURE_FLAG_EXTRA_DUNGEON_BOSS)) -}; - -#define MAX_AGGRO_RESET_TIME 10 // in seconds - -#define MAX_KILL_CREDIT 2 -#define CREATURE_REGEN_INTERVAL 2 * IN_MILLISECONDS -#define PET_FOCUS_REGEN_INTERVAL 4 * IN_MILLISECONDS - -#define MAX_CREATURE_QUEST_ITEMS 6 - -// from `creature_template` table -struct CreatureTemplate -{ - uint32 Entry; - uint32 DifficultyEntry[MAX_DIFFICULTY - 1]; - uint32 KillCredit[MAX_KILL_CREDIT]; - uint32 Modelid1; - uint32 Modelid2; - uint32 Modelid3; - uint32 Modelid4; - std::string Name; - std::string SubName; - std::string IconName; - uint32 GossipMenuId; - uint8 minlevel; - uint8 maxlevel; - uint32 expansion; - uint32 faction; - uint32 npcflag; - float speed_walk; - float speed_run; - float scale; - uint32 rank; - uint32 dmgschool; - float DamageModifier; - uint32 BaseAttackTime; - uint32 RangeAttackTime; - float BaseVariance; - float RangeVariance; - uint32 unit_class; // enum Classes. Note only 4 classes are known for creatures. - uint32 unit_flags; // enum UnitFlags mask values - uint32 unit_flags2; // enum UnitFlags2 mask values - uint32 dynamicflags; - uint32 family; // enum CreatureFamily values (optional) - uint32 trainer_type; - uint32 trainer_spell; - uint32 trainer_class; - uint32 trainer_race; - uint32 type; // enum CreatureType values - uint32 type_flags; // enum CreatureTypeFlags mask values - uint32 lootid; - uint32 pickpocketLootId; - uint32 SkinLootId; - int32 resistance[MAX_SPELL_SCHOOL]; - uint32 spells[MAX_CREATURE_SPELLS]; - uint32 PetSpellDataId; - uint32 VehicleId; - uint32 mingold; - uint32 maxgold; - std::string AIName; - uint32 MovementType; - uint32 InhabitType; - float HoverHeight; - float ModHealth; - float ModMana; - float ModArmor; - bool RacialLeader; - uint32 movementId; - bool RegenHealth; - uint32 MechanicImmuneMask; - uint8 SpellSchoolImmuneMask; - uint32 flags_extra; - uint32 ScriptID; - WorldPacket queryData; // pussywizard - [[nodiscard]] uint32 GetRandomValidModelId() const; - [[nodiscard]] uint32 GetFirstValidModelId() const; - - // helpers - [[nodiscard]] SkillType GetRequiredLootSkill() const - { - if (type_flags & CREATURE_TYPE_FLAG_SKIN_WITH_HERBALISM) - return SKILL_HERBALISM; - else if (type_flags & CREATURE_TYPE_FLAG_SKIN_WITH_MINING) - return SKILL_MINING; - else if (type_flags & CREATURE_TYPE_FLAG_SKIN_WITH_ENGINEERING) - return SKILL_ENGINEERING; - else - return SKILL_SKINNING; // normal case - } - - [[nodiscard]] bool IsExotic() const - { - return (type_flags & CREATURE_TYPE_FLAG_TAMEABLE_EXOTIC) != 0; - } - - [[nodiscard]] bool IsTameable(bool exotic) const - { - if (type != CREATURE_TYPE_BEAST || family == 0 || (type_flags & CREATURE_TYPE_FLAG_TAMEABLE) == 0) - return false; - - // if can tame exotic then can tame any tameable - return exotic || (type_flags & CREATURE_TYPE_FLAG_TAMEABLE_EXOTIC) == 0; - } - - void InitializeQueryData(); -}; - -typedef std::vector CreatureQuestItemList; -typedef std::unordered_map CreatureQuestItemMap; - -// Benchmarked: Faster than std::map (insert/find) -typedef std::unordered_map CreatureTemplateContainer; - -// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push, N), also any gcc version not support it at some platform -#if defined(__GNUC__) -#pragma pack(1) -#else -#pragma pack(push, 1) -#endif - -// Defines base stats for creatures (used to calculate HP/mana/armor/attackpower/rangedattackpower/all damage). -struct CreatureBaseStats -{ - uint32 BaseHealth[MAX_EXPANSIONS]; - uint32 BaseMana; - uint32 BaseArmor; - uint32 AttackPower; - uint32 RangedAttackPower; - float BaseDamage[MAX_EXPANSIONS]; - - // Helpers - - uint32 GenerateHealth(CreatureTemplate const* info) const - { - return uint32(ceil(BaseHealth[info->expansion] * info->ModHealth)); - } - - uint32 GenerateMana(CreatureTemplate const* info) const - { - // Mana can be 0. - if (!BaseMana) - return 0; - - return uint32(ceil(BaseMana * info->ModMana)); - } - - uint32 GenerateArmor(CreatureTemplate const* info) const - { - return uint32(ceil(BaseArmor * info->ModArmor)); - } - - float GenerateBaseDamage(CreatureTemplate const* info) const - { - return BaseDamage[info->expansion]; - } - - static CreatureBaseStats const* GetBaseStats(uint8 level, uint8 unitClass); -}; - -typedef std::unordered_map CreatureBaseStatsContainer; - -struct CreatureLocale -{ - StringVector Name; - StringVector Title; -}; - -struct GossipMenuItemsLocale -{ - StringVector OptionText; - StringVector BoxText; -}; - -struct PointOfInterestLocale -{ - StringVector Name; -}; - -#define MAX_EQUIPMENT_ITEMS 3 - -struct EquipmentInfo -{ - uint32 ItemEntry[MAX_EQUIPMENT_ITEMS]; -}; - -// Benchmarked: Faster than std::map (insert/find) -typedef std::unordered_map EquipmentInfoContainerInternal; -typedef std::unordered_map EquipmentInfoContainer; - -// from `creature` table -struct CreatureData -{ - CreatureData() { } - uint32 id{0}; // entry in creature_template - uint16 mapid{0}; - uint32 phaseMask{0}; - uint32 displayid{0}; - int8 equipmentId{0}; - float posX{0.0f}; - float posY{0.0f}; - float posZ{0.0f}; - float orientation{0.0f}; - uint32 spawntimesecs{0}; - float wander_distance{0.0f}; - uint32 currentwaypoint{0}; - uint32 curhealth{0}; - uint32 curmana{0}; - uint8 movementType{0}; - uint8 spawnMask{0}; - uint32 npcflag{0}; - uint32 unit_flags{0}; // enum UnitFlags mask values - uint32 dynamicflags{0}; - bool dbData{true}; - bool overwrittenZ{false}; -}; - -struct CreatureModelInfo -{ - float bounding_radius; - float combat_reach; - uint8 gender; - uint32 modelid_other_gender; -}; - -// Benchmarked: Faster than std::map (insert/find) -typedef std::unordered_map CreatureModelContainer; - -enum InhabitTypeValues -{ - INHABIT_GROUND = 1, - INHABIT_WATER = 2, - INHABIT_AIR = 4, - INHABIT_ROOT = 8, - INHABIT_ANYWHERE = INHABIT_GROUND | INHABIT_WATER | INHABIT_AIR | INHABIT_ROOT -}; - -// Enums used by StringTextData::Type (CreatureEventAI) -enum ChatType -{ - CHAT_TYPE_SAY = 0, - CHAT_TYPE_YELL = 1, - CHAT_TYPE_TEXT_EMOTE = 2, - CHAT_TYPE_BOSS_EMOTE = 3, - CHAT_TYPE_WHISPER = 4, - CHAT_TYPE_BOSS_WHISPER = 5, - CHAT_TYPE_ZONE_YELL = 6, - CHAT_TYPE_END = 255 -}; - -// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform -#if defined(__GNUC__) -#pragma pack() -#else -#pragma pack(pop) -#endif - -// `creature_addon` table -struct CreatureAddon -{ - uint32 path_id; - uint32 mount; - uint32 bytes1; - uint32 bytes2; - uint32 emote; - bool isLarge; - std::vector auras; -}; - -typedef std::unordered_map CreatureAddonContainer; - -// Vendors -struct VendorItem -{ - VendorItem(uint32 _item, int32 _maxcount, uint32 _incrtime, uint32 _ExtendedCost) - : item(_item), maxcount(_maxcount), incrtime(_incrtime), ExtendedCost(_ExtendedCost) {} - - uint32 item; - uint32 maxcount; // 0 for infinity item amount - uint32 incrtime; // time for restore items amount if maxcount != 0 - uint32 ExtendedCost; - - //helpers - bool IsGoldRequired(ItemTemplate const* pProto) const { return pProto->Flags2 & ITEM_FLAGS_EXTRA_EXT_COST_REQUIRES_GOLD || !ExtendedCost; } -}; -typedef std::vector VendorItemList; - -struct VendorItemData -{ - VendorItemList m_items; - - [[nodiscard]] VendorItem* GetItem(uint32 slot) const - { - if (slot >= m_items.size()) - return nullptr; - - return m_items[slot]; - } - [[nodiscard]] bool Empty() const { return m_items.empty(); } - [[nodiscard]] uint8 GetItemCount() const { return m_items.size(); } - void AddItem(uint32 item, int32 maxcount, uint32 ptime, uint32 ExtendedCost) - { - m_items.push_back(new VendorItem(item, maxcount, ptime, ExtendedCost)); - } - bool RemoveItem(uint32 item_id); - [[nodiscard]] VendorItem const* FindItemCostPair(uint32 item_id, uint32 extendedCost) const; - void Clear() - { - for (VendorItemList::const_iterator itr = m_items.begin(); itr != m_items.end(); ++itr) - delete (*itr); - m_items.clear(); - } -}; - -struct VendorItemCount -{ - explicit VendorItemCount(uint32 _item, uint32 _count) - : itemId(_item), count(_count), lastIncrementTime(time(nullptr)) {} - - uint32 itemId; - uint32 count; - time_t lastIncrementTime; -}; - -typedef std::list VendorItemCounts; - -struct TrainerSpell -{ - TrainerSpell() - { - for (unsigned int & i : learnedSpell) - i = 0; - } - - uint32 spell{0}; - uint32 spellCost{0}; - uint32 reqSkill{0}; - uint32 reqSkillValue{0}; - uint32 reqLevel{0}; - uint32 learnedSpell[3]; - - // helpers - [[nodiscard]] bool IsCastable() const { return learnedSpell[0] != spell; } -}; - -typedef std::unordered_map TrainerSpellMap; - -struct TrainerSpellData -{ - TrainerSpellData() {} - ~TrainerSpellData() { spellList.clear(); } - - TrainerSpellMap spellList; - uint32 trainerType{0}; // trainer type based at trainer spells, can be different from creature_template value. - // req. for correct show non-prof. trainers like weaponmaster, allowed values 0 and 2. - [[nodiscard]] TrainerSpell const* Find(uint32 spell_id) const; -}; - -typedef std::map CreatureSpellCooldowns; - // max different by z coordinate for creature aggro reaction #define CREATURE_Z_ATTACK_RANGE 3 diff --git a/src/server/game/Entities/Creature/CreatureData.h b/src/server/game/Entities/Creature/CreatureData.h new file mode 100644 index 000000000..99d60719f --- /dev/null +++ b/src/server/game/Entities/Creature/CreatureData.h @@ -0,0 +1,422 @@ +/* + * Copyright (C) 2016+ AzerothCore , released under GNU GPL v2 license, you may redistribute it and/or modify it under version 2 of the License, or (at your option), any later version. + * Copyright (C) 2008-2016 TrinityCore + * Copyright (C) 2005-2009 MaNGOS + */ + +#ifndef AZEROTHCORE_CREATUREDATA_H +#define AZEROTHCORE_CREATUREDATA_H + +#include "DBCEnums.h" +#include "Cell.h" +#include "Common.h" +#include "DatabaseEnv.h" +#include "ItemTemplate.h" +#include "LootMgr.h" +#include "Unit.h" +#include "UpdateMask.h" +#include "World.h" +#include + +#define MAX_AGGRO_RESET_TIME 10 // in seconds + +#define MAX_KILL_CREDIT 2 +#define CREATURE_REGEN_INTERVAL 2 * IN_MILLISECONDS +#define PET_FOCUS_REGEN_INTERVAL 4 * IN_MILLISECONDS + +#define MAX_CREATURE_QUEST_ITEMS 6 + +#define MAX_EQUIPMENT_ITEMS 3 + +enum CreatureFlagsExtra : uint32 +{ + // TODO: Implement missing flags from TC in places that custom flags from xinef&pussywizzard use flag values. + CREATURE_FLAG_EXTRA_INSTANCE_BIND = 0x00000001, // creature kill bind instance with killer and killer's group + CREATURE_FLAG_EXTRA_CIVILIAN = 0x00000002, // not aggro (ignore faction/reputation hostility) + CREATURE_FLAG_EXTRA_NO_PARRY = 0x00000004, // creature can't parry + CREATURE_FLAG_EXTRA_NO_PARRY_HASTEN = 0x00000008, // creature can't counter-attack at parry + CREATURE_FLAG_EXTRA_NO_BLOCK = 0x00000010, // creature can't block + CREATURE_FLAG_EXTRA_NO_CRUSHING_BLOWS = 0x00000020, // creature can't do crush attacks + CREATURE_FLAG_EXTRA_NO_XP = 0x00000040, // creature kill does not provide XP + CREATURE_FLAG_EXTRA_TRIGGER = 0x00000080, // trigger creature + CREATURE_FLAG_EXTRA_NO_TAUNT = 0x00000100, // creature is immune to taunt auras and 'attack me' effects + CREATURE_FLAG_EXTRA_UNUSED_10 = 0x00000200, // TODO: Implement CREATURE_FLAG_EXTRA_NO_MOVE_FLAGS_UPDATE (creature won't update movement flags) + CREATURE_FLAG_EXTRA_GHOST_VISIBILITY = 0x00000400, // creature will only be visible to dead players + CREATURE_FLAG_EXTRA_UNUSED_12 = 0x00000800, // TODO: Implement CREATURE_FLAG_EXTRA_USE_OFFHAND_ATTACK (creature will use offhand attacks) + CREATURE_FLAG_EXTRA_NO_SELL_VENDOR = 0x00001000, // players can't sell items to this vendor + CREATURE_FLAG_EXTRA_IGNORE_COMBAT = 0x00002000, + CREATURE_FLAG_EXTRA_WORLDEVENT = 0x00004000, // custom flag for world event creatures (left room for merging) + CREATURE_FLAG_EXTRA_GUARD = 0x00008000, // Creature is guard + CREATURE_FLAG_EXTRA_IGNORE_FEIGN_DEATH = 0x00010000, // creature ignores feign death + CREATURE_FLAG_EXTRA_NO_CRIT = 0x00020000, // creature can't do critical strikes + CREATURE_FLAG_EXTRA_NO_SKILL_GAINS = 0x00040000, // creature won't increase weapon skills + CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS = 0x00080000, // Taunt is subject to diminishing returns on this creature + CREATURE_FLAG_EXTRA_ALL_DIMINISH = 0x00100000, // creature is subject to all diminishing returns as players are + CREATURE_FLAG_EXTRA_UNUSED_22 = 0x00200000, + CREATURE_FLAG_EXTRA_AVOID_AOE = 0x00400000, // pussywizard: ignored by aoe attacks (for icc blood prince council npc - Dark Nucleus) + CREATURE_FLAG_EXTRA_NO_DODGE = 0x00800000, // xinef: target cannot dodge + CREATURE_FLAG_EXTRA_UNUSED_25 = 0x01000000, + CREATURE_FLAG_EXTRA_UNUSED_26 = 0x02000000, + CREATURE_FLAG_EXTRA_UNUSED_27 = 0x04000000, + CREATURE_FLAG_EXTRA_UNUSED_28 = 0x08000000, + CREATURE_FLAG_EXTRA_DUNGEON_BOSS = 0x10000000, // creature is a dungeon boss (SET DYNAMICALLY, DO NOT ADD IN DB) + CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING = 0x20000000, // creature ignore pathfinding + CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK = 0x40000000, // creature is immune to knockback effects + CREATURE_FLAG_EXTRA_UNUSED_32 = 0x80000000, + + // Masks + CREATURE_FLAG_EXTRA_UNUSED = (CREATURE_FLAG_EXTRA_UNUSED_10 | CREATURE_FLAG_EXTRA_UNUSED_12 | + CREATURE_FLAG_EXTRA_UNUSED_22 | CREATURE_FLAG_EXTRA_UNUSED_25 | CREATURE_FLAG_EXTRA_UNUSED_26 | + CREATURE_FLAG_EXTRA_UNUSED_27 | CREATURE_FLAG_EXTRA_UNUSED_28 | CREATURE_FLAG_EXTRA_UNUSED_32), + CREATURE_FLAG_EXTRA_DB_ALLOWED = (0xFFFFFFFF & ~(CREATURE_FLAG_EXTRA_UNUSED | CREATURE_FLAG_EXTRA_DUNGEON_BOSS)) +}; + +// from `creature_template` table +struct CreatureTemplate +{ + uint32 Entry; + uint32 DifficultyEntry[MAX_DIFFICULTY - 1]; + uint32 KillCredit[MAX_KILL_CREDIT]; + uint32 Modelid1; + uint32 Modelid2; + uint32 Modelid3; + uint32 Modelid4; + std::string Name; + std::string SubName; + std::string IconName; + uint32 GossipMenuId; + uint8 minlevel; + uint8 maxlevel; + uint32 expansion; + uint32 faction; + uint32 npcflag; + float speed_walk; + float speed_run; + float scale; + uint32 rank; + uint32 dmgschool; + float DamageModifier; + uint32 BaseAttackTime; + uint32 RangeAttackTime; + float BaseVariance; + float RangeVariance; + uint32 unit_class; // enum Classes. Note only 4 classes are known for creatures. + uint32 unit_flags; // enum UnitFlags mask values + uint32 unit_flags2; // enum UnitFlags2 mask values + uint32 dynamicflags; + uint32 family; // enum CreatureFamily values (optional) + uint32 trainer_type; + uint32 trainer_spell; + uint32 trainer_class; + uint32 trainer_race; + uint32 type; // enum CreatureType values + uint32 type_flags; // enum CreatureTypeFlags mask values + uint32 lootid; + uint32 pickpocketLootId; + uint32 SkinLootId; + int32 resistance[MAX_SPELL_SCHOOL]; + uint32 spells[MAX_CREATURE_SPELLS]; + uint32 PetSpellDataId; + uint32 VehicleId; + uint32 mingold; + uint32 maxgold; + std::string AIName; + uint32 MovementType; + uint32 InhabitType; + float HoverHeight; + float ModHealth; + float ModMana; + float ModArmor; + bool RacialLeader; + uint32 movementId; + bool RegenHealth; + uint32 MechanicImmuneMask; + uint8 SpellSchoolImmuneMask; + uint32 flags_extra; + uint32 ScriptID; + WorldPacket queryData; // pussywizard + [[nodiscard]] uint32 GetRandomValidModelId() const; + [[nodiscard]] uint32 GetFirstValidModelId() const; + + // helpers + [[nodiscard]] SkillType GetRequiredLootSkill() const + { + if (type_flags & CREATURE_TYPE_FLAG_SKIN_WITH_HERBALISM) + return SKILL_HERBALISM; + else if (type_flags & CREATURE_TYPE_FLAG_SKIN_WITH_MINING) + return SKILL_MINING; + else if (type_flags & CREATURE_TYPE_FLAG_SKIN_WITH_ENGINEERING) + return SKILL_ENGINEERING; + else + return SKILL_SKINNING; // normal case + } + + [[nodiscard]] bool IsExotic() const + { + return (type_flags & CREATURE_TYPE_FLAG_TAMEABLE_EXOTIC) != 0; + } + + [[nodiscard]] bool IsTameable(bool exotic) const + { + if (type != CREATURE_TYPE_BEAST || family == 0 || (type_flags & CREATURE_TYPE_FLAG_TAMEABLE) == 0) + return false; + + // if can tame exotic then can tame any tameable + return exotic || (type_flags & CREATURE_TYPE_FLAG_TAMEABLE_EXOTIC) == 0; + } + + void InitializeQueryData(); +}; + +typedef std::vector CreatureQuestItemList; +typedef std::unordered_map CreatureQuestItemMap; + +// Benchmarked: Faster than std::map (insert/find) +typedef std::unordered_map CreatureTemplateContainer; + +// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push, N), also any gcc version not support it at some platform +#if defined(__GNUC__) +#pragma pack(1) +#else +#pragma pack(push, 1) +#endif + +// Defines base stats for creatures (used to calculate HP/mana/armor/attackpower/rangedattackpower/all damage). +struct CreatureBaseStats +{ + uint32 BaseHealth[MAX_EXPANSIONS]; + uint32 BaseMana; + uint32 BaseArmor; + uint32 AttackPower; + uint32 RangedAttackPower; + float BaseDamage[MAX_EXPANSIONS]; + + // Helpers + + uint32 GenerateHealth(CreatureTemplate const* info) const + { + return uint32(ceil(BaseHealth[info->expansion] * info->ModHealth)); + } + + uint32 GenerateMana(CreatureTemplate const* info) const + { + // Mana can be 0. + if (!BaseMana) + return 0; + + return uint32(ceil(BaseMana * info->ModMana)); + } + + uint32 GenerateArmor(CreatureTemplate const* info) const + { + return uint32(ceil(BaseArmor * info->ModArmor)); + } + + float GenerateBaseDamage(CreatureTemplate const* info) const + { + return BaseDamage[info->expansion]; + } + + static CreatureBaseStats const* GetBaseStats(uint8 level, uint8 unitClass); +}; + +typedef std::unordered_map CreatureBaseStatsContainer; + +struct CreatureLocale +{ + StringVector Name; + StringVector Title; +}; + +struct GossipMenuItemsLocale +{ + StringVector OptionText; + StringVector BoxText; +}; + +struct PointOfInterestLocale +{ + StringVector Name; +}; + +struct EquipmentInfo +{ + uint32 ItemEntry[MAX_EQUIPMENT_ITEMS]; +}; + +// Benchmarked: Faster than std::map (insert/find) +typedef std::unordered_map EquipmentInfoContainerInternal; +typedef std::unordered_map EquipmentInfoContainer; + +// from `creature` table +struct CreatureData +{ + CreatureData() { } + uint32 id{0}; // entry in creature_template + uint16 mapid{0}; + uint32 phaseMask{0}; + uint32 displayid{0}; + int8 equipmentId{0}; + float posX{0.0f}; + float posY{0.0f}; + float posZ{0.0f}; + float orientation{0.0f}; + uint32 spawntimesecs{0}; + float wander_distance{0.0f}; + uint32 currentwaypoint{0}; + uint32 curhealth{0}; + uint32 curmana{0}; + uint8 movementType{0}; + uint8 spawnMask{0}; + uint32 npcflag{0}; + uint32 unit_flags{0}; // enum UnitFlags mask values + uint32 dynamicflags{0}; + bool dbData{true}; + bool overwrittenZ{false}; +}; + + +struct CreatureModelInfo +{ + float bounding_radius; + float combat_reach; + uint8 gender; + uint32 modelid_other_gender; +}; + +// Benchmarked: Faster than std::map (insert/find) +typedef std::unordered_map CreatureModelContainer; + +enum InhabitTypeValues +{ + INHABIT_GROUND = 1, + INHABIT_WATER = 2, + INHABIT_AIR = 4, + INHABIT_ROOT = 8, + INHABIT_ANYWHERE = INHABIT_GROUND | INHABIT_WATER | INHABIT_AIR | INHABIT_ROOT +}; + +// Enums used by StringTextData::Type (CreatureEventAI) +enum ChatType +{ + CHAT_TYPE_SAY = 0, + CHAT_TYPE_YELL = 1, + CHAT_TYPE_TEXT_EMOTE = 2, + CHAT_TYPE_BOSS_EMOTE = 3, + CHAT_TYPE_WHISPER = 4, + CHAT_TYPE_BOSS_WHISPER = 5, + CHAT_TYPE_ZONE_YELL = 6, + CHAT_TYPE_END = 255 +}; + +// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform +#if defined(__GNUC__) +#pragma pack() +#else +#pragma pack(pop) +#endif + +// `creature_addon` table +struct CreatureAddon +{ + uint32 path_id; + uint32 mount; + uint32 bytes1; + uint32 bytes2; + uint32 emote; + bool isLarge; + std::vector auras; +}; + +typedef std::unordered_map CreatureAddonContainer; + +// Vendors +struct VendorItem +{ + VendorItem(uint32 _item, int32 _maxcount, uint32 _incrtime, uint32 _ExtendedCost) + : item(_item), maxcount(_maxcount), incrtime(_incrtime), ExtendedCost(_ExtendedCost) {} + + uint32 item; + uint32 maxcount; // 0 for infinity item amount + uint32 incrtime; // time for restore items amount if maxcount != 0 + uint32 ExtendedCost; + + //helpers + bool IsGoldRequired(ItemTemplate const* pProto) const { return pProto->Flags2 & ITEM_FLAGS_EXTRA_EXT_COST_REQUIRES_GOLD || !ExtendedCost; } +}; +typedef std::vector VendorItemList; + +struct VendorItemData +{ + VendorItemList m_items; + + [[nodiscard]] VendorItem* GetItem(uint32 slot) const + { + if (slot >= m_items.size()) + return nullptr; + + return m_items[slot]; + } + [[nodiscard]] bool Empty() const { return m_items.empty(); } + [[nodiscard]] uint8 GetItemCount() const { return m_items.size(); } + void AddItem(uint32 item, int32 maxcount, uint32 ptime, uint32 ExtendedCost) + { + m_items.push_back(new VendorItem(item, maxcount, ptime, ExtendedCost)); + } + bool RemoveItem(uint32 item_id); + [[nodiscard]] VendorItem const* FindItemCostPair(uint32 item_id, uint32 extendedCost) const; + void Clear() + { + for (VendorItemList::const_iterator itr = m_items.begin(); itr != m_items.end(); ++itr) + delete (*itr); + m_items.clear(); + } +}; + +struct VendorItemCount +{ + explicit VendorItemCount(uint32 _item, uint32 _count) + : itemId(_item), count(_count), lastIncrementTime(time(nullptr)) {} + + uint32 itemId; + uint32 count; + time_t lastIncrementTime; +}; + +typedef std::list VendorItemCounts; + +struct TrainerSpell +{ + TrainerSpell() + { + for (unsigned int & i : learnedSpell) + i = 0; + } + + uint32 spell{0}; + uint32 spellCost{0}; + uint32 reqSkill{0}; + uint32 reqSkillValue{0}; + uint32 reqLevel{0}; + uint32 learnedSpell[3]; + + // helpers + [[nodiscard]] bool IsCastable() const { return learnedSpell[0] != spell; } +}; + +typedef std::unordered_map TrainerSpellMap; + +struct TrainerSpellData +{ + TrainerSpellData() {} + ~TrainerSpellData() { spellList.clear(); } + + TrainerSpellMap spellList; + uint32 trainerType{0}; // trainer type based at trainer spells, can be different from creature_template value. + // req. for correct show non-prof. trainers like weaponmaster, allowed values 0 and 2. + [[nodiscard]] TrainerSpell const* Find(uint32 spell_id) const; +}; + +typedef std::map CreatureSpellCooldowns; + +#endif // AZEROTHCORE_CREATUREDATA_H