mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-30 17:13:47 +00:00
refactor(Core/Creature): Split creature.h (#5974)
This commit is contained in:
@@ -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<uint32> CreatureQuestItemList;
|
||||
typedef std::unordered_map<uint32, CreatureQuestItemList> CreatureQuestItemMap;
|
||||
|
||||
// Benchmarked: Faster than std::map (insert/find)
|
||||
typedef std::unordered_map<uint32, CreatureTemplate> 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<uint16, CreatureBaseStats> 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<uint8, EquipmentInfo> EquipmentInfoContainerInternal;
|
||||
typedef std::unordered_map<uint32, EquipmentInfoContainerInternal> 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<uint16, CreatureModelInfo> 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<uint32> auras;
|
||||
};
|
||||
|
||||
typedef std::unordered_map<uint32, CreatureAddon> 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<VendorItem*> 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<VendorItemCount> 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<uint32 /*spellid*/, TrainerSpell> 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<uint32, time_t> CreatureSpellCooldowns;
|
||||
|
||||
// max different by z coordinate for creature aggro reaction
|
||||
#define CREATURE_Z_ATTACK_RANGE 3
|
||||
|
||||
|
||||
422
src/server/game/Entities/Creature/CreatureData.h
Normal file
422
src/server/game/Entities/Creature/CreatureData.h
Normal file
@@ -0,0 +1,422 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, 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 <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*/
|
||||
|
||||
#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 <list>
|
||||
|
||||
#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<uint32> CreatureQuestItemList;
|
||||
typedef std::unordered_map<uint32, CreatureQuestItemList> CreatureQuestItemMap;
|
||||
|
||||
// Benchmarked: Faster than std::map (insert/find)
|
||||
typedef std::unordered_map<uint32, CreatureTemplate> 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<uint16, CreatureBaseStats> 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<uint8, EquipmentInfo> EquipmentInfoContainerInternal;
|
||||
typedef std::unordered_map<uint32, EquipmentInfoContainerInternal> 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<uint16, CreatureModelInfo> 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<uint32> auras;
|
||||
};
|
||||
|
||||
typedef std::unordered_map<uint32, CreatureAddon> 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<VendorItem*> 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<VendorItemCount> 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<uint32 /*spellid*/, TrainerSpell> 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<uint32, time_t> CreatureSpellCooldowns;
|
||||
|
||||
#endif // AZEROTHCORE_CREATUREDATA_H
|
||||
Reference in New Issue
Block a user