/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see .
*/
#ifndef CreatureData_h__
#define CreatureData_h__
#include "DBCEnums.h"
#include "SharedDefines.h"
#include "SpawnData.h"
#include "UnitDefines.h"
#include "WorldPacket.h"
#include
#include
#include
#include
class WorldPacket;
struct ItemTemplate;
enum class VisibilityDistanceType : uint8;
enum CreatureFlagsExtra : uint32
{
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_CRUSH = 0x00000020, // creature can't do crush attacks
CREATURE_FLAG_EXTRA_NO_XP_AT_KILL = 0x00000040, // creature kill not provide XP
CREATURE_FLAG_EXTRA_TRIGGER = 0x00000080, // trigger creature
CREATURE_FLAG_EXTRA_NO_TAUNT = 0x00000100, // creature is immune to taunt auras and effect attack me
CREATURE_FLAG_EXTRA_NO_MOVE_FLAGS_UPDATE = 0x00000200, // creature won't update movement flags
CREATURE_FLAG_EXTRA_GHOST_VISIBILITY = 0x00000400, // creature will be only visible for dead players
CREATURE_FLAG_EXTRA_USE_OFFHAND_ATTACK = 0x00000800, // creature will use offhand attacks
CREATURE_FLAG_EXTRA_NO_SELL_VENDOR = 0x00001000, // players can't sell items to this vendor
CREATURE_FLAG_EXTRA_NO_COMBAT = 0x00002000, // creature is not allowed to enter combat
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_UNUSED_16 = 0x00010000,
CREATURE_FLAG_EXTRA_NO_CRIT = 0x00020000, // creature can't do critical strikes
CREATURE_FLAG_EXTRA_NO_SKILLGAIN = 0x00040000, // creature won't increase weapon skills
CREATURE_FLAG_EXTRA_TAUNT_DIMINISH = 0x00080000, // Taunt is a subject to diminishing returns on this creautre
CREATURE_FLAG_EXTRA_ALL_DIMINISH = 0x00100000, // creature is subject to all diminishing returns as player are
CREATURE_FLAG_EXTRA_NO_PLAYER_DAMAGE_REQ = 0x00200000, // creature does not need to take player damage for kill credit
CREATURE_FLAG_EXTRA_UNUSED_22 = 0x00400000,
CREATURE_FLAG_EXTRA_UNUSED_23 = 0x00800000,
CREATURE_FLAG_EXTRA_UNUSED_24 = 0x01000000,
CREATURE_FLAG_EXTRA_UNUSED_25 = 0x02000000,
CREATURE_FLAG_EXTRA_UNUSED_26 = 0x04000000,
CREATURE_FLAG_EXTRA_UNUSED_27 = 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_31 = 0x80000000,
// Masks
CREATURE_FLAG_EXTRA_UNUSED = (CREATURE_FLAG_EXTRA_UNUSED_16 | CREATURE_FLAG_EXTRA_UNUSED_22 |
CREATURE_FLAG_EXTRA_UNUSED_23 | CREATURE_FLAG_EXTRA_UNUSED_24 | CREATURE_FLAG_EXTRA_UNUSED_25 |
CREATURE_FLAG_EXTRA_UNUSED_26 | CREATURE_FLAG_EXTRA_UNUSED_27 | CREATURE_FLAG_EXTRA_UNUSED_31),
CREATURE_FLAG_EXTRA_DB_ALLOWED = (0xFFFFFFFF & ~(CREATURE_FLAG_EXTRA_UNUSED | CREATURE_FLAG_EXTRA_DUNGEON_BOSS))
};
enum class CreatureGroundMovementType : uint8
{
None,
Run,
Hover,
Max
};
enum class CreatureFlightMovementType : uint8
{
None,
DisableGravity,
CanFly,
Max
};
enum class CreatureRandomMovementType : uint8
{
Walk,
CanRun,
AlwaysRun,
Max
};
struct TC_GAME_API CreatureMovementData
{
CreatureMovementData() : Ground(CreatureGroundMovementType::Run), Flight(CreatureFlightMovementType::None),
Swim(true), Rooted(false), Random(CreatureRandomMovementType::Walk) { }
CreatureGroundMovementType Ground;
CreatureFlightMovementType Flight;
bool Swim;
bool Rooted;
CreatureRandomMovementType Random;
bool IsGroundAllowed() const { return Ground != CreatureGroundMovementType::None; }
bool IsSwimAllowed() const { return Swim; }
bool IsFlightAllowed() const { return Flight != CreatureFlightMovementType::None; }
bool IsRooted() const { return Rooted; }
CreatureRandomMovementType GetRandom() const { return Random; }
std::string ToString() const;
};
static uint32 const CREATURE_NOPATH_EVADE_TIME = 5 * IN_MILLISECONDS;
static uint8 const MAX_KILL_CREDIT = 2;
static uint32 const MAX_CREATURE_MODELS = 4;
static uint32 const MAX_CREATURE_QUEST_ITEMS = 6;
static uint32 const MAX_CREATURE_SPELLS = 8;
// from `creature_template` table
struct TC_GAME_API 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 FemaleName;
std::string Title;
std::string IconName;
uint32 GossipMenuId;
uint8 minlevel;
uint8 maxlevel;
uint32 expansion;
uint32 expansionUnknown; // either 0 or 3, sent to the client / wdb
uint32 faction;
uint32 npcflag;
float speed_walk;
float speed_run;
float scale;
uint32 rank;
uint32 dmgschool;
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;
CreatureFamily family; // enum CreatureFamily values (optional)
uint32 trainer_class;
uint32 type; // enum CreatureType values
uint32 type_flags; // enum CreatureTypeFlags mask values
uint32 type_flags2; // unknown enum, only set for 4 creatures (with value 1)
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;
CreatureMovementData Movement;
float HoverHeight;
float ModHealth;
float ModHealthExtra;
float ModMana;
float ModManaExtra; // Added in 4.x, this value is usually 2 for a small group of creatures with double mana
float ModArmor;
float ModDamage;
float ModExperience;
bool RacialLeader;
uint32 movementId;
bool RegenHealth;
uint32 MechanicImmuneMask;
uint32 SpellSchoolImmuneMask;
uint32 flags_extra;
uint32 ScriptID;
WorldPacket QueryData[TOTAL_LOCALES];
uint32 GetRandomValidModelId() const;
uint32 GetFirstValidModelId() const;
uint32 GetFirstInvisibleModel() const;
uint32 GetFirstVisibleModel() const;
// helpers
SkillType GetRequiredLootSkill() const
{
if (type_flags & CREATURE_TYPE_FLAG_HERB_SKINNING_SKILL)
return SKILL_HERBALISM;
else if (type_flags & CREATURE_TYPE_FLAG_MINING_SKINNING_SKILL)
return SKILL_MINING;
else if (type_flags & CREATURE_TYPE_FLAG_ENGINEERING_SKINNING_SKILL)
return SKILL_ENGINEERING;
else
return SKILL_SKINNING; // normal case
}
bool IsExotic() const
{
return (type_flags & CREATURE_TYPE_FLAG_EXOTIC_PET) != 0;
}
bool IsTameable(bool canTameExotic) const
{
if (type != CREATURE_TYPE_BEAST || family == CREATURE_FAMILY_NONE || (type_flags & CREATURE_TYPE_FLAG_TAMEABLE_PET) == 0)
return false;
// if can tame exotic then can tame any tameable
return canTameExotic || !IsExotic();
}
void InitializeQueryData();
WorldPacket BuildQueryData(LocaleConstant loc) const;
};
#pragma pack(push, 1)
// Defines base stats for creatures (used to calculate HP/mana/armor/attackpower/rangedattackpower/all damage).
struct TC_GAME_API 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 * info->ModHealthExtra));
}
uint32 GenerateMana(CreatureTemplate const* info) const
{
// Mana can be 0.
if (!BaseMana)
return 0;
return uint32(ceil(BaseMana * info->ModMana * info->ModManaExtra));
}
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
{
std::vector Name;
std::vector FemaleName;
std::vector Title;
};
struct EquipmentInfo
{
uint32 ItemEntry[MAX_EQUIPMENT_ITEMS];
};
// from `creature` table
struct CreatureData : public SpawnData
{
CreatureData() : SpawnData(SPAWN_TYPE_CREATURE) { }
uint32 displayid = 0;
int8 equipmentId = 0;
float spawndist = 0.0f;
uint32 currentwaypoint = 0;
uint32 curhealth = 0;
uint32 curmana = 0;
uint8 movementType = 0;
uint32 npcflag = 0;
uint32 unit_flags = 0;
uint32 dynamicflags = 0;
};
struct CreatureModelInfo
{
float bounding_radius;
float combat_reach;
uint8 gender;
uint32 modelid_other_gender;
bool is_trigger;
};
enum InhabitTypeValues
{
INHABIT_GROUND = 1,
INHABIT_WATER = 2,
INHABIT_AIR = 4,
INHABIT_ROOT = 8,
INHABIT_ANYWHERE = INHABIT_GROUND | INHABIT_WATER | INHABIT_AIR | INHABIT_ROOT
};
#pragma pack(pop)
// `creature_addon` table
struct CreatureAddon
{
uint32 path_id;
uint32 mount;
uint32 bytes1;
uint32 bytes2;
uint32 emote;
uint16 aiAnimKit;
uint16 movementAnimKit;
uint16 meleeAnimKit;
std::vector auras;
VisibilityDistanceType visibilityDistanceType;
};
// Vendors
struct VendorItem
{
VendorItem() : item(0), maxcount(0), incrtime(0), ExtendedCost(0), Type(0) { }
uint32 item;
uint32 maxcount; // 0 for infinity item amount
uint32 incrtime; // time for restore items amount if maxcount != 0
uint32 ExtendedCost;
uint8 Type;
//helpers
bool IsGoldRequired(ItemTemplate const* pProto) const;
};
struct VendorItemData
{
std::vector m_items;
VendorItem const* GetItem(uint32 slot) const
{
if (slot >= m_items.size())
return nullptr;
return &m_items[slot];
}
bool Empty() const { return m_items.empty(); }
uint32 GetItemCount() const { return m_items.size(); }
void AddItem(VendorItem vItem)
{
m_items.emplace_back(std::move(vItem));
}
bool RemoveItem(uint32 item_id, uint8 type);
VendorItem const* FindItemCostPair(uint32 item_id, uint32 extendedCost, uint8 type) const;
void Clear()
{
m_items.clear();
}
};
typedef std::unordered_map CreatureSparringTemplateMap;
#endif // CreatureData_h__