diff options
-rw-r--r-- | src/server/game/Entities/Creature/Creature.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Pet/Pet.cpp | 53 | ||||
-rw-r--r-- | src/server/game/Entities/Pet/Pet.h | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 39 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 2 | ||||
-rw-r--r-- | src/server/game/Miscellaneous/SharedDefines.h | 2 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 11 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.h | 1 | ||||
-rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 29 |
9 files changed, 112 insertions, 29 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 7e79dc42664..9278c6c323b 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -260,7 +260,7 @@ bool Creature::InitEntry(uint32 Entry, uint32 /*team*/, const CreatureData *data CreatureInfo const *normalInfo = objmgr.GetCreatureTemplate(Entry); if (!normalInfo) { - sLog.outErrorDb("Creature::UpdateEntry creature entry %u does not exist.", Entry); + sLog.outErrorDb("Creature::InitEntry creature entry %u does not exist.", Entry); return false; } diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index 1f0533ddcda..7e122adc8c1 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -745,16 +745,9 @@ void Pet::GivePetLevel(uint8 level) bool Pet::CreateBaseAtCreature(Creature* creature) { - if (!creature) - { - sLog.outError("CRITICAL: NULL pointer parsed into CreateBaseAtCreature()"); - return false; - } - uint32 guid=objmgr.GenerateLowGuid(HIGHGUID_PET); + assert(creature); - sLog.outDebug("Create pet"); - uint32 pet_number = objmgr.GeneratePetNumber(); - if (!Create(guid, creature->GetMap(), creature->GetPhaseMask(), creature->GetEntry(), pet_number)) + if (!CreateBaseAtTamed(creature->GetCreatureInfo(), creature->GetMap(), creature->GetPhaseMask())) return false; Relocate(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), creature->GetOrientation()); @@ -774,27 +767,51 @@ bool Pet::CreateBaseAtCreature(Creature* creature) } SetDisplayId(creature->GetDisplayId()); - SetNativeDisplayId(creature->GetNativeDisplayId()); + + if (CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cinfo->family)) + SetName(cFamily->Name[sWorld.GetDefaultDbcLocale()]); + else + SetName(creature->GetNameForLocaleIdx(objmgr.GetDBCLocaleIndex())); + + return true; +} + +bool Pet::CreateBaseAtCreatureInfo(CreatureInfo const* cinfo, Unit * owner) +{ + if (!CreateBaseAtTamed(cinfo, owner->GetMap(), owner->GetPhaseMask())) + return false; + + if (CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cinfo->family)) + SetName(cFamily->Name[sWorld.GetDefaultDbcLocale()]); + + Relocate(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ(), owner->GetOrientation()); + + return true; +} + +bool Pet::CreateBaseAtTamed(CreatureInfo const * cinfo, Map * map, uint32 phaseMask) +{ + sLog.outDebug("Pet::CreateBaseForTamed"); + uint32 guid=objmgr.GenerateLowGuid(HIGHGUID_PET); + uint32 pet_number = objmgr.GeneratePetNumber(); + if (!Create(guid, map, phaseMask, cinfo->Entry, pet_number)) + return false; + SetMaxPower(POWER_HAPPINESS, GetCreatePowers(POWER_HAPPINESS)); SetPower(POWER_HAPPINESS, 166500); setPowerType(POWER_FOCUS); SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, 0); SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0); - SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, objmgr.GetXPForLevel(creature->getLevel())*PET_XP_FACTOR); + SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, objmgr.GetXPForLevel(getLevel()+1)*PET_XP_FACTOR); SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE); - if (CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cinfo->family)) - SetName(cFamily->Name[sWorld.GetDefaultDbcLocale()]); - else - SetName(creature->GetNameForLocaleIdx(objmgr.GetDBCLocaleIndex())); - if (cinfo->type == CREATURE_TYPE_BEAST) { SetUInt32Value(UNIT_FIELD_BYTES_0, 0x02020100); SetSheath(SHEATH_STATE_MELEE); SetByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED | UNIT_CAN_BE_ABANDONED); - SetUInt32Value(UNIT_MOD_CAST_SPEED, creature->GetUInt32Value(UNIT_MOD_CAST_SPEED)); } + return true; } @@ -833,7 +850,7 @@ bool Guardian::InitStatsForLevel(uint8 petlevel) SetAttackTime(OFF_ATTACK, BASE_ATTACK_TIME); SetAttackTime(RANGED_ATTACK, BASE_ATTACK_TIME); - SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0); + SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f); //scale CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cinfo->family); diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h index 2c9b72b4fa6..72ae2d678c4 100644 --- a/src/server/game/Entities/Pet/Pet.h +++ b/src/server/game/Entities/Pet/Pet.h @@ -140,6 +140,8 @@ class Pet : public Guardian bool Create (uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 pet_number); bool CreateBaseAtCreature(Creature* creature); + bool CreateBaseAtCreatureInfo(CreatureInfo const* cinfo,Unit * owner); + bool CreateBaseAtTamed(CreatureInfo const * cinfo, Map * map, uint32 phaseMask); bool LoadPetFromDB(Player* owner,uint32 petentry = 0,uint32 petnumber = 0, bool current = false); bool isBeingLoaded() const { return m_loading;} void SavePetToDB(PetSaveMode mode); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 1fb662c43df..b127592f8ef 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -14530,6 +14530,35 @@ Pet* Unit::CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id) return NULL; } + uint8 level = (creatureTarget->getLevel() < (getLevel() - 5)) ? (getLevel() - 5) : creatureTarget->getLevel(); + + InitTamedPet(pet, level, spell_id); + + return pet; +} + +Pet* Unit::CreateTamedPetFrom(uint32 creatureEntry, uint32 spell_id) +{ + if (GetTypeId() != TYPEID_PLAYER) + return NULL; + + CreatureInfo const* creatureInfo = objmgr.GetCreatureTemplate(creatureEntry); + if (!creatureInfo) + return NULL; + + Pet* pet = new Pet((Player*)this, HUNTER_PET); + + if (!pet->CreateBaseAtCreatureInfo(creatureInfo, this) || !InitTamedPet(pet, getLevel(), spell_id)) + { + delete pet; + return NULL; + } + + return pet; +} + +bool Unit::InitTamedPet(Pet * pet, uint8 level, uint32 spell_id) +{ pet->SetCreatorGUID(GetGUID()); pet->setFaction(getFaction()); pet->SetUInt32Value(UNIT_CREATED_BY_SPELL, spell_id); @@ -14537,13 +14566,10 @@ Pet* Unit::CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id) if (GetTypeId() == TYPEID_PLAYER) pet->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); - uint8 level = (creatureTarget->getLevel() < (getLevel() - 5)) ? (getLevel() - 5) : creatureTarget->getLevel(); - if (!pet->InitStatsForLevel(level)) { - sLog.outError("Pet::InitStatsForLevel() failed for creature (Entry: %u)!",creatureTarget->GetEntry()); - delete pet; - return NULL; + sLog.outError("Pet::InitStatsForLevel() failed for creature (Entry: %u)!",pet->GetEntry()); + return false; } pet->GetCharmInfo()->SetPetNumber(objmgr.GeneratePetNumber(), true); @@ -14551,8 +14577,7 @@ Pet* Unit::CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id) pet->InitPetCreateSpells(); //pet->InitLevelupSpellsForLevel(); pet->SetHealth(pet->GetMaxHealth()); - - return pet; + return true; } bool Unit::IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura * aura, SpellEntry const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const *& spellProcEvent) diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 347a862b5d4..9b50a47f3c8 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1538,6 +1538,8 @@ class Unit : public WorldObject void RemoveCharmAuras(); Pet* CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id = 0); + Pet* CreateTamedPetFrom(uint32 creatureEntry,uint32 spell_id = 0); + bool InitTamedPet(Pet * pet, uint8 level, uint32 spell_id); // aura apply/remove helpers - you should better not use these void _AddAura(UnitAura * aura, Unit * caster); diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index fb30ce98f4c..115e5337e5b 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -754,7 +754,7 @@ enum SpellEffects SPELL_EFFECT_QUEST_START = 150, SPELL_EFFECT_TRIGGER_SPELL_2 = 151, SPELL_EFFECT_152 = 152, - SPELL_EFFECT_153 = 153, + SPELL_EFFECT_CREATE_TAMED_PET = 153, SPELL_EFFECT_DISCOVER_TAXI = 154, SPELL_EFFECT_TITAN_GRIP = 155, SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC = 156, diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 510be691d18..d68d4587d56 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -5218,6 +5218,17 @@ SpellCastResult Spell::CheckCast(bool strict) } break; } + case SPELL_EFFECT_CREATE_TAMED_PET: + { + if (m_targets.getUnitTarget()) + { + if (m_targets.getUnitTarget()->GetTypeId() != TYPEID_PLAYER) + return SPELL_FAILED_BAD_TARGETS; + if (m_targets.getUnitTarget()->GetPetGUID()) + return SPELL_FAILED_ALREADY_HAVE_SUMMON; + } + break; + } case SPELL_EFFECT_SUMMON_PET: { if (m_caster->GetPetGUID()) //let warlock do a replacement summon diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index f7ad4173e22..d7ed3d8eeb6 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -383,6 +383,7 @@ class Spell void EffectWMODamage(uint32 i); void EffectWMORepair(uint32 i); void EffectActivateRune(uint32 i); + void EffectCreateTamedPet(uint32 i); void EffectDiscoverTaxi(uint32 i); void EffectTitanGrip(uint32 i); void EffectEnchantItemPrismatic(uint32 i); diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 881ff1d8f68..2a42961df1b 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -213,12 +213,12 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= &Spell::EffectPlayerPull, //145 SPELL_EFFECT_145 Black Hole Effect &Spell::EffectActivateRune, //146 SPELL_EFFECT_ACTIVATE_RUNE &Spell::EffectQuestFail, //147 SPELL_EFFECT_QUEST_FAIL quest fail - &Spell::EffectUnused, //148 SPELL_EFFECT_148 unused + &Spell::EffectUnused, //148 SPELL_EFFECT_148 1 spell - 43509 &Spell::EffectChargeDest, //149 SPELL_EFFECT_CHARGE_DEST &Spell::EffectQuestStart, //150 SPELL_EFFECT_QUEST_START &Spell::EffectTriggerRitualOfSummoning, //151 SPELL_EFFECT_TRIGGER_SPELL_2 &Spell::EffectNULL, //152 SPELL_EFFECT_152 summon Refer-a-Friend - &Spell::EffectNULL, //153 SPELL_EFFECT_CREATE_PET misc value is creature entry + &Spell::EffectCreateTamedPet, //153 SPELL_EFFECT_CREATE_TAMED_PET misc value is creature entry &Spell::EffectDiscoverTaxi, //154 SPELL_EFFECT_DISCOVER_TAXI &Spell::EffectTitanGrip, //155 SPELL_EFFECT_TITAN_GRIP Allows you to equip two-handed axes, maces and swords in one hand, but you attack $49152s1% slower than normal. &Spell::EffectEnchantItemPrismatic, //156 SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC @@ -7848,6 +7848,31 @@ void Spell::EffectActivateRune(uint32 eff_idx) } } +void Spell::EffectCreateTamedPet(uint32 i) +{ + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER || unitTarget->GetPetGUID() || unitTarget->getClass() != CLASS_HUNTER) + return; + + uint32 creatureEntry = m_spellInfo->EffectMiscValue[i]; + Pet * pet = unitTarget->CreateTamedPetFrom(creatureEntry, m_spellInfo->Id); + if (!pet) + return; + + // add to world + pet->GetMap()->Add(pet->ToCreature()); + + // unitTarget has pet now + unitTarget->SetMinion(pet, true); + + pet->InitTalentForLevel(); + + if (unitTarget->GetTypeId() == TYPEID_PLAYER) + { + pet->SavePetToDB(PET_SAVE_AS_CURRENT); + unitTarget->ToPlayer()->PetSpellInitialize(); + } +} + void Spell::EffectDiscoverTaxi(uint32 i) { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) |