bool Pet::CreateBaseAtTamed(CreatureTemplate const* cinfo, Map* map, uint32 phaseMask) { sLog->outDebug(LOG_FILTER_PETS, "Pet::CreateBaseForTamed"); uint32 guid=sObjectMgr->GenerateLowGuid(HIGHGUID_PET); uint32 pet_number = sObjectMgr->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, uint32(sObjectMgr->GetXPForLevel(getLevel()+1)*PET_XP_FACTOR)); SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE); 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); } return true; }
void Guardian::UpdateMaxPower(Powers power) { UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + power); float addValue = (power == POWER_MANA) ? GetStat(STAT_INTELLECT) - GetCreateStat(STAT_INTELLECT) : 0.0f; float multiplicator = 15.0f; switch (GetEntry()) { case ENTRY_IMP: multiplicator = 4.95f; break; case ENTRY_VOIDWALKER: case ENTRY_SUCCUBUS: case ENTRY_FELHUNTER: case ENTRY_FELGUARD: multiplicator = 11.5f; break; default: multiplicator = 15.0f; break; } float value = GetModifierValue(unitMod, BASE_VALUE) + GetCreatePowers(power); value *= GetModifierValue(unitMod, BASE_PCT); value += GetModifierValue(unitMod, TOTAL_VALUE) + addValue * multiplicator; value *= GetModifierValue(unitMod, TOTAL_PCT); SetMaxPower(power, uint32(value)); }
bool Creature::UpdateAllStats() { UpdateMaxHealth(); UpdateAttackPowerAndDamage(); for (uint32 i = 0; i <= sChrPowerTypesStore.GetNumRows(); i++) { ChrPowerTypesEntry const* cEntry = sChrPowerTypesStore.LookupEntry(i); if (!cEntry) continue; if (getClass() != cEntry->classId) continue; if (cEntry->power == 10) continue; SetMaxPower(Powers(cEntry->power), uint32(GetCreatePowers(Powers(cEntry->power)))); } for(int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; ++i) UpdateResistances(i); return true; }
bool Pet::UpdateAllStats() { for (int i = STAT_STRENGTH; i < MAX_STATS; ++i) UpdateStats(Stats(i)); for (uint32 i = 0; i <= sChrPowerTypesStore.GetNumRows(); i++) { ChrPowerTypesEntry const* cEntry = sChrPowerTypesStore.LookupEntry(i); if (!cEntry) continue; if (getClass() != cEntry->classId) continue; if (cEntry->power == 10) continue; SetMaxPower(Powers(cEntry->power), uint32(GetCreatePowers(Powers(cEntry->power)))); } for (int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; ++i) UpdateResistances(i); return true; }
void Pet::UpdateMaxPower(Powers power) { UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + power); float addValue = (power == POWER_MANA) ? GetStat(STAT_INTELLECT) - GetCreateStat(STAT_INTELLECT) : 0.0f; float multiplicator; // nesocips warlock pet stats calculation switch(GetEntry()) { case 416: multiplicator = 4.95f; break; // imp case 1860: // voidwalker case 1863: // succubus case 417: // felhunter case 17252: multiplicator = 11.5f; break; // felguard default: multiplicator = 15.0f; break; } float value = GetModifierValue(unitMod, BASE_VALUE) + GetCreatePowers(power); value *= GetModifierValue(unitMod, BASE_PCT); value += GetModifierValue(unitMod, TOTAL_VALUE) + addValue * multiplicator; value *= GetModifierValue(unitMod, TOTAL_PCT); SetMaxPower(power, uint32(value)); }
void Creature::SelectLevel(const CreatureInfo *cinfo) { uint32 minlevel = min(cinfo->maxlevel, cinfo->minlevel); uint32 maxlevel = max(cinfo->maxlevel, cinfo->minlevel); uint32 level = minlevel == maxlevel ? minlevel : urand(minlevel, maxlevel); SetLevel(level); float rellevel = maxlevel == minlevel ? 0 : (float(level - minlevel))/(maxlevel - minlevel); uint32 minhealth = min(cinfo->maxhealth, cinfo->minhealth); uint32 maxhealth = max(cinfo->maxhealth, cinfo->minhealth); uint32 health = uint32(_GetHealthMod(isPet() ? 0 : cinfo->rank) * (minhealth + uint32(rellevel*(maxhealth - minhealth)))); SetMaxHealth(health); SetUInt32Value(UNIT_FIELD_BASE_HEALTH,health); SetHealth(health); uint32 minmana = min(cinfo->maxmana, cinfo->minmana); uint32 maxmana = max(cinfo->maxmana, cinfo->minmana); uint32 mana = minmana + uint32(rellevel*(maxmana - minmana)); SetMaxPower(POWER_MANA, mana); //MAX Mana SetUInt32Value(UNIT_FIELD_BASE_MANA, mana); SetPower(POWER_MANA, mana); }
void Vehicle::AddToWorld() { if(!IsInWorld()) { if(m_zoneScript) m_zoneScript->OnCreatureCreate(this, true); ObjectAccessor::Instance().AddObject(this); for(uint32 i = 0; i < MAX_SPELL_VEHICLE; ++i) { if(!m_spells[i]) continue; SpellEntry const *spellInfo = sSpellStore.LookupEntry(m_spells[i]); if(!spellInfo) continue; if(spellInfo->powerType == POWER_MANA) break; if(spellInfo->powerType == POWER_ENERGY) { setPowerType(POWER_ENERGY); SetMaxPower(POWER_ENERGY, 100); break; } } Unit::AddToWorld(); InstallAllAccessories(); AIM_Initialize(); } }
void Guardian::UpdateMaxPower(Powers power) { UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + power); float addValue = (power == POWER_MANA) ? std::max<float>(GetStat(STAT_INTELLECT) - GetCreateStat(STAT_INTELLECT), 0.0f) : 0.0f; float multiplicator = 15.0f; switch (GetEntry()) { case NPC_IMP: case NPC_WATER_ELEMENTAL_TEMP: case NPC_WATER_ELEMENTAL_PERM: multiplicator = 4.95f; break; case NPC_VOIDWALKER: case NPC_SUCCUBUS: case NPC_FELHUNTER: case NPC_FELGUARD: multiplicator = 11.5f; break; default: multiplicator = 15.0f; break; } // xinef: Do NOT add base mana TWICE float value = GetModifierValue(unitMod, BASE_VALUE) + (power != POWER_MANA ? GetCreatePowers(power) : 0); value *= GetModifierValue(unitMod, BASE_PCT); value += GetModifierValue(unitMod, TOTAL_VALUE) + addValue * multiplicator; value *= GetModifierValue(unitMod, TOTAL_PCT); SetMaxPower(power, uint32(value)); }
void Creature::UpdateMaxPower(Powers power) { UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + power); float value = GetTotalAuraModValue(unitMod); SetMaxPower(power, uint32(value)); }
void TotemSummon::Load(CreatureProto* proto, Unit* owner, LocationVector & position, uint32 spellid, int32 summonslot) { Summon::Load(proto, owner, position, spellid, summonslot); TotemDisplayIdEntry* totemdisplay = TotemDisplayIdStorage.LookupEntry(creature_info->Male_DisplayID); uint32 displayID = 0; if(totemdisplay != NULL) { switch(owner->getRace()) { case RACE_DRAENEI: displayID = totemdisplay->DraeneiId; break; case RACE_TROLL: displayID = totemdisplay->TrollId; break; case RACE_ORC: displayID = totemdisplay->OrcId; break; } } if(displayID == 0) displayID = creature_info->Male_DisplayID; // Set up the creature. SetMaxPower(POWER_TYPE_FOCUS, owner->getLevel() * 30); SetPower(POWER_TYPE_FOCUS, owner->getLevel() * 30); setLevel(owner->getLevel()); setRace(0); setClass(1); setGender(2); SetPowerType(1); SetBaseAttackTime(MELEE, 2000); SetBaseAttackTime(OFFHAND, 2000); SetBoundingRadius(1.0f); SetCombatReach(1.0f); SetDisplayId(displayID); SetNativeDisplayId(creature_info->Male_DisplayID); SetCastSpeedMod(1.0f); SetUInt32Value(OBJECT_FIELD_DYNAMIC_FLAGS, 0); InheritSMMods(owner); for(uint8 school = 0; school < SCHOOL_COUNT; school++) { ModDamageDone[ school ] = owner->GetDamageDoneMod(school); HealDoneMod[ school ] = owner->HealDoneMod[ school ]; } m_aiInterface->Init(this, AITYPE_TOTEM, MOVEMENTTYPE_NONE, owner); DisableAI(); }
void Player::UpdateMaxPower(Powers power) { UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + power); float value = GetModifierValue(unitMod, BASE_VALUE) + GetCreatePowers(power); value *= GetModifierValue(unitMod, BASE_PCT); value += GetModifierValue(unitMod, TOTAL_VALUE); value *= GetModifierValue(unitMod, TOTAL_PCT); SetMaxPower(power, uint32(value)); }
void Pet::UpdateMaxPower(Powers power) { UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + power); float addValue = (power == POWER_MANA) ? GetStat(STAT_INTELLECT) - GetCreateStat(STAT_INTELLECT) : 0.0f; float value = GetModifierValue(unitMod, BASE_VALUE) + GetCreatePowers(power); value *= GetModifierValue(unitMod, BASE_PCT); value += GetModifierValue(unitMod, TOTAL_VALUE) + addValue * 15.0f; value *= GetModifierValue(unitMod, TOTAL_PCT); SetMaxPower(power, uint32(value)); }
void Player::UpdateMaxPower(Powers power) { UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + power); float bonusPower = (power == POWER_MANA && GetCreatePowers(power) > 0) ? GetManaBonusFromIntellect() : 0; float value = GetModifierValue(unitMod, BASE_VALUE) + GetCreatePowers(power); value *= GetModifierValue(unitMod, BASE_PCT); value += GetModifierValue(unitMod, TOTAL_VALUE) + bonusPower; value *= GetModifierValue(unitMod, TOTAL_PCT); SetMaxPower(power, uint32(value)); }
void Pet::UpdateMaxPower(Powers power) { if (!CanModifyStats()) return; UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + power); float intellectBonus = (power == POWER_MANA) ? (GetStat(STAT_INTELLECT) - GetCreateStat(STAT_INTELLECT))*(CalculateScalingData()->powerScale / 100.0f) : 0.0f; float value = GetModifierValue(unitMod, BASE_VALUE) + GetCreatePowers(power) + intellectBonus; value *= GetModifierValue(unitMod, BASE_PCT); value += GetModifierValue(unitMod, TOTAL_VALUE); value *= GetModifierValue(unitMod, TOTAL_PCT); SetMaxPower(power, uint32(value)); }
void Player::UpdateMaxPower(Powers power) { UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + power); float bonusPower = (power == POWER_MANA) ? GetManaBonusFromIntellect() : 0; float value = GetModifierValue(unitMod, BASE_VALUE) + GetCreatePowers(power); value *= GetModifierValue(unitMod, BASE_PCT); value += GetModifierValue(unitMod, TOTAL_VALUE) + bonusPower; value *= GetModifierValue(unitMod, TOTAL_PCT); if (HasAura(30422, 0)) // Netherspite's Green Beam - Serenity if (power == POWER_MANA) SetPower(power, uint32(value)); SetMaxPower(power, uint32(value)); }
void Player::UpdateMaxPower(Powers power) { MANGOS_ASSERT(power < MAX_POWERS); UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + power); uint32 create_power = GetCreateMaxPowers(power); // ignore classes without mana float bonusPower = (power == POWER_MANA && create_power > 0) ? GetManaBonusFromIntellect() : 0; float value = GetModifierValue(unitMod, BASE_VALUE) + create_power; value *= GetModifierValue(unitMod, BASE_PCT); value += GetModifierValue(unitMod, TOTAL_VALUE) + bonusPower; value *= GetModifierValue(unitMod, TOTAL_PCT); SetMaxPower(power, uint32(value)); }
void GuardianSummon::Load(CreatureProto* proto, Unit* owner, LocationVector & position, uint32 spellid, int32 summonslot) { Summon::Load(proto, owner, position, spellid, summonslot); SetPowerType(POWER_TYPE_MANA); SetMaxPower(POWER_TYPE_MANA, GetMaxPower(POWER_TYPE_MANA) + 28 + 10 * getLevel()); SetPower(POWER_TYPE_MANA, GetPower(POWER_TYPE_MANA) + 28 + 10 * getLevel()); setLevel(owner->getLevel()); SetMaxHealth(GetMaxHealth() + 28 + 30 * getLevel()); SetHealth(GetMaxHealth()); SetType(CREATURE_TYPE_GUARDIAN); m_aiInterface->Init(this, AITYPE_PET , MOVEMENTTYPE_NONE, owner); m_aiInterface->SetUnitToFollow(owner); m_aiInterface->SetFollowDistance(3.0f); m_noRespawn = true; }
bool Player::UpdateAllStats() { for (int i = STAT_STRENGTH; i < MAX_STATS; ++i) { float value = GetTotalStatValue(Stats(i)); SetStat(Stats(i), (int32)value); } UpdateArmor(); // calls UpdateAttackPowerAndDamage() in UpdateArmor for SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR UpdateAttackPowerAndDamage(true); UpdateMaxHealth(); for (uint32 i = 0; i <= sChrPowerTypesStore.GetNumRows(); i++) { ChrPowerTypesEntry const* cEntry = sChrPowerTypesStore.LookupEntry(i); if (!cEntry) continue; if (getClass() != cEntry->classId) continue; if (cEntry->power == 10) continue; SetMaxPower(Powers(cEntry->power), uint32(GetCreatePowers(Powers(cEntry->power)))); } UpdateAllRatings(); UpdateAllCritPercentages(); UpdateAllSpellCritChances(); UpdateDefenseBonusesMod(); UpdateShieldBlockValue(); UpdateArmorPenetration(); UpdateSpellDamageAndHealingBonus(); UpdateManaRegen(); UpdateExpertise(BASE_ATTACK); UpdateExpertise(OFF_ATTACK); for (int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; ++i) UpdateResistances(i); return true; }
void CActorCondition::UpdateCondition() { if(psActorFlags.test(AF_GODMODE_RT)) { UpdateSatiety(); UpdateBoosters(); m_fAlcohol += m_fV_Alcohol*m_fDeltaTime; clamp (m_fAlcohol, 0.0f, 1.0f); if(IsGameTypeSingle()) { CEffectorCam* ce = Actor()->Cameras().GetCamEffector((ECamEffectorType)effAlcohol); if(ce) RemoveEffector(m_object,effAlcohol); } } if (GodMode()) return; if (!object().g_Alive()) return; if (!object().Local() && m_object != Level().CurrentViewEntity()) return; float base_weight = object().MaxCarryWeight(); float cur_weight = object().inventory().TotalWeight(); if ((object().mstate_real&mcAnyMove)) { ConditionWalk( cur_weight / base_weight, isActorAccelerated( object().mstate_real,object().IsZoomAimingMode() ), (object().mstate_real&mcSprint) != 0 ); } else { ConditionStand( cur_weight / base_weight ); } if ( IsGameTypeSingle() ) { float k_max_power = 1.0f; if( true ) { k_max_power = 1.0f + _min(cur_weight, base_weight) / base_weight + _max(0.0f, (cur_weight - base_weight) / 10.0f); } else { k_max_power = 1.0f; } SetMaxPower (GetMaxPower() - m_fPowerLeakSpeed * m_fDeltaTime * k_max_power); } m_fAlcohol += m_fV_Alcohol*m_fDeltaTime; clamp (m_fAlcohol, 0.0f, 1.0f); if ( IsGameTypeSingle() ) { CEffectorCam* ce = Actor()->Cameras().GetCamEffector((ECamEffectorType)effAlcohol); if ((m_fAlcohol>0.0001f) ){ if(!ce){ AddEffector(m_object,effAlcohol, "effector_alcohol", GET_KOEFF_FUNC(this, &CActorCondition::GetAlcohol)); } }else{ if(ce) RemoveEffector(m_object,effAlcohol); } string512 pp_sect_name; shared_str ln = Level().name(); if(ln.size()) { CEffectorPP* ppe = object().Cameras().GetPPEffector((EEffectorPPType)effPsyHealth); strconcat (sizeof(pp_sect_name),pp_sect_name, "effector_psy_health", "_", *ln); if(!pSettings->section_exist(pp_sect_name)) xr_strcpy (pp_sect_name, "effector_psy_health"); if ( !fsimilar(GetPsyHealth(), 1.0f, 0.05f) ) { if(!ppe) { AddEffector(m_object,effPsyHealth, pp_sect_name, GET_KOEFF_FUNC(this, &CActorCondition::GetPsy)); } }else { if(ppe) RemoveEffector(m_object,effPsyHealth); } } //- if(fis_zero(GetPsyHealth())) //- SetHealth( 0.0f ); }; UpdateSatiety(); UpdateBoosters(); inherited::UpdateCondition(); if( IsGameTypeSingle() ) UpdateTutorialThresholds(); if(GetHealth()<0.05f && m_death_effector==NULL && IsGameTypeSingle()) { if(pSettings->section_exist("actor_death_effector")) m_death_effector = xr_new<CActorDeathEffector>(this, "actor_death_effector"); } if(m_death_effector && m_death_effector->IsActual()) { m_death_effector->UpdateCL (); if(!m_death_effector->IsActual()) m_death_effector->Stop(); } AffectDamage_InjuriousMaterialAndMonstersInfluence(); }
bool Vehicle::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 vehicleId, uint32 team, const CreatureData *data) { SetMap(map); SetPhaseMask(phaseMask,false); CreatureInfo const *cinfo = sObjectMgr.GetCreatureTemplate(Entry); if(!cinfo) { sLog.outErrorDb("Creature entry %u does not exist.", Entry); return false; } Object::_Create(guidlow, Entry, HIGHGUID_VEHICLE); if(!UpdateEntry(Entry, team, data)) return false; if(!vehicleId) { CreatureDataAddon const *cainfo = GetCreatureAddon(); if(!cainfo) return false; vehicleId = cainfo->vehicle_id; } if(!SetVehicleId(vehicleId)) return false; LoadCreaturesAddon(); m_regenHealth = false; m_creation_time = getMSTime(); SetFloatValue(UNIT_FIELD_HOVERHEIGHT, 1.0f); //RemoveMonsterMoveFlag(MONSTER_MOVE_WALK); //Notify the map's instance data. //Only works if you create the object in it, not if it is moves to that map. //Normally non-players do not teleport to other maps. if(map->IsDungeon() && ((InstanceMap*)map)->GetInstanceData()) { ((InstanceMap*)map)->GetInstanceData()->OnCreatureCreate(this); } if(m_vehicleInfo->m_powerType == POWER_TYPE_STEAM) { setPowerType(POWER_ENERGY); SetMaxPower(POWER_ENERGY, 100); SetPower(POWER_ENERGY, 100); } else if(m_vehicleInfo->m_powerType == POWER_TYPE_PYRITE) { setPowerType(POWER_ENERGY); SetMaxPower(POWER_ENERGY, 50); SetPower(POWER_ENERGY, 50); } else { for (uint32 i = 0; i < MAX_VEHICLE_SPELLS; ++i) { if(!GetVehicleData()->v_spells[i]) continue; SpellEntry const *spellInfo = sSpellStore.LookupEntry(GetVehicleData()->v_spells[i]); if(!spellInfo) continue; if(spellInfo->powerType == POWER_MANA) break; if(spellInfo->powerType == POWER_ENERGY) { setPowerType(POWER_ENERGY); SetMaxPower(POWER_ENERGY, 100); SetPower(POWER_ENERGY, 100); break; } } } SetHealth(GetMaxHealth()); InstallAllAccessories(); return true; }
bool Pet::LoadPetFromDB(Player* owner, uint32 petentry, uint32 petnumber, bool current) { m_loading = true; uint32 ownerid = owner->GetGUIDLow(); QueryResult result; if (petnumber) // known petnumber entry 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType " "FROM character_pet WHERE owner = '%u' AND id = '%u'", ownerid, petnumber); else if (current) // current pet (slot 0) 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType " "FROM character_pet WHERE owner = '%u' AND slot = '%u'", ownerid, PET_SAVE_AS_CURRENT); else if (petentry) // known petentry entry (unique for summoned pet, but non unique for hunter pet (only from current or not stabled pets) // 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType " "FROM character_pet WHERE owner = '%u' AND entry = '%u' AND (slot = '%u' OR slot > '%u') ", ownerid, petentry, PET_SAVE_AS_CURRENT, PET_SAVE_LAST_STABLE_SLOT); else // any current or other non-stabled pet (for hunter "call pet") // 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType " "FROM character_pet WHERE owner = '%u' AND (slot = '%u' OR slot > '%u') ", ownerid, PET_SAVE_AS_CURRENT, PET_SAVE_LAST_STABLE_SLOT); if (!result) { m_loading = false; return false; } Field* fields = result->Fetch(); // update for case of current pet "slot = 0" petentry = fields[1].GetUInt32(); if (!petentry) return false; uint32 summon_spell_id = fields[15].GetUInt32(); SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(summon_spell_id); bool is_temporary_summoned = spellInfo && spellInfo->GetDuration() > 0; // check temporary summoned pets like mage water elemental if (current && is_temporary_summoned) return false; PetType pet_type = PetType(fields[16].GetUInt8()); if (pet_type == HUNTER_PET) { CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(petentry); if (!creatureInfo || !creatureInfo->isTameable(owner->CanTameExoticPets())) return false; } uint32 pet_number = fields[0].GetUInt32(); if (current && owner->IsPetNeedBeTemporaryUnsummoned()) { owner->SetTemporaryUnsummonedPetNumber(pet_number); return false; } Map* map = owner->GetMap(); uint32 guid = sObjectMgr->GenerateLowGuid(HIGHGUID_PET); if (!Create(guid, map, owner->GetPhaseMask(), petentry, pet_number)) return false; float px, py, pz; owner->GetClosePoint(px, py, pz, GetObjectSize(), PET_FOLLOW_DIST, GetFollowAngle()); Relocate(px, py, pz, owner->GetOrientation()); if (!IsPositionValid()) { sLog->outError("Pet (guidlow %d, entry %d) not loaded. Suggested coordinates isn't valid (X: %f Y: %f)", GetGUIDLow(), GetEntry(), GetPositionX(), GetPositionY()); return false; } setPetType(pet_type); setFaction(owner->getFaction()); SetUInt32Value(UNIT_CREATED_BY_SPELL, summon_spell_id); CreatureTemplate const* cinfo = GetCreatureInfo(); if (cinfo->type == CREATURE_TYPE_CRITTER) { map->AddToMap(this->ToCreature()); return true; } m_charmInfo->SetPetNumber(pet_number, IsPermanentPetFor(owner)); SetDisplayId(fields[3].GetUInt32()); SetNativeDisplayId(fields[3].GetUInt32()); uint32 petlevel = fields[4].GetUInt16(); SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE); SetName(fields[8].GetString()); switch (getPetType()) { case SUMMON_PET: petlevel = owner->getLevel(); SetUInt32Value(UNIT_FIELD_BYTES_0, 0x800); // class = mage SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); // this enables popup window (pet dismiss, cancel) break; case HUNTER_PET: SetUInt32Value(UNIT_FIELD_BYTES_0, 0x02020100); // class = warrior, gender = none, power = focus SetSheath(SHEATH_STATE_MELEE); SetByteFlag(UNIT_FIELD_BYTES_2, 2, fields[9].GetBool() ? UNIT_CAN_BE_ABANDONED : UNIT_CAN_BE_RENAMED | UNIT_CAN_BE_ABANDONED); SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); // this enables popup window (pet abandon, cancel) SetMaxPower(POWER_HAPPINESS, GetCreatePowers(POWER_HAPPINESS)); SetPower(POWER_HAPPINESS, fields[12].GetUInt32()); setPowerType(POWER_FOCUS); break; default: if (!IsPetGhoul()) sLog->outError("Pet have incorrect type (%u) for pet loading.", getPetType()); break; } SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(NULL))); // cast can't be helped here SetCreatorGUID(owner->GetGUID()); InitStatsForLevel(petlevel); SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, fields[5].GetUInt32()); SynchronizeLevelWithOwner(); SetReactState(ReactStates(fields[6].GetUInt8())); SetCanModifyStats(true); if (getPetType() == SUMMON_PET && !current) //all (?) summon pets come with full health when called, but not when they are current SetPower(POWER_MANA, GetMaxPower(POWER_MANA)); else { uint32 savedhealth = fields[10].GetUInt32(); uint32 savedmana = fields[11].GetUInt32(); if (!savedhealth && getPetType() == HUNTER_PET) setDeathState(JUST_DIED); else { SetHealth(savedhealth > GetMaxHealth() ? GetMaxHealth() : savedhealth); SetPower(POWER_MANA, savedmana > GetMaxPower(POWER_MANA) ? GetMaxPower(POWER_MANA) : savedmana); } } // set current pet as current // 0=current // 1..MAX_PET_STABLES in stable slot // PET_SAVE_NOT_IN_SLOT(100) = not stable slot (summoning)) if (fields[7].GetUInt8()) { SQLTransaction trans = CharacterDatabase.BeginTransaction(); trans->PAppend("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND slot = '%u' AND id <> '%u'", PET_SAVE_NOT_IN_SLOT, ownerid, PET_SAVE_AS_CURRENT, m_charmInfo->GetPetNumber()); trans->PAppend("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND id = '%u'", PET_SAVE_AS_CURRENT, ownerid, m_charmInfo->GetPetNumber()); CharacterDatabase.CommitTransaction(trans); } // Send fake summon spell cast - this is needed for correct cooldown application for spells // Example: 46584 - without this cooldown (which should be set always when pet is loaded) isn't set clientside // TODO: pets should be summoned from real cast instead of just faking it? if (summon_spell_id) { WorldPacket data(SMSG_SPELL_GO, (8+8+4+4+2)); data.append(owner->GetPackGUID()); data.append(owner->GetPackGUID()); data << uint8(0); data << uint32(summon_spell_id); data << uint32(256); // CAST_FLAG_UNKNOWN3 data << uint32(0); owner->SendMessageToSet(&data, true); } owner->SetMinion(this, true); map->AddToMap(this->ToCreature()); InitTalentForLevel(); // set original talents points before spell loading uint32 timediff = uint32(time(NULL) - fields[14].GetUInt32()); _LoadAuras(timediff); // load action bar, if data broken will fill later by default spells. if (!is_temporary_summoned) { m_charmInfo->LoadPetActionBar(fields[13].GetString()); _LoadSpells(); InitTalentForLevel(); // re-init to check talent count _LoadSpellCooldowns(); LearnPetPassives(); InitLevelupSpellsForLevel(); CastPetAuras(current); } CleanupActionBar(); // remove unknown spells from action bar after load sLog->outDebug(LOG_FILTER_PETS, "New Pet has guid %u", GetGUIDLow()); owner->PetSpellInitialize(); if (owner->GetGroup()) owner->SetGroupUpdateFlag(GROUP_UPDATE_PET); owner->SendTalentsInfoData(true); if (getPetType() == HUNTER_PET) { result = CharacterDatabase.PQuery("SELECT genitive, dative, accusative, instrumental, prepositional FROM character_pet_declinedname WHERE owner = '%u' AND id = '%u'", owner->GetGUIDLow(), GetCharmInfo()->GetPetNumber()); if (result) { delete m_declinedname; m_declinedname = new DeclinedName; Field* fields2 = result->Fetch(); for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i) { m_declinedname->name[i] = fields2[i].GetString(); } } } //set last used pet number (for use in BG's) if (owner->GetTypeId() == TYPEID_PLAYER && isControlled() && !isTemporarySummoned() && (getPetType() == SUMMON_PET || getPetType() == HUNTER_PET)) owner->ToPlayer()->SetLastPetNumber(pet_number); m_loading = false; return true; }