void Totem::InitSummon() { if (m_type == TOTEM_PASSIVE) { SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(GetSpell()); // use AddAura instead of CastSpell if it's a passive aura - this in fact should be an AddSpell equivalent for creatures, but nothing like that exists so far. if (spellInfo->Attributes & SPELL_ATTR0_PASSIVE) AddAura(spellInfo->Id, this); else CastSpell(this, spellInfo->Id, true); } // Some totems can have both instant effect and passive spell if (GetSpell(1)) CastSpell(this, GetSpell(1), true); }
void Totem::InitSummon() { if (m_type == TOTEM_PASSIVE) { switch (GetSpell()) { case 33663: // Earth Elemental Totem case 32982: // Fire Elemental Totem case 50461: // Anti-Magic Zone CastSpell(this, GetSpell(), true); break; default: AddAura(GetSpell(), this); break; } } if (GetSpell(1)) CastSpell(this, GetSpell(1), true); }
void AuraInterface::UpdateAuraStateAuras(uint32 oldflag) { if( oldflag == AURASTATE_FLAG_STUNNED && m_Unit->IsPlayer() && m_Unit->HasDummyAura(SPELL_HASH_PRIMAL_TENACITY) && TO_PLAYER(m_Unit)->GetShapeShift() == FORM_CAT ) { for(uint32 i = 0; i < TOTAL_AURAS; i++) { if(m_auras.find(i) != m_auras.end()) { if( m_auras.at(i)->GetSpellProto()->NameHash == SPELL_HASH_PRIMAL_TENACITY ) { Aura* aura = new Aura(m_auras.at(i)->GetSpellProto(), -1, TO_OBJECT(this), TO_UNIT(this)); RemoveAuraBySlot(i); aura->AddMod(232, -31, 5, 0); aura->AddMod(SPELL_AURA_DUMMY, 0, 0, 2); aura->AddMod(SPELL_AURA_ADD_PCT_MODIFIER, -51, 14, 2); AddAura(aura); continue; } if( m_auras.at(i)->m_applied) // try to apply m_auras.at(i)->ApplyModifiers(true); if( m_auras.at(i)->m_applied) // try to remove, if we lack the aurastate m_auras.at(i)->RemoveIfNecessary(); } } } else { for(uint32 i = 0; i < TOTAL_AURAS; i++) { if(m_auras.find(i) != m_auras.end()) { if( !m_auras.at(i)->m_applied) // try to apply m_auras.at(i)->ApplyModifiers(true); if( m_auras.at(i)->m_applied) // try to remove, if we lack the aurastate m_auras.at(i)->RemoveIfNecessary(); } } } }
void Totem::InitSummon() { if (m_type == TOTEM_PASSIVE) { switch (GetSpell()) { case 33663: // Earth Elemental Totem case 32982: // Fire Elemental Totem case 50461: // Anti-Magic Zone CastSpell(this, GetSpell(), true); break; default: AddAura(GetSpell(), this); break; } } // Some totems can have both instant effect and passive spell if (GetSpell(1)) CastSpell(this, GetSpell(1), true); }
void Totem::InitSummon() { // use AddAura instead of CastSpell - this in fact should be an AddSpell equivalent for creatures, but nothing like that exists so far. if (m_type == TOTEM_PASSIVE) { switch (GetSpell()) { case 33663: // Earth Elemental Totem case 32982: // Fire Elemental Totem case 50461: // Anti-Magic Zone CastSpell(this, GetSpell(), true); break; default: AddAura(GetSpell(), this); break; } } // Some totems can have both instant effect and passive spell if (GetSpell(1)) CastSpell(this, GetSpell(1), true); }
// TODO: Move stat mods code to pet passive auras bool Guardian::InitStatsForLevel(uint8 petlevel) { CreatureTemplate const* cinfo = GetCreatureInfo(); ASSERT(cinfo); SetLevel(petlevel); //Determine pet type PetType petType = MAX_PET_TYPE; if (isPet() && m_owner->GetTypeId() == TYPEID_PLAYER) { if ((m_owner->getClass() == CLASS_WARLOCK) || (m_owner->getClass() == CLASS_SHAMAN) // Fire Elemental || (m_owner->getClass() == CLASS_DEATH_KNIGHT)) // Risen Ghoul petType = SUMMON_PET; else if (m_owner->getClass() == CLASS_HUNTER) { petType = HUNTER_PET; m_unitTypeMask |= UNIT_MASK_HUNTER_PET; } else sLog->outError("Unknown type pet %u is summoned by player class %u", GetEntry(), m_owner->getClass()); } uint32 creature_ID = (petType == HUNTER_PET) ? 1 : cinfo->Entry; SetMeleeDamageSchool(SpellSchools(cinfo->dmgschool)); SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, float(petlevel*50)); SetAttackTime(BASE_ATTACK, BASE_ATTACK_TIME); SetAttackTime(OFF_ATTACK, BASE_ATTACK_TIME); SetAttackTime(RANGED_ATTACK, BASE_ATTACK_TIME); SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f); //scale CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cinfo->family); if (cFamily && cFamily->minScale > 0.0f && petType == HUNTER_PET) { float scale; if (getLevel() >= cFamily->maxScaleLevel) scale = cFamily->maxScale; else if (getLevel() <= cFamily->minScaleLevel) scale = cFamily->minScale; else scale = cFamily->minScale + float(getLevel() - cFamily->minScaleLevel) / cFamily->maxScaleLevel * (cFamily->maxScale - cFamily->minScale); SetFloatValue(OBJECT_FIELD_SCALE_X, scale); } // Resistance for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) SetModifierValue(UnitMods(UNIT_MOD_RESISTANCE_START + i), BASE_VALUE, float(cinfo->resistance[i])); //health, mana, armor and resistance PetLevelInfo const* pInfo = sObjectMgr->GetPetLevelInfo(creature_ID, petlevel); if (pInfo) // exist in DB { SetCreateHealth(pInfo->health); if (petType != HUNTER_PET) //hunter pet use focus SetCreateMana(pInfo->mana); if (pInfo->armor > 0) SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, float(pInfo->armor)); for (uint8 stat = 0; stat < MAX_STATS; ++stat) SetCreateStat(Stats(stat), float(pInfo->stats[stat])); } else // not exist in DB, use some default fake data { // remove elite bonuses included in DB values CreatureBaseStats const* stats = sObjectMgr->GetCreatureBaseStats(petlevel, cinfo->unit_class); SetCreateHealth(stats->BaseHealth[cinfo->expansion]); SetCreateMana(stats->BaseMana); SetCreateStat(STAT_STRENGTH, 22); SetCreateStat(STAT_AGILITY, 22); SetCreateStat(STAT_STAMINA, 25); SetCreateStat(STAT_INTELLECT, 28); SetCreateStat(STAT_SPIRIT, 27); } SetBonusDamage(0); switch (petType) { case SUMMON_PET: { //the damage bonus used for pets is either fire or shadow damage, whatever is higher uint32 fire = m_owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FIRE); uint32 shadow = m_owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_SHADOW); uint32 val = (fire > shadow) ? fire : shadow; SetBonusDamage(int32 (val * 0.15f)); //bonusAP += val * 0.57; SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4))); SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4))); //SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, float(cinfo->attackpower)); break; } case HUNTER_PET: { SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, uint32(sObjectMgr->GetXPForLevel(petlevel)*PET_XP_FACTOR)); //these formula may not be correct; however, it is designed to be close to what it should be //this makes dps 0.5 of pets level SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4))); //damage range is then petlevel / 2 SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4))); //damage is increased afterwards as strength and pet scaling modify attack power break; } default: { switch (GetEntry()) { case 510: // mage Water Elemental { SetBonusDamage(int32(m_owner->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_FROST) * 0.33f)); break; } case 1964: //force of nature { if (!pInfo) SetCreateHealth(30 + 30*petlevel); float bonusDmg = m_owner->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_NATURE) * 0.15f; SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel * 2.5f - (petlevel / 2) + bonusDmg)); SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel * 2.5f + (petlevel / 2) + bonusDmg)); break; } case 15352: //earth elemental 36213 { if (!pInfo) SetCreateHealth(100 + 120*petlevel); SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4))); SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4))); break; } case 15438: //fire elemental { if (!pInfo) { SetCreateHealth(40*petlevel); SetCreateMana(28 + 10*petlevel); } SetBonusDamage(m_owner->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_FIRE) * 0.5f); SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel * 4 - petlevel)); SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel * 4 + petlevel)); break; } case 19668: // Shadowfiend { if (!pInfo) { SetCreateMana(28 + 10*petlevel); SetCreateHealth(28 + 30*petlevel); } int32 bonus_dmg = (int32(m_owner->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_SHADOW)* 0.3f)); SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float((petlevel * 4 - petlevel) + bonus_dmg)); SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float((petlevel * 4 + petlevel) + bonus_dmg)); break; } case 19833: //Snake Trap - Venomous Snake { SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float((petlevel / 2) - 25)); SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float((petlevel / 2) - 18)); break; } case 19921: //Snake Trap - Viper { SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel / 2 - 10)); SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel / 2)); break; } case 29264: // Feral Spirit { if (!pInfo) SetCreateHealth(30*petlevel); float dmg_multiplier = 0.3f; if (m_owner->GetAuraEffect(63271, 0)) // Glyph of Feral Spirit dmg_multiplier = 0.6f; SetBonusDamage(int32(m_owner->GetTotalAttackPowerValue(BASE_ATTACK) * dmg_multiplier)); // 14AP == 1dps, wolf's strike speed == 2s so dmg = basedmg + AP / 14 * 2 SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float((petlevel * 4 - petlevel) + (m_owner->GetTotalAttackPowerValue(BASE_ATTACK) * dmg_multiplier * 2 / 14))); SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float((petlevel * 4 + petlevel) + (m_owner->GetTotalAttackPowerValue(BASE_ATTACK) * dmg_multiplier * 2 / 14))); SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, float(m_owner->GetArmor()) * 0.35f); // Bonus Armor (35% of player armor) SetModifierValue(UNIT_MOD_STAT_STAMINA, BASE_VALUE, float(m_owner->GetStat(STAT_STAMINA)) * 0.3f); // Bonus Stamina (30% of player stamina) if (!HasAura(58877))//prevent apply twice for the 2 wolves AddAura(58877, this);//Spirit Hunt, passive, Spirit Wolves' attacks heal them and their master for 150% of damage done. break; } case 31216: // Mirror Image { SetBonusDamage(int32(m_owner->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_FROST) * 0.33f)); SetDisplayId(m_owner->GetDisplayId()); if (!pInfo) { SetCreateMana(28 + 30*petlevel); SetCreateHealth(28 + 10*petlevel); } break; } case 27829: // Ebon Gargoyle { if (!pInfo) { SetCreateMana(28 + 10*petlevel); SetCreateHealth(28 + 30*petlevel); } SetBonusDamage(int32(m_owner->GetTotalAttackPowerValue(BASE_ATTACK) * 0.5f)); SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4))); SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4))); break; } } break; } } UpdateAllStats(); SetFullHealth(); SetPower(POWER_MANA, GetMaxPower(POWER_MANA)); return true; }
void Vehicle::_AddToSlot(Unit* pPassenger, uint8 slot) { assert( slot < m_seatSlotMax ); if(pPassenger->IsPlayer() && TO_PLAYER(pPassenger)->m_CurrentCharm) return; if(pPassenger->IsPlayer() && TO_PLAYER(pPassenger)->m_isGmInvisible) { sChatHandler.GreenSystemMessage(TO_PLAYER(pPassenger)->GetSession(), "Please turn off invis before entering vehicle."); return; } CreatureProtoVehicle* vehicleproto = CreatureProtoVehicleStorage.LookupEntry(GetEntry()); m_passengers[slot] = pPassenger; LocationVector v; v.x = m_vehicleSeats[slot]->m_attachmentOffsetX; /* pPassenger->m_TransporterX = */ v.y = m_vehicleSeats[slot]->m_attachmentOffsetY; /* pPassenger->m_TransporterY = */ v.z = m_vehicleSeats[slot]->m_attachmentOffsetZ; /* pPassenger->m_TransporterZ = */ v.o = 0; /* pPassenger->m_TransporterO = */ //pPassenger->m_transportPosition =& v; // This is handled elsewhere, do not initialize here. pPassenger->movement_info.flags |= MOVEFLAG_TAXI; pPassenger->movement_info.transX = v.x; pPassenger->movement_info.transY = v.y; pPassenger->movement_info.transZ = v.z; pPassenger->movement_info.transO = GetOrientation(); pPassenger->movement_info.transSeat = slot; pPassenger->movement_info.transGuid = WoWGuid(GetGUID()); pPassenger->SetSeatID(slot); pPassenger->m_TransporterGUID = GetGUID(); if( m_CastSpellOnMount ) pPassenger->CastSpell( pPassenger, m_CastSpellOnMount, true ); RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SELF_RES); // This is where the real magic happens if( pPassenger->IsPlayer() ) { Player* pPlayer = TO_PLAYER(pPassenger); //pPlayer->Root(); //Dismount if(pPlayer->m_MountSpellId && pPlayer->m_MountSpellId != m_mountSpell) pPlayer->RemoveAura(pPlayer->m_MountSpellId); //Remove morph spells if(pPlayer->GetUInt32Value(UNIT_FIELD_DISPLAYID) != pPlayer->GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID)) { pPlayer->RemoveAllAurasOfType(SPELL_AURA_TRANSFORM); pPlayer->RemoveAllAurasOfType(SPELL_AURA_MOD_SHAPESHIFT); } //Dismiss any pets if(pPlayer->GetSummon()) { if(pPlayer->GetSummon()->GetUInt32Value(UNIT_CREATED_BY_SPELL) > 0) pPlayer->GetSummon()->Dismiss(false); // warlock summon -> dismiss else pPlayer->GetSummon()->Remove(false, true, true); // hunter pet -> just remove for later re-call } pPlayer->SetVehicle(this); pPlayer->SetUInt64Value(PLAYER_FARSIGHT, GetGUID()); pPlayer->SetPlayerStatus(TRANSFER_PENDING); sEventMgr.AddEvent(pPlayer, &Player::CheckPlayerStatus, (uint8)TRANSFER_PENDING, EVENT_PLAYER_CHECK_STATUS_Transfer, 5000, 0, 0); pPlayer->m_sentTeleportPosition.ChangeCoords(GetPositionX(), GetPositionY(), GetPositionZ()); WorldPacket data(SMSG_MONSTER_MOVE_TRANSPORT, 100); data << pPlayer->GetNewGUID(); // Passengerguid data << GetNewGUID(); // Transporterguid (vehicleguid) data << uint8(slot); // Vehicle Seat ID data << uint8(0); // Unknown data << GetPositionX() - pPlayer->GetPositionX(); // OffsetTransporterX data << GetPositionY() - pPlayer->GetPositionY(); // OffsetTransporterY data << GetPositionZ() - pPlayer->GetPositionZ(); // OffsetTransporterZ data << getMSTime(); // Timestamp data << uint8(0x04); // Flags data << float(0); // Orientation Offset data << uint32(MOVEFLAG_TB_MOVED); // MovementFlags data << uint32(0); // MoveTime data << uint32(1); // Points data << v.x; // GetTransOffsetX(); data << v.y; // GetTransOffsetY(); data << v.z; // GetTransOffsetZ(); SendMessageToSet(&data, true); if(vehicleproto) { // We have proto, no accessory in slot, and slot sets unselectable, unlike some seats if(!vehicleproto->seats[slot].accessoryentry && vehicleproto->seats[slot].unselectableaccessory) pPlayer->SetFlag(UNIT_FIELD_FLAGS, (UNIT_FLAG_UNKNOWN_5 | UNIT_FLAG_PREPARATION | UNIT_FLAG_NOT_SELECTABLE)); } else pPlayer->SetFlag(UNIT_FIELD_FLAGS, (UNIT_FLAG_UNKNOWN_5 | UNIT_FLAG_PREPARATION | UNIT_FLAG_NOT_SELECTABLE)); if(slot == 0) { if(m_vehicleSeats[slot]->IsControllable()) { m_redirectSpellPackets = pPlayer; SetSpeed(RUN, m_runSpeed); SetSpeed(FLY, m_flySpeed); // send "switch mover" packet data.Initialize(SMSG_CLIENT_CONTROL_UPDATE); data << GetNewGUID() << uint8(1); pPlayer->GetSession()->SendPacket(&data); pPlayer->m_CurrentCharm = TO_UNIT(this); pPlayer->SetUInt64Value(UNIT_FIELD_CHARM, GetGUID()); SetUInt64Value(UNIT_FIELD_CHARMEDBY, pPlayer->GetGUID()); SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED_CREATURE); if(!m_faction || m_faction->ID == 35 || m_faction->ID == 2105) { SetCharmTempVal(pPlayer->GetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE)); SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, pPlayer->GetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE)); } if(vehicleproto && vehicleproto->healthfromdriver) { uint32 health = GetUInt32Value(UNIT_FIELD_HEALTH); uint32 maxhealth = GetUInt32Value(UNIT_FIELD_MAXHEALTH); uint32 healthdiff = maxhealth - health; SetUInt32Value(UNIT_FIELD_MAXHEALTH, (maxhealth+((pPlayer->GetTotalItemLevel())*(vehicleproto->healthunitfromitemlev)))); SetUInt32Value(UNIT_FIELD_HEALTH, (health+((pPlayer->GetTotalItemLevel())*(vehicleproto->healthunitfromitemlev))) - healthdiff); } SendSpells(GetEntry(), pPlayer); if(pPlayer->HasAura(62064)) { uint32 stack = pPlayer->FindActiveAura(62064)->stackSize; AddAura(new Aura(dbcSpell.LookupEntry(62064),-1,this,this)); FindActiveAura(62064)->ModStackSize(stack); } } } else { data.Initialize(SMSG_CLIENT_CONTROL_UPDATE); data << GetNewGUID() << uint8(0); pPlayer->GetSession()->SendPacket(&data); } data.Initialize(SMSG_PET_DISMISS_SOUND); data << uint32(m_vehicleSeats[slot]->m_enterUISoundID); data << pPlayer->GetPosition(); pPlayer->GetSession()->SendPacket(&data); ++m_ppassengerCount; } else { pPassenger->SetVehicle(this); if(vehicleproto != NULL) if(vehicleproto->seats[slot].accessoryentry == pPassenger->GetEntry()) if(vehicleproto->seats[slot].unselectableaccessory == true) pPassenger->SetFlag(UNIT_FIELD_FLAGS, (UNIT_FLAG_UNKNOWN_5 | UNIT_FLAG_PREPARATION | UNIT_FLAG_NOT_SELECTABLE)); else pPassenger->SetFlag(UNIT_FIELD_FLAGS, (UNIT_FLAG_UNKNOWN_5 | UNIT_FLAG_PREPARATION)); else pPassenger->SetFlag(UNIT_FIELD_FLAGS, (UNIT_FLAG_UNKNOWN_5 | UNIT_FLAG_PREPARATION | UNIT_FLAG_NOT_SELECTABLE)); pPassenger->SetPosition(GetPositionX()+v.x, GetPositionY()+v.y, GetPositionZ()+v.z, GetOrientation()); } SendHeartBeatMsg(false); if(IsFull()) RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); if(canFly()) EnableFlight(); _setFaction(); }
// This creates an aura from a casted spell void Mob::MakeAura(uint16 spell_id) { // TODO: verify room in AuraMgr if (!IsValidSpell(spell_id)) return; AuraRecord record; if (!database.GetAuraEntry(spell_id, record)) { Message(13, "Unable to find data for aura %s", spells[spell_id].name); Log(Logs::General, Logs::Error, "Unable to find data for aura %d, check auras table.", spell_id); return; } if (!IsValidSpell(record.spell_id)) { Message(13, "Casted spell (%d) is not valid for aura %s", record.spell_id, spells[spell_id].name); Log(Logs::General, Logs::Error, "Casted spell (%d) is not valid for aura %d, check auras table.", record.spell_id, spell_id); return; } if (record.aura_type > static_cast<int>(AuraType::Max)) { return; // TODO: log } bool trap = false; switch (static_cast<AuraType>(record.aura_type)) { case AuraType::ExitTrap: case AuraType::EnterTrap: case AuraType::Totem: trap = true; break; default: trap = false; break; } if (!CanSpawnAura(trap)) return; const auto base = database.LoadNPCTypesData(record.npc_type); if (base == nullptr) { Message(13, "Unable to load NPC data for aura %s", spells[spell_id].teleport_zone); Log(Logs::General, Logs::Error, "Unable to load NPC data for aura %s (NPC ID %d), check auras and npc_types tables.", spells[spell_id].teleport_zone, record.npc_type); return; } auto npc_type = new NPCType; memcpy(npc_type, base, sizeof(NPCType)); strn0cpy(npc_type->name, record.name, 64); auto npc = new Aura(npc_type, this, record); npc->SetAuraID(spell_id); if (trap) npc->TryMoveAlong(5.0f, 0.0f, false); // try to place 5 units in front entity_list.AddNPC(npc, false); if (trap) AddTrap(npc, record); else AddAura(npc, record); }