void ChangeDamage(SpellEffIndex /*effIndex*/) { Unit* caster = GetCaster(); int32 damage = GetHitDamage(); if (caster->HasAura(SPELL_PALADIN_DIVINE_PURPOSE_PROC)) damage *= 7.5; // 7.5*30% = 225% else { switch (caster->GetPower(POWER_HOLY_POWER)) { case 0: // 1 Holy Power // same damage break; case 1: // 2 Holy Power damage *= 3; // 3*30 = 90% break; case 2: // 3 Holy Power damage *= 7.5; // 7.5*30% = 225% break; } } SetHitDamage(damage); }
void HandleEffect(SpellEffIndex effIndex) { Unit* caster = GetCaster(); if (Unit* target = GetHitUnit()) { SpellInfo const* spellInfo = GetSpellInfo(); int32 rageUsed = std::min<int32>(300 - spellInfo->CalcPowerCost(caster, SpellSchoolMask(spellInfo->SchoolMask)), caster->GetPower(POWER_RAGE)); int32 newRage = std::max<int32>(0, caster->GetPower(POWER_RAGE) - rageUsed); // Sudden Death rage save if (AuraEffect* aurEff = caster->GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_GENERIC, WARRIOR_ICON_ID_SUDDEN_DEATH, EFFECT_0)) { int32 ragesave = aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue() * 10; newRage = std::max(newRage, ragesave); } caster->SetPower(POWER_RAGE, uint32(newRage)); // Glyph of Execution bonus if (AuraEffect* aurEff = caster->GetAuraEffect(SPELL_WARRIOR_GLYPH_OF_EXECUTION, EFFECT_0)) rageUsed += aurEff->GetAmount() * 10; int32 bp = GetEffectValue() + int32(rageUsed * spellInfo->Effects[effIndex].DamageMultiplier + caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.2f); caster->CastCustomSpell(target, SPELL_WARRIOR_EXECUTE, &bp, NULL, NULL, true, NULL, NULL, GetOriginalCaster()->GetGUID()); } }
void UpdateAI(const uint32 diff) { //Return since we have no target if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() ) return; //ShadowVolley_Timer if (ShadowVolley_Timer < diff) { DoCast(m_creature->getVictim(), SPELL_SHADOWVOLLEY); ShadowVolley_Timer = 4000 + rand()%2000; }else ShadowVolley_Timer -= diff; //Cleave_Timer if (Cleave_Timer < diff) { DoCast(m_creature->getVictim(),SPELL_CLEAVE); Cleave_Timer = 8000 + rand()%4000; }else Cleave_Timer -= diff; //ThunderClap_Timer if (ThunderClap_Timer < diff) { DoCast(m_creature->getVictim(),SPELL_THUNDERCLAP); ThunderClap_Timer = 10000 + rand()%4000; }else ThunderClap_Timer -= diff; //VoidBolt_Timer if (VoidBolt_Timer < diff) { DoCast(m_creature->getVictim(),SPELL_VOIDBOLT); VoidBolt_Timer = 15000 + rand()%3000; }else VoidBolt_Timer -= diff; //MarkOfKazzak_Timer if (MarkOfKazzak_Timer < diff) { Unit* victim = SelectUnit(SELECT_TARGET_RANDOM, 0); if(victim->GetPower(POWER_MANA)) { DoCast(victim, SPELL_MARKOFKAZZAK); MarkOfKazzak_Timer = 20000; } }else MarkOfKazzak_Timer -= diff; //Enrage_Timer if (Enrage_Timer < diff) { DoCast(m_creature,SPELL_ENRAGE); Enrage_Timer = 30000; }else Enrage_Timer -= diff; if(Twisted_Reflection_Timer < diff) { DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_TWISTEDREFLECTION); Twisted_Reflection_Timer = 15000; }else Twisted_Reflection_Timer -= diff; DoMeleeAttackIfReady(); }
void HandleBeforeCast() { Unit* caster = GetCaster(); if(caster) { int32 Rage_val = 0; PlayerSpellMap const& sp_list = caster->ToPlayer()->GetSpellMap(); // Retrieves max rage to retain for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr) { if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->disabled) continue; SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); if (spellInfo && spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR && spellInfo->SpellIconID == 139) { Rage_val += caster->CalculateSpellDamage(caster, spellInfo, EFFECT_0); } } // Check and update (do not forget the * 10 on each SetPower with POWER_RAGE) if (caster->GetPower(POWER_RAGE) > Rage_val * 10) { Rage_val *= sWorld->getRate(RATE_POWER_RAGE_INCOME); caster->SetPower(POWER_RAGE, Rage_val * 10); } } }
void HandleEffect(SpellEffIndex /*effIndex*/) { Unit* caster = GetCaster(); if (GetHitUnit()) { SpellInfo const* spellInfo = GetSpellInfo(); int32 rageUsed = std::min<int32>(200 - spellInfo->CalcPowerCost(caster, SpellSchoolMask(spellInfo->SchoolMask)), caster->GetPower(POWER_RAGE)); int32 newRage = std::max<int32>(0, caster->GetPower(POWER_RAGE) - rageUsed); // Sudden Death rage save if (AuraEffect* aurEff = caster->GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_GENERIC, ICON_ID_SUDDEN_DEATH, EFFECT_0)) { int32 ragesave = aurEff->GetSpellInfo()->Effects[EFFECT_0].CalcValue() * 10; newRage = std::max(newRage, ragesave); } caster->SetPower(POWER_RAGE, uint32(newRage)); /// Formula taken from the DBC: "${10+$AP*0.437*$m1/100}" int32 baseDamage = int32(10 + caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.437f * GetEffectValue() / 100.0f); /// Formula taken from the DBC: "${$ap*0.874*$m1/100-1} = 20 rage" int32 moreDamage = int32(rageUsed * (caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.874f * GetEffectValue() / 100.0f - 1) / 200); SetHitDamage(baseDamage + moreDamage); } }
void OnLoad() { if (_unit->IsSummon()) { Summon* s = TO< Summon* >(_unit); Unit* owner = s->GetOwner(); owner->CastSpell(_unit, 45204, true); // clone me owner->CastSpell(_unit, 58838, true); // inherit threat list // Mage mirror image spell if (_unit->GetCreatedBySpell() == 58833) { _unit->SetMaxHealth(2500); _unit->SetHealth(2500); _unit->SetMaxPower(POWER_TYPE_MANA, owner->GetMaxPower(POWER_TYPE_MANA)); _unit->SetPower(POWER_TYPE_MANA, owner->GetPower(POWER_TYPE_MANA)); SpellRange* range = NULL; AI_Spell sp1; sp1.entryId = 59638; sp1.spell = dbcSpell.LookupEntryForced(sp1.entryId); sp1.spellType = STYPE_DAMAGE; sp1.agent = AGENT_SPELL; sp1.spelltargetType = TTYPE_SINGLETARGET; sp1.cooldown = 0; sp1.cooldowntime = 0; sp1.Misc2 = 0; sp1.procCount = 0; sp1.procChance = 100; range = dbcSpellRange.LookupEntry(sp1.spell->rangeIndex); sp1.minrange = GetMinRange(range); sp1.maxrange = GetMaxRange(range); _unit->GetAIInterface()->addSpellToList(&sp1); AI_Spell sp2; sp2.entryId = 59637; sp2.spell = dbcSpell.LookupEntryForced(sp2.entryId); sp2.spellType = STYPE_DAMAGE; sp2.agent = AGENT_SPELL; sp2.spelltargetType = TTYPE_SINGLETARGET; sp2.cooldown = 0; sp2.cooldowntime = 0; sp2.Misc2 = 0; sp2.procCount = 0; sp2.procChance = 100; range = dbcSpellRange.LookupEntry(sp2.spell->rangeIndex); sp2.minrange = GetMinRange(range); sp2.maxrange = GetMaxRange(range); _unit->GetAIInterface()->addSpellToList(&sp2); } } }
void HandleOnCast() { Unit* caster = GetCaster(); if(caster && caster->GetPower(POWER_RAGE) > 0) { float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK); // Formula taken from the DBC: "${10+$AP*0.437*$m1/100}" damage = int32(10 + ap * 0.437); // Normalized rage (-10 because the execute base cost is not yet applied) uint32 powerAfterBaseCost = caster->GetPower(POWER_RAGE) /10 -10; uint32 extraRage = powerAfterBaseCost > 20 ? 20 : powerAfterBaseCost; uint32 newPowerAmount = powerAfterBaseCost - extraRage; // Sudden Death rage saving if (AuraEffect* aurEff = caster->GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_WARRIOR, WARRIOR_ICON_ID_SUDDEN_DEATH, EFFECT_0)) { if(newPowerAmount < 10) { newPowerAmount = aurEff->GetAmount(); } } // Enter if there is extra rage to add as bonus damage if(extraRage > 0) { // Add bonus damage // Formula taken from the DBC: "${$ap*0.874*$m1/100-1} = 20 rage" damage += int32 (ap * 0.874 * extraRage / 10 - 1); } // For remaining at the desidered rage when the warrior will use the base execute cost (10) newPowerAmount += 10; newPowerAmount *= sWorld->getRate(RATE_POWER_RAGE_INCOME); // Sets new rage caster->SetPower(POWER_RAGE, newPowerAmount * 10); } }
void OnPeriodic(AuraEffect const* aurEff) { Unit* target = GetTarget(); if (target->GetPower(POWER_MANA) == 0) { target->CastSpell(target, SPELL_MARK_DAMAGE, true, NULL, aurEff); // Remove aura SetDuration(0); } }
void UpdateAI(const uint32 diff) { //Return since we have no target if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if(CleaveTimer < diff) { if(m_creature->getVictim()) DoCast(m_creature->getVictim(), SPELL_CLEAVE); CleaveTimer = 6000+rand()%15000; }else CleaveTimer -= diff; if(WarStompTimer < diff) { DoCast(m_creature, SPELL_WARSTOMP); WarStompTimer = 60000; }else WarStompTimer -= diff; if(m_creature->HasAura(SPELL_MARK)) m_creature->RemoveAurasDueToSpell(SPELL_MARK); if(MarkBlastTimer < diff) { std::list<HostileReference *> t_list = m_creature->getThreatManager().getThreatList(); for(std::list<HostileReference *>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) { Unit *target = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid()); if (target && target->GetTypeId() == TYPEID_PLAYER && target->getPowerType() == POWER_MANA) if(target->HasAura(SPELL_MARK)) if((target->GetPower(POWER_MANA)*100) / target->GetMaxPower(POWER_MANA) <= 1) target->CastSpell(target, SPELL_MARK2, true); } MarkBlastTimer = 1000; }MarkBlastTimer -= diff; if(MarkTimer < diff) { CastMark(); MarkTimer = BaseMarkTimer - MarkCount * 10000; if(MarkCount < 6) ++MarkCount; else MarkTimer = 5000; }else MarkTimer -= diff; DoMeleeAttackIfReady(); }
void ChangeDamage(SpellEffIndex effIndex) { Unit* caster = GetCaster(); Unit* target = GetHitUnit(); if (!target) return; int32 rageUsed = std::min<int32>(300 - GetSpellInfo()->CalcPowerCost(caster, SpellSchoolMask(GetSpellInfo()->SchoolMask)), caster->GetPower(POWER_RAGE)); int32 newRage = std::max<int32>(0, caster->GetPower(POWER_RAGE) - rageUsed); // Sudden Death rage refund if (AuraEffect* aurEff = caster->GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_GENERIC, ICON_ID_SUDDEN_DEATH, EFFECT_0)) { int32 ragesave = aurEff->GetAmount() * 10; newRage = std::max(newRage, ragesave); } caster->SetPower(POWER_RAGE, uint32(newRage)); // DBC formula: ap * 0.874 * 100 / 100 - rageUsed int32 rageBonus = ((caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.874f) * 1000) / (1000 - rageUsed); int32 totalDamage = (GetHitDamage() + rageBonus); SetHitDamage(totalDamage); }
void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; switch(m_uiPhase) { case PHASE_ATTACKING: if (m_uiCheckoutMana_Timer <= uiDiff) { m_uiCheckoutMana_Timer = 1500; if (m_creature->GetPower(POWER_MANA) * 100 / m_creature->GetMaxPower(POWER_MANA) > 75.0f) { DoCastSpellIfCan(m_creature, SPELL_ENERGIZE); DoScriptText(EMOTE_ENERGIZING, m_creature); m_uiPhase = PHASE_ENERGIZING; return; } } else m_uiCheckoutMana_Timer -= uiDiff; if (m_uiSummonManaFiends_Timer <= uiDiff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_SUMMON_MANAFIEND_1, CAST_TRIGGERED); DoCastSpellIfCan(m_creature->getVictim(), SPELL_SUMMON_MANAFIEND_2, CAST_TRIGGERED); DoCastSpellIfCan(m_creature->getVictim(), SPELL_SUMMON_MANAFIEND_3, CAST_TRIGGERED); m_uiSummonManaFiends_Timer = 90000; } else m_uiSummonManaFiends_Timer -= uiDiff; if (m_uiManaDrain_Timer <= uiDiff) { m_uiManaDrain_Timer = urand(2000, 6000); // choose random target with mana std::list<Unit*> lTargets; ThreatList const& threatlist = m_creature->getThreatManager().getThreatList(); if (threatlist.empty()) return; for (ThreatList::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr) { Unit* pUnit = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid()); if (pUnit && pUnit->isAlive() && pUnit->GetPower(POWER_MANA)) lTargets.push_back(pUnit); } if (lTargets.empty()) return; std::list<Unit*>::iterator itr = lTargets.begin(); std::advance(itr, urand(0, lTargets.size()-1)); DoCastSpellIfCan(*itr, SPELL_DRAIN_MANA); } else m_uiManaDrain_Timer -= uiDiff; if (m_uiTrample_Timer <= uiDiff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_TRAMPLE); m_uiTrample_Timer = 15000; } else m_uiTrample_Timer -= uiDiff; DoMeleeAttackIfReady(); break; case PHASE_ENERGIZING: if (m_uiCheckoutMana_Timer <= uiDiff) { m_uiCheckoutMana_Timer = 1500; if (m_creature->GetPower(POWER_MANA) == m_creature->GetMaxPower(POWER_MANA)) { m_creature->RemoveAurasDueToSpell(SPELL_ENERGIZE); DoCastSpellIfCan(m_creature, SPELL_ARCANE_ERUPTION); DoScriptText(EMOTE_MANA_FULL, m_creature); m_uiPhase = PHASE_ATTACKING; return; } } else m_uiCheckoutMana_Timer -= uiDiff; break; } }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data ) { DEBUG_LOG("WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); uint64 Guid; recv_data >> Guid; Player *player = sObjectMgr.GetPlayer(Guid); if(!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.appendPackGUID(Guid); data << uint32(GROUP_UPDATE_FLAG_STATUS); data << uint16(MEMBER_STATUS_OFFLINE); SendPacket(&data); return; } Unit *pet = player->GetCharmOrPet(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data << player->GetPackGUID(); uint32 mask1 = 0x00040BFF; // common mask, real flags used 0x000040BFF if(pet) mask1 = 0xFFFFFFFF; // for hunters and other classes with pets Powers powerType = player->getPowerType(); data << uint32(mask1); // group update mask data << uint16(MEMBER_STATUS_ONLINE); // member's online status data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP data << uint8(powerType); // GROUP_UPDATE_FLAG_POWER_TYPE data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL data << uint16(player->GetZoneId()); // GROUP_UPDATE_FLAG_ZONE data << uint16(player->GetPositionX()); // GROUP_UPDATE_FLAG_POSITION data << uint16(player->GetPositionY()); // GROUP_UPDATE_FLAG_POSITION uint64 auramask = 0; size_t maskPos = data.wpos(); data << uint64(auramask); // placeholder for(uint8 i = 0; i < MAX_AURAS; ++i) { if(uint32 aura = player->GetVisibleAura(i)) { auramask |= (uint64(1) << i); data << uint32(aura); data << uint8(1); } } data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS if(pet) { Powers petpowertype = pet->getPowerType(); data << pet->GetObjectGuid(); // GROUP_UPDATE_FLAG_PET_GUID data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(pet->GetDisplayId()); // GROUP_UPDATE_FLAG_PET_MODEL_ID data << uint32(pet->GetHealth()); // GROUP_UPDATE_FLAG_PET_CUR_HP data << uint32(pet->GetMaxHealth()); // GROUP_UPDATE_FLAG_PET_MAX_HP data << uint8(petpowertype); // GROUP_UPDATE_FLAG_PET_POWER_TYPE data << uint16(pet->GetPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_CUR_POWER data << uint16(pet->GetMaxPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_MAX_POWER uint64 petauramask = 0; size_t petMaskPos = data.wpos(); data << uint64(petauramask); // placeholder for(uint8 i = 0; i < MAX_AURAS; ++i) { if(uint32 petaura = pet->GetVisibleAura(i)) { petauramask |= (uint64(1) << i); data << uint32(petaura); data << uint8(1); } } data.put<uint64>(petMaskPos, petauramask); // GROUP_UPDATE_FLAG_PET_AURAS data << (uint32) player->m_movementInfo.GetTransportDBCSeat(); } else { data << uint8(0); // GROUP_UPDATE_FLAG_PET_NAME data << uint64(0); // GROUP_UPDATE_FLAG_PET_AURAS } SendPacket(&data); }
void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacket *data) { uint32 mask = player->GetGroupUpdateFlag(); if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) // if update power type, update current/max power also mask |= (GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER); if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) // same for pets mask |= (GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER); uint32 byteCount = 0; for (int i = 1; i < GROUP_UPDATE_FLAGS_COUNT; ++i) if (mask & (1 << i)) byteCount += GroupUpdateLength[i]; data->Initialize(SMSG_PARTY_MEMBER_STATS, 8 + 4 + byteCount); *data << player->GetPackGUID(); *data << uint32(mask); if (mask & GROUP_UPDATE_FLAG_STATUS) { if (player) { if (player->IsPvP()) *data << uint16(MEMBER_STATUS_ONLINE | MEMBER_STATUS_PVP); else *data << uint16(MEMBER_STATUS_ONLINE); } else *data << uint16(MEMBER_STATUS_OFFLINE); } if (mask & GROUP_UPDATE_FLAG_CUR_HP) *data << uint32(player->GetHealth()); if (mask & GROUP_UPDATE_FLAG_MAX_HP) *data << uint32(player->GetMaxHealth()); Powers powerType = player->getPowerType(); if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) *data << uint8(powerType); if (mask & GROUP_UPDATE_FLAG_CUR_POWER) *data << uint16(player->GetPower(powerType)); if (mask & GROUP_UPDATE_FLAG_MAX_POWER) *data << uint16(player->GetMaxPower(powerType)); if (mask & GROUP_UPDATE_FLAG_LEVEL) *data << uint16(player->getLevel()); if (mask & GROUP_UPDATE_FLAG_ZONE) *data << uint16(player->GetZoneId()); if (mask & GROUP_UPDATE_FLAG_POSITION) *data << uint16(player->GetPositionX()) << uint16(player->GetPositionY()); if (mask & GROUP_UPDATE_FLAG_AURAS) { const uint64& auramask = player->GetAuraUpdateMask(); *data << uint64(auramask); for(uint32 i = 0; i < MAX_AURAS; ++i) { if(auramask & (uint64(1) << i)) { *data << uint32(player->GetVisibleAura(i)); *data << uint8(1); } } } Unit *pet = player->GetCharmOrPet(); if (mask & GROUP_UPDATE_FLAG_PET_GUID) *data << (pet ? pet->GetObjectGuid() : ObjectGuid()); if (mask & GROUP_UPDATE_FLAG_PET_NAME) { if(pet) *data << pet->GetName(); else *data << uint8(0); } if (mask & GROUP_UPDATE_FLAG_PET_MODEL_ID) { if(pet) *data << uint16(pet->GetDisplayId()); else *data << uint16(0); } if (mask & GROUP_UPDATE_FLAG_PET_CUR_HP) { if(pet) *data << uint32(pet->GetHealth()); else *data << uint32(0); } if (mask & GROUP_UPDATE_FLAG_PET_MAX_HP) { if(pet) *data << uint32(pet->GetMaxHealth()); else *data << uint32(0); } if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) { if(pet) *data << uint8(pet->getPowerType()); else *data << uint8(0); } if (mask & GROUP_UPDATE_FLAG_PET_CUR_POWER) { if(pet) *data << uint16(pet->GetPower(pet->getPowerType())); else *data << uint16(0); } if (mask & GROUP_UPDATE_FLAG_PET_MAX_POWER) { if(pet) *data << uint16(pet->GetMaxPower(pet->getPowerType())); else *data << uint16(0); } if (mask & GROUP_UPDATE_FLAG_PET_AURAS) { if(pet) { const uint64& auramask = pet->GetAuraUpdateMask(); *data << uint64(auramask); for(uint32 i = 0; i < MAX_AURAS; ++i) { if(auramask & (uint64(1) << i)) { *data << uint32(pet->GetVisibleAura(i)); *data << uint8(1); } } } else *data << uint64(0); } if (mask & GROUP_UPDATE_FLAG_VEHICLE_SEAT) { *data << (uint32) player->m_movementInfo.GetTransportDBCSeat(); } }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data ) { DEBUG_LOG("WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); ObjectGuid guid; recv_data >> guid; Player * player = HashMapHolder<Player>::Find(guid); if(!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data << guid.WriteAsPacked(); data << uint32(GROUP_UPDATE_FLAG_STATUS); data << uint16(MEMBER_STATUS_OFFLINE); SendPacket(&data); return; } Unit *pet = player->GetCharmOrPet(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data << player->GetPackGUID(); uint32 mask1 = 0x00040BFF; // common mask, real flags used 0x000040BFF if(pet) mask1 = 0xFFFFFFFF; // for hunters and other classes with pets Powers powerType = player->getPowerType(); data << uint32(mask1); // group update mask data << uint16(MEMBER_STATUS_ONLINE); // member's online status data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP data << uint8(powerType); // GROUP_UPDATE_FLAG_POWER_TYPE data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL //verify player coordinates and zoneid to send to teammates uint16 iZoneId = 0; uint16 iCoordX = 0; uint16 iCoordY = 0; if (player->IsInWorld()) { iZoneId = player->GetZoneId(); iCoordX = player->GetPositionX(); iCoordY = player->GetPositionY(); } else if (player->IsBeingTeleported()) // Player is in teleportation { WorldLocation& loc = player->GetTeleportDest(); // So take teleportation destination iZoneId = sTerrainMgr.GetZoneId(loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z); iCoordX = loc.coord_x; iCoordY = loc.coord_y; } else { //unknown player status. } data << uint16(iZoneId); // GROUP_UPDATE_FLAG_ZONE data << uint16(iCoordX); // GROUP_UPDATE_FLAG_POSITION data << uint16(iCoordY); // GROUP_UPDATE_FLAG_POSITION uint64 auramask = 0; size_t maskPos = data.wpos(); data << uint64(auramask); // placeholder for(uint8 i = 0; i < MAX_AURAS; ++i) { if(uint32 aura = player->GetVisibleAura(i)) { auramask |= (uint64(1) << i); data << uint32(aura); data << uint8(1); } } data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS if(pet) { Powers petpowertype = pet->getPowerType(); data << pet->GetObjectGuid(); // GROUP_UPDATE_FLAG_PET_GUID data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(pet->GetDisplayId()); // GROUP_UPDATE_FLAG_PET_MODEL_ID data << uint32(pet->GetHealth()); // GROUP_UPDATE_FLAG_PET_CUR_HP data << uint32(pet->GetMaxHealth()); // GROUP_UPDATE_FLAG_PET_MAX_HP data << uint8(petpowertype); // GROUP_UPDATE_FLAG_PET_POWER_TYPE data << uint16(pet->GetPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_CUR_POWER data << uint16(pet->GetMaxPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_MAX_POWER uint64 petauramask = 0; size_t petMaskPos = data.wpos(); data << uint64(petauramask); // placeholder for(uint8 i = 0; i < MAX_AURAS; ++i) { if(uint32 petaura = pet->GetVisibleAura(i)) { petauramask |= (uint64(1) << i); data << uint32(petaura); data << uint8(1); } } data.put<uint64>(petMaskPos, petauramask); // GROUP_UPDATE_FLAG_PET_AURAS data << (uint32) player->m_movementInfo.GetTransportDBCSeat(); } else { data << uint8(0); // GROUP_UPDATE_FLAG_PET_NAME data << uint64(0); // GROUP_UPDATE_FLAG_PET_AURAS } SendPacket(&data); }
void UpdateAI(const uint32 uiDiff) { // Return since we have no target if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; // Supreme mode - Causes Kazzak to cast his Shadowbolt every second. if (m_uiSupremeTimer < uiDiff && !m_bSupremeMode) m_bSupremeMode = true; else if (!m_bSupremeMode) m_uiSupremeTimer -= uiDiff; // Shadowbolt Volley if (m_uiShadowVolleyTimer < uiDiff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_SHADOW_VOLLEY); if (m_bSupremeMode) m_uiShadowVolleyTimer = 1000; else m_uiShadowVolleyTimer = urand(4000,20000); } else m_uiShadowVolleyTimer -= uiDiff; // Cleave if (m_uiCleaveTimer < uiDiff) { DoCastSpellIfCan(m_creature->getVictim(),SPELL_CLEAVE); m_uiCleaveTimer = urand(8000,12000); } else m_uiCleaveTimer -= uiDiff; // Thunder Clap if (m_uiThunderClapTimer < uiDiff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_THUNDERCLAP); m_uiThunderClapTimer = urand(10000,14000); } else m_uiThunderClapTimer -= uiDiff; // Void Bolt if (m_uiVoidBoltTimer < uiDiff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_VOIDBOLT); m_uiVoidBoltTimer = urand(15000,28000); } else m_uiVoidBoltTimer -= uiDiff; // Mark of Kazzak if (m_uiMarkOfKazzakTimer < uiDiff) { Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0); if (pTarget && pTarget->getPowerType() == POWER_MANA && pTarget->GetPower(POWER_MANA) > 1000) { DoCastSpellIfCan(pTarget, SPELL_MARK_OF_KAZZAK); m_uiMarkOfKazzakTimer = 20000; } } else m_uiMarkOfKazzakTimer -= uiDiff; // Mark of Kazzak - Explode the target when does not have more mana ThreatList const& tMarkList = m_creature->getThreatManager().getThreatList(); for (ThreatList::const_iterator iter = tMarkList.begin(); iter != tMarkList.end(); ++iter) { Unit* pMarked = m_creature->GetMap()->GetUnit((*iter)->getUnitGuid()); if (pMarked && pMarked->HasAura(SPELL_MARK_OF_KAZZAK, EFFECT_INDEX_0) && pMarked->GetPower(POWER_MANA) < 250) { pMarked->RemoveAurasDueToSpell(SPELL_MARK_OF_KAZZAK); pMarked->CastSpell(pMarked, SPELL_MARK_OF_KAZZAK_EXP, false); break; } } // Twisted Reflection if (m_uiTwistedReflectionTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) DoCastSpellIfCan(pTarget, SPELL_TWISTEDREFLECTION); m_uiTwistedReflectionTimer = 15000; } else m_uiTwistedReflectionTimer -= uiDiff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { //Return since we have no target if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; //ShadowVolley_Timer if (ShadowVolley_Timer < diff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_SHADOWVOLLEY); ShadowVolley_Timer = urand(4000, 6000); }else ShadowVolley_Timer -= diff; //Cleave_Timer if (Cleave_Timer < diff) { DoCastSpellIfCan(m_creature->getVictim(),SPELL_CLEAVE); Cleave_Timer = urand(8000, 12000); }else Cleave_Timer -= diff; //ThunderClap_Timer if (ThunderClap_Timer < diff) { DoCastSpellIfCan(m_creature->getVictim(),SPELL_THUNDERCLAP); ThunderClap_Timer = urand(10000, 14000); }else ThunderClap_Timer -= diff; //VoidBolt_Timer if (VoidBolt_Timer < diff) { DoCastSpellIfCan(m_creature->getVictim(),SPELL_VOIDBOLT); VoidBolt_Timer = urand(15000, 18000); }else VoidBolt_Timer -= diff; //MarkOfKazzak_Timer if (MarkOfKazzak_Timer < diff) { Unit* victim = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0); if (victim->GetPower(POWER_MANA)) { DoCastSpellIfCan(victim, SPELL_MARKOFKAZZAK); MarkOfKazzak_Timer = 20000; } }else MarkOfKazzak_Timer -= diff; //Enrage_Timer if (Enrage_Timer < diff) { DoScriptText(EMOTE_GENERIC_FRENZY, m_creature); DoCastSpellIfCan(m_creature,SPELL_ENRAGE); Enrage_Timer = 30000; }else Enrage_Timer -= diff; if (Twisted_Reflection_Timer < diff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) DoCastSpellIfCan(pTarget, SPELL_TWISTEDREFLECTION); Twisted_Reflection_Timer = 15000; }else Twisted_Reflection_Timer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (!m_pInstance || m_pInstance->GetData(TYPE_KELTHUZAD) != IN_PROGRESS) return; if (m_uiPhase == PHASE_INTRO) { if (m_uiIntroPackCount < 7) { if (m_uiSummonIntroTimer < uiDiff) { if (!m_uiIntroPackCount) DoScriptText(SAY_SUMMON_MINIONS, m_creature); SummonIntroCreatures(m_uiIntroPackCount); ++m_uiIntroPackCount; m_uiSummonIntroTimer = 2000; } else m_uiSummonIntroTimer -= uiDiff; } else { if (m_uiPhase1Timer < uiDiff) { m_uiPhase = PHASE_NORMAL; DespawnIntroCreatures(); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); SetCombatMovement(true); m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); DoScriptText(EMOTE_PHASE2, m_creature); switch(urand(0, 2)) { case 0: DoScriptText(SAY_AGGRO1, m_creature); break; case 1: DoScriptText(SAY_AGGRO2, m_creature); break; case 2: DoScriptText(SAY_AGGRO3, m_creature); break; }; } else m_uiPhase1Timer -= uiDiff; if (m_uiSoldierCount < MAX_SOLDIER_COUNT) { if (m_uiSoldierTimer < uiDiff) { SummonMob(NPC_SOLDIER_FROZEN); ++m_uiSoldierCount; m_uiSoldierTimer = 3000; } else m_uiSoldierTimer -= uiDiff; } if (m_uiAbominationCount < MAX_ABOMINATION_COUNT) { if (m_uiAbominationTimer < uiDiff) { SummonMob(NPC_UNSTOPPABLE_ABOM); ++m_uiAbominationCount; m_uiAbominationTimer = 25000; } else m_uiAbominationTimer -= uiDiff; } if (m_uiBansheeCount < MAX_BANSHEE_COUNT) { if (m_uiBansheeTimer < uiDiff) { SummonMob(NPC_SOUL_WEAVER); ++m_uiBansheeCount; m_uiBansheeTimer = 25000; } else m_uiBansheeTimer -= uiDiff; } } } else // normal or guardian phase { if (m_uiFrostBoltTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_FROST_BOLT : SPELL_FROST_BOLT_H) == CAST_OK) m_uiFrostBoltTimer = urand(1000, 60000); } else m_uiFrostBoltTimer -= uiDiff; if (m_uiFrostBoltNovaTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_FROST_BOLT_NOVA : SPELL_FROST_BOLT_NOVA_H) == CAST_OK) m_uiFrostBoltNovaTimer = 15000; } else m_uiFrostBoltNovaTimer -= uiDiff; if (m_uiManaDetonationTimer < uiDiff) { Unit* pTarget; uint8 counter = 0; do { counter++; if (counter >= 25) { break; pTarget = NULL; } else pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0); } while(pTarget->getPowerType() != POWER_MANA); if (pTarget) { if (DoCastSpellIfCan(pTarget, SPELL_MANA_DETONATION) == CAST_OK) { if (urand(0, 1)) DoScriptText(SAY_SPECIAL1_MANA_DET, m_creature); m_uiManaDetonationTargetGUID = pTarget->GetGUID(); m_uiManaDetonationMana = m_bIsRegularMode ? urand(2500,4000) : urand(3500,5500); uint32 newMana = pTarget->GetPower(POWER_MANA) - m_uiManaDetonationMana; uint32 mana = newMana < 0 ? 0 : newMana; m_uiManaDetonationMana *= 1+(urand(2,m_bIsRegularMode?5:9)/10.f); // random increase damage output, not blizzlike pTarget->SetPower(POWER_MANA, mana); m_uiManaDetonationTimer = 20000; m_uiManaDetonationEndTimer = 5000; m_bManaDetonationActive = true; } } } else m_uiManaDetonationTimer -= uiDiff; if (m_bManaDetonationActive) if (m_uiManaDetonationEndTimer < uiDiff) { if (Player* pTarget = m_creature->GetMap()->GetPlayer(m_uiManaDetonationTargetGUID)) { Map *map = m_creature->GetMap(); Map::PlayerList const &PlayerList = map->GetPlayers(); if (!PlayerList.isEmpty()) for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if(i->getSource()->isDead() || i->getSource() == pTarget || i->getSource()->isGameMaster()) // no dmg on dead, self and GMs continue; if (pTarget->GetDistance2d(i->getSource()) < 15.f) i->getSource()->DealDamage(i->getSource(), m_uiManaDetonationMana, NULL, SPELL_DIRECT_DAMAGE, SPELL_SCHOOL_MASK_ARCANE, NULL, true); } } m_bManaDetonationActive = false; } else m_uiManaDetonationEndTimer -= uiDiff; if (m_uiShadowFissureTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) if(DoCastSpellIfCan(pTarget, SPELL_SHADOW_FISSURE) == CAST_OK) { m_fFissureX = pTarget->GetPositionX(); m_fFissureY = pTarget->GetPositionY(); if (urand(0, 1)) DoScriptText(SAY_SPECIAL3_MANA_DET, m_creature); m_uiShadowFissureTimer = 25000; m_uiShadowFissureActiveTimer = 5000; m_bShadowFissureActive = true; } } else m_uiShadowFissureTimer -= uiDiff; if(m_bShadowFissureActive) if(m_uiShadowFissureActiveTimer < uiDiff) { // hack for shadow fissure damage, shadow fissure spell does not give damage to players Map::PlayerList const& pPlayers = m_creature->GetMap()->GetPlayers(); if (!pPlayers.isEmpty()) for (Map::PlayerList::const_iterator itr = pPlayers.begin(); itr != pPlayers.end(); ++itr) if(itr->getSource() && !itr->getSource()->isGameMaster() && (itr->getSource()->GetDistance2d(m_fFissureX,m_fFissureY) < 4.0f)) m_creature->DealDamage(itr->getSource(),itr->getSource()->GetHealth(),NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); m_bShadowFissureActive = false; } else m_uiShadowFissureActiveTimer -= uiDiff; if (m_uiFrostBlastTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0), SPELL_FROST_BLAST) == CAST_OK) { if (urand(0, 1)) DoScriptText(SAY_FROST_BLAST, m_creature); m_uiFrostBlastTimer = urand(30000, 60000); } } else m_uiFrostBlastTimer -= uiDiff; if (!m_bIsRegularMode) { if (m_uiChainsTimer < uiDiff) { m_lChainsTargets.clear(); if (SpellEntry* TempSpell = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_CHAINS_OF_KELTHUZAD_TARGET)) { TempSpell->EffectApplyAuraName[0]=SPELL_AURA_MOD_CHARM; uint8 uiChainsTargetsCount = 0; for (uint8 i=0; i<25; ++i) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { if (pTarget->GetTypeId() == TYPEID_PLAYER && !pTarget->HasAura(SPELL_CHAINS_OF_KELTHUZAD_TARGET, EFFECT_INDEX_0)) { m_creature->InterruptNonMeleeSpells(false); m_creature->CastCustomSpell(pTarget, TempSpell, NULL, NULL, NULL, true); ((Player*)pTarget)->SetClientControl(pTarget, 0); m_lChainsTargets.insert(pTarget->GetGUID()); pTarget->setFaction(14); ++uiChainsTargetsCount; } if (uiChainsTargetsCount>=3) break; } } m_uiChainsEndTimer = 20000; m_uiChainsTargetsCastTimer = 3500; DoResetThreat(); } //DoCastSpellIfCan(pTarget, SPELL_CHAINS_OF_KELTHUZAD); DoScriptText(urand(0, 1) ? SAY_CHAIN1 : SAY_CHAIN2, m_creature); m_uiChainsTimer = urand(60000, 90000); } else m_uiChainsTimer -= uiDiff; if (!m_lChainsTargets.empty()) { if (m_uiChainsTargetsCastTimer < uiDiff) { for (std::set<uint64>::iterator itr = m_lChainsTargets.begin(); itr != m_lChainsTargets.end(); ++itr) if (Unit* pUnit = m_creature->GetMap()->GetUnit(*itr)) { if (pUnit->isDead()) continue; if (pUnit->getClass() == CLASS_PRIEST || pUnit->getClass() == CLASS_SHAMAN || pUnit->getClass() == CLASS_MAGE || pUnit->getClass() == CLASS_WARLOCK) // healer classes heal kelthuzad { int32 amount = urand(11000,19000); pUnit->CastCustomSpell(m_creature, 36983, &amount, NULL, NULL, false); } else // other classes melee players if (Unit* pVictim = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) { pUnit->GetMotionMaster()->MoveChase(pVictim); pUnit->Attack(pVictim,true); } } m_uiChainsTargetsCastTimer = 4500; } else m_uiChainsTargetsCastTimer -= uiDiff; if (m_uiChainsEndTimer < uiDiff) { for(std::set<uint64>::iterator itr = m_lChainsTargets.begin(); itr != m_lChainsTargets.end(); ++itr) if (Player* pPlayer = m_creature->GetMap()->GetPlayer(*itr)) { pPlayer->setFactionForRace(pPlayer->getRace()); pPlayer->SetClientControl(pPlayer, 1); } m_lChainsTargets.clear(); } else m_uiChainsEndTimer -= uiDiff; } } if (m_uiPhase == PHASE_NORMAL) { if (m_creature->GetHealthPercent() < 45.0f) { m_uiPhase = PHASE_GUARDIANS; DoScriptText(SAY_REQUEST_AID, m_creature); // here Lich King should respond to Kel'Thuzad but I don't know which creature to make talk // so for now just make Kel'Thuzad says it. DoScriptText(SAY_ANSWER_REQUEST, m_creature); } } else if (m_uiPhase == PHASE_GUARDIANS && m_uiGuardiansCount < m_uiGuardiansCountMax) { if (m_uiGuardiansTimer < uiDiff) { // Summon a Guardian of Icecrown in a random alcove SummonMob(NPC_GUARDIAN); m_uiGuardiansTimer = 5000; } else m_uiGuardiansTimer -= uiDiff; } DoMeleeAttackIfReady(); } }