void HandleAfterCast() { Unit* caster = GetCaster(); if (!caster->IsInCombat() || roll_chance_i(50)) return; std::list<Creature*> triggers; caster->GetCreatureListWithEntryInGrid(triggers, NPC_VIAL_BUNNY, 100.0f); Creature* trigger = Trinity::Containers::SelectRandomContainerElement(triggers); caster->GetMotionMaster()->MovePoint(0, trigger->GetPosition()); }
void EffectMovementGenerator::Finalize(Unit& unit) { if (unit.GetTypeId() != TYPEID_UNIT) return; // Need restore previous movement since we have no proper states system if (unit.IsAlive() && !unit.HasUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_FLEEING | UNIT_STATE_DISTRACTED)) { if (Unit* victim = unit.GetVictim()) unit.GetMotionMaster()->MoveChase(victim); else unit.GetMotionMaster()->Initialize(); } else if (!unit.IsAlive()) { unit.GetMotionMaster()->MoveIdle(); } if (unit.ToCreature()->AI()) unit.ToCreature()->AI()->MovementInform(EFFECT_MOTION_TYPE, m_Id); }
void FetchDragons() { Unit* pTene = Unit::GetUnit(*m_creature,m_pInstance->GetData64(DATA_TENEBRON)); Unit* pShad = Unit::GetUnit(*m_creature,m_pInstance->GetData64(DATA_SHADRON)); Unit* pVesp = Unit::GetUnit(*m_creature,m_pInstance->GetData64(DATA_VESPERON)); //if at least one of the dragons are alive and are being called bool bCanUseWill = false; if (pTene && pTene->isAlive() && !pTene->getVictim()) { bCanUseWill = true; pTene->GetMotionMaster()->MovePoint(POINT_ID_INIT, m_aTene[0].m_fX, m_aTene[0].m_fY, m_aTene[0].m_fZ); if (!pTene->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) pTene->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); } if (pShad && pShad->isAlive() && !pShad->getVictim()) { bCanUseWill = true; pShad->GetMotionMaster()->MovePoint(POINT_ID_INIT, m_aShad[0].m_fX, m_aShad[0].m_fY, m_aShad[0].m_fZ); if (!pShad->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) pShad->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); } if (pVesp && pVesp->isAlive() && !pVesp->getVictim()) { bCanUseWill = true; pVesp->GetMotionMaster()->MovePoint(POINT_ID_INIT, m_aVesp[0].m_fX, m_aVesp[0].m_fY, m_aVesp[0].m_fZ); if (!pVesp->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) pVesp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); } if (bCanUseWill) DoCastSpellIfCan(m_creature, SPELL_WILL_OF_SARTHARION); }
void EffectMovementGenerator::Finalize(Unit& unit) { if (unit.GetTypeId() != TYPEID_UNIT) { return; } if (((Creature&)unit).AI() && unit.movespline->Finalized()) { ((Creature&)unit).AI()->MovementInform(EFFECT_MOTION_TYPE, m_Id); } // Need restore previous movement since we have no proper states system if (unit.IsAlive() && !unit.hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING | UNIT_STAT_NO_COMBAT_MOVEMENT)) { if (Unit* victim = unit.getVictim()) { unit.GetMotionMaster()->MoveChase(victim); } else { unit.GetMotionMaster()->Initialize(); } } }
void SendLavaWaves(bool start) { Unit* cr = NULL; for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr) { cr = ObjectAccessor::GetUnit(*me, *itr); if (!cr || cr->GetEntry() != NPC_FLAME_TSUNAMI) continue; if (start) cr->GetMotionMaster()->MovePoint(0, ((cr->GetPositionX() < 3250.0f) ? 3283.44f : 3208.44f), cr->GetPositionY(), cr->GetPositionZ()); else cr->SetObjectScale(0.1f); } }
void HandlePull(SpellEffIndex effIndex) { PreventHitDefaultEffect(effIndex); Unit* target = GetHitUnit(); if (!target) return; Position pos; if (target->GetDistance(GetCaster()) < 5.0f) { float o = frand(0, 2*M_PI); pos.Relocate(GetCaster()->GetPositionX() + 4.0f*cos(o), GetCaster()->GetPositionY() + 4.0f*sin(o), GetCaster()->GetPositionZ()+frand(10.0f, 15.0f)); } else pos.Relocate(GetCaster()->GetPositionX(), GetCaster()->GetPositionY(), GetCaster()->GetPositionZ()+1.0f); float speedXY = float(GetSpellInfo()->Effects[effIndex].MiscValue) * 0.1f; float speedZ = target->GetDistance(pos) / speedXY * 0.5f * Movement::gravity; target->GetMotionMaster()->MoveJump(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), speedXY, speedZ); }
void OnRemoveVehicle(constAuraEffectPtr /*aurEff*/, AuraEffectHandleModes mode) { PreventDefaultAction(); Unit* caster = GetCaster(); if (!caster) return; Position exitPosition; exitPosition.m_positionX = 1750.0f; exitPosition.m_positionY = -7.5f + frand(-3.0f, 3.0f); exitPosition.m_positionZ = 457.9322f; caster->_ExitVehicle(&exitPosition); caster->RemoveAurasDueToSpell(GetId()); Position oldPos; caster->GetPosition(&oldPos); caster->Relocate(exitPosition); caster->GetMotionMaster()->MoveFall(); caster->Relocate(oldPos); }
uint32 NextStep(uint32 Step) { Unit* Spark = Unit::GetUnit((*me), SparkGUID); switch(Step) { case 0: return 99999; case 1: //DespawnNagaFlag(true); DoScriptText(EMOTE_SPARK, Spark); return 1000; case 2: DoScriptText(GEEZLE_SAY_1, me, Spark); if (Spark) { Spark->SetInFront(me); me->SetInFront(Spark); } return 5000; case 3: DoScriptText(SPARK_SAY_2, Spark); return 7000; case 4: DoScriptText(SPARK_SAY_3, Spark); return 8000; case 5: DoScriptText(GEEZLE_SAY_4, me, Spark); return 8000; case 6: DoScriptText(SPARK_SAY_5, Spark); return 9000; case 7: DoScriptText(SPARK_SAY_6, Spark); return 8000; case 8: DoScriptText(GEEZLE_SAY_7, me, Spark); return 2000; case 9: me->GetMotionMaster()->MoveTargetedHome(); if (Spark) Spark->GetMotionMaster()->MovePoint(0, -5030.95f, -11291.99f, 7.97f); return 20000; case 10: if (Spark) Spark->DealDamage(Spark,Spark->GetHealth(),NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); //DespawnNagaFlag(false); me->SetVisibility(VISIBILITY_OFF); default: return 99999999; } }
void DamageTaken(Unit* pKiller, uint32 &damage) { if (Gripped) { ArmDamage += damage; int32 dmg = RAID_MODE(100000, 480000); if (ArmDamage >= dmg || damage >= me->GetHealth()) { for (uint8 n = 0; n < RAID_MODE(1, 3); ++n) { Unit* pGripTarget = me->GetVehicleKit()->GetPassenger(n); if (pGripTarget && pGripTarget->isAlive()) { pGripTarget->RemoveAurasDueToSpell(SPELL_STONE_GRIP); pGripTarget->RemoveAurasDueToSpell(SPELL_STONE_GRIP_STUN); pGripTarget->ExitVehicle(); pGripTarget->GetMotionMaster()->MoveJump(1767.80f, -18.38f, 448.808f, 10, 10); } } Gripped = false; } } }
void OnRemoveVehicle(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { PreventDefaultAction(); Unit* caster = GetCaster(); if (!caster) return; Position exitPosition; exitPosition.m_positionX = 1750.0f; exitPosition.m_positionY = -7.5f + frand(-3.0f, 3.0f); exitPosition.m_positionZ = 457.9322f; // Remove pending passengers before exiting vehicle - might cause an Uninstall GetTarget()->GetVehicleKit()->RemovePendingEventsForPassenger(caster); caster->_ExitVehicle(&exitPosition); caster->RemoveAurasDueToSpell(GetId()); // Temporarily relocate player to vehicle exit dest serverside to send proper fall movement // beats me why blizzard sends these 2 spline packets one after another instantly Position oldPos = caster->GetPosition(); caster->Relocate(exitPosition); caster->GetMotionMaster()->MoveFall(); caster->Relocate(oldPos); }
void HandleAnimation() { Player* plr = Unit::GetPlayer(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.61,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.61,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->SetVisibility(VISIBILITY_OFF); break; case 15: Arygos->GetMotionMaster()->MoveCharge(-8065,1530,2.61,10); Merithra->GetMotionMaster()->MoveCharge(-8034.535,1535.14,2.61,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.61,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.61,10); Arygos->SetVisibility(VISIBILITY_OFF); Arygos->GetMotionMaster()->MoveCharge(-8034.535,1535.14,2.61,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.61,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->SetVisibility(VISIBILITY_OFF); Caelestrasz->GetMotionMaster()->MoveCharge(-8034.535,1535.14,2.61,42); Fandral->GetMotionMaster()->MoveCharge(-8108,1529,2.77,8); me->GetMotionMaster()->MoveCharge(-8113,1525,2.77,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.43,2.67,25158,true); break; case 36: DoCast(plr, 25159, true); break; case 37: me->SummonGameObject(GO_GATE_OF_AHN_QIRAJ,-8130,1525,17.5,0,0,0,0,0,0); break; case 38: DoCast(plr, 25166, true); me->SummonGameObject(GO_GLYPH_OF_AHN_QIRAJ,-8130,1525,17.5,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.5,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.77,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.5,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.75, 1538.795, 2.61,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->SetVisibility(VISIBILITY_OFF); break; case 56: DoScriptText(ANACHRONOS_EMOTE_3, me); me->GetMotionMaster()->MoveCharge(-8116,1522,3.65,4); break; case 57: me->GetMotionMaster()->MoveCharge(-8116.7,1527,3.7,4); break; case 58: me->GetMotionMaster()->MoveCharge(-8112.67,1529.9,2.86,4); break; case 59: me->GetMotionMaster()->MoveCharge(-8117.99,1532.24,3.94,4); break; case 60: if (plr) DoScriptText(ANACHRONOS_SAY_10, me,plr); me->GetMotionMaster()->MoveCharge(-8113.46,1524.16,2.89,4); break; case 61: me->GetMotionMaster()->MoveCharge(-8057.1,1470.32,2.61,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->SetVisibility(VISIBILITY_OFF); if (Creature* AnachronosQuestTrigger = (Unit::GetCreature(*me, AnachronosQuestTriggerGUID))) { DoScriptText(ARYGOS_YELL_1,me); AnachronosQuestTrigger->AI()->EnterEvadeMode(); eventEnd=true; } break; } } ++AnimationCount; }
void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; switch(stage) { case 0: { timedCast(SPELL_POUND, uiDiff); timedCast(SPELL_COLD, uiDiff); if (timedQuery(SUMMON_BORROWER, uiDiff)) { doCast(SUMMON_BORROWER); DoScriptText(-1713556,m_creature); }; if (timedQuery(SPELL_SUBMERGE_0, uiDiff)) stage = 1; break;} case 1: { doCast(SPELL_SUBMERGE_0); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); stage = 2; DoScriptText(-1713557,m_creature); break;} case 2: { if (timedQuery(SPELL_SPIKE_CALL, uiDiff)) { pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0); // doCast(SPELL_SPIKE_CALL); // This summon not supported in database. Temporary override. Unit* spike = doSummon(NPC_SPIKE,TEMPSUMMON_TIMED_DESPAWN,60000); if (spike) { spike->AddThreat(pTarget, 1000.0f); DoScriptText(-1713558,m_creature,pTarget); doCast(SPELL_MARK,pTarget); spike->GetMotionMaster()->MoveChase(pTarget); } }; if (timedQuery(SPELL_SUMMON_BEATLES, uiDiff)) { doCast(SPELL_SUMMON_BEATLES); doCast(SUMMON_SCARAB); DoScriptText(-1713560,m_creature); }; if (timedQuery(SPELL_SUBMERGE_0, uiDiff)) stage = 3; break;} case 3: { stage = 0; DoScriptText(-1713559,m_creature); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); doRemove(SPELL_SUBMERGE_0,m_creature); break;} case 4: { doCast(SPELL_LEECHING_SWARM); DoScriptText(-1713561,m_creature); stage = 5; break;} case 5: { timedCast(SPELL_POUND, uiDiff); timedCast(SPELL_COLD, uiDiff); break;} } timedCast(SUMMON_FROSTSPHERE, uiDiff); timedCast(SPELL_BERSERK, uiDiff); if (m_creature->GetHealthPercent() < 30.0f && stage == 0) stage = 4; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if(!UpdateVictim()) return; if (checkTimer2 < diff) { if (!m_creature->IsWithinDistInMap(&wLoc, 50)) EnterEvadeMode(); else DoZoneInCombat(); checkTimer2 = 3000; } else checkTimer2 -= diff; if(BerserkTimer < diff) { AddSpellToCastWithScriptText(m_creature, SPELL_BERSERK, YELL_BERSERK); BerserkTimer = 60000; }else BerserkTimer -= diff; if(Phase == PHASE_LYNX || Phase == PHASE_ENRAGE) { if(SaberlashTimer < diff) { AddSpellToCastWithScriptText(m_creature->getVictim(), SPELL_SABER_LASH, RAND(YELL_SABER_ONE, YELL_SABER_TWO)); SaberlashTimer = 5000 + rand() % 10000; }else SaberlashTimer -= diff; if(FrenzyTimer < diff) { AddSpellToCast(m_creature, SPELL_FRENZY); FrenzyTimer = (10+rand()%5)*1000; }else FrenzyTimer -= diff; if(Phase == PHASE_LYNX) if(CheckTimer < diff) { if(m_creature->GetHealth() * 4 < m_creature->GetMaxHealth() * (3 - TransformCount)) EnterPhase(PHASE_SPLIT); CheckTimer = 1000; }else CheckTimer -= diff; } if(Phase == PHASE_HUMAN || Phase == PHASE_ENRAGE) { if(TotemTimer < diff) { AddSpellToCast(m_creature, SPELL_SUMMON_TOTEM); TotemTimer = 20000; }else TotemTimer -= diff; if(ShockTimer < diff) { if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0,GetSpellMaxRange(SPELL_EARTHSHOCK), true)) { if(target->IsNonMeleeSpellCasted(false)) AddSpellToCast(target,SPELL_EARTHSHOCK); else AddSpellToCast(target,SPELL_FLAMESHOCK); ShockTimer = 10000 + rand()%5000; } }else ShockTimer -= diff; if(Phase == PHASE_HUMAN) if(CheckTimer < diff) { if( ((m_creature->GetHealth()*100) / m_creature->GetMaxHealth() <= 20)/*m_creature->GetHealth() * 10 < m_creature->GetMaxHealth()*/) EnterPhase(PHASE_MERGE); else { Unit *Lynx = Unit::GetUnit(*m_creature, LynxGUID); if(Lynx && ((Lynx->GetHealth()*100) / Lynx->GetMaxHealth() <= 20)/*Lynx->GetHealth() * 10 < Lynx->GetMaxHealth()*/) EnterPhase(PHASE_MERGE); } CheckTimer = 1000; }else CheckTimer -= diff; } if(Phase == PHASE_MERGE) { if(CheckTimer < diff) { Unit *Lynx = Unit::GetUnit(*m_creature, LynxGUID); if(Lynx) { Lynx->GetMotionMaster()->MoveFollow(m_creature, 0, 0); m_creature->GetMotionMaster()->MoveFollow(Lynx, 0, 0); if(m_creature->IsWithinDistInMap(Lynx, 6.0f)) { if(TransformCount < 3) EnterPhase(PHASE_LYNX); else EnterPhase(PHASE_ENRAGE); } } CheckTimer = 1000; }else CheckTimer -= diff; } CastNextSpellIfAnyAndReady(); DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) { if (m_creature->isAlive() && !m_addedRiss) { if (m_rissCount < 1) m_creature->SummonGameObject(GO_WASSERRISS_PORTAL, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ() + 2.0f, m_creature->GetOrientation(), m_creature->GetRespawnTime()); for (int i = 0; i < 8; i++) { int coords = urand(0, 1); if (coords > 0) { int wertX = urand(1, 125); int wertY = urand(1, 125); int rndX = urand(m_creature->GetPositionX(), m_creature->GetPositionX() - wertX); int rndY = urand(m_creature->GetPositionY(), m_creature->GetPositionY() - wertY); //m_creature->SummonGameObject(GO_WASSERRISS, rndX, rndY, m_creature->GetPositionZ() + 1.0f, m_creature->GetOrientation(), m_creature->GetRespawnTime()); } else { int wertX = urand(1, 125); int wertY = urand(1, 125); int rndX = urand(m_creature->GetPositionX(), m_creature->GetPositionX() + wertX); int rndY = urand(m_creature->GetPositionY(), m_creature->GetPositionY() + wertY); //m_creature->SummonGameObject(GO_WASSERRISS, rndX, rndY, m_creature->GetPositionZ() + 1.0f, m_creature->GetOrientation(), m_creature->GetRespawnTime()); } m_rissCount++; } if (m_rissCount == 8) m_addedRiss = true; } if (m_addCount < MAX_ADD_COUNT) { if (m_uiSpawnAddTimer < uiDiff) { Unit* pAdd = m_creature->SummonCreature(NPC_WAESSRIGER, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 0, TEMPSUMMON_DEAD_DESPAWN, 20000); m_creature->InterruptNonMeleeSpells(true); if (pAdd) DoCastSpellIfCan(pAdd, SPELL_VISUAL_SPAWN, 0, m_creature->GetGUID()); if (pAdd) pAdd->GetMotionMaster()->MoveRandomAroundPoint(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 30.0f, 0); m_uiSpawnAddTimer = urand(15000, 30000); m_addCount++; } else m_uiSpawnAddTimer -= uiDiff; } if (m_bossCount < MAX_BOSS_COUNT) { if (m_uiSpawnBossTimer < uiDiff) { Unit* pBoss = GetClosestCreatureWithEntry(m_creature, NPC_TEMPESTRIA, VISIBLE_RANGE); if (pBoss) { pBoss->SetVisibility(VISIBILITY_ON); pBoss->setFaction(14); pBoss->GetMotionMaster()->MoveWaypoint(); } m_uiSpawnBossTimer = 0; m_bossCount++; } else m_uiSpawnBossTimer -= uiDiff; } }
uint32 NextStep(uint32 Step) { Unit* arca = Unit::GetUnit(*me, ArcanagosGUID); Map* map = me->GetMap(); switch (Step) { case 0: return 9999999; case 1: me->MonsterYell(SAY_DIALOG_MEDIVH_1, LANG_UNIVERSAL, 0); return 10000; case 2: if (arca) CAST_CRE(arca)->MonsterYell(SAY_DIALOG_ARCANAGOS_2, LANG_UNIVERSAL, 0); return 20000; case 3: me->MonsterYell(SAY_DIALOG_MEDIVH_3, LANG_UNIVERSAL, 0); return 10000; case 4: if (arca) CAST_CRE(arca)->MonsterYell(SAY_DIALOG_ARCANAGOS_4, LANG_UNIVERSAL, 0); return 20000; case 5: me->MonsterYell(SAY_DIALOG_MEDIVH_5, LANG_UNIVERSAL, 0); return 20000; case 6: if (arca) CAST_CRE(arca)->MonsterYell(SAY_DIALOG_ARCANAGOS_6, LANG_UNIVERSAL, 0); return 10000; case 7: FireArcanagosTimer = 500; return 5000; case 8: FireMedivhTimer = 500; DoCast(me, SPELL_MANA_SHIELD); return 10000; case 9: me->MonsterTextEmote(EMOTE_DIALOG_MEDIVH_7, 0, false); return 10000; case 10: if (arca) DoCast(arca, SPELL_CONFLAGRATION_BLAST, false); return 1000; case 11: if (arca) CAST_CRE(arca)->MonsterYell(SAY_DIALOG_ARCANAGOS_8, LANG_UNIVERSAL, 0); return 5000; case 12: arca->GetMotionMaster()->MovePoint(0, -11010.82f, -1761.18f, 156.47f); arca->setActive(true); arca->InterruptNonMeleeSpells(true); arca->SetSpeed(MOVE_FLIGHT, 2.0f); return 10000; case 13: me->MonsterYell(SAY_DIALOG_MEDIVH_9, LANG_UNIVERSAL, 0); return 10000; case 14: me->SetVisible(false); me->ClearInCombat(); if (map->IsDungeon()) { InstanceMap::PlayerList const &PlayerList = map->GetPlayers(); for (InstanceMap::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if (i->getSource()->isAlive()) { if (i->getSource()->GetQuestStatus(9645) == QUEST_STATUS_INCOMPLETE) i->getSource()->CompleteQuest(9645); } } } return 50000; case 15: arca->DealDamage(arca, arca->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); return 5000; default : return 9999999; } }
void UpdateAI(const uint32 diff) { if (SayTimer <= diff) { if (Event) SayTimer = NextStep(++Step); } else SayTimer -= diff; if (Attack) { Player* pPlayer = Unit::GetPlayer(*me, PlayerGUID); me->SetFaction(14); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); if (pPlayer) { Unit* Creepjack = me->FindNearestCreature(NPC_CREEPJACK, 20); if (Creepjack) { Creepjack->Attack(pPlayer, true); Creepjack->SetFaction(14); Creepjack->GetMotionMaster()->MoveChase(pPlayer); Creepjack->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); } Unit* Malone = me->FindNearestCreature(NPC_MALONE, 20); if (Malone) { Malone->Attack(pPlayer, true); Malone->SetFaction(14); Malone->GetMotionMaster()->MoveChase(pPlayer); Malone->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); } DoStartMovement(pPlayer); AttackStart(pPlayer); } Attack = false; } if ((me->GetHealth() * 100) / me->GetMaxHealth() < 15 && !Done) { Unit* Creepjack = me->FindNearestCreature(NPC_CREEPJACK, 20); if (Creepjack) { CAST_CRE(Creepjack)->AI()->EnterEvadeMode(); Creepjack->SetFaction(1194); Creepjack->GetMotionMaster()->MoveTargetedHome(); Creepjack->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); } Unit* Malone = me->FindNearestCreature(NPC_MALONE, 20); if (Malone) { CAST_CRE(Malone)->AI()->EnterEvadeMode(); Malone->SetFaction(1194); Malone->GetMotionMaster()->MoveTargetedHome(); Malone->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); } me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->SetFaction(1194); Done = true; DoScriptText(SAY_GIVEUP, me, NULL); me->DeleteThreatList(); me->CombatStop(); me->GetMotionMaster()->MoveTargetedHome(); Player* player = Unit::GetPlayer(*me, PlayerGUID); if (player) player->GroupEventHappens(QUEST_WBI, me); reset_timer = 30000; } if (Done == true && reset_timer <= diff) { Reset(); } else reset_timer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; switch(stage) { case 0: { bsw->timedCast(SPELL_POUND, uiDiff); bsw->timedCast(SPELL_COLD, uiDiff); if (bsw->timedQuery(SUMMON_BORROWER, uiDiff)) { bsw->doCast(SUMMON_BORROWER); DoScriptText(-1713556,m_creature); }; if (bsw->timedQuery(SPELL_SUBMERGE_0, uiDiff)) stage = 1; break;} case 1: { bsw->doCast(SPELL_SUBMERGE_0); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); stage = 2; DoScriptText(-1713557,m_creature); break;} case 2: { if (bsw->timedQuery(SPELL_SPIKE_CALL, uiDiff)) { pTarget = bsw->SelectUnit(); // bsw->doCast(SPELL_SPIKE_CALL); Unit* spike = bsw->doSummon(NPC_SPIKE,TEMPSUMMON_TIMED_DESPAWN,60000); // Creature* spike = GetClosestCreatureWithEntry(m_creature, NPC_SPIKE, 50.0f); if (spike) { spike->AddThreat(pTarget, 1000.0f); DoScriptText(-1713558,m_creature,pTarget); bsw->doCast(SPELL_MARK,pTarget); spike->GetMotionMaster()->MoveChase(pTarget); } }; if (bsw->timedQuery(SPELL_SUMMON_BEATLES, uiDiff)) { bsw->doCast(SPELL_SUMMON_BEATLES); bsw->doCast(SUMMON_SCARAB); DoScriptText(-1713560,m_creature); }; if (bsw->timedQuery(SPELL_SUBMERGE_0, uiDiff)) stage = 3; break;} case 3: { stage = 0; DoScriptText(-1713559,m_creature); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); bsw->doRemove(SPELL_SUBMERGE_0,m_creature); break;} case 4: { bsw->doCast(SPELL_LEECHING_SWARM); DoScriptText(-1713561,m_creature); stage = 5; break;} case 5: { bsw->timedCast(SPELL_POUND, uiDiff); bsw->timedCast(SPELL_COLD, uiDiff); break;} } bsw->timedCast(SUMMON_FROSTSPHERE, uiDiff); bsw->timedCast(SPELL_BERSERK, uiDiff); if (m_creature->GetHealthPercent() < 30.0f && stage == 0) stage = 4; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (!m_bFirstPlanar && !m_bIsRegularMode && m_creature->GetHealthPercent() < 50.0f) { m_bFirstPlanar = true; Events.ScheduleEvent(EVENT_PLANAR_SHIFT, 0); } if (!m_bSecondPlanar && !m_bIsRegularMode && m_creature->GetHealthPercent() < 25.0f) { m_bSecondPlanar = true; Events.ScheduleEvent(EVENT_PLANAR_SHIFT, 0); } if (m_creature->GetDistance2d(m_creature->getVictim()) > 35.0f && !m_bIsMove) { m_bIsMove = true; SetCombatMovement(m_bIsMove); if (Unit* pTarget = m_creature->getVictim()) m_creature->GetMotionMaster()->MoveChase(pTarget); } if (m_creature->GetDistance2d(m_creature->getVictim()) < 20.0f && m_bIsMove) { m_bIsMove = false; SetCombatMovement(m_bIsMove); m_creature->GetMotionMaster()->Clear(false); m_creature->GetMotionMaster()->MoveIdle(); m_creature->StopMoving(); } Events.Update(uiDiff); while (uint32 uiEventId = Events.ExecuteEvent()) switch (uiEventId) { case EVENT_DRAKE_COLOR_CHECK: CheckDrakeColors(); break; case EVENT_ARCANE_BARRAGE: DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_ARCANE_BARRAGE_N : SPELL_ARCANE_BARRAGE_H); break; case EVENT_ARCANE_VOLLEY: DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_ARCANE_VOLLEY_N : SPELL_ARCANE_VOLLEY_H); break; case EVENT_PLANAR_SHIFT: m_creature->MonsterTextEmote(EMOTE_PLANAR_SHIFT, m_creature, true); Events.DelayEvents(18*IN_MILLISECONDS); m_creature->InterruptNonMeleeSpells(false); DoCast(m_creature, SPELL_PLANAR_SHIFT, false); Events.ScheduleEvent(EVENT_ENRAGED_ASSAULT, 19*IN_MILLISECONDS); Events.ScheduleEvent(EVENT_PLANAR_ANOMALITIES, 2*IN_MILLISECONDS); break; case EVENT_ENRAGED_ASSAULT: DoCast(m_creature, SPELL_ENRAGED_ASSAULT, true); break; case EVENT_PLANAR_ANOMALITIES: DoCast(m_creature, SPELL_PLANAR_ANOMALIES, true); break; case EVENT_SUMMON_DRAKES: if (SummonMgr.GetSummonCount(NPC_DRAGON) > MAX_DRAGON_COUNT) break; for (int i = 0 ; i < 3 ; i++) { //DoCast(m_creature, SPELL_SUMMON_DRAKE, true); // summoned @ ground position Unit* pSumm = SummonMgr.SummonCreature(NPC_DRAGON, m_creature->GetPositionX() - 5 + urand(0, 10), m_creature->GetPositionY() - 5 + urand(0, 10), m_creature->GetPositionZ() - 5 + urand(0, 10), 0, TEMPSUMMON_CORPSE_DESPAWN, 0); if (Unit* pPlayer = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM_PLAYER, 0)) { if (pPlayer->GetVehicle()) if (Unit* pDrake = pPlayer->GetVehicle()->GetBase()) { pSumm->AddThreat(pDrake, 10000.0f); pSumm->GetMotionMaster()->MoveIdle(); pSumm->StopMoving(); pSumm->GetMotionMaster()->MoveChase(pDrake, 20.0f); } } } break; default: break; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if(!UpdateVictim()) return; if(m_creature->GetPositionX() < 308) { if(!m_creature->HasAura(SPELL_BERSERK,0)) { m_creature->CastSpell(m_creature,SPELL_BERSERK,true); if(pInstance) pInstance->SetData(DATA_TIMERDELETE, SPECIAL); } } if(BerserkTimer < diff) { DoYell(YELL_BERSERK, LANG_UNIVERSAL, NULL); DoPlaySoundToSet(m_creature, SOUND_BERSERK); DoCast(m_creature, SPELL_BERSERK, true); BerserkTimer = 60000; }else BerserkTimer -= diff; if(Phase == PHASE_LYNX || Phase == PHASE_ENRAGE) { if(SaberlashTimer < diff) { // A tank with more than 490 defense skills should receive no critical hit //m_creature->CastSpell(m_creature, 41296, true); m_creature->CastSpell(m_creature->getVictim(), SPELL_SABER_LASH, true); //m_creature->RemoveAurasDueToSpell(41296); SaberlashTimer = 30000; }else SaberlashTimer -= diff; if(FrenzyTimer < diff) { DoCast(m_creature, SPELL_FRENZY); FrenzyTimer = (10+rand()%5)*1000; }else FrenzyTimer -= diff; if(Phase == PHASE_LYNX) if(CheckTimer < diff) { if(m_creature->GetHealth() * 4 < m_creature->GetMaxHealth() * (3 - TransformCount)) EnterPhase(PHASE_SPLIT); CheckTimer = 1000; }else CheckTimer -= diff; } if(Phase == PHASE_HUMAN || Phase == PHASE_ENRAGE) { if(TotemTimer < diff) { DoCast(m_creature, SPELL_SUMMON_TOTEM); TotemTimer = 20000; }else TotemTimer -= diff; if(ShockTimer < diff) { if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0)) { if(target->IsNonMeleeSpellCasted(false)) DoCast(target,SPELL_EARTHSHOCK); else DoCast(target,SPELL_FLAMESHOCK); ShockTimer = 10000 + rand()%5000; } }else ShockTimer -= diff; if(Phase == PHASE_HUMAN) if(CheckTimer < diff) { if( ((m_creature->GetHealth()*100) / m_creature->GetMaxHealth() <= 20)/*m_creature->GetHealth() * 10 < m_creature->GetMaxHealth()*/) EnterPhase(PHASE_MERGE); else { Unit *Lynx = Unit::GetUnit(*m_creature, LynxGUID); if(Lynx && ((Lynx->GetHealth()*100) / Lynx->GetMaxHealth() <= 20)/*Lynx->GetHealth() * 10 < Lynx->GetMaxHealth()*/) EnterPhase(PHASE_MERGE); } CheckTimer = 1000; }else CheckTimer -= diff; } if(Phase == PHASE_MERGE) { if(CheckTimer < diff) { Unit *Lynx = Unit::GetUnit(*m_creature, LynxGUID); if(Lynx) { Lynx->GetMotionMaster()->MoveFollow(m_creature, 0, 0); m_creature->GetMotionMaster()->MoveFollow(Lynx, 0, 0); if(m_creature->IsWithinDistInMap(Lynx, 6.0f)) { if(TransformCount < 3) EnterPhase(PHASE_LYNX); else EnterPhase(PHASE_ENRAGE); } } CheckTimer = 1000; }else CheckTimer -= diff; } DoMeleeAttackIfReady(); }
void UpdateAI(const 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 *pTemp = Unit::GetCreature(*me, AddGUID[i])) if (pTemp->isAlive() && !pTemp->getVictim()) pTemp->AI()->AttackStart(me->getVictim()); CheckAddState_Timer = 5000; } else CheckAddState_Timer -= diff; if (DrainPower_Timer <= diff) { DoCast(me, SPELL_DRAIN_POWER, true); Map *map = me->GetMap(); if (!map->IsDungeon()) return; Map::PlayerList const &PlayerList = map->GetPlayers(); for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if (Player* i_pl = i->getSource()) if (i_pl->isAlive())me->AddAura(44132, me); //+1% Damage for each active player on boss (+ActivePlayer_Stack) } //me->AddAura(44132, me); me->MonsterYell(YELL_DRAIN_POWER, LANG_UNIVERSAL, NULL); 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, true); me->MonsterYell(YELL_SPIRIT_BOLTS, LANG_UNIVERSAL, NULL); 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 *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 70, true); Unit *trigger = DoSpawnCreature(MOB_TEMP_TRIGGER, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 30000); if (!pTarget || !trigger) { EnterEvadeMode(); return; } else { trigger->SetDisplayId(11686); trigger->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); trigger->CastSpell(pTarget, SPELL_SIPHON_SOUL, true); trigger->GetMotionMaster()->MoveChase(me); //DoCast(pTarget, SPELL_SIPHON_SOUL, true); //me->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, pTarget->GetGUID()); //me->SetUInt32Value(UNIT_CHANNEL_SPELL, SPELL_SIPHON_SOUL); PlayerGUID = pTarget->GetGUID(); PlayerAbility_Timer = urand(8000,10000); PlayerClass = pTarget->getClass() - 1; if (PlayerClass == 10) PlayerClass = 9; // druid else if (PlayerClass == 4 && pTarget->HasSpell(15473)) PlayerClass = 5; // shadow priest SiphonSoul_Timer = 99999; // buff lasts 30 sec } } else SiphonSoul_Timer -= diff; if (PlayerAbility_Timer <= diff) { //Unit *pTarget = Unit::GetUnit(*me, PlayerGUID); //if (pTarget && pTarget->isAlive()) //{ UseAbility(); PlayerAbility_Timer = urand(8000,10000); //} } else PlayerAbility_Timer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if (BerserkTimer <= diff) { me->MonsterYell(YELL_BERSERK, LANG_UNIVERSAL, NULL); DoPlaySoundToSet(me, SOUND_BERSERK); DoCast(me, SPELL_BERSERK, true); BerserkTimer = 60000; } else BerserkTimer -= diff; if (Phase == PHASE_LYNX || Phase == PHASE_ENRAGE) { if (SaberlashTimer <= diff) { // A tank with more than 490 defense skills should receive no critical hit //DoCast(me, 41296, true); DoCast(me->getVictim(), SPELL_SABER_LASH, true); //me->RemoveAurasDueToSpell(41296); SaberlashTimer = 30000; } else SaberlashTimer -= diff; if (FrenzyTimer <= diff) { DoCast(me, SPELL_FRENZY); FrenzyTimer = urand(10000, 15000); } else FrenzyTimer -= diff; if (Phase == PHASE_LYNX) { if (CheckTimer <= diff) { if (HealthBelowPct(25 * (3 - TransformCount))) EnterPhase(PHASE_SPLIT); CheckTimer = 1000; } else CheckTimer -= diff; } } if (Phase == PHASE_HUMAN || Phase == PHASE_ENRAGE) { if (TotemTimer <= diff) { DoCast(me, SPELL_SUMMON_TOTEM); TotemTimer = 20000; } else TotemTimer -= diff; if (ShockTimer <= diff) { if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) { if (pTarget->IsNonMeleeSpellCasted(false)) DoCast(pTarget, SPELL_EARTHSHOCK); else DoCast(pTarget, SPELL_FLAMESHOCK); ShockTimer = 10000 + rand()%5000; } } else ShockTimer -= diff; if (Phase == PHASE_HUMAN) { if (CheckTimer <= diff) { if (!HealthAbovePct(20) /*HealthBelowPct(10)*/) EnterPhase(PHASE_MERGE); else { Unit *Lynx = Unit::GetUnit(*me, LynxGUID); if (Lynx && !Lynx->HealthAbovePct(20) /*Lynx->HealthBelowPct(10)*/) EnterPhase(PHASE_MERGE); } CheckTimer = 1000; } else CheckTimer -= diff; } } if (Phase == PHASE_MERGE) { if (CheckTimer <= diff) { Unit *Lynx = Unit::GetUnit(*me, LynxGUID); if (Lynx) { Lynx->GetMotionMaster()->MoveFollow(me, 0, 0); me->GetMotionMaster()->MoveFollow(Lynx, 0, 0); if (me->IsWithinDistInMap(Lynx, 6.0f)) { if (TransformCount < 3) EnterPhase(PHASE_LYNX); else EnterPhase(PHASE_ENRAGE); } } CheckTimer = 1000; } else CheckTimer -= diff; } DoMeleeAttackIfReady(); }
/// Remove control and such modifiers to a passenger if they were added void VehicleInfo::RemoveSeatMods(Unit* passenger, uint32 seatFlags) { Unit* pVehicle = (Unit*)m_owner; if (seatFlags & SEAT_FLAG_NOT_SELECTABLE) passenger->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); // ToDo: reset passenger model id for SEAT_FLAG_HIDE_PASSENGER? if (passenger->GetTypeId() == TYPEID_PLAYER) { Player* pPlayer = (Player*)passenger; // group update if (pPlayer->GetGroup()) pPlayer->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_VEHICLE_SEAT); if (seatFlags & SEAT_FLAG_CAN_CONTROL) { pPlayer->SetCharm(nullptr); pVehicle->SetCharmer(nullptr); pPlayer->UpdateClientControl(pVehicle, false); pPlayer->SetMover(nullptr); pVehicle->StopMoving(true); pVehicle->GetMotionMaster()->Clear(); pVehicle->clearUnitState(UNIT_STAT_POSSESSED); pVehicle->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_POSSESSED); pVehicle->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); // must be called after movement control unapplying pPlayer->GetCamera().ResetView(); if (pVehicle->GetTypeId() == TYPEID_UNIT) { // reset vehicle faction ((Creature*)pVehicle)->ClearTemporaryFaction(); // Reset react state if (!(GetVehicleEntry()->m_flags & VEHICLE_FLAG_PASSIVE)) pVehicle->AI()->SetReactState(REACT_AGGRESSIVE); } } if (seatFlags & SEAT_FLAG_CAN_CAST) pPlayer->RemovePetActionBar(); } else if (passenger->GetTypeId() == TYPEID_UNIT) { if (seatFlags & SEAT_FLAG_CAN_CONTROL) { passenger->SetCharm(nullptr); pVehicle->SetCharmer(nullptr); } // Reinitialize movement if (((Creature*)passenger)->AI()) ((Creature*)passenger)->AI()->SetCombatMovement(true, true); if (!passenger->getVictim()) passenger->GetMotionMaster()->Initialize(); } }
void WorldSession::HandlePetAction(WorldPacket& recv_data) { ObjectGuid petGuid; uint32 data; ObjectGuid targetGuid; recv_data >> petGuid; recv_data >> data; recv_data >> targetGuid; uint32 spellid = UNIT_ACTION_BUTTON_ACTION(data); uint8 flag = UNIT_ACTION_BUTTON_TYPE(data); // delete = 0x07 CastSpell = C1 DETAIL_LOG("HandlePetAction: %s flag is %u, spellid is %u, target %s.", petGuid.GetString().c_str(), uint32(flag), spellid, targetGuid.GetString().c_str()); // used also for charmed creature/player Unit* petUnit = _player->GetMap()->GetUnit(petGuid); if (!petUnit) { sLog.outError("HandlePetAction: %s not exist.", petGuid.GetString().c_str()); return; } if (_player->GetObjectGuid() != petUnit->GetMasterGuid()) { sLog.outError("HandlePetAction: %s isn't controlled by %s.", petGuid.GetString().c_str(), _player->GetGuidStr().c_str()); return; } if (!petUnit->isAlive()) return; CharmInfo* charmInfo = petUnit->GetCharmInfo(); if (!charmInfo) { sLog.outError("WorldSession::HandlePetAction: object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", petUnit->GetGUIDLow(), petUnit->GetTypeId()); return; } Pet* pet = nullptr; Creature* creature = nullptr; if (petUnit->GetTypeId() == TYPEID_UNIT) { creature = static_cast<Creature*>(petUnit); if (creature->IsPet()) { pet = static_cast<Pet*>(petUnit); if (pet->GetModeFlags() & PET_MODE_DISABLE_ACTIONS) return; } } if (!pet) { if (petUnit->hasUnitState(UNIT_STAT_POSSESSED)) { // possess case if (flag != uint8(ACT_COMMAND)) { sLog.outError("PetHAndler: unknown PET flag Action %i and spellid %i. For possessed %s", uint32(flag), spellid, petUnit->GetGuidStr().c_str()); return; } switch (spellid) { case COMMAND_STAY: case COMMAND_FOLLOW: charmInfo->SetCommandState(CommandStates(spellid)); break; case COMMAND_ATTACK: { Unit* targetUnit = targetGuid ? _player->GetMap()->GetUnit(targetGuid) : nullptr; if (targetUnit && targetUnit != petUnit && petUnit->CanAttack(targetUnit)) { // This is true if pet has no target or has target but targets differs. if (petUnit->getVictim() != targetUnit) petUnit->Attack(targetUnit, true); } break; } case COMMAND_DISMISS: _player->BreakCharmOutgoing(petUnit); break; default: sLog.outError("PetHandler: Not allowed action %i and spellid %i. Pet %s owner is %s", uint32(flag), spellid, petUnit->GetGuidStr().c_str(), _player->GetGuidStr().c_str()); break; } } if (!petUnit->HasCharmer()) return; } switch (flag) { case ACT_COMMAND: // 0x07 switch (spellid) { case COMMAND_STAY: // flat=1792 // STAY { if (!petUnit->hasUnitState(UNIT_STAT_POSSESSED)) { petUnit->StopMoving(); petUnit->GetMotionMaster()->Clear(); } petUnit->AttackStop(true, true); charmInfo->SetCommandState(COMMAND_STAY); break; } case COMMAND_FOLLOW: // spellid=1792 // FOLLOW { if (!petUnit->hasUnitState(UNIT_STAT_POSSESSED)) { petUnit->StopMoving(); petUnit->GetMotionMaster()->Clear(); charmInfo->SetIsRetreating(true); } petUnit->AttackStop(true, true); charmInfo->SetCommandState(COMMAND_FOLLOW); break; } case COMMAND_ATTACK: // spellid=1792 // ATTACK { charmInfo->SetIsRetreating(); charmInfo->SetSpellOpener(); Unit* targetUnit = targetGuid ? _player->GetMap()->GetUnit(targetGuid) : nullptr; if (targetUnit && targetUnit != petUnit && petUnit->CanAttack(targetUnit) && targetUnit->isInAccessablePlaceFor((Creature*)petUnit)) { // This is true if pet has no target or has target but targets differs. if (petUnit->getVictim() != targetUnit) { petUnit->AttackStop(); if (!petUnit->hasUnitState(UNIT_STAT_POSSESSED)) { petUnit->GetMotionMaster()->Clear(); petUnit->AI()->AttackStart(targetUnit); if (pet) { // 10% chance to play special warlock pet attack talk, else growl if (pet->getPetType() == SUMMON_PET && roll_chance_i(10)) pet->SendPetTalk((uint32)PET_TALK_ATTACK); pet->SendPetAIReaction(); } } else petUnit->Attack(targetUnit, true); } } break; } case COMMAND_DISMISS: // dismiss permanent pet, remove temporary pet, uncharm unit { if (pet) { pet->PlayDismissSound(); // No action for Hunter pets, Hunters must use their Dismiss Pet spell if (pet->getPetType() != HUNTER_PET) pet->ForcedDespawn(); } else { // dismissing a summoned pet is like killing them (this prevents returning a soulshard...) if (creature && creature->IsTemporarySummon()) creature->ForcedDespawn(); else _player->BreakCharmOutgoing(petUnit); } charmInfo->SetStayPosition(); break; } default: sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", uint32(flag), spellid); } break; case ACT_REACTION: // 0x6 switch (spellid) { case REACT_PASSIVE: // passive { petUnit->AttackStop(true, true); charmInfo->SetSpellOpener(); } case REACT_DEFENSIVE: // recovery case REACT_AGGRESSIVE: // activete { petUnit->AI()->SetReactState(ReactStates(spellid)); break; } } break; case ACT_DISABLED: // 0x81 spell (disabled), ignore case ACT_PASSIVE: // 0x01 case ACT_ENABLED: // 0xC1 spell { charmInfo->SetIsRetreating(); charmInfo->SetSpellOpener(); Unit* unit_target = targetGuid ? _player->GetMap()->GetUnit(targetGuid) : nullptr; // do not cast unknown spells SpellEntry const* spellInfo = sSpellTemplate.LookupEntry<SpellEntry>(spellid); if (!spellInfo) { sLog.outError("WORLD: unknown PET spell id %i", spellid); return; } // do not cast not learned spells if (IsPassiveSpell(spellInfo) || !petUnit->HasSpell(spellid)) return; if (!petUnit->IsSpellReady(*spellInfo)) return; for (unsigned int i : spellInfo->EffectImplicitTargetA) { if (i == TARGET_ENUM_UNITS_ENEMY_AOE_AT_SRC_LOC || i == TARGET_ENUM_UNITS_ENEMY_AOE_AT_DEST_LOC || i == TARGET_ENUM_UNITS_ENEMY_AOE_AT_DYNOBJ_LOC) return; } petUnit->clearUnitState(UNIT_STAT_MOVING); uint32 flags = TRIGGERED_NONE; if (!petUnit->hasUnitState(UNIT_STAT_POSSESSED)) flags |= TRIGGERED_PET_CAST; Spell* spell = new Spell(petUnit, spellInfo, flags); SpellCastResult result = spell->CheckPetCast(unit_target); const SpellRangeEntry* sRange = sSpellRangeStore.LookupEntry(spellInfo->rangeIndex); if (unit_target && !(petUnit->IsWithinDistInMap(unit_target, sRange->maxRange) && petUnit->IsWithinLOSInMap(unit_target)) && petUnit->CanAttackNow(unit_target)) { charmInfo->SetSpellOpener(spellid, sRange->minRange, sRange->maxRange); spell->finish(false); delete spell; petUnit->AttackStop(); if (!petUnit->hasUnitState(UNIT_STAT_POSSESSED)) { petUnit->GetMotionMaster()->Clear(); petUnit->AI()->AttackStart(unit_target); // 10% chance to play special warlock pet attack talk, else growl if (pet && pet->getPetType() == SUMMON_PET && pet != unit_target && roll_chance_i(10)) petUnit->SendPetTalk((uint32)PET_TALK_ATTACK); petUnit->SendPetAIReaction(); } else petUnit->Attack(unit_target, true); return; } // auto turn to target unless possessed if (result == SPELL_FAILED_UNIT_NOT_INFRONT && !petUnit->hasUnitState(UNIT_STAT_POSSESSED)) { if (unit_target) { petUnit->SetInFront(unit_target); if (unit_target->GetTypeId() == TYPEID_PLAYER) petUnit->SendCreateUpdateToPlayer((Player*)unit_target); } else if (Unit* unit_target2 = spell->m_targets.getUnitTarget()) { petUnit->SetInFront(unit_target2); if (unit_target2->GetTypeId() == TYPEID_PLAYER) petUnit->SendCreateUpdateToPlayer((Player*)unit_target2); } if (Unit* powner = petUnit->GetMaster()) if (powner->GetTypeId() == TYPEID_PLAYER) petUnit->SendCreateUpdateToPlayer((Player*)powner); result = SPELL_CAST_OK; } if (result == SPELL_CAST_OK) { charmInfo->SetSpellOpener(); spell->SpellStart(&(spell->m_targets)); } else { if (creature && creature->IsSpellReady(*spellInfo)) GetPlayer()->SendClearCooldown(spellid, petUnit); charmInfo->SetSpellOpener(); spell->finish(false); delete spell; } break; } default: sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", uint32(flag), spellid); } }
void UpdateAI(const 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(); }
bool MovementGenerator::IsActive( Unit& u ) { // When movement generator list modified from Update movegen object erase delayed, // so pointer still valid and be used for check return !u.GetMotionMaster()->empty() && u.GetMotionMaster()->top() == this; }
void UpdateAI(const uint32 uiDiff) { if (!bEventInProgress) return; ScriptedAI::UpdateAI(uiDiff); if (bRemoveFlag) { if (uiRemoveFlagTimer <= uiDiff) { m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); bRemoveFlag = false; uiRemoveFlagTimer = 5000; } else uiRemoveFlagTimer -= uiDiff; } if (uiPhase) { if (uiTimer <= uiDiff) { switch (uiPhase) { case 1: pSummon = m_creature->SummonCreature(NPC_ORINOKO_TUSKBREAKER, SpawnPosition[0], TEMPSUMMON_CORPSE_DESPAWN, 1000); uiPhase = 2; uiTimer = 4000; break; case 2: if (pSummon) pSummon->GetMotionMaster()->MoveJump(5776.319824, -2981.005371, 273.100037, 10.0f, 20.0f); uiPhase = 0; pSummon = NULL; break; case 3: DoScriptText(SAY_QUEST_ACCEPT_KORRAK_2, m_creature); uiTimer = 3000; uiPhase = 4; break; case 4: pSummon = m_creature->SummonCreature(NPC_KORRAK_BLOODRAGER, SpawnPosition[0], TEMPSUMMON_CORPSE_DESPAWN, 1000); uiTimer = 3000; uiPhase = 0; break; case 6: m_creature->SummonCreature(NPC_YGGDRAS, SpawnPosition[1], TEMPSUMMON_CORPSE_DESPAWN, 1000); uiPhase = 0; break; case 7: DoScriptText(SAY_QUEST_ACCEPT_MAGNATAUR, m_creature); uiTimer = 3000; uiPhase = 8; break; case 8: m_creature->SummonCreature(NPC_STINKBEARD, SpawnPosition[0], TEMPSUMMON_CORPSE_DESPAWN, 1000); uiPhase = 0; break; } } else uiTimer -= uiDiff; } }
void WorldSession::HandlePetAction( WorldPacket & recv_data ) { ObjectGuid petGuid; uint32 data; ObjectGuid targetGuid; recv_data >> petGuid; recv_data >> data; recv_data >> targetGuid; uint32 spellid = UNIT_ACTION_BUTTON_ACTION(data); uint8 flag = UNIT_ACTION_BUTTON_TYPE(data); //delete = 0x07 CastSpell = C1 DETAIL_LOG("HandlePetAction: %s flag is %u, spellid is %u, target %s.", petGuid.GetString().c_str(), uint32(flag), spellid, targetGuid.GetString().c_str()); // used also for charmed creature/player Unit* pet = _player->GetMap()->GetUnit(petGuid); if (!pet) { sLog.outError("HandlePetAction: %s not exist.", petGuid.GetString().c_str()); return; } if (GetPlayer()->GetObjectGuid() != pet->GetCharmerOrOwnerGuid()) { sLog.outError("HandlePetAction: %s isn't controlled by %s.", petGuid.GetString().c_str(), GetPlayer()->GetGuidStr().c_str()); return; } if (!pet->isAlive()) return; if (pet->GetTypeId() == TYPEID_PLAYER) { // controller player can only do melee attack if (!(flag == ACT_COMMAND && spellid == COMMAND_ATTACK)) return; } else if (((Creature*)pet)->IsPet()) { // pet can have action bar disabled if(((Pet*)pet)->GetModeFlags() & PET_MODE_DISABLE_ACTIONS) return; } CharmInfo *charmInfo = pet->GetCharmInfo(); if(!charmInfo) { sLog.outError("WorldSession::HandlePetAction: object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", pet->GetGUIDLow(), pet->GetTypeId()); return; } switch(flag) { case ACT_COMMAND: //0x07 switch(spellid) { case COMMAND_STAY: //flat=1792 //STAY pet->StopMoving(); pet->GetMotionMaster()->Clear(false); pet->GetMotionMaster()->MoveIdle(); charmInfo->SetCommandState( COMMAND_STAY ); break; case COMMAND_FOLLOW: //spellid=1792 //FOLLOW pet->AttackStop(); pet->GetMotionMaster()->MoveFollow(_player,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE); charmInfo->SetCommandState( COMMAND_FOLLOW ); break; case COMMAND_ATTACK: //spellid=1792 //ATTACK { Unit *TargetUnit = _player->GetMap()->GetUnit(targetGuid); if(!TargetUnit) return; // not let attack friendly units. if(GetPlayer()->IsFriendlyTo(TargetUnit)) return; // Not let attack through obstructions if(!pet->IsWithinLOSInMap(TargetUnit)) return; // This is true if pet has no target or has target but targets differs. if(pet->getVictim() != TargetUnit) { if (pet->getVictim()) pet->AttackStop(); if (pet->hasUnitState(UNIT_STAT_CONTROLLED)) { pet->Attack(TargetUnit, true); pet->SendPetAIReaction(); } else { pet->GetMotionMaster()->Clear(); if (((Creature*)pet)->AI()) ((Creature*)pet)->AI()->AttackStart(TargetUnit); // 10% chance to play special pet attack talk, else growl if(((Creature*)pet)->IsPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != TargetUnit && roll_chance_i(10)) pet->SendPetTalk((uint32)PET_TALK_ATTACK); else { // 90% chance for pet and 100% chance for charmed creature pet->SendPetAIReaction(); } } } break; } case COMMAND_ABANDON: // abandon (hunter pet) or dismiss (summoned pet) if(((Creature*)pet)->IsPet()) { Pet* p = (Pet*)pet; if(p->getPetType() == HUNTER_PET) p->Unsummon(PET_SAVE_AS_DELETED, _player); else //dismissing a summoned pet is like killing them (this prevents returning a soulshard...) p->SetDeathState(CORPSE); } else // charmed _player->Uncharm(); break; default: sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", uint32(flag), spellid); } break; case ACT_REACTION: // 0x6 switch(spellid) { case REACT_PASSIVE: //passive case REACT_DEFENSIVE: //recovery case REACT_AGGRESSIVE: //activete charmInfo->SetReactState( ReactStates(spellid) ); break; } break; case ACT_DISABLED: // 0x81 spell (disabled), ignore case ACT_PASSIVE: // 0x01 case ACT_ENABLED: // 0xC1 spell { Unit* unit_target = NULL; if (!targetGuid.IsEmpty()) unit_target = _player->GetMap()->GetUnit(targetGuid); // do not cast unknown spells SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellid ); if (!spellInfo) { sLog.outError("WORLD: unknown PET spell id %i", spellid); return; } if (pet->GetCharmInfo() && pet->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo)) return; for(int i = 0; i < MAX_EFFECT_INDEX;++i) { if(spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA || spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA_INSTANT || spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED) return; } // do not cast not learned spells if(!pet->HasSpell(spellid) || IsPassiveSpell(spellInfo)) return; pet->clearUnitState(UNIT_STAT_MOVING); Spell *spell = new Spell(pet, spellInfo, false); SpellCastResult result = spell->CheckPetCast(unit_target); //auto turn to target unless possessed if(result == SPELL_FAILED_UNIT_NOT_INFRONT && !pet->HasAuraType(SPELL_AURA_MOD_POSSESS)) { if(unit_target) { pet->SetInFront(unit_target); if (unit_target->GetTypeId() == TYPEID_PLAYER) pet->SendCreateUpdateToPlayer( (Player*)unit_target ); } else if(Unit *unit_target2 = spell->m_targets.getUnitTarget()) { pet->SetInFront(unit_target2); if (unit_target2->GetTypeId() == TYPEID_PLAYER) pet->SendCreateUpdateToPlayer( (Player*)unit_target2 ); } if (Unit* powner = pet->GetCharmerOrOwner()) if(powner->GetTypeId() == TYPEID_PLAYER) pet->SendCreateUpdateToPlayer((Player*)powner); result = SPELL_CAST_OK; } if(result == SPELL_CAST_OK) { ((Creature*)pet)->AddCreatureSpellCooldown(spellid); unit_target = spell->m_targets.getUnitTarget(); //10% chance to play special pet attack talk, else growl //actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell if(((Creature*)pet)->IsPet() && (((Pet*)pet)->getPetType() == SUMMON_PET) && (pet != unit_target) && (urand(0, 100) < 10)) pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL); else { pet->SendPetAIReaction(); } if( unit_target && !GetPlayer()->IsFriendlyTo(unit_target) && !pet->HasAuraType(SPELL_AURA_MOD_POSSESS)) { // This is true if pet has no target or has target but targets differs. if (pet->getVictim() != unit_target) { if (pet->getVictim()) pet->AttackStop(); pet->GetMotionMaster()->Clear(); if (((Creature*)pet)->AI()) ((Creature*)pet)->AI()->AttackStart(unit_target); } } spell->prepare(&(spell->m_targets)); } else { if(pet->HasAuraType(SPELL_AURA_MOD_POSSESS)) Spell::SendCastResult(GetPlayer(),spellInfo,0,result); else pet->SendPetCastFail(spellid, result); if (!((Creature*)pet)->HasSpellCooldown(spellid)) GetPlayer()->SendClearCooldown(spellid, pet); spell->finish(false); delete spell; } break; } default: sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", uint32(flag), spellid); } }
void WorldSession::HandlePetAction(WorldPacket& recv_data) { ObjectGuid petGuid; uint32 data; ObjectGuid targetGuid; float x, y, z; recv_data >> petGuid; recv_data >> data; recv_data >> targetGuid; recv_data >> x >> y >> z; uint32 spellid = UNIT_ACTION_BUTTON_ACTION(data); uint8 flag = UNIT_ACTION_BUTTON_TYPE(data); // delete = 0x07 CastSpell = C1 DETAIL_LOG("HandlePetAction: %s flag is %u, spellid is %u, target %s.", petGuid.GetString().c_str(), uint32(flag), spellid, targetGuid.GetString().c_str()); // used also for charmed creature/player Unit* pet = _player->GetMap()->GetUnit(petGuid); if (!pet) { sLog.outError("HandlePetAction: %s not exist.", petGuid.GetString().c_str()); return; } if (_player->GetObjectGuid() != pet->GetCharmerOrOwnerGuid()) { sLog.outError("HandlePetAction: %s isn't controlled by %s.", petGuid.GetString().c_str(), _player->GetGuidStr().c_str()); return; } if (!pet->isAlive()) return; if (pet->GetTypeId() == TYPEID_PLAYER && pet->GetCharmer()->GetTypeId() == TYPEID_PLAYER) { // controller player cannot use controlled player's spells if (flag != (ACT_COMMAND || ACT_REACTION)) return; } else if (((Creature*)pet)->IsPet()) { // pet can have action bar disabled if (((Pet*)pet)->GetModeFlags() & PET_MODE_DISABLE_ACTIONS) return; } CharmInfo* charmInfo = pet->GetCharmInfo(); if (!charmInfo) { sLog.outError("WorldSession::HandlePetAction: object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", pet->GetGUIDLow(), pet->GetTypeId()); return; } switch (flag) { case ACT_COMMAND: // 0x07 switch (spellid) { case COMMAND_STAY: // flat=1792 // STAY { pet->StopMoving(); pet->AttackStop(true, true); pet->GetMotionMaster()->Clear(); ((Pet*)pet)->SetStayPosition(true); ((Pet*)pet)->SetIsRetreating(); ((Pet*)pet)->SetSpellOpener(); charmInfo->SetCommandState(COMMAND_STAY); break; } case COMMAND_FOLLOW: // spellid=1792 // FOLLOW { pet->StopMoving(); pet->AttackStop(true, true); pet->GetMotionMaster()->Clear(); ((Pet*)pet)->SetStayPosition(); ((Pet*)pet)->SetIsRetreating(true); ((Pet*)pet)->SetSpellOpener(); charmInfo->SetCommandState(COMMAND_FOLLOW); break; } case COMMAND_ATTACK: // spellid=1792 // ATTACK { ((Pet*)pet)->SetIsRetreating(); ((Pet*)pet)->SetSpellOpener(); Unit* targetUnit = targetGuid ? _player->GetMap()->GetUnit(targetGuid) : nullptr; if (targetUnit && targetUnit != pet && targetUnit->isTargetableForAttack() && targetUnit->isInAccessablePlaceFor((Creature*)pet)) { _player->SetInCombatState(true, targetUnit); // This is true if pet has no target or has target but targets differs. if (pet->getVictim() != targetUnit) { pet->AttackStop(); pet->GetMotionMaster()->Clear(); if (((Creature*)pet)->AI()) { ((Creature*)pet)->AI()->AttackStart(targetUnit); // 10% chance to play special warlock pet attack talk, else growl if (((Creature*)pet)->IsPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && roll_chance_i(10)) pet->SendPetTalk((uint32)PET_TALK_ATTACK); pet->SendPetAIReaction(); } else pet->Attack(targetUnit, true); } } break; } case COMMAND_ABANDON: // abandon (hunter pet) or dismiss (summoned pet) { Creature* petC = (Creature*)pet; if (petC->IsPet()) { Pet* p = (Pet*)petC; if (p->getPetType() == HUNTER_PET) p->Unsummon(PET_SAVE_AS_DELETED, _player); else // dismissing a summoned pet is like killing them (this prevents returning a soulshard...) p->SetDeathState(CORPSE); } else // charmed _player->Uncharm(); if (petC->IsTemporarySummon()) // special case when pet was temporary summon through DoSummonPossesed { petC->ForcedDespawn(); return; } ((Pet*)pet)->SetStayPosition(); break; } default: sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", uint32(flag), spellid); } break; case ACT_REACTION: // 0x6 switch (spellid) { case REACT_PASSIVE: // passive { pet->AttackStop(true, true); ((Pet*)pet)->SetSpellOpener(); } case REACT_DEFENSIVE: // recovery case REACT_AGGRESSIVE: // activete { charmInfo->SetReactState(ReactStates(spellid)); break; } } break; case ACT_DISABLED: // 0x81 spell (disabled), ignore case ACT_PASSIVE: // 0x01 case ACT_ENABLED: // 0xC1 spell { ((Pet*)pet)->SetIsRetreating(); ((Pet*)pet)->SetSpellOpener(); Unit* unit_target = targetGuid ? _player->GetMap()->GetUnit(targetGuid) : nullptr; // do not cast unknown spells SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid); if (!spellInfo) { sLog.outError("WORLD: unknown PET spell id %i", spellid); return; } if (pet->GetCharmInfo() && pet->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo)) return; for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(SpellEffectIndex(i)); if (!spellEffect) continue; if (spellEffect->EffectImplicitTargetA == TARGET_ALL_ENEMY_IN_AREA || spellEffect->EffectImplicitTargetA == TARGET_ALL_ENEMY_IN_AREA_INSTANT || spellEffect->EffectImplicitTargetA == TARGET_ALL_ENEMY_IN_AREA_CHANNELED) return; } // do not cast not learned spells if (!pet->HasSpell(spellid) || IsPassiveSpell(spellInfo)) return; pet->clearUnitState(UNIT_STAT_MOVING); Spell* spell = new Spell(pet, spellInfo, false); SpellCastResult result = spell->CheckPetCast(unit_target); const SpellRangeEntry* sRange = sSpellRangeStore.LookupEntry(spellInfo->rangeIndex); if (unit_target && !(pet->IsWithinDistInMap(unit_target, sRange->maxRange) && pet->IsWithinLOSInMap(unit_target)) && !(GetPlayer()->IsFriendlyTo(unit_target) || pet->HasAuraType(SPELL_AURA_MOD_POSSESS))) { ((Pet*)pet)->SetSpellOpener(spellid, sRange->minRange, sRange->maxRange); spell->finish(false); delete spell; pet->AttackStop(); pet->GetMotionMaster()->Clear(); ((Creature*)pet)->AI()->AttackStart(unit_target); // 10% chance to play special warlock pet attack talk, else growl if (((Creature*)pet)->IsPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != unit_target && roll_chance_i(10)) pet->SendPetTalk((uint32)PET_TALK_ATTACK); pet->SendPetAIReaction(); return; } // auto turn to target unless possessed if (result == SPELL_FAILED_UNIT_NOT_INFRONT && !pet->HasAuraType(SPELL_AURA_MOD_POSSESS)) { if (unit_target) { pet->SetInFront(unit_target); if (unit_target->GetTypeId() == TYPEID_PLAYER) pet->SendCreateUpdateToPlayer((Player*)unit_target); } else if (Unit* unit_target2 = spell->m_targets.getUnitTarget()) { pet->SetInFront(unit_target2); if (unit_target2->GetTypeId() == TYPEID_PLAYER) pet->SendCreateUpdateToPlayer((Player*)unit_target2); } if (Unit* powner = pet->GetCharmerOrOwner()) if (powner->GetTypeId() == TYPEID_PLAYER) pet->SendCreateUpdateToPlayer((Player*)powner); result = SPELL_CAST_OK; } if (result == SPELL_CAST_OK) { ((Creature*)pet)->AddCreatureSpellCooldown(spellid); unit_target = spell->m_targets.getUnitTarget(); if (unit_target && !GetPlayer()->IsFriendlyTo(unit_target) && !pet->HasAuraType(SPELL_AURA_MOD_POSSESS)) { // This is true if pet has no target or has target but targets differs. if (pet->getVictim() != unit_target) { pet->AttackStop(); pet->GetMotionMaster()->Clear(); _player->SetInCombatState(true, unit_target); if (((Creature*)pet)->AI()) { ((Creature*)pet)->AI()->AttackStart(unit_target); // 10% chance to play special warlock pet attack talk, else growl if (((Creature*)pet)->IsPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != unit_target && roll_chance_i(10)) pet->SendPetTalk((uint32)PET_TALK_ATTACK); pet->SendPetAIReaction(); } else pet->Attack(unit_target, true); } } ((Pet*)pet)->SetSpellOpener(); spell->SpellStart(&(spell->m_targets)); } else { if (pet->HasAuraType(SPELL_AURA_MOD_POSSESS)) Spell::SendCastResult(GetPlayer(), spellInfo, 0, result); else { Unit* owner = pet->GetCharmerOrOwner(); if (owner && owner->GetTypeId() == TYPEID_PLAYER) Spell::SendCastResult((Player*)owner, spellInfo, 0, result, true); } if (!((Creature*)pet)->HasSpellCooldown(spellid)) GetPlayer()->SendClearCooldown(spellid, pet); ((Pet*)pet)->SetSpellOpener(); spell->finish(false); delete spell; } break; } default: sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", uint32(flag), spellid); } }
void UpdateAI(const uint32 diff) { if (SayTimer <= diff) { if (Event) SayTimer = NextStep(++Step); } else SayTimer -= diff; if (Attack) { Player* player = Unit::GetPlayer(*me, PlayerGUID); me->setFaction(14); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); if (player) { Unit* Creepjack = me->FindNearestCreature(NPC_CREEPJACK, 20); if (Creepjack) { Creepjack->Attack(player, true); Creepjack->setFaction(14); Creepjack->GetMotionMaster()->MoveChase(player); Creepjack->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); } Unit* Malone = me->FindNearestCreature(NPC_MALONE, 20); if (Malone) { Malone->Attack(player, true); Malone->setFaction(14); Malone->GetMotionMaster()->MoveChase(player); Malone->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); } DoStartMovement(player); AttackStart(player); } Attack = false; } if (HealthBelowPct(5) && !Done) { me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->RemoveAllAuras(); Unit* Creepjack = me->FindNearestCreature(NPC_CREEPJACK, 20); if (Creepjack) { CAST_CRE(Creepjack)->AI()->EnterEvadeMode(); Creepjack->setFaction(1194); Creepjack->GetMotionMaster()->MoveTargetedHome(); Creepjack->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); } Unit* Malone = me->FindNearestCreature(NPC_MALONE, 20); if (Malone) { CAST_CRE(Malone)->AI()->EnterEvadeMode(); Malone->setFaction(1194); Malone->GetMotionMaster()->MoveTargetedHome(); Malone->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); } me->setFaction(1194); Done = true; Talk(SAY_GIVEUP); me->DeleteThreatList(); me->CombatStop(); me->GetMotionMaster()->MoveTargetedHome(); Player* player = Unit::GetPlayer(*me, PlayerGUID); if (player) CAST_PLR(player)->GroupEventHappens(QUEST_WBI, me); } DoMeleeAttackIfReady(); }
/// Add control and such modifiers to a passenger if required void VehicleInfo::ApplySeatMods(Unit* passenger, uint32 seatFlags) { Unit* pVehicle = (Unit*)m_owner; // Vehicles are alawys Unit if (seatFlags & SEAT_FLAG_NOT_SELECTABLE) passenger->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); // ToDo: change passenger model id for SEAT_FLAG_HIDE_PASSENGER? if (passenger->GetTypeId() == TYPEID_PLAYER) { Player* pPlayer = (Player*)passenger; // group update if (pPlayer->GetGroup()) pPlayer->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_VEHICLE_SEAT); if (seatFlags & SEAT_FLAG_CAN_CONTROL) { pPlayer->GetCamera().SetView(pVehicle); pPlayer->SetCharm(pVehicle); pVehicle->SetCharmer(pPlayer); pVehicle->GetMotionMaster()->Clear(); pVehicle->GetMotionMaster()->MoveIdle(); pVehicle->StopMoving(true); pVehicle->addUnitState(UNIT_STAT_POSSESSED); pVehicle->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_POSSESSED); pVehicle->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); pPlayer->UpdateClientControl(pVehicle, true); pPlayer->SetMover(pVehicle); // Unconfirmed - default speed handling if (pVehicle->GetTypeId() == TYPEID_UNIT) { if (!pPlayer->IsWalking() && pVehicle->IsWalking()) { ((Creature*)pVehicle)->SetWalk(false, true); } else if (pPlayer->IsWalking() && !pVehicle->IsWalking()) { ((Creature*)pVehicle)->SetWalk(true, true); } // set vehicle faction as per the controller faction ((Creature*)pVehicle)->SetFactionTemporary(pPlayer->getFaction(), TEMPFACTION_NONE); // set vehicle react state to passive; player will control the vehicle pVehicle->AI()->SetReactState(REACT_PASSIVE); } } if (seatFlags & SEAT_FLAG_CAN_CAST) { CharmInfo* charmInfo = pVehicle->InitCharmInfo(pVehicle); charmInfo->InitVehicleCreateSpells(); pPlayer->PossessSpellInitialize(); } } else if (passenger->GetTypeId() == TYPEID_UNIT) { if (seatFlags & SEAT_FLAG_CAN_CONTROL) { passenger->SetCharm(pVehicle); pVehicle->SetCharmer(passenger); // Change vehicle react state; ToDo: also change the vehicle faction? if (pVehicle->GetTypeId() == TYPEID_UNIT) pVehicle->AI()->SetReactState(passenger->AI()->GetReactState()); } ((Creature*)passenger)->AI()->SetCombatMovement(false); // Not entirely sure how this must be handled in relation to CONTROL // But in any way this at least would require some changes in the movement system most likely passenger->GetMotionMaster()->Clear(false, true); passenger->GetMotionMaster()->MoveIdle(); } }