/
Pet.h
304 lines (248 loc) · 11.5 KB
/
Pet.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
/*
* This file is part of the CMaNGOS 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MANGOSSERVER_PET_H
#define MANGOSSERVER_PET_H
#include "Common.h"
#include "Entities/ObjectGuid.h"
#include "Entities/Creature.h"
#include "Entities/Unit.h"
enum PetType
{
SUMMON_PET = 0,
HUNTER_PET = 1,
GUARDIAN_PET = 2,
MINI_PET = 3,
PROTECTOR_PET = 4, // work as defensive guardian with mini pet suffix in name
MAX_PET_TYPE = 5
};
#define MAX_PET_STABLES 4
// stored in character_pet.slot
enum PetSaveMode
{
PET_SAVE_AS_DELETED = -1, // not saved in fact
PET_SAVE_AS_CURRENT = 0, // in current slot (with player)
PET_SAVE_FIRST_STABLE_SLOT = 1,
PET_SAVE_LAST_STABLE_SLOT = MAX_PET_STABLES, // last in DB stable slot index (including), all higher have same meaning as PET_SAVE_NOT_IN_SLOT
PET_SAVE_NOT_IN_SLOT = 100, // for avoid conflict with stable size grow will use 100
PET_SAVE_REAGENTS = 101 // PET_SAVE_NOT_IN_SLOT with reagents return
};
// There might be a lot more
enum PetModeFlags
{
PET_MODE_STAY = 0x0000000,
PET_MODE_FOLLOW = 0x0000001,
PET_MODE_ATTACK = 0x0000002,
PET_MODE_PASSIVE = 0x0000000,
PET_MODE_DEFENSIVE = 0x0000100,
PET_MODE_AGGRESSIVE = 0x0000200,
PET_MODE_DISABLE_ACTIONS = 0x8000000,
// autoset in client at summon
PET_MODE_DEFAULT = PET_MODE_FOLLOW | PET_MODE_DEFENSIVE,
};
enum HappinessState
{
UNHAPPY = 1,
CONTENT = 2,
HAPPY = 3
};
enum PetSpellState
{
PETSPELL_UNCHANGED = 0,
PETSPELL_CHANGED = 1,
PETSPELL_NEW = 2,
PETSPELL_REMOVED = 3
};
enum PetSpellType
{
PETSPELL_NORMAL = 0,
PETSPELL_FAMILY = 1,
};
struct PetSpell
{
uint8 active; // use instead enum (not good use *uint8* limited enum in case when value in enum not possitive in *int8*)
PetSpellState state : 8;
PetSpellType type : 8;
};
enum ActionFeedback
{
FEEDBACK_NONE = 0,
FEEDBACK_PET_DEAD = 1,
FEEDBACK_NOTHING_TO_ATT = 2,
FEEDBACK_CANT_ATT_TARGET = 3
};
enum PetTalk
{
PET_TALK_SPECIAL_SPELL = 0,
PET_TALK_ATTACK = 1
};
enum PetNameInvalidReason
{
// custom, not send
PET_NAME_SUCCESS = 0,
PET_NAME_INVALID = 1,
PET_NAME_NO_NAME = 2,
PET_NAME_TOO_SHORT = 3,
PET_NAME_TOO_LONG = 4,
PET_NAME_MIXED_LANGUAGES = 6,
PET_NAME_PROFANE = 7,
PET_NAME_RESERVED = 8,
PET_NAME_THREE_CONSECUTIVE = 11,
PET_NAME_INVALID_SPACE = 12,
PET_NAME_CONSECUTIVE_SPACES = 13,
PET_NAME_RUSSIAN_CONSECUTIVE_SILENT_CHARACTERS = 14,
PET_NAME_RUSSIAN_SILENT_CHARACTER_AT_BEGINNING_OR_END = 15,
PET_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 16
};
typedef std::unordered_map<uint32, PetSpell> PetSpellMap;
typedef std::vector<uint32> AutoSpellList;
#define HAPPINESS_LEVEL_SIZE 333000
#define ACTIVE_SPELLS_MAX 4
#define PET_FOLLOW_DIST 1.0f
#define PET_FOLLOW_ANGLE (M_PI_F / 4.00f) * 3.50f
class Player;
class Pet : public Creature
{
public:
explicit Pet(PetType type = MAX_PET_TYPE);
virtual ~Pet();
void AddToWorld() override;
void RemoveFromWorld() override;
PetType getPetType() const { return m_petType; }
void setPetType(PetType type) { m_petType = type; }
bool isControlled() const { return getPetType() == SUMMON_PET || getPetType() == HUNTER_PET; }
bool isTemporarySummoned() const { return m_duration > 0; }
ObjectGuid const GetSpawnerGuid() const override { return GetOwnerGuid(); }
bool Create(uint32 guidlow, CreatureCreatePos& cPos, CreatureInfo const* cinfo, uint32 pet_number);
bool CreateBaseAtCreature(Creature* creature);
bool LoadPetFromDB(Player* owner, uint32 petentry = 0, uint32 petnumber = 0, bool current = false, uint32 healthPercentage = 0, bool permanentOnly = false, bool forced = false);
void SavePetToDB(PetSaveMode mode);
void Unsummon(PetSaveMode mode, Unit* owner = nullptr);
static void DeleteFromDB(uint32 guidlow, bool separate_transaction = true);
static void DeleteFromDB(Unit* owner, PetSaveMode slot);
static SpellCastResult TryLoadFromDB(Unit* owner, uint32 petentry = 0, uint32 petnumber = 0, bool current = false, PetType mandatoryPetType = MAX_PET_TYPE);
void SetOwnerGuid(ObjectGuid owner) override;
void SetDeathState(DeathState s) override; // overwrite virtual Creature::SetDeathState and Unit::SetDeathState
void Update(uint32 update_diff, uint32 diff) override; // overwrite virtual Creature::Update and Unit::Update
uint8 GetPetAutoSpellSize() const { return m_autospells.size(); }
uint32 GetPetAutoSpellOnPos(uint8 pos) const override
{
if (pos >= m_autospells.size())
return 0;
else
return m_autospells[pos];
}
bool CanSwim() const
{
Unit const* owner = GetOwner();
if (owner)
return owner->GetTypeId() == TYPEID_PLAYER ? true : ((Creature const*)owner)->CanSwim();
else
return Creature::CanSwim();
}
bool CanFly() const { return false; } // pet are not able to fly. TODO: check if this is right
void RegenerateAll(uint32 update_diff) override; // overwrite Creature::RegenerateAll
void LooseHappiness();
HappinessState GetHappinessState() const;
void GivePetXP(uint32 xp);
void GivePetLevel(uint32 level);
void SynchronizeLevelWithOwner();
void InitStatsForLevel(uint32 level);
bool HaveInDiet(ItemPrototype const* item) const;
uint32 GetCurrentFoodBenefitLevel(uint32 itemlevel) const;
void SetDuration(int32 dur) { m_duration = dur; }
int32 GetDuration() const { return m_duration; }
int32 GetBonusDamage() const { return m_bonusdamage; }
void SetBonusDamage(int32 damage) { m_bonusdamage = damage; }
bool UpdateStats(Stats stat) override;
bool UpdateAllStats() override;
void UpdateResistances(uint32 school) override;
void UpdateArmor() override;
void UpdateMaxHealth() override;
void UpdateMaxPower(Powers power) override;
void UpdateAttackPowerAndDamage(bool ranged = false) override;
void UpdateDamagePhysical(WeaponAttackType attType) override;
bool CanTakeMoreActiveSpells(uint32 SpellIconID);
void ToggleAutocast(uint32 spellid, bool apply);
void SetModeFlags(PetModeFlags mode);
PetModeFlags GetModeFlags() const { return m_petModeFlags; }
bool HasSpell(uint32 spell) const override;
void LearnPetPassives();
void CastPetAuras(bool current);
void CastOwnerTalentAuras();
void CastPetAura(PetAura const* aura);
void _LoadSpellCooldowns();
void _SaveSpellCooldowns();
void _LoadAuras(uint32 timediff);
void _SaveAuras();
void _LoadSpells();
void _SaveSpells();
bool addSpell(uint32 spell_id, ActiveStates active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, PetSpellType type = PETSPELL_NORMAL);
bool learnSpell(uint32 spell_id);
void learnSpellHighRank(uint32 spellid);
void InitLevelupSpellsForLevel();
bool unlearnSpell(uint32 spell_id, bool learn_prev, bool clear_ab = true);
bool removeSpell(uint32 spell_id, bool learn_prev, bool clear_ab = true);
void CleanupActionBar();
PetSpellMap m_spells;
AutoSpellList m_autospells;
void InitPetCreateSpells();
bool resetTalents(bool no_cost = false);
static void resetTalentsForAllPetsOf(Player* owner, Pet* online_pet = nullptr);
uint32 resetTalentsCost() const;
void InitTalentForLevel();
virtual CharmInfo* InitCharmInfo(Unit* charm) override;
virtual void DeleteCharmInfo() override;
uint8 GetMaxTalentPointsForLevel(uint32 level) const;
uint8 GetFreeTalentPoints() const { return GetByteValue(UNIT_FIELD_BYTES_1, 1); }
void SetFreeTalentPoints(uint8 points) { SetByteValue(UNIT_FIELD_BYTES_1, 1, points); }
void UpdateFreeTalentPoints(bool resetIfNeed = true);
uint32 m_resetTalentsCost;
time_t m_resetTalentsTime;
uint32 m_usedTalentCount;
const uint64& GetAuraUpdateMask() const { return m_auraUpdateMask; }
void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); }
void ResetAuraUpdateMask() { m_auraUpdateMask = 0; }
// overwrite Creature function for name localization back to WorldObject version without localization
const char* GetNameForLocaleIdx(int32 locale_idx) const { return WorldObject::GetNameForLocaleIdx(locale_idx); }
DeclinedName const* GetDeclinedNames() const { return m_declinedname; }
bool m_removed; // prevent overwrite pet state in DB at next Pet::Update if pet already removed(saved)
// return charminfo ai only when this pet is possessed. (eye of the beast case for ex.)
virtual CreatureAI* AI() override { if (hasUnitState(UNIT_STAT_POSSESSED) && m_charmInfo->GetAI()) return m_charmInfo->GetAI(); else return m_ai.get(); }
virtual CombatData* GetCombatData() override { return m_combatData; }
void InitTamedPetPassives(Unit* player);
protected:
uint32 m_happinessTimer;
PetType m_petType;
int32 m_duration; // time until unsummon (used mostly for summoned guardians and not used for controlled pets)
int32 m_bonusdamage;
uint64 m_auraUpdateMask;
bool m_loading;
DeclinedName* m_declinedname;
private:
PetModeFlags m_petModeFlags;
CharmInfo* m_originalCharminfo;
void SaveToDB(uint32, uint8, uint32) override // overwrite of Creature::SaveToDB - don't must be called
{
MANGOS_ASSERT(false);
}
void DeleteFromDB() override // overwrite of Creature::DeleteFromDB - don't must be called
{
MANGOS_ASSERT(false);
}
};
#endif