void UpdateAI(const uint32 diff) { if (IsEvent) { //Must update npc_escortAI npc_escortAI::UpdateAI(diff); if (!pGo) { pGo = true; if (pInstance) { AddWaypoint(0, 5492.91f, -2404.61f, 1462.63f); AddWaypoint(1, 5531.76f, -2460.87f, 1469.55f); AddWaypoint(2, 5554.58f, -2514.66f, 1476.12f); AddWaypoint(3, 5554.16f, -2567.23f, 1479.90f); AddWaypoint(4, 5540.67f, -2625.99f, 1480.89f); AddWaypoint(5, 5508.16f, -2659.2f, 1480.15f); AddWaypoint(6, 5489.62f, -2704.05f, 1482.18f); AddWaypoint(7, 5457.04f, -2726.26f, 1485.10f); Start(false, true); SetDespawnAtEnd(false); } } } //Return since we have no target if (!UpdateVictim()) return; if (CleaveTimer <= diff) { DoCast(me, SPELL_CLEAVE); CleaveTimer = 6000 + rand() % 15000; } else CleaveTimer -= diff; if (WarStompTimer <= diff) { DoCast(me, SPELL_WARSTOMP); WarStompTimer = 60000; } else WarStompTimer -= diff; if (me->HasAura(SPELL_MARK, 0)) me->RemoveAurasDueToSpell(SPELL_MARK); if (MarkTimer <= diff) { //cast dummy, useful for bos addons me->CastCustomSpell(me, SPELL_MARK, NULL, NULL, NULL, false, NULL, NULL, me->GetGUID()); std::list<HostileReference*> t_list = me->getThreatManager().getThreatList(); for (std::list<HostileReference*>::iterator itr = t_list.begin(); itr != t_list.end(); ++itr) { Unit* pTarget = Unit::GetUnit(*me, (*itr)->getUnitGuid()); if (pTarget && pTarget->GetTypeId() == TYPEID_PLAYER && pTarget->getPowerType() == POWER_MANA) { pTarget->CastSpell(pTarget, SPELL_MARK, true); //only cast on mana users } } MarkTimerBase -= 5000; if (MarkTimerBase < 5500) MarkTimerBase = 5500; MarkTimer = MarkTimerBase; switch (urand(0, 2)) { case 0: DoPlaySoundToSet(me, SOUND_MARK1); me->MonsterYell(SAY_MARK1, LANG_UNIVERSAL, 0); break; case 1: DoPlaySoundToSet(me, SOUND_MARK2); me->MonsterYell(SAY_MARK2, LANG_UNIVERSAL, 0); break; } } else MarkTimer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if (HealthBelowPct(10) && !Enraged) { Enraged = true; DoCast(me, SPELL_ENRAGE, true); DoScriptText(SAY_ENRAGE, me); } //Randomly cast one beam. if (BeamTimer <= diff) { Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0); if (!pTarget || !pTarget->isAlive()) return; BeamTimer = 9000; switch(CurrentBeam) { case 0: DoCast(pTarget, SPELL_BEAM_SINISTER); break; case 1: DoCast(pTarget, SPELL_BEAM_VILE); break; case 2: DoCast(pTarget, SPELL_BEAM_WICKED); break; case 3: DoCast(pTarget, SPELL_BEAM_SINFUL); break; } ++BeamCount; uint32 Beam = CurrentBeam; if (BeamCount > 3) while (CurrentBeam == Beam) CurrentBeam = rand()%3; } else BeamTimer -= diff; // Random Prismatic Shield every 15 seconds. if (PrismaticShieldTimer <= diff) { uint32 random = rand()%6; if (PrismaticAuras[random]) DoCast(me, PrismaticAuras[random]); PrismaticShieldTimer = 15000; } else PrismaticShieldTimer -= diff; // Select 3 random targets (can select same target more than once), teleport to a random location then make them cast explosions until they get away from each other. if (FatalAttractionTimer <= diff) { ExplosionCount = 0; TeleportPlayers(); DoScriptText(RAND(SAY_SPELL2,SAY_SPELL3), me); FatalAttractionExplodeTimer = 2000; FatalAttractionTimer = 40000 + rand()%31 * 1000; } else FatalAttractionTimer -= diff; if (FatalAttractionExplodeTimer <= diff) { // Just make them explode three times... they're supposed to keep exploding while they are in range, but it'll take too much code. I'll try to think of an efficient way for it later. if (ExplosionCount < 3) { for (uint8 i = 0; i < 3; ++i) { Unit* pUnit = NULL; if (TargetGUID[i]) { pUnit = Unit::GetUnit((*me), TargetGUID[i]); if (pUnit) pUnit->CastSpell(pUnit, SPELL_ATTRACTION, true); TargetGUID[i] = 0; } } ++ExplosionCount; FatalAttractionExplodeTimer = 1000; } else { FatalAttractionExplodeTimer = FatalAttractionTimer + 2000; ExplosionCount = 0; } } else FatalAttractionExplodeTimer -= diff; if (ShriekTimer <= diff) { DoCast(me->getVictim(), SPELL_SILENCING_SHRIEK); ShriekTimer = 25000+rand()%10 * 1000; } else ShriekTimer -= diff; if (SaberTimer <= diff) { DoCast(me->getVictim(), SPELL_SABER_LASH); SaberTimer = 25000+rand()%10 * 1000; } else SaberTimer -= diff; //Enrage if (!me->HasAura(SPELL_BERSERK)) { if (EnrageTimer <= diff) { DoCast(me, SPELL_BERSERK); DoScriptText(SAY_ENRAGE, me); } else EnrageTimer -= diff; } //Random taunts if (RandomYellTimer <= diff) { DoScriptText(RAND(SAY_TAUNT1,SAY_TAUNT2,SAY_TAUNT3), me); RandomYellTimer = 60000 + rand()%91 * 1000; } else RandomYellTimer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(uint32 diff) { if (!UpdateVictim()) return; if (StormCount) { Unit* target = Unit::GetUnit(*me, CloudGUID); if (!target || !target->isAlive()) { EnterEvadeMode(); return; } else if (Unit* Cyclone = Unit::GetUnit(*me, CycloneGUID)) Cyclone->CastSpell(target, 25160, true); // keep casting or... if (StormSequenceTimer <= diff) HandleStormSequence(target); else StormSequenceTimer -= diff; return; } if (Enrage_Timer <= diff) { Talk(SAY_ENRAGE); DoCast(me, SPELL_BERSERK, true); Enrage_Timer = 600000; } else Enrage_Timer -= diff; if (StaticDisruption_Timer <= diff) { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1); if (!target) target = me->getVictim(); TargetGUID = target->GetGUID(); DoCast(target, SPELL_STATIC_DISRUPTION, false); me->SetInFront(me->getVictim()); StaticDisruption_Timer = (10+rand()%8)*1000; // < 20s /*if (float dist = me->IsWithinDist3d(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 5.0f) dist = 5.0f; SDisruptAOEVisual_Timer = 1000 + floor(dist / 30 * 1000.0f);*/ } else StaticDisruption_Timer -= diff; if (GustOfWind_Timer <= diff) { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1); if (!target) target = me->getVictim(); DoCast(target, SPELL_GUST_OF_WIND); GustOfWind_Timer = urand(20, 30) * 1000; //20 to 30 seconds(bosskillers) } else GustOfWind_Timer -= diff; if (CallLighting_Timer <= diff) { DoCast(me->getVictim(), SPELL_CALL_LIGHTNING); CallLighting_Timer = urand(12, 17) * 1000; //totaly random timer. can't find any info on this } else CallLighting_Timer -= diff; if (!isRaining && ElectricalStorm_Timer < uint32(8000 + rand() % 5000)) { SetWeather(WEATHER_STATE_HEAVY_RAIN, 0.9999f); isRaining = true; } if (ElectricalStorm_Timer <= diff) { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50, true); if (!target) { EnterEvadeMode(); return; } target->CastSpell(target, 44007, true);//cloud visual DoCast(target, SPELL_ELECTRICAL_STORM, false);//storm cyclon + visual float x, y, z; target->GetPosition(x, y, z); if (target) { target->SetUnitMovementFlags(MOVEMENTFLAG_DISABLE_GRAVITY); target->MonsterMoveWithSpeed(x, y, me->GetPositionZ()+15, 0); } Unit* Cloud = me->SummonTrigger(x, y, me->GetPositionZ()+16, 0, 15000); if (Cloud) { CloudGUID = Cloud->GetGUID(); Cloud->SetUnitMovementFlags(MOVEMENTFLAG_DISABLE_GRAVITY); Cloud->StopMoving(); Cloud->SetObjectScale(1.0f); Cloud->setFaction(35); Cloud->SetMaxHealth(9999999); Cloud->SetHealth(9999999); Cloud->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } ElectricalStorm_Timer = 60000; //60 seconds(bosskillers) StormCount = 1; StormSequenceTimer = 0; } else ElectricalStorm_Timer -= diff; if (SummonEagles_Timer <= diff) { Talk(SAY_SUMMON); float x, y, z; me->GetPosition(x, y, z); for (uint8 i = 0; i < 8; ++i) { Unit* bird = Unit::GetUnit(*me, BirdGUIDs[i]); if (!bird) //they despawned on die { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { x = target->GetPositionX() + irand(-10, 10); y = target->GetPositionY() + irand(-10, 10); z = target->GetPositionZ() + urand(16, 20); if (z > 95) z = 95.0f - urand(0, 5); } Creature* creature = me->SummonCreature(MOB_SOARING_EAGLE, x, y, z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); if (creature) { creature->AddThreat(me->getVictim(), 1.0f); creature->AI()->AttackStart(me->getVictim()); BirdGUIDs[i] = creature->GetGUID(); } } } SummonEagles_Timer = 999999; } else SummonEagles_Timer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(uint32 diff) override { events.Update(diff); // Speech if (!UpdateVictim()) { while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_SPEECH_1: Talk(SAY_LINE1); me->SetStandState(UNIT_STAND_STATE_STAND); me->HandleEmoteCommand(EMOTE_ONESHOT_TALK); events.ScheduleEvent(EVENT_SPEECH_2, 12000); break; case EVENT_SPEECH_2: Talk(SAY_LINE2); me->HandleEmoteCommand(EMOTE_ONESHOT_TALK); events.ScheduleEvent(EVENT_SPEECH_3, 12000); break; case EVENT_SPEECH_3: Talk(SAY_LINE3); me->HandleEmoteCommand(EMOTE_ONESHOT_TALK); events.ScheduleEvent(EVENT_SPEECH_4, 16000); break; case EVENT_SPEECH_4: me->setFaction(103); if (PlayerGUID && ObjectAccessor::GetUnit(*me, PlayerGUID)) AttackStart(ObjectAccessor::GetUnit(*me, PlayerGUID));; break; } } return; } if (me->HasUnitState(UNIT_STATE_CASTING)) return; while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_CLEAVE: events.ScheduleEvent(EVENT_CLEAVE, 15000); DoCastVictim(SPELL_CLEAVE); break; case EVENT_FLAMEBREATH: DoCastVictim(SPELL_FLAMEBREATH); events.ScheduleEvent(EVENT_FLAMEBREATH, urand(8000, 14000)); break; case EVENT_FIRENOVA: DoCastVictim(SPELL_FIRENOVA); events.ScheduleEvent(EVENT_FIRENOVA, 15000); break; case EVENT_TAILSWIPE: //Only cast if we are behind /*if (!me->HasInArc(M_PI, me->GetVictim())) { DoCast(me->GetVictim(), SPELL_TAILSWIPE); }*/ events.ScheduleEvent(EVENT_TAILSWIPE, 15000); break; case EVENT_BURNINGADRENALINE_CASTER: { Unit* target = NULL; uint8 i = 0; while (i < 3) // max 3 tries to get a random target with power_mana { ++i; target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true); // not aggro leader if (target && target->getPowerType() == POWER_MANA) i = 3; } if (target) // cast on self (see below) target->CastSpell(target, SPELL_BURNINGADRENALINE, true); } events.ScheduleEvent(EVENT_BURNINGADRENALINE_CASTER, 15000); break; case EVENT_BURNINGADRENALINE_TANK: // have the victim cast the spell on himself otherwise the third effect aura will be applied to Vael instead of the player me->EnsureVictim()->CastSpell(me->GetVictim(), SPELL_BURNINGADRENALINE, true); events.ScheduleEvent(EVENT_BURNINGADRENALINE_TANK, 45000); break; } } // Yell if hp lower than 15% if (HealthBelowPct(15) && !HasYelled) { Talk(SAY_HALFLIFE); HasYelled = true; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; //Shimmer_Timer Timer if (Shimmer_Timer <= diff) { //Remove old vulnerabilty spell if (CurrentVurln_Spell) me->RemoveAurasDueToSpell(CurrentVurln_Spell); //Cast new random vulnerabilty on self uint32 spell = RAND(SPELL_FIRE_VULNERABILITY, SPELL_FROST_VULNERABILITY, SPELL_SHADOW_VULNERABILITY, SPELL_NATURE_VULNERABILITY, SPELL_ARCANE_VULNERABILITY); DoCast(me, spell); CurrentVurln_Spell = spell; DoScriptText(EMOTE_SHIMMER, me); Shimmer_Timer = 45000; } else Shimmer_Timer -= diff; //Breath1_Timer if (Breath1_Timer <= diff) { DoCast(me->getVictim(), Breath1_Spell); Breath1_Timer = 60000; } else Breath1_Timer -= diff; //Breath2_Timer if (Breath2_Timer <= diff) { DoCast(me->getVictim(), Breath2_Spell); Breath2_Timer = 60000; } else Breath2_Timer -= diff; //Affliction_Timer if (Affliction_Timer <= diff) { std::list<HostileReference*> threatlist = me->getThreatManager().getThreatList(); for (std::list<HostileReference*>::const_iterator i = threatlist.begin(); i != threatlist.end(); ++i) { Unit* pUnit; if ((*i) && (*i)->getSource()) { pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid()); if (pUnit) { //Cast affliction DoCast(pUnit, RAND(SPELL_BROODAF_BLUE, SPELL_BROODAF_BLACK, SPELL_BROODAF_RED, SPELL_BROODAF_BRONZE, SPELL_BROODAF_GREEN), true); //Chromatic mutation if target is effected by all afflictions if (pUnit->HasAura(SPELL_BROODAF_BLUE, 0) && pUnit->HasAura(SPELL_BROODAF_BLACK, 0) && pUnit->HasAura(SPELL_BROODAF_RED, 0) && pUnit->HasAura(SPELL_BROODAF_BRONZE, 0) && pUnit->HasAura(SPELL_BROODAF_GREEN, 0)) { //pTarget->RemoveAllAuras(); //DoCast(pTarget, SPELL_CHROMATIC_MUT_1); //Chromatic mutation is causing issues //Assuming it is caused by a lack of core support for Charm //So instead we instant kill our target //WORKAROUND if (pUnit->GetTypeId() == TYPEID_PLAYER) pUnit->CastSpell(pUnit, 5, false); } } } } Affliction_Timer = 10000; } else Affliction_Timer -= diff; //Frenzy_Timer if (Frenzy_Timer <= diff) { DoCast(me, SPELL_FRENZY); DoScriptText(EMOTE_FRENZY, me); Frenzy_Timer = urand(10000,15000); } else Frenzy_Timer -= diff; //Enrage if not already enraged and below 20% if (!Enraged && (me->GetHealth()*100 / me->GetMaxHealth()) < 20) { DoCast(me, SPELL_ENRAGE); Enraged = true; } DoMeleeAttackIfReady(); }
void HandleDummy(SpellEffIndex /*effIndex*/) { Unit* caster = GetCaster(); caster->CastSpell(caster, SPELL_HUNTER_PET_CARRION_FEEDER_TRIGGERED, false); }
void HandleDummy(SpellEffIndex /*effIndex*/) { Unit* caster = GetCaster(); uint32 spellId = roll_chance_i(50) ? SPELL_CREATE_RESONATING_SKULL : SPELL_CREATE_BONE_DUST; caster->CastSpell(caster, spellId, true, NULL); }
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { Unit* target = GetTarget(); target->CastSpell(target, SPELL_DAMAGE_REDUCTION_AURA, true); }
void HandleDummy(SpellEffIndex /*effIndex*/) { Unit* caster = GetCaster(); if (Unit* unitTarget = GetHitUnit()) caster->CastSpell(unitTarget, SPELL_ROGUE_SHIV_TRIGGERED, true); }
/// Process queued scripts void Map::ScriptsProcess() { if (m_scriptSchedule.empty()) return; ///- Process overdue queued scripts ScriptScheduleMap::iterator iter = m_scriptSchedule.begin(); // ok as multimap is a *sorted* associative container while (!m_scriptSchedule.empty() && (iter->first <= sWorld->GetGameTime())) { ScriptAction const& step = iter->second; Object* source = NULL; if (step.sourceGUID) { switch (GUID_HIPART(step.sourceGUID)) { case HIGHGUID_ITEM: // as well as HIGHGUID_CONTAINER if (Player* player = GetPlayer(step.ownerGUID)) source = player->GetItemByGuid(step.sourceGUID); break; case HIGHGUID_UNIT: case HIGHGUID_VEHICLE: source = GetCreature(step.sourceGUID); break; case HIGHGUID_PET: source = GetPet(step.sourceGUID); break; case HIGHGUID_PLAYER: source = GetPlayer(step.sourceGUID); break; case HIGHGUID_TRANSPORT: case HIGHGUID_GAMEOBJECT: source = GetGameObject(step.sourceGUID); break; case HIGHGUID_CORPSE: source = GetCorpse(step.sourceGUID); break; case HIGHGUID_MO_TRANSPORT: { GameObject* go = GetGameObject(step.sourceGUID); source = go ? go->ToTransport() : NULL; break; } default: sLog->outError("%s source with unsupported high guid (GUID: " UI64FMTD ", high guid: %u).", step.script->GetDebugInfo().c_str(), step.sourceGUID, GUID_HIPART(step.sourceGUID)); break; } } WorldObject* target = NULL; if (step.targetGUID) { switch (GUID_HIPART(step.targetGUID)) { case HIGHGUID_UNIT: case HIGHGUID_VEHICLE: target = GetCreature(step.targetGUID); break; case HIGHGUID_PET: target = GetPet(step.targetGUID); break; case HIGHGUID_PLAYER: // empty GUID case also target = GetPlayer(step.targetGUID); break; case HIGHGUID_TRANSPORT: case HIGHGUID_GAMEOBJECT: target = GetGameObject(step.targetGUID); break; case HIGHGUID_CORPSE: target = GetCorpse(step.targetGUID); break; case HIGHGUID_MO_TRANSPORT: { GameObject* go = GetGameObject(step.targetGUID); target = go ? go->ToTransport() : NULL; break; } default: sLog->outError("%s target with unsupported high guid (GUID: " UI64FMTD ", high guid: %u).", step.script->GetDebugInfo().c_str(), step.targetGUID, GUID_HIPART(step.targetGUID)); break; } } switch (step.script->command) { case SCRIPT_COMMAND_TALK: if (step.script->Talk.ChatType > CHAT_TYPE_WHISPER && step.script->Talk.ChatType != CHAT_MSG_RAID_BOSS_WHISPER) { sLog->outError("%s invalid chat type (%u) specified, skipping.", step.script->GetDebugInfo().c_str(), step.script->Talk.ChatType); break; } if (step.script->Talk.Flags & SF_TALK_USE_PLAYER) { if (Player* player = _GetScriptPlayerSourceOrTarget(source, target, step.script)) { LocaleConstant loc_idx = player->GetSession()->GetSessionDbLocaleIndex(); std::string text(sObjectMgr->GetTrinityString(step.script->Talk.TextID, loc_idx)); switch (step.script->Talk.ChatType) { case CHAT_TYPE_SAY: player->Say(text, LANG_UNIVERSAL); break; case CHAT_TYPE_YELL: player->Yell(text, LANG_UNIVERSAL); break; case CHAT_TYPE_TEXT_EMOTE: case CHAT_TYPE_BOSS_EMOTE: player->TextEmote(text); break; case CHAT_TYPE_WHISPER: case CHAT_MSG_RAID_BOSS_WHISPER: { uint64 targetGUID = target ? target->GetGUID() : 0; if (!targetGUID || !IS_PLAYER_GUID(targetGUID)) sLog->outError("%s attempt to whisper to non-player unit, skipping.", step.script->GetDebugInfo().c_str()); else player->Whisper(text, LANG_UNIVERSAL, targetGUID); break; } default: break; // must be already checked at load } } } else { // Source or target must be Creature. if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script)) { uint64 targetGUID = target ? target->GetGUID() : 0; switch (step.script->Talk.ChatType) { case CHAT_TYPE_SAY: cSource->MonsterSay(step.script->Talk.TextID, LANG_UNIVERSAL, target); break; case CHAT_TYPE_YELL: cSource->MonsterYell(step.script->Talk.TextID, LANG_UNIVERSAL, target); break; case CHAT_TYPE_TEXT_EMOTE: cSource->MonsterTextEmote(step.script->Talk.TextID, target); break; case CHAT_TYPE_BOSS_EMOTE: cSource->MonsterTextEmote(step.script->Talk.TextID, target, true); break; case CHAT_TYPE_WHISPER: if (!targetGUID || !IS_PLAYER_GUID(targetGUID)) sLog->outError("%s attempt to whisper to non-player unit, skipping.", step.script->GetDebugInfo().c_str()); else cSource->MonsterWhisper(step.script->Talk.TextID, target->ToPlayer()); break; case CHAT_MSG_RAID_BOSS_WHISPER: if (!targetGUID || !IS_PLAYER_GUID(targetGUID)) sLog->outError("%s attempt to raidbosswhisper to non-player unit, skipping.", step.script->GetDebugInfo().c_str()); else cSource->MonsterWhisper(step.script->Talk.TextID, target->ToPlayer(), true); break; default: break; // must be already checked at load } } } break; case SCRIPT_COMMAND_EMOTE: // Source or target must be Creature. if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script)) { if (step.script->Emote.Flags & SF_EMOTE_USE_STATE) cSource->SetUInt32Value(UNIT_NPC_EMOTESTATE, step.script->Emote.EmoteID); else cSource->HandleEmoteCommand(step.script->Emote.EmoteID); } break; case SCRIPT_COMMAND_FIELD_SET: // Source or target must be Creature. if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script)) { // Validate field number. if (step.script->FieldSet.FieldID <= OBJECT_FIELD_ENTRY || step.script->FieldSet.FieldID >= cSource->GetValuesCount()) sLog->outError("%s wrong field %u (max count: %u) in object (TypeId: %u, Entry: %u, GUID: %u) specified, skipping.", step.script->GetDebugInfo().c_str(), step.script->FieldSet.FieldID, cSource->GetValuesCount(), cSource->GetTypeId(), cSource->GetEntry(), cSource->GetGUIDLow()); else cSource->SetUInt32Value(step.script->FieldSet.FieldID, step.script->FieldSet.FieldValue); } break; case SCRIPT_COMMAND_MOVE_TO: // Source or target must be Creature. if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script)) { Unit * unit = (Unit*)cSource; if (step.script->MoveTo.TravelTime != 0) { float speed = unit->GetDistance(step.script->MoveTo.DestX, step.script->MoveTo.DestY, step.script->MoveTo.DestZ) / ((float)step.script->MoveTo.TravelTime * 0.001f); unit->MonsterMoveWithSpeed(step.script->MoveTo.DestX, step.script->MoveTo.DestY, step.script->MoveTo.DestZ, speed); } else unit->NearTeleportTo(step.script->MoveTo.DestX, step.script->MoveTo.DestY, step.script->MoveTo.DestZ, unit->GetOrientation()); } break; case SCRIPT_COMMAND_FLAG_SET: // Source or target must be Creature. if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script)) { // Validate field number. if (step.script->FlagToggle.FieldID <= OBJECT_FIELD_ENTRY || step.script->FlagToggle.FieldID >= cSource->GetValuesCount()) sLog->outError("%s wrong field %u (max count: %u) in object (TypeId: %u, Entry: %u, GUID: %u) specified, skipping.", step.script->GetDebugInfo().c_str(), step.script->FlagToggle.FieldID, cSource->GetValuesCount(), cSource->GetTypeId(), cSource->GetEntry(), cSource->GetGUIDLow()); else cSource->SetFlag(step.script->FlagToggle.FieldID, step.script->FlagToggle.FieldValue); } break; case SCRIPT_COMMAND_FLAG_REMOVE: // Source or target must be Creature. if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script)) { // Validate field number. if (step.script->FlagToggle.FieldID <= OBJECT_FIELD_ENTRY || step.script->FlagToggle.FieldID >= cSource->GetValuesCount()) sLog->outError("%s wrong field %u (max count: %u) in object (TypeId: %u, Entry: %u, GUID: %u) specified, skipping.", step.script->GetDebugInfo().c_str(), step.script->FlagToggle.FieldID, cSource->GetValuesCount(), cSource->GetTypeId(), cSource->GetEntry(), cSource->GetGUIDLow()); else cSource->RemoveFlag(step.script->FlagToggle.FieldID, step.script->FlagToggle.FieldValue); } break; case SCRIPT_COMMAND_TELEPORT_TO: if (step.script->TeleportTo.Flags & SF_TELEPORT_USE_CREATURE) { // Source or target must be Creature. if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script, true)) cSource->NearTeleportTo(step.script->TeleportTo.DestX, step.script->TeleportTo.DestY, step.script->TeleportTo.DestZ, step.script->TeleportTo.Orientation); } else { // Source or target must be Player. if (Player* player = _GetScriptPlayerSourceOrTarget(source, target, step.script)) player->TeleportTo(step.script->TeleportTo.MapID, step.script->TeleportTo.DestX, step.script->TeleportTo.DestY, step.script->TeleportTo.DestZ, step.script->TeleportTo.Orientation); } break; case SCRIPT_COMMAND_QUEST_EXPLORED: { if (!source) { sLog->outError("%s source object is NULL.", step.script->GetDebugInfo().c_str()); break; } if (!target) { sLog->outError("%s target object is NULL.", step.script->GetDebugInfo().c_str()); break; } // when script called for item spell casting then target == (unit or GO) and source is player WorldObject* worldObject; Player* player = target->ToPlayer(); if (player) { if (source->GetTypeId() != TYPEID_UNIT && source->GetTypeId() != TYPEID_GAMEOBJECT && source->GetTypeId() != TYPEID_PLAYER) { sLog->outError("%s source is not unit, gameobject or player (TypeId: %u, Entry: %u, GUID: %u), skipping.", step.script->GetDebugInfo().c_str(), source->GetTypeId(), source->GetEntry(), source->GetGUIDLow()); break; } worldObject = dynamic_cast<WorldObject*>(source); } else { player = source->ToPlayer(); if (player) { if (target->GetTypeId() != TYPEID_UNIT && target->GetTypeId() != TYPEID_GAMEOBJECT && target->GetTypeId() != TYPEID_PLAYER) { sLog->outError("%s target is not unit, gameobject or player (TypeId: %u, Entry: %u, GUID: %u), skipping.", step.script->GetDebugInfo().c_str(), target->GetTypeId(), target->GetEntry(), target->GetGUIDLow()); break; } worldObject = dynamic_cast<WorldObject*>(target); } else { sLog->outError("%s neither source nor target is player (source: TypeId: %u, Entry: %u, GUID: %u; target: TypeId: %u, Entry: %u, GUID: %u), skipping.", step.script->GetDebugInfo().c_str(), source->GetTypeId(), source->GetEntry(), source->GetGUIDLow(), target->GetTypeId(), target->GetEntry(), target->GetGUIDLow()); break; } } // quest id and flags checked at script loading if ((worldObject->GetTypeId() != TYPEID_UNIT || ((Unit*)worldObject)->IsAlive()) && (step.script->QuestExplored.Distance == 0 || worldObject->IsWithinDistInMap(player, float(step.script->QuestExplored.Distance)))) player->AreaExploredOrEventHappens(step.script->QuestExplored.QuestID); else player->FailQuest(step.script->QuestExplored.QuestID); break; } case SCRIPT_COMMAND_KILL_CREDIT: // Source or target must be Player. if (Player* player = _GetScriptPlayerSourceOrTarget(source, target, step.script)) { if (step.script->KillCredit.Flags & SF_KILLCREDIT_REWARD_GROUP) player->RewardPlayerAndGroupAtEvent(step.script->KillCredit.CreatureEntry, player); else player->KilledMonsterCredit(step.script->KillCredit.CreatureEntry, 0); } break; case SCRIPT_COMMAND_RESPAWN_GAMEOBJECT: if (!step.script->RespawnGameobject.GOGuid) { sLog->outError("%s gameobject guid (datalong) is not specified.", step.script->GetDebugInfo().c_str()); break; } // Source or target must be WorldObject. if (WorldObject* pSummoner = _GetScriptWorldObject(source, true, step.script)) { GameObject* pGO = _FindGameObject(pSummoner, step.script->RespawnGameobject.GOGuid); if (!pGO) { sLog->outError("%s gameobject was not found (guid: %u).", step.script->GetDebugInfo().c_str(), step.script->RespawnGameobject.GOGuid); break; } if (pGO->GetGoType() == GAMEOBJECT_TYPE_FISHINGNODE || pGO->GetGoType() == GAMEOBJECT_TYPE_DOOR || pGO->GetGoType() == GAMEOBJECT_TYPE_BUTTON || pGO->GetGoType() == GAMEOBJECT_TYPE_TRAP) { sLog->outError("%s can not be used with gameobject of type %u (guid: %u).", step.script->GetDebugInfo().c_str(), uint32(pGO->GetGoType()), step.script->RespawnGameobject.GOGuid); break; } // Check that GO is not spawned if (!pGO->isSpawned()) { int32 nTimeToDespawn = std::max(5, int32(step.script->RespawnGameobject.DespawnDelay)); pGO->SetLootState(GO_READY); pGO->SetRespawnTime(nTimeToDespawn); pGO->GetMap()->AddToMap(pGO); } } break; case SCRIPT_COMMAND_TEMP_SUMMON_CREATURE: { // Source must be WorldObject. if (WorldObject* pSummoner = _GetScriptWorldObject(source, true, step.script)) { if (!step.script->TempSummonCreature.CreatureEntry) sLog->outError("%s creature entry (datalong) is not specified.", step.script->GetDebugInfo().c_str()); else { uint32 entry = step.script->TempSummonCreature.CreatureEntry; float x = step.script->TempSummonCreature.PosX; float y = step.script->TempSummonCreature.PosY; float z = step.script->TempSummonCreature.PosZ; float o = step.script->TempSummonCreature.Orientation; if (step.script->TempSummonCreature.CheckIfExists) if (Unit* trigger = pSummoner->SummonTrigger(x, y, z, o, 1)) if (trigger->FindNearestCreature(entry, 60.0f)) break; if (!pSummoner->SummonCreature(entry, x, y, z, o, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, step.script->TempSummonCreature.DespawnDelay)) sLog->outError("%s creature was not spawned (entry: %u).", step.script->GetDebugInfo().c_str(), step.script->TempSummonCreature.CreatureEntry); } } break; } case SCRIPT_COMMAND_OPEN_DOOR: case SCRIPT_COMMAND_CLOSE_DOOR: _ScriptProcessDoor(source, target, step.script); break; case SCRIPT_COMMAND_ACTIVATE_OBJECT: // Source must be Unit. if (Unit* unit = _GetScriptUnit(source, true, step.script)) { // Target must be GameObject. if (!target) { sLog->outError("%s target object is NULL.", step.script->GetDebugInfo().c_str()); break; } if (target->GetTypeId() != TYPEID_GAMEOBJECT) { sLog->outError("%s target object is not gameobject (TypeId: %u, Entry: %u, GUID: %u), skipping.", step.script->GetDebugInfo().c_str(), target->GetTypeId(), target->GetEntry(), target->GetGUIDLow()); break; } if (GameObject* pGO = target->ToGameObject()) pGO->Use(unit); } break; case SCRIPT_COMMAND_REMOVE_AURA: { // Source (datalong2 != 0) or target (datalong2 == 0) must be Unit. bool bReverse = step.script->RemoveAura.Flags & SF_REMOVEAURA_REVERSE; if (Unit* unit = _GetScriptUnit(bReverse ? source : target, bReverse, step.script)) unit->RemoveAurasDueToSpell(step.script->RemoveAura.SpellID); break; } case SCRIPT_COMMAND_CAST_SPELL: { // TODO: Allow gameobjects to be targets and casters if (!source && !target) { sLog->outError("%s source and target objects are NULL.", step.script->GetDebugInfo().c_str()); break; } Unit* uSource = NULL; Unit* uTarget = NULL; // source/target cast spell at target/source (script->datalong2: 0: s->t 1: s->s 2: t->t 3: t->s switch (step.script->CastSpell.Flags) { case SF_CASTSPELL_SOURCE_TO_TARGET: // source -> target uSource = source ? source->ToUnit() : NULL; uTarget = target ? target->ToUnit() : NULL; break; case SF_CASTSPELL_SOURCE_TO_SOURCE: // source -> source uSource = source ? source->ToUnit() : NULL; uTarget = uSource; break; case SF_CASTSPELL_TARGET_TO_TARGET: // target -> target uSource = target ? target->ToUnit() : NULL; uTarget = uSource; break; case SF_CASTSPELL_TARGET_TO_SOURCE: // target -> source uSource = target ? target->ToUnit() : NULL; uTarget = source ? source->ToUnit() : NULL; break; case SF_CASTSPELL_SEARCH_CREATURE: // source -> creature with entry uSource = source ? source->ToUnit() : NULL; uTarget = uSource ? GetClosestCreatureWithEntry(uSource, abs(step.script->CastSpell.CreatureEntry), step.script->CastSpell.SearchRadius) : NULL; break; } if (!uSource || !uSource->isType(TYPEMASK_UNIT)) { sLog->outError("%s no source unit found for spell %u", step.script->GetDebugInfo().c_str(), step.script->CastSpell.SpellID); break; } if (!uTarget || !uTarget->isType(TYPEMASK_UNIT)) { sLog->outError("%s no target unit found for spell %u", step.script->GetDebugInfo().c_str(), step.script->CastSpell.SpellID); break; } bool triggered = (step.script->CastSpell.Flags != 4) ? step.script->CastSpell.CreatureEntry & SF_CASTSPELL_TRIGGERED : step.script->CastSpell.CreatureEntry < 0; uSource->CastSpell(uTarget, step.script->CastSpell.SpellID, triggered); break; } case SCRIPT_COMMAND_PLAY_SOUND: // Source must be WorldObject. if (WorldObject* object = _GetScriptWorldObject(source, true, step.script)) { // PlaySound.Flags bitmask: 0/1=anyone/target Player* player = NULL; if (step.script->PlaySound.Flags & SF_PLAYSOUND_TARGET_PLAYER) { // Target must be Player. player = _GetScriptPlayer(target, false, step.script); if (!target) break; } // PlaySound.Flags bitmask: 0/2=without/with distance dependent if (step.script->PlaySound.Flags & SF_PLAYSOUND_DISTANCE_SOUND) object->PlayDistanceSound(step.script->PlaySound.SoundID, player); else object->PlayDirectSound(step.script->PlaySound.SoundID, player); } break; case SCRIPT_COMMAND_CREATE_ITEM: // Target or source must be Player. if (Player* pReceiver = _GetScriptPlayerSourceOrTarget(source, target, step.script)) { ItemPosCountVec dest; InventoryResult msg = pReceiver->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, step.script->CreateItem.ItemEntry, step.script->CreateItem.Amount); if (msg == EQUIP_ERR_OK) { if (Item* item = pReceiver->StoreNewItem(dest, step.script->CreateItem.ItemEntry, true)) pReceiver->SendNewItem(item, step.script->CreateItem.Amount, false, true); } else pReceiver->SendEquipError(msg, NULL, NULL, step.script->CreateItem.ItemEntry); } break; case SCRIPT_COMMAND_DESPAWN_SELF: // Target or source must be Creature. if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script, true)) cSource->DespawnOrUnsummon(step.script->DespawnSelf.DespawnDelay); break; case SCRIPT_COMMAND_LOAD_PATH: // Source must be Unit. if (Unit* unit = _GetScriptUnit(source, true, step.script)) { if (!sWaypointMgr->GetPath(step.script->LoadPath.PathID)) sLog->outError("%s source object has an invalid path (%u), skipping.", step.script->GetDebugInfo().c_str(), step.script->LoadPath.PathID); else unit->GetMotionMaster()->MovePath(step.script->LoadPath.PathID, step.script->LoadPath.IsRepeatable); } break; case SCRIPT_COMMAND_CALLSCRIPT_TO_UNIT: { if (!step.script->CallScript.CreatureEntry) { sLog->outError("%s creature entry is not specified, skipping.", step.script->GetDebugInfo().c_str()); break; } if (!step.script->CallScript.ScriptID) { sLog->outError("%s script id is not specified, skipping.", step.script->GetDebugInfo().c_str()); break; } Creature* cTarget = NULL; WorldObject* wSource = dynamic_cast <WorldObject*> (source); if (wSource) //using grid searcher { CellCoord p(Trinity::ComputeCellCoord(wSource->GetPositionX(), wSource->GetPositionY())); Cell cell(p); Trinity::CreatureWithDbGUIDCheck target_check(wSource, step.script->CallScript.CreatureEntry); Trinity::CreatureSearcher<Trinity::CreatureWithDbGUIDCheck> checker(wSource, cTarget, target_check); TypeContainerVisitor<Trinity::CreatureSearcher <Trinity::CreatureWithDbGUIDCheck>, GridTypeMapContainer > unit_checker(checker); cell.Visit(p, unit_checker, *wSource->GetMap(), *wSource, wSource->GetGridActivationRange()); } else //check hashmap holders { if (CreatureData const* data = sObjectMgr->GetCreatureData(step.script->CallScript.CreatureEntry)) cTarget = ObjectAccessor::GetObjectInWorld<Creature>(data->mapid, data->posX, data->posY, MAKE_NEW_GUID(step.script->CallScript.CreatureEntry, data->id, HIGHGUID_UNIT), cTarget); } if (!cTarget) { sLog->outError("%s target was not found (entry: %u)", step.script->GetDebugInfo().c_str(), step.script->CallScript.CreatureEntry); break; } //Lets choose our ScriptMap map ScriptMapMap* datamap = GetScriptsMapByType(ScriptsType(step.script->CallScript.ScriptType)); //if no scriptmap present... if (!datamap) { sLog->outError("%s unknown scriptmap (%u) specified, skipping.", step.script->GetDebugInfo().c_str(), step.script->CallScript.ScriptType); break; } // Insert script into schedule but do not start it ScriptsStart(*datamap, step.script->CallScript.ScriptID, cTarget, NULL); break; } case SCRIPT_COMMAND_KILL: // Source or target must be Creature. if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script)) { if (cSource->isDead()) sLog->outError("%s creature is already dead (Entry: %u, GUID: %u)", step.script->GetDebugInfo().c_str(), cSource->GetEntry(), cSource->GetGUIDLow()); else { cSource->setDeathState(JUST_DIED); if (step.script->Kill.RemoveCorpse == 1) cSource->RemoveCorpse(); } } break; case SCRIPT_COMMAND_ORIENTATION: // Source must be Unit. if (Unit* sourceUnit = _GetScriptUnit(source, true, step.script)) { if (step.script->Orientation.Flags & SF_ORIENTATION_FACE_TARGET) { // Target must be Unit. Unit* targetUnit = _GetScriptUnit(target, false, step.script); if (!targetUnit) break; sourceUnit->SetFacingToObject(targetUnit); } else sourceUnit->SetFacingTo(step.script->Orientation.Orientation); } break; case SCRIPT_COMMAND_EQUIP: // Source must be Creature. if (Creature* cSource = _GetScriptCreature(source, true, step.script)) cSource->LoadEquipment(step.script->Equip.EquipmentID); break; case SCRIPT_COMMAND_MODEL: // Source must be Creature. if (Creature* cSource = _GetScriptCreature(source, true, step.script)) cSource->SetDisplayId(step.script->Model.ModelID); break; case SCRIPT_COMMAND_CLOSE_GOSSIP: // Source must be Player. if (Player* player = _GetScriptPlayer(source, true, step.script)) player->PlayerTalkClass->SendCloseGossip(); break; case SCRIPT_COMMAND_PLAYMOVIE: // Source must be Player. if (Player* player = _GetScriptPlayer(source, true, step.script)) player->SendMovieStart(step.script->PlayMovie.MovieID); break; default: sLog->outError("Unknown script command %s.", step.script->GetDebugInfo().c_str()); break; } m_scriptSchedule.erase(iter); iter = m_scriptSchedule.begin(); sScriptMgr->DecreaseScheduledScriptCount(); } }
void HandleDummy(SpellEffIndex /*effIndex*/) { uint32 roll = urand(1, 100); uint8 ev; if (roll <= 50) ev = EVENT_MISS; else if (roll <= 83) ev = EVENT_HIT; else ev = EVENT_MISS_BIRD; Unit* shooter = GetCaster(); Creature* wilhelm = GetHitUnit()->ToCreature(); Creature* apple = shooter->FindNearestCreature(NPC_APPLE, 30); Creature* drostan = shooter->FindNearestCreature(NPC_DROSTAN, 30); if (!wilhelm || !apple || !drostan) return; switch (ev) { case EVENT_MISS_BIRD: { Creature* crunchy = shooter->FindNearestCreature(NPC_CRUNCHY, 30); Creature* bird = shooter->FindNearestCreature(NPC_THICKBIRD, 30); if (!bird || !crunchy) ; // fall to EVENT_MISS else { shooter->CastSpell(bird, SPELL_MISS_BIRD_APPLE); bird->CastSpell(bird, SPELL_BIRD_FALL); wilhelm->AI()->Talk(SAY_WILHELM_MISS); drostan->AI()->Talk(SAY_DROSTAN_REPLY_MISS); bird->Kill(bird); crunchy->GetMotionMaster()->MovePoint(0, bird->GetPositionX(), bird->GetPositionY(), bird->GetMap()->GetWaterOrGroundLevel(bird->GetPositionX(), bird->GetPositionY(), bird->GetPositionZ())); /// @todo Make crunchy perform emote eat when he reaches the bird break; } } case EVENT_MISS: { shooter->CastSpell(wilhelm, SPELL_MISS_APPLE); wilhelm->AI()->Talk(SAY_WILHELM_MISS); drostan->AI()->Talk(SAY_DROSTAN_REPLY_MISS); break; } case EVENT_HIT: { shooter->CastSpell(apple, SPELL_HIT_APPLE); apple->CastSpell(apple, SPELL_APPLE_FALL); wilhelm->AI()->Talk(SAY_WILHELM_HIT); if (Player* player = shooter->ToPlayer()) player->KilledMonsterCredit(NPC_APPLE); apple->DespawnOrUnsummon(); break; } } }
void WorldSession::HandleSpellClick(WorldPacket& recvPacket) { LOG_DETAIL("WORLD: got CMSG_SPELLCLICK packet, data length = %i", recvPacket.size()); if (_player->getDeathState() == CORPSE) return; uint64_t unitGuid; // this will store the guid of the object we are going to use it's spell. There must be a dbc that indicates what spells a unit has recvPacket >> unitGuid; //we have only 1 example atm for entry : 28605 Unit* unitTarget = _player->GetMapMgr()->GetUnit(unitGuid); if (!unitTarget) return; if (!_player->isInRange(unitTarget, MAX_INTERACTION_RANGE)) return; if (unitTarget->isVehicle()) { if (unitTarget->GetVehicleComponent() != nullptr) unitTarget->GetVehicleComponent()->AddPassenger(_player); return; } uint32_t creature_id = unitTarget->getEntry(); uint32_t cast_spell_id = 0; if (unitTarget->RemoveAura(59907)) { uint32 lightwellRenew[] = { //SPELL_HASH_LIGHTWELL_RENEW 7001, 27873, 27874, 28276, 48084, 48085, 60123, 0 }; if (!_player->hasAurasWithId(lightwellRenew)) { SpellClickSpell const* sp = sMySQLStore.getSpellClickSpell(creature_id); if (sp == nullptr) { if (unitTarget->isCreature()) { Creature* c = static_cast<Creature*>(unitTarget); sChatHandler.BlueSystemMessage(this, "NPC Id %u (%s) has no spellclick spell associated with it.", c->GetCreatureProperties()->Id, c->GetCreatureProperties()->Name.c_str()); LOG_ERROR("Spellclick packet received for creature %u but there is no spell associated with it.", creature_id); return; } } else { cast_spell_id = sp->SpellID; unitTarget->CastSpell(_player, cast_spell_id, true); } if (!unitTarget->HasAura(59907)) static_cast<Creature*>(unitTarget)->Despawn(0, 0); //IsCreature() check is not needed, refer to r2387 and r3230 return; } } SpellClickSpell const* sp = sMySQLStore.getSpellClickSpell(creature_id); if (sp == nullptr) { if (unitTarget->isCreature()) { Creature* c = static_cast< Creature* >(unitTarget); sChatHandler.BlueSystemMessage(this, "NPC Id %u (%s) has no spellclick spell associated with it.", c->GetCreatureProperties()->Id, c->GetCreatureProperties()->Name.c_str()); LOG_ERROR("Spellclick packet received for creature %u but there is no spell associated with it.", creature_id); return; } } else { cast_spell_id = sp->SpellID; SpellInfo* spellInfo = sSpellCustomizations.GetSpellInfo(cast_spell_id); if (spellInfo == nullptr) return; Spell* spell = sSpellFactoryMgr.NewSpell(_player, spellInfo, false, nullptr); SpellCastTargets targets(unitGuid); spell->prepare(&targets); } }
void boss_kalecgos::boss_kalecgosAI::UpdateAI(const uint32 diff) { if(TalkTimer) { if(!TalkSequence) { me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE); me->InterruptNonMeleeSpells(true); me->RemoveAllAuras(); me->DeleteThreatList(); me->CombatStop(); TalkSequence++; if(pInstance) { pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_FORECEFIELD_COLL_1),true); pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_FORECEFIELD_COLL_2),true); } } if(TalkTimer <= diff) { if(isFriendly) GoodEnding(); else BadEnding(); TalkSequence++; }else TalkTimer -= diff; } else { if (!UpdateVictim()) return; if(!doorClosed) { if(Close_Timer <= diff) { if(pInstance) { pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_FORECEFIELD_COLL_1),false); pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_FORECEFIELD_COLL_2),false); doorClosed = true; } Close_Timer = 10000; }else Close_Timer -= diff; } if(ResetThreat <= diff) { if ( ( me->getVictim()->HasAuraEffect(AURA_SPECTRAL_REALM,0)) && (me->getVictim()->GetTypeId() == TYPEID_PLAYER) ) { for(std::list<HostileReference*>::iterator itr = me->getThreatManager().getThreatList().begin(); itr != me->getThreatManager().getThreatList().end(); ++itr) { if(((*itr)->getUnitGuid()) == (me->getVictim()->GetGUID())) { (*itr)->removeReference(); break; } } } if(me->getVictim() && (me->getVictim()->HasAuraEffect(AURA_SPECTRAL_REALM,0) || me->GetPositionZ() < DRAGON_REALM_Z-10)) me->getThreatManager().modifyThreatPercent(me->getVictim(), -100); ResetThreat = 1000; }else ResetThreat -= diff; if(CheckTimer <= diff) { if (((me->GetHealth()*100 / me->GetMaxHealth()) < 10) && !isEnraged) { Unit* Sath = Unit::GetUnit(*me, SathGUID); if(Sath) { Sath->CastSpell(Sath, SPELL_ENRAGE, true); CAST_AI(boss_sathrovarr::boss_sathrovarrAI,((Creature*)Sath)->AI())->isEnraged = true; } DoCast(me, SPELL_ENRAGE, true); isEnraged = true; } if(!isBanished && (me->GetHealth()*100)/me->GetMaxHealth() < 1) { if(Unit *Sath = Unit::GetUnit(*me, SathGUID)) { if(CAST_AI(boss_sathrovarr::boss_sathrovarrAI,((Creature*)Sath)->AI())->isBanished) { Sath->DealDamage(Sath, Sath->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); return; } else { DoCast(me, SPELL_BANISH); isBanished = true; } } else { sLog->outError("TSCR: Didn't find Shathrowar. Kalecgos event reseted."); EnterEvadeMode(); return; } } CheckTimer = 1000; }else CheckTimer -= diff; if(ArcaneBuffetTimer <= diff) { if(TryDoCastAOE(SPELL_ARCANE_BUFFET)) ArcaneBuffetTimer = 8000; }else ArcaneBuffetTimer -= diff; if(FrostBreathTimer <= diff) { if(TryDoCastAOE(SPELL_FROST_BREATH)) FrostBreathTimer = 15000; }else FrostBreathTimer -= diff; if(TailLashTimer <= diff) { if(TryDoCastAOE(SPELL_TAIL_LASH)) TailLashTimer = 15000; }else TailLashTimer -= diff; if(WildMagicTimer <= diff) { if(TryDoCastAOE(WildMagic[rand()%6])) WildMagicTimer = 20000; }else WildMagicTimer -= diff; if(SpectralBlastTimer <= diff) { //this is a hack. we need to find a victim without aura in core Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true); if( target && target->isAlive() && !(target->HasAuraEffect(AURA_SPECTRAL_EXHAUSTION, 0)) ) { if(TryDoCast(target, SPELL_SPECTRAL_BLAST)) SpectralBlastTimer = 20000+(rand()%5000); } else { SpectralBlastTimer = 1000; } }else SpectralBlastTimer -= diff; DoMeleeAttackIfReady(); } };
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if(CheckTimer <= diff) { if (((me->GetHealth()*100 / me->GetMaxHealth()) < 10) && !isEnraged) { Unit* Kalecgos = Unit::GetUnit(*me, KalecgosGUID); if(Kalecgos) { Kalecgos->CastSpell(Kalecgos, SPELL_ENRAGE, true); CAST_AI(boss_kalecgos::boss_kalecgosAI,((Creature*)Kalecgos)->AI())->isEnraged = true; } DoCast(me, SPELL_ENRAGE, true); isEnraged = true; } if(!isBanished && (me->GetHealth()*100)/me->GetMaxHealth() < 1) { if(Unit *Kalecgos = Unit::GetUnit(*me, KalecgosGUID)) { if(CAST_AI(boss_kalecgos::boss_kalecgosAI,((Creature*)Kalecgos)->AI())->isBanished) { me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); return; } else { DoCast(me, SPELL_BANISH); isBanished = true; } } else { sLog->outError("Sathrovarr is unable to find Kalecgos"); EnterEvadeMode(); return; } } CheckTimer = 1000; }else CheckTimer -= diff; if(ResetThreat <= diff) { if ( ( me->getVictim()->HasAuraEffect(AURA_SPECTRAL_EXHAUSTION,0)) && (me->getVictim()->GetTypeId() == TYPEID_PLAYER) ) { for(std::list<HostileReference*>::iterator itr = me->getThreatManager().getThreatList().begin(); itr != me->getThreatManager().getThreatList().end(); ++itr) { if(((*itr)->getUnitGuid()) == (me->getVictim()->GetGUID())) { (*itr)->removeReference(); break; } } } ResetThreat = 1000; }else ResetThreat -= diff; if(ShadowBoltTimer <= diff) { if(TryDoCast(me, SPELL_SHADOW_BOLT)) { DoScriptText(SAY_SATH_SPELL1, me); ShadowBoltTimer = 7000+(rand()%3000); } }else ShadowBoltTimer -= diff; if(AgonyCurseTimer <= diff) { Unit *ptarget = SelectTarget(SELECT_TARGET_RANDOM, 0); if(!ptarget) ptarget = me->getVictim(); if(TryDoCast(ptarget, SPELL_AGONY_CURSE)) AgonyCurseTimer = 20000; }else AgonyCurseTimer -= diff; if(CorruptionStrikeTimer <= diff) { if(TryDoCast(me->getVictim(), SPELL_CORRUPTION_STRIKE)) { DoScriptText(SAY_SATH_SPELL2, me); CorruptionStrikeTimer = 13000; } }else CorruptionStrikeTimer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { //Return since we have no target if (!UpdateVictim()) return; // Growth // Gruul can cast this spell up to 30 times if (Growth_Timer <= diff) { DoCast(me,SPELL_GROWTH); DoScriptText(EMOTE_GROW, me); Growth_Timer = 30000; } else Growth_Timer -= diff; if (PerformingGroundSlam) { if (GroundSlamTimer <= diff) { switch (GroundSlamStage) { case 0: { //Begin the whole ordeal std::list<HostileReference*>& m_threatlist = me->getThreatManager().getThreatList(); std::vector<Unit*> knockback_targets; //First limit the list to only players for (std::list<HostileReference*>::iterator itr = m_threatlist.begin(); itr != m_threatlist.end(); ++itr) { Unit* pTarget = Unit::GetUnit(*me, (*itr)->getUnitGuid()); if (pTarget && pTarget->GetTypeId() == TYPEID_PLAYER) knockback_targets.push_back(pTarget); } //Now to totally disoriend those players for (std::vector<Unit*>::iterator itr = knockback_targets.begin(); itr != knockback_targets.end(); ++itr) { Unit* target = *itr; Unit* target2 = *(knockback_targets.begin() + rand()%knockback_targets.size()); if (target && target2) { switch (rand()%2) { case 0: target2->CastSpell(target, SPELL_MAGNETIC_PULL, true, NULL, NULL, me->GetGUID()); break; case 1: target2->CastSpell(target, SPELL_KNOCK_BACK, true, NULL, NULL, me->GetGUID()); break; } } } GroundSlamTimer = 7000; break; } case 1: { //Players are going to get stoned std::list<HostileReference*>& m_threatlist = me->getThreatManager().getThreatList(); for (std::list<HostileReference*>::iterator itr = m_threatlist.begin(); itr != m_threatlist.end(); ++itr) { Unit* pTarget = Unit::GetUnit(*me, (*itr)->getUnitGuid()); if (pTarget) { pTarget->RemoveAurasDueToSpell(SPELL_GRONN_LORDS_GRASP); pTarget->CastSpell(pTarget, SPELL_STONED, true, NULL, NULL, me->GetGUID()); } } GroundSlamTimer = 5000; break; } case 2: { DoCast(me, SPELL_SHATTER); GroundSlamTimer = 1000; break; } case 3: { //Shatter takes effect // Not Needet Anymore Handled in Spell SPELL_SHATTER //std::list<HostileReference*>& m_threatlist = me->getThreatManager().getThreatList(); //for (std::list<HostileReference*>::iterator itr = m_threatlist.begin(); itr != m_threatlist.end(); ++itr) //{ // Unit* target = Unit::GetUnit(*me, (*itr)->getUnitGuid()); // if (target) // { // target->RemoveAurasDueToSpell(SPELL_STONED); // if (target->GetTypeId() == TYPEID_PLAYER) // target->CastSpell(target, SPELL_SHATTER_EFFECT, false, NULL, NULL, me->GetGUID()); // } //} me->GetMotionMaster()->Clear(); Unit* victim = me->getVictim(); if (victim) { me->GetMotionMaster()->MoveChase(victim); me->SetUInt64Value(UNIT_FIELD_TARGET, victim->GetGUID()); } PerformingGroundSlam = false; GroundSlamTimer =120000; HurtfulStrike_Timer= 8000; if (Reverberation_Timer < 10000) //Give a little time to the players to undo the damage from shatter Reverberation_Timer += 10000; break; } } GroundSlamStage++; } else GroundSlamTimer-=diff; } else { // Hurtful Strike if (HurtfulStrike_Timer <= diff) { Unit* pTarget = NULL; pTarget = SelectUnit(SELECT_TARGET_TOPAGGRO,1); if (pTarget && me->IsWithinMeleeRange(me->getVictim())) DoCast(pTarget,SPELL_HURTFUL_STRIKE); else DoCast(me->getVictim(),SPELL_HURTFUL_STRIKE); HurtfulStrike_Timer= 8000; } else HurtfulStrike_Timer -= diff; // Reverberation if (Reverberation_Timer <= diff) { DoCast(me->getVictim(), SPELL_REVERBERATION, true); Reverberation_Timer = 30000; } else Reverberation_Timer -= diff; // Cave In if (CaveIn_Timer <= diff) { if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,0)) DoCast(pTarget,SPELL_CAVE_IN); CaveIn_Timer = 20000; } else CaveIn_Timer -= diff; // Ground Slam, Gronn Lord's Grasp, Stoned, Shatter if (GroundSlamTimer <= diff) { me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MoveIdle(); me->SetUInt64Value(UNIT_FIELD_TARGET, 0); PerformingGroundSlam= true; GroundSlamTimer = 0; GroundSlamStage = 0; DoCast(me->getVictim(), SPELL_GROUND_SLAM); } else GroundSlamTimer -=diff; DoMeleeAttackIfReady(); } }
void UpdateAI(uint32 diff) override { if (!UpdateVictim()) return; if (CloseDoorTimer) { if (CloseDoorTimer <= diff) { instance->HandleGameObject(instance->GetData64(DATA_GO_LIBRARY_DOOR), false); CloseDoorTimer = 0; } else CloseDoorTimer -= diff; } //Cooldowns for casts if (ArcaneCooldown) { if (ArcaneCooldown >= diff) ArcaneCooldown -= diff; else ArcaneCooldown = 0; } if (FireCooldown) { if (FireCooldown >= diff) FireCooldown -= diff; else FireCooldown = 0; } if (FrostCooldown) { if (FrostCooldown >= diff) FrostCooldown -= diff; else FrostCooldown = 0; } if (!Drinking && me->GetMaxPower(POWER_MANA) && (me->GetPower(POWER_MANA)*100 / me->GetMaxPower(POWER_MANA)) < 20) { Drinking = true; me->InterruptNonMeleeSpells(false); Talk(SAY_DRINK); if (!DrinkInturrupted) { DoCast(me, SPELL_MASS_POLY, true); DoCast(me, SPELL_CONJURE, false); DoCast(me, SPELL_DRINK, false); me->SetStandState(UNIT_STAND_STATE_SIT); DrinkInterruptTimer = 10000; } } //Drink Interrupt if (Drinking && DrinkInturrupted) { Drinking = false; me->RemoveAurasDueToSpell(SPELL_DRINK); me->SetStandState(UNIT_STAND_STATE_STAND); me->SetPower(POWER_MANA, me->GetMaxPower(POWER_MANA)-32000); DoCast(me, SPELL_POTION, false); } //Drink Interrupt Timer if (Drinking && !DrinkInturrupted) { if (DrinkInterruptTimer >= diff) DrinkInterruptTimer -= diff; else { me->SetStandState(UNIT_STAND_STATE_STAND); DoCast(me, SPELL_POTION, true); DoCast(me, SPELL_AOE_PYROBLAST, false); DrinkInturrupted = true; Drinking = false; } } //Don't execute any more code if we are drinking if (Drinking) return; //Normal casts if (NormalCastTimer <= diff) { if (!me->IsNonMeleeSpellCast(false)) { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); if (!target) return; uint32 Spells[3]; uint8 AvailableSpells = 0; //Check for what spells are not on cooldown if (!ArcaneCooldown) { Spells[AvailableSpells] = SPELL_ARCMISSLE; ++AvailableSpells; } if (!FireCooldown) { Spells[AvailableSpells] = SPELL_FIREBALL; ++AvailableSpells; } if (!FrostCooldown) { Spells[AvailableSpells] = SPELL_FROSTBOLT; ++AvailableSpells; } //If no available spells wait 1 second and try again if (AvailableSpells) { CurrentNormalSpell = Spells[rand() % AvailableSpells]; DoCast(target, CurrentNormalSpell); } } NormalCastTimer = 1000; } else NormalCastTimer -= diff; if (SecondarySpellTimer <= diff) { switch (urand(0, 1)) { case 0: DoCast(me, SPELL_AOE_CS); break; case 1: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) DoCast(target, SPELL_CHAINSOFICE); break; } SecondarySpellTimer = urand(5000, 20000); } else SecondarySpellTimer -= diff; if (SuperCastTimer <= diff) { uint8 Available[2]; switch (LastSuperSpell) { case SUPER_AE: Available[0] = SUPER_FLAME; Available[1] = SUPER_BLIZZARD; break; case SUPER_FLAME: Available[0] = SUPER_AE; Available[1] = SUPER_BLIZZARD; break; case SUPER_BLIZZARD: Available[0] = SUPER_FLAME; Available[1] = SUPER_AE; break; } LastSuperSpell = Available[urand(0, 1)]; switch (LastSuperSpell) { case SUPER_AE: Talk(SAY_EXPLOSION); DoCast(me, SPELL_BLINK_CENTER, true); DoCast(me, SPELL_PLAYERPULL, true); DoCast(me, SPELL_MASSSLOW, true); DoCast(me, SPELL_AEXPLOSION, false); break; case SUPER_FLAME: Talk(SAY_FLAMEWREATH); FlameWreathTimer = 20000; FlameWreathCheckTime = 500; FlameWreathTarget[0] = 0; FlameWreathTarget[1] = 0; FlameWreathTarget[2] = 0; FlameWreathEffect(); break; case SUPER_BLIZZARD: Talk(SAY_BLIZZARD); if (Creature* pSpawn = me->SummonCreature(CREATURE_ARAN_BLIZZARD, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 25000)) { pSpawn->setFaction(me->getFaction()); pSpawn->CastSpell(pSpawn, SPELL_CIRCULAR_BLIZZARD, false); } break; } SuperCastTimer = urand(35000, 40000); } else SuperCastTimer -= diff; if (!ElementalsSpawned && HealthBelowPct(40)) { ElementalsSpawned = true; for (uint32 i = 0; i < 4; ++i) { if (Creature* unit = me->SummonCreature(CREATURE_WATER_ELEMENTAL, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 90000)) { unit->Attack(me->GetVictim(), true); unit->setFaction(me->getFaction()); } } Talk(SAY_ELEMENTALS); } if (BerserkTimer <= diff) { for (uint32 i = 0; i < 5; ++i) { if (Creature* unit = me->SummonCreature(CREATURE_SHADOW_OF_ARAN, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000)) { unit->Attack(me->GetVictim(), true); unit->setFaction(me->getFaction()); } } Talk(SAY_TIMEOVER); BerserkTimer = 60000; } else BerserkTimer -= diff; //Flame Wreath check if (FlameWreathTimer) { if (FlameWreathTimer >= diff) FlameWreathTimer -= diff; else FlameWreathTimer = 0; if (FlameWreathCheckTime <= diff) { for (uint8 i = 0; i < 3; ++i) { if (!FlameWreathTarget[i]) continue; Unit* unit = ObjectAccessor::GetUnit(*me, FlameWreathTarget[i]); if (unit && !unit->IsWithinDist2d(FWTargPosX[i], FWTargPosY[i], 3)) { unit->CastSpell(unit, 20476, true, 0, 0, me->GetGUID()); unit->CastSpell(unit, 11027, true); FlameWreathTarget[i] = 0; } } FlameWreathCheckTime = 500; } else FlameWreathCheckTime -= diff; } if (ArcaneCooldown && FireCooldown && FrostCooldown) DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; //Shimmer_Timer Timer if (Shimmer_Timer < diff) { //Remove old vurlnability spell if (CurrentVurln_Spell) m_creature->RemoveAurasDueToSpell(CurrentVurln_Spell); //Cast new random vurlnabilty on self uint32 spell; switch(urand(0, 4)) { case 0: spell = SPELL_FIRE_VURNALBILTY; break; case 1: spell = SPELL_FROST_VURNALBILTY; break; case 2: spell = SPELL_SHADOW_VURNALBILTY; break; case 3: spell = SPELL_NATURE_VURNALBILTY; break; case 4: spell = SPELL_ARCANE_VURNALBILTY; break; } if (DoCastSpellIfCan(m_creature, spell) == CAST_OK) { CurrentVurln_Spell = spell; DoScriptText(EMOTE_SHIMMER, m_creature); Shimmer_Timer = 45000; } }else Shimmer_Timer -= diff; //Breath1_Timer if (Breath1_Timer < diff) { DoCastSpellIfCan(m_creature->getVictim(),Breath1_Spell); Breath1_Timer = 60000; }else Breath1_Timer -= diff; //Breath2_Timer if (Breath2_Timer < diff) { DoCastSpellIfCan(m_creature->getVictim(),Breath2_Spell); Breath2_Timer = 60000; }else Breath2_Timer -= diff; //Affliction_Timer if (Affliction_Timer < diff) { uint32 SpellAfflict = 0; switch(urand(0, 4)) { case 0: SpellAfflict = SPELL_BROODAF_BLUE; break; case 1: SpellAfflict = SPELL_BROODAF_BLACK; break; case 2: SpellAfflict = SPELL_BROODAF_RED; break; case 3: SpellAfflict = SPELL_BROODAF_BRONZE; break; case 4: SpellAfflict = SPELL_BROODAF_GREEN; break; } ThreatList const& tList = m_creature->getThreatManager().getThreatList(); for (ThreatList::const_iterator i = tList.begin();i != tList.end(); ++i) { Unit* pUnit = NULL; pUnit = m_creature->GetMap()->GetUnit( (*i)->getUnitGuid()); if (pUnit) { //Cast affliction DoCastSpellIfCan(pUnit, SpellAfflict, true); //Chromatic mutation if target is effected by all afflictions if (pUnit->HasAura(SPELL_BROODAF_BLUE, EFFECT_INDEX_0) && pUnit->HasAura(SPELL_BROODAF_BLACK, EFFECT_INDEX_0) && pUnit->HasAura(SPELL_BROODAF_RED, EFFECT_INDEX_0) && pUnit->HasAura(SPELL_BROODAF_BRONZE, EFFECT_INDEX_0) && pUnit->HasAura(SPELL_BROODAF_GREEN, EFFECT_INDEX_0)) { //target->RemoveAllAuras(); //DoCastSpellIfCan(target,SPELL_CHROMATIC_MUT_1); //Chromatic mutation is causing issues //Assuming it is caused by a lack of core support for Charm //So instead we instant kill our target //WORKAROUND if (pUnit->GetTypeId() == TYPEID_PLAYER) pUnit->CastSpell(pUnit, 5, false); } } } Affliction_Timer = 10000; }else Affliction_Timer -= diff; //Frenzy_Timer if (Frenzy_Timer < diff) { if (DoCastSpellIfCan(m_creature,SPELL_FRENZY) == CAST_OK) { DoScriptText(EMOTE_GENERIC_FRENZY_KILL, m_creature); Frenzy_Timer = urand(10000, 15000); } }else Frenzy_Timer -= diff; //Enrage if not already enraged and below 20% if (!Enraged && m_creature->GetHealthPercent() < 20.0f) { DoCastSpellIfCan(m_creature,SPELL_ENRAGE); Enraged = true; } DoMeleeAttackIfReady(); }
void UpdateAI(uint32 diff) { if (!UpdateVictim()) return; if (ResetTimer <= diff) { if (me->IsWithinDist3d(119.223f, 1035.45f, 29.4481f, 10)) { EnterEvadeMode(); return; } ResetTimer = 5000; } else ResetTimer -= diff; if (CheckAddState_Timer <= diff) { for (uint8 i = 0; i < 4; ++i) if (Creature* temp = Unit::GetCreature(*me, AddGUID[i])) if (temp->IsAlive() && !temp->GetVictim()) temp->AI()->AttackStart(me->GetVictim()); CheckAddState_Timer = 5000; } else CheckAddState_Timer -= diff; if (DrainPower_Timer <= diff) { DoCast(me, SPELL_DRAIN_POWER, true); me->MonsterYell(YELL_DRAIN_POWER, LANG_UNIVERSAL, 0); DoPlaySoundToSet(me, SOUND_YELL_DRAIN_POWER); DrainPower_Timer = urand(40000, 55000); // must cast in 60 sec, or buff/debuff will disappear } else DrainPower_Timer -= diff; if (SpiritBolts_Timer <= diff) { if (DrainPower_Timer < 12000) // channel 10 sec SpiritBolts_Timer = 13000; // cast drain power first else { DoCast(me, SPELL_SPIRIT_BOLTS, false); me->MonsterYell(YELL_SPIRIT_BOLTS, LANG_UNIVERSAL, 0); DoPlaySoundToSet(me, SOUND_YELL_SPIRIT_BOLTS); SpiritBolts_Timer = 40000; SiphonSoul_Timer = 10000; // ready to drain PlayerAbility_Timer = 99999; } } else SpiritBolts_Timer -= diff; if (SiphonSoul_Timer <= diff) { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 70, true); Unit* trigger = DoSpawnCreature(MOB_TEMP_TRIGGER, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 30000); if (!target || !trigger) { EnterEvadeMode(); return; } else { trigger->SetDisplayId(11686); trigger->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); trigger->CastSpell(target, SPELL_SIPHON_SOUL, true); trigger->GetMotionMaster()->MoveChase(me); //DoCast(target, SPELL_SIPHON_SOUL, true); //me->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, target->GetGUID()); //me->SetUInt32Value(UNIT_CHANNEL_SPELL, SPELL_SIPHON_SOUL); PlayerGUID = target->GetGUID(); PlayerAbility_Timer = urand(8000, 10000); PlayerClass = target->getClass() - 1; if (PlayerClass == CLASS_DRUID-1) PlayerClass = CLASS_DRUID; else if (PlayerClass == CLASS_PRIEST-1 && target->HasSpell(15473)) PlayerClass = CLASS_PRIEST; // shadow priest SiphonSoul_Timer = 99999; // buff lasts 30 sec } } else SiphonSoul_Timer -= diff; if (PlayerAbility_Timer <= diff) { //Unit* target = Unit::GetUnit(*me, PlayerGUID); //if (target && target->IsAlive()) //{ UseAbility(); PlayerAbility_Timer = urand(8000, 10000); //} } else PlayerAbility_Timer -= diff; DoMeleeAttackIfReady(); }
void HandleScriptEffect(SpellEffIndex /*effIndex*/) { Unit* caster = GetCaster(); caster->CastSpell(caster, RAND(SUMMON_ANGRY_KVALDIR, SUMMON_NORTH_SEA_MAKO, SUMMON_NORTH_SEA_THRESHER, SUMMON_NORTH_SEA_BLUE_SHARK)); }
void HandleAnimation() { Player* plr = Unit::GetPlayer(*me, PlayerGUID); if (!plr) return; Unit* Fandral = plr->FindNearestCreature(C_FANDRAL_STAGHELM, 100, me); Unit* Arygos = plr->FindNearestCreature(C_ARYGOS, 100, me); Unit* Caelestrasz = plr->FindNearestCreature(C_CAELESTRASZ, 100, me); Unit* Merithra = plr->FindNearestCreature(C_MERITHRA, 100, me); if (!Fandral || !Arygos || !Caelestrasz || !Merithra) return; Unit* mob; AnimationTimer = EventAnim[AnimationCount].Timer; if (eventEnd == false) { switch(AnimationCount) { case 0: DoScriptText(ANACHRONOS_SAY_1, me , Fandral); break; case 1: Fandral->SetUInt64Value(UNIT_FIELD_TARGET, me->GetGUID()); DoScriptText(FANDRAL_SAY_1, Fandral, me); break; case 2: Fandral->SetUInt64Value(UNIT_FIELD_TARGET, NULL); DoScriptText(MERITHRA_EMOTE_1, Merithra); break; case 3: DoScriptText(MERITHRA_SAY_1, Merithra); break; case 4: DoScriptText(ARYGOS_EMOTE_1, Arygos); break; case 5: Caelestrasz->SetUInt64Value(UNIT_FIELD_TARGET, Fandral->GetGUID()); DoScriptText(CAELESTRASZ_SAY_1, Caelestrasz); break; case 6: DoScriptText(MERITHRA_SAY_2, Merithra); break; case 7: Caelestrasz->SetUInt64Value(UNIT_FIELD_TARGET, NULL); Merithra->GetMotionMaster()->MoveCharge(-8065, 1530, 2.61f, 10); break; case 8: DoScriptText(MERITHRA_YELL_1, Merithra); break; case 9: Merithra->CastSpell(Merithra, 25105, true); break; case 10: Merithra->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); Merithra->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING); Merithra->GetMotionMaster()->MoveCharge(-8065, 1530, 6.61f, 3); break; case 11: Merithra->CastSpell(Merithra, 24818, false); break; case 12: Merithra->GetMotionMaster()->MoveCharge(-8100, 1530, 50, 42); break; case 13: break; case 14: DoScriptText(ARYGOS_SAY_1, Arygos); Merithra->SetVisible(false); break; case 15: Arygos->GetMotionMaster()->MoveCharge(-8065, 1530, 2.61f, 10); Merithra->GetMotionMaster()->MoveCharge(-8034.535f, 1535.14f, 2.61f, 42); break; case 16: DoScriptText(ARYGOS_YELL_1, Arygos); break; case 17: Arygos->CastSpell(Arygos, 25107, true); break; case 18: Arygos->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); Arygos->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING); Arygos->GetMotionMaster()->MoveCharge(-8065, 1530, 6.61f, 42); break; case 19: Arygos->CastSpell(Arygos, 50505, false); break; case 20: Arygos->GetMotionMaster()->MoveCharge(-8095, 1530, 50, 42); break; case 21: break; case 22: DoScriptText(CAELESTRASZ_SAY_2, Caelestrasz, Fandral); break; case 23: Caelestrasz->GetMotionMaster()->MoveCharge(-8065, 1530, 2.61f, 10); Arygos->SetVisible(false); Arygos->GetMotionMaster()->MoveCharge(-8034.535f, 1535.14f, 2.61f, 10); break; case 24: DoScriptText(CAELESTRASZ_YELL_1, Caelestrasz); break; case 25: Caelestrasz->CastSpell(Caelestrasz, 25106, true); break; case 26: Caelestrasz->HandleEmoteCommand(254); Caelestrasz->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING); Caelestrasz->GetMotionMaster()->MoveCharge(-8065, 1530, 7.61f, 4); break; case 27: Caelestrasz->CastSpell(Caelestrasz, 54293, false); break; case 28: DoScriptText(ANACHRONOS_SAY_2, me, Fandral); break; case 29: Caelestrasz->GetMotionMaster()->MoveCharge(-8095, 1530, 50, 42); DoScriptText(FANDRAL_SAY_2, Fandral, me); break; case 30: break; case 31: DoScriptText(ANACHRONOS_SAY_3, me, Fandral); break; case 32: Caelestrasz->SetVisible(false); Caelestrasz->GetMotionMaster()->MoveCharge(-8034.535f, 1535.14f, 2.61f, 42); Fandral->GetMotionMaster()->MoveCharge(-8108, 1529, 2.77f, 8); me->GetMotionMaster()->MoveCharge(-8113, 1525, 2.77f, 8); break;//both run to the gate case 33: DoScriptText(ANACHRONOS_SAY_4, me); Caelestrasz->GetMotionMaster()->MoveCharge(-8050, 1473, 65, 15); break; //Text: sands will stop case 34: DoCast(plr, 23017, true);//Arcane Channeling break; case 35: me->CastSpell(-8088, 1520.43f, 2.67f, 25158, true); break; case 36: DoCast(plr, 25159, true); break; case 37: me->SummonGameObject(GO_GATE_OF_AHN_QIRAJ, -8130, 1525, 17.5f, 0, 0, 0, 0, 0, 0); break; case 38: DoCast(plr, 25166, true); me->SummonGameObject(GO_GLYPH_OF_AHN_QIRAJ, -8130, 1525, 17.5f, 0, 0, 0, 0, 0, 0); break; case 39: DoScriptText(ANACHRONOS_SAY_5, me, Fandral); break; case 40: Fandral->CastSpell(me, 25167, true); break; case 41: Fandral->SummonGameObject(GO_ROOTS_OF_AHN_QIRAJ, -8130, 1525, 17.5f, 0, 0, 0, 0, 0, 0); DoScriptText(FANDRAL_SAY_3, Fandral); break; case 42: me->CastStop(); DoScriptText(FANDRAL_EMOTE_1, Fandral); break; case 43: Fandral->CastStop(); break; case 44: DoScriptText(ANACHRONOS_SAY_6, me); break; case 45: DoScriptText(ANACHRONOS_SAY_7, me); break; case 46: DoScriptText(ANACHRONOS_SAY_8, me); me->GetMotionMaster()->MoveCharge(-8110, 1527, 2.77f, 4); break; case 47: DoScriptText(ANACHRONOS_EMOTE_1, me); break; case 48: DoScriptText(FANDRAL_SAY_4, Fandral, me); break; case 49: DoScriptText(FANDRAL_SAY_5, Fandral, me); break; case 50: DoScriptText(FANDRAL_EMOTE_2, Fandral); Fandral->CastSpell(-8127, 1525, 17.5f, 33806, true); break; case 51: { uint32 entries[4] = { 15423, 15424, 15414, 15422 }; for (uint8 i = 0; i < 4; ++i) { mob = plr->FindNearestCreature(entries[i], 50, me); while (mob) { mob->RemoveFromWorld(); mob = plr->FindNearestCreature(15423, 50, me); } } break; } case 52: Fandral->GetMotionMaster()->MoveCharge(-8028.75f, 1538.795f, 2.61f, 4); DoScriptText(ANACHRONOS_SAY_9, me, Fandral); break; case 53: DoScriptText(FANDRAL_SAY_6, Fandral); break; case 54: DoScriptText(ANACHRONOS_EMOTE_2, me); break; case 55: Fandral->SetVisible(false); break; case 56: DoScriptText(ANACHRONOS_EMOTE_3, me); me->GetMotionMaster()->MoveCharge(-8116, 1522, 3.65f, 4); break; case 57: me->GetMotionMaster()->MoveCharge(-8116.7f, 1527, 3.7f, 4); break; case 58: me->GetMotionMaster()->MoveCharge(-8112.67f, 1529.9f, 2.86f, 4); break; case 59: me->GetMotionMaster()->MoveCharge(-8117.99f, 1532.24f, 3.94f, 4); break; case 60: if (plr) DoScriptText(ANACHRONOS_SAY_10, me, plr); me->GetMotionMaster()->MoveCharge(-8113.46f, 1524.16f, 2.89f, 4); break; case 61: me->GetMotionMaster()->MoveCharge(-8057.1f, 1470.32f, 2.61f, 6); if (plr->IsInRange(me, 0, 15)) plr->GroupEventHappens(QUEST_A_PAWN_ON_THE_ETERNAL_BOARD , me); break; case 62: me->SetDisplayId(15500); break; case 63: me->HandleEmoteCommand(254); me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING); break; case 64: me->GetMotionMaster()->MoveCharge(-8000, 1400, 150, 9); break; case 65: me->SetVisible(false); if (Creature* AnachronosQuestTrigger = (Unit::GetCreature(*me, AnachronosQuestTriggerGUID))) { DoScriptText(ARYGOS_YELL_1, me); AnachronosQuestTrigger->AI()->EnterEvadeMode(); eventEnd=true; } break; } } ++AnimationCount; }
void PlayerbotHunterAI::DoNonCombatActions() { if (!m_ai) return; if (!m_bot) return; if (!m_rangedCombat || m_ai->GetCombatStyle() == PlayerbotAI::COMBAT_MELEE) { m_rangedCombat = true; m_ai->SetCombatStyle(PlayerbotAI::COMBAT_RANGED); } // buff group if (TRUESHOT_AURA > 0 && !m_bot->HasAura(TRUESHOT_AURA, EFFECT_INDEX_0)) m_ai->CastSpell(TRUESHOT_AURA, *m_bot); // buff myself if (ASPECT_OF_THE_HAWK > 0 && !m_bot->HasAura(ASPECT_OF_THE_HAWK, EFFECT_INDEX_0)) m_ai->CastSpell(ASPECT_OF_THE_HAWK, *m_bot); // hp/mana check if (m_bot->getStandState() != UNIT_STAND_STATE_STAND) m_bot->SetStandState(UNIT_STAND_STATE_STAND); if (EatDrinkBandage()) return; if (m_bot->getRace() == RACE_DRAENEI && !m_bot->HasAura(GIFT_OF_THE_NAARU, EFFECT_INDEX_0) && m_ai->GetHealthPercent() < 70) { m_ai->TellMaster("I'm casting gift of the naaru."); m_ai->CastSpell(GIFT_OF_THE_NAARU, *m_bot); return; } // check for pet if (PET_SUMMON > 0 && !m_petSummonFailed && m_bot->GetPetGuid()) { // we can summon pet, and no critical summon errors before Pet *pet = m_bot->GetPet(); if (!pet) { // summon pet if (PET_SUMMON > 0 && m_ai->CastSpell(PET_SUMMON, *m_bot)) m_ai->TellMaster("summoning pet."); else { m_petSummonFailed = true; m_ai->TellMaster("summon pet failed!"); } } else if (!(pet->isAlive())) { if (PET_REVIVE > 0 && m_ai->CastSpell(PET_REVIVE, *m_bot)) m_ai->TellMaster("reviving pet."); } else if (pet->GetHealthPercent() < 50) { if (PET_MEND > 0 && pet->isAlive() && !pet->HasAura(PET_MEND, EFFECT_INDEX_0) && m_ai->CastSpell(PET_MEND, *m_bot)) m_ai->TellMaster("healing pet."); } else if (pet->GetHappinessState() != HAPPY) // if pet is hungry { Unit *caster = (Unit *) m_bot; // list out items in main backpack for (uint8 slot = INVENTORY_SLOT_ITEM_START; slot < INVENTORY_SLOT_ITEM_END; slot++) { Item* const pItem = m_bot->GetItemByPos(INVENTORY_SLOT_BAG_0, slot); if (pItem) { const ItemPrototype* const pItemProto = pItem->GetProto(); if (!pItemProto) continue; if (pet->HaveInDiet(pItemProto)) // is pItem in pets diet { // DEBUG_LOG ("[PlayerbotHunterAI]: DoNonCombatActions - Food for pet: %s",pItemProto->Name1); caster->CastSpell(caster, 51284, true); // pet feed visual uint32 count = 1; // number of items used int32 benefit = pet->GetCurrentFoodBenefitLevel(pItemProto->ItemLevel); // nutritional value of food m_bot->DestroyItemCount(pItem, count, true); // remove item from inventory m_bot->CastCustomSpell(m_bot, PET_FEED, &benefit, NULL, NULL, true); // feed pet m_ai->TellMaster("feeding pet."); m_ai->SetIgnoreUpdateTime(10); return; } } } // list out items in other removable backpacks for (uint8 bag = INVENTORY_SLOT_BAG_START; bag < INVENTORY_SLOT_BAG_END; ++bag) { const Bag* const pBag = (Bag *) m_bot->GetItemByPos(INVENTORY_SLOT_BAG_0, bag); if (pBag) for (uint8 slot = 0; slot < pBag->GetBagSize(); ++slot) { Item* const pItem = m_bot->GetItemByPos(bag, slot); if (pItem) { const ItemPrototype* const pItemProto = pItem->GetProto(); if (!pItemProto) continue; if (pet->HaveInDiet(pItemProto)) // is pItem in pets diet { // DEBUG_LOG ("[PlayerbotHunterAI]: DoNonCombatActions - Food for pet: %s",pItemProto->Name1); caster->CastSpell(caster, 51284, true); // pet feed visual uint32 count = 1; // number of items used int32 benefit = pet->GetCurrentFoodBenefitLevel(pItemProto->ItemLevel); // nutritional value of food m_bot->DestroyItemCount(pItem, count, true); // remove item from inventory m_bot->CastCustomSpell(m_bot, PET_FEED, &benefit, NULL, NULL, true); // feed pet m_ai->TellMaster("feeding pet."); m_ai->SetIgnoreUpdateTime(10); return; } } } } if (pet->HasAura(PET_MEND, EFFECT_INDEX_0) && !pet->HasAura(PET_FEED, EFFECT_INDEX_0)) m_ai->TellMaster("..no pet food!"); m_ai->SetIgnoreUpdateTime(7); } } } // end DoNonCombatActions
void UpdateAI(const uint32 diff) { if (!UpdateVictim() ) return; //Shimmer_Timer Timer if (Shimmer_Timer < diff) { //Remove old vurlnability spell if (CurrentVurln_Spell) m_creature->RemoveAurasDueToSpell(CurrentVurln_Spell); //Cast new random vurlnabilty on self uint32 spell; switch (rand()%5) { case 0: spell = SPELL_FIRE_VURNALBILTY; break; case 1: spell = SPELL_FROST_VURNALBILTY; break; case 2: spell = SPELL_SHADOW_VURNALBILTY; break; case 3: spell = SPELL_NATURE_VURNALBILTY; break; case 4: spell = SPELL_ARCANE_VURNALBILTY; break; } DoCast(m_creature,spell); CurrentVurln_Spell = spell; DoScriptText(EMOTE_SHIMMER, m_creature); Shimmer_Timer = 45000; }else Shimmer_Timer -= diff; //Breath1_Timer if (Breath1_Timer < diff) { DoCast(m_creature->getVictim(),Breath1_Spell); Breath1_Timer = 60000; }else Breath1_Timer -= diff; //Breath2_Timer if (Breath2_Timer < diff) { DoCast(m_creature->getVictim(),Breath2_Spell); Breath2_Timer = 60000; }else Breath2_Timer -= diff; //Affliction_Timer if (Affliction_Timer < diff) { uint32 SpellAfflict = 0; switch (rand()%5) { case 0: SpellAfflict = SPELL_BROODAF_BLUE; break; case 1: SpellAfflict = SPELL_BROODAF_BLACK; break; case 2: SpellAfflict = SPELL_BROODAF_RED; break; case 3: SpellAfflict = SPELL_BROODAF_BRONZE; break; case 4: SpellAfflict = SPELL_BROODAF_GREEN; break; } std::list<HostilReference*>::iterator i; for (i = m_creature->getThreatManager().getThreatList().begin();i != m_creature->getThreatManager().getThreatList().end();) { Unit* pUnit = NULL; pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid()); ++i; if (pUnit) { //Cast affliction DoCast(pUnit, SpellAfflict, true); //Chromatic mutation if target is effected by all afflictions if (pUnit->HasAura(SPELL_BROODAF_BLUE,0) && pUnit->HasAura(SPELL_BROODAF_BLACK,0) && pUnit->HasAura(SPELL_BROODAF_RED,0) && pUnit->HasAura(SPELL_BROODAF_BRONZE,0) && pUnit->HasAura(SPELL_BROODAF_GREEN,0)) { //target->RemoveAllAuras(); //DoCast(target,SPELL_CHROMATIC_MUT_1); //Chromatic mutation is causing issues //Assuming it is caused by a lack of core support for Charm //So instead we instant kill our target //WORKAROUND if (pUnit->GetTypeId() == TYPEID_PLAYER) pUnit->CastSpell(pUnit, 5, false); } } } Affliction_Timer = 10000; }else Affliction_Timer -= diff; //Frenzy_Timer if (Frenzy_Timer < diff) { DoCast(m_creature,SPELL_FRENZY); DoScriptText(EMOTE_FRENZY, m_creature); Frenzy_Timer = 10000 + (rand() % 5000); }else Frenzy_Timer -= diff; //Enrage if not already enraged and below 20% if (!Enraged && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 20) { DoCast(m_creature,SPELL_ENRAGE); Enraged = true; } DoMeleeAttackIfReady(); }