/*
* Ascent MMORPG Server
* Copyright (C) 2005-2007 Ascent Team
*
* 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 3 of the License, or
* 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 _PET_H
#define _PET_H
/* Taken from ItemPetFood.dbc
* Each value is equal to a flag
* so 1 << PET_FOOD_BREAD for example
* will result in a usable value.
*/
enum PET_FOOD
{
PET_FOOD_NONE,
PET_FOOD_MEAT,
PET_FOOD_FISH,
PET_FOOD_CHEESE,
PET_FOOD_BREAD,
PET_FOOD_FUNGUS,
PET_FOOD_FRUIT,
PET_FOOD_RAW_MEAT, // not used in pet diet
PET_FOOD_RAW_FISH // not used in pet diet
};
/* Pet Diet:
taken from http://www.wowwiki.com/Pet_(Hunter)
filled with "0" for unknown / non existing creature family's
how to use:
value = PetDiet[number_creature_family];
*/
static const unsigned char PetDiet[30] = { 0,1,3,1,63,63,3,3,58,48,0,1,52,0,0,0,0,0,0,0,1,178,0,0,48,33,1,14,0};
/*Loyalty and happiness ticks*/
static const char LoyaltyTicks[3] = {-20, 10, 20};//loyalty_ticks for unhappy, content, happy
static const unsigned char HappinessTicks[6] = {70, 35, 17, 8, 4, 2};//loose_happiness ticks per loyalty lvl
enum PET_ACTION
{
PET_ACTION_STAY,
PET_ACTION_FOLLOW,
PET_ACTION_ATTACK,
PET_ACTION_DISMISS,
PET_ACTION_CASTING,
};
enum PET_STATE
{
PET_STATE_PASSIVE,
PET_STATE_DEFENSIVE,
PET_STATE_AGGRESSIVE
};
enum PET_SPELL
{
PET_SPELL_PASSIVE = 0x06000000,
PET_SPELL_DEFENSIVE,
PET_SPELL_AGRESSIVE,
PET_SPELL_STAY = 0x07000000,
PET_SPELL_FOLLOW,
PET_SPELL_ATTACK
};
enum StableState
{
STABLE_STATE_ACTIVE = 1,
STABLE_STATE_PASSIVE = 3
};
enum HappinessState
{
UNHAPPY =0,
CONTENT =1,
HAPPY =2
};
enum LoyaltyLevel
{
REBELIOUS =1,
UNRULY =2,
SUBMISIVE =3,
DEPENDABLE =4,
FAITHFUL =5,
BEST_FRIEND =6
};
#define PET_DELAYED_REMOVAL_TIME 60000 // 1 min
#define DEFAULT_SPELL_STATE 0x8100
typedef map PetSpellMap;
struct PlayerPet;
class SERVER_DECL Pet : public Creature
{
friend class Player;
friend class Creature;
friend class WorldSession;
public:
Pet(uint32 high, uint32 low);
~Pet();
void LoadFromDB(Player* owner, PlayerPet * pi);
void CreateAsSummon(uint32 entry, CreatureInfo *ci, Creature *created_from_creature, Unit* owner, SpellEntry *created_by_spell, uint32 type, uint32 expiretime);
virtual void Update(uint32 time);
inline uint32 GetXP(void) { return m_PetXP; }
void InitializeSpells();
void ReInitializeSpells();
void InitializeMe(bool first);
void SendSpellsToOwner();
void SendNullSpellsToOwner();
inline void SetPetAction(uint32 act) { m_Action = act; }
inline uint32 GetPetAction(void) { return m_Action; }
inline void SetPetState(uint32 state) { m_State = state; }
inline uint32 GetPetState(void) { return m_State; }
inline void SetPetDiet(uint32 diet) { m_Diet = diet; }
inline void SetPetDiet() { m_Diet = PetDiet[this->creature_info->Family]; }
inline uint32 GetPetDiet(void) { return m_Diet; }
inline AI_Spell* GetAISpellForSpellId(uint32 spellid)
{
std::map::iterator itr = m_AISpellStore.find(spellid);
if(itr != m_AISpellStore.end())
return itr->second;
else
return NULL;
}
void UpdatePetInfo(bool bSetToOffline);
void Remove(bool bSafeDelete, bool bUpdate, bool bSetOffline);
void Dismiss(bool bSafeDelete = false);
void DelayedRemove(bool bTime, bool bDeath);
inline Player* GetPetOwner() { return m_Owner; }
inline void ClearPetOwner() { m_Owner = 0; }
void GiveXP(uint32 xp);
uint32 GetNextLevelXP(uint32 currentlevel);
void ApplyStatsForLevel();
void ApplySummonLevelAbilities();
void ApplyPetLevelAbilities();
void PetSafeDelete();
void SetDefaultSpells();
void SetDefaultActionbar();
void LoadSpells();
void AddSpell(SpellEntry * sp, bool putInBar = false);
void RemoveSpell(SpellEntry * sp);
void SetSpellState(SpellEntry * sp, uint16 State);
uint16 GetSpellState(SpellEntry * sp);
inline void AddSpell(uint32 SpellID)
{
SpellEntry * sp = sSpellStore.LookupEntry(SpellID);
if(sp)
{
AddSpell(sp);
UpdateTP();
}
}
inline void RemoveSpell(uint32 SpellID)
{
SpellEntry * sp = sSpellStore.LookupEntry(SpellID);
if(sp) RemoveSpell(sp);
}
inline void SetSpellState(uint32 SpellID, uint16 State)
{
SpellEntry * sp = sSpellStore.LookupEntry(SpellID);
if(sp) SetSpellState(sp, State);
}
inline uint16 GetSpellState(uint32 SpellID)
{
if(SpellID == 0)
return DEFAULT_SPELL_STATE;
SpellEntry * sp = sSpellStore.LookupEntry(SpellID);
if(sp)
return GetSpellState(sp);
return DEFAULT_SPELL_STATE;
}
void CreateAISpell(SpellEntry * info);
inline PetSpellMap* GetSpells() { return &mSpells; }
inline bool IsSummon() { return Summon; }
void __fastcall SetAutoCastSpell(AI_Spell * sp);
void Rename(string NewName);
inline string& GetName() { return m_name; }
void AddPetSpellToOwner(uint32 spellId);
uint16 SpellTP(uint32 spellId);
uint16 GetUsedTP();
void UpdateTP();
bool CanLearnSpellTP(uint32 spellId);
protected:
bool bHasLoyalty;
Player *m_Owner;
uint32 m_PetXP;
PetSpellMap mSpells;
PlayerPet * mPi;
uint32 ActionBar[10]; // 10 slots
std::map m_AISpellStore;
uint32 m_AutoCombatSpell;
uint32 m_PartySpellsUpdateTimer;
uint32 m_HappinessTimer;
uint32 m_LoyaltyTimer;
uint32 m_PetNumber;
uint32 m_Action;
uint32 m_State;
uint32 m_ExpireTime;
uint32 m_Diet;
uint64 m_OwnerGuid;
int16 TP;
int32 LoyaltyPts;
bool bExpires;
bool Summon;
string m_name;
uint8 GetLoyaltyLevel(){return ((GetUInt32Value(UNIT_FIELD_BYTES_1) >> 8) & 0xff);};
HappinessState GetHappinessState();
uint32 GetHighestRankSpell(uint32 spellId);
void UpdateLoyalty(char pts);
void SetLoyaltyLvl(LoyaltyLevel lvl);
};
#define PET_LOYALTY_UPDATE_TIMER 120000
#define PET_LOYALTY_LVL_RANGE 300 //range for each layalty lvl, now (300) if pet HAPPY, it will gain higher loyalty lvl in 30 minutes (no idea what is Blizz): 300 / 20 * 120 000 = 1 800 000 ms = 30 min
#define PET_HAPPINESS_UPDATE_VALUE 333000
#define PET_HAPPINESS_UPDATE_TIMER 7500
#define PET_PARTY_SPELLS_UPDATE_TIMER 10000
#define PET_ACTION_ACTION 0x700
#define PET_ACTION_STATE 0x600
//TODO: grep see the way pet spells contain the same flag?
#define PET_ACTION_SPELL 0xC100
#define PET_ACTION_SPELL_1 0x8100
#define PET_ACTION_SPELL_2 0x0100
#define PET_SPELL_AUTOCAST_CHANCE 50
#endif