void BeginEncounter() { if (instance->GetBossState(BOSS_HORSEMEN) == IN_PROGRESS) return; if (!instance->CheckRequiredBosses(BOSS_HORSEMEN)) { ResetEncounter(); return; } instance->SetBossState(BOSS_HORSEMEN, IN_PROGRESS); Map::PlayerList const &players = me->GetMap()->GetPlayers(); if (players.isEmpty()) // sanity check ResetEncounter(); for (Horseman boss : horsemen) { if (Creature* cBoss = getHorsemanHandle(boss)) { if (!cBoss->IsAlive()) { ResetEncounter(); return; } cBoss->SetReactState(REACT_PASSIVE); cBoss->AttackStop(); // clear initial target that was set on enter combat cBoss->setActive(true); for (Map::PlayerList::const_iterator it = players.begin(); it != players.end(); ++it) { if (Player* player = it->GetSource()) { if (player->IsGameMaster()) continue; if (player->IsAlive()) { cBoss->AddThreat(player, 0.0f); cBoss->SetInCombatWith(player); player->SetInCombatWith(cBoss); } } } /* Why do the Four Horsemen run to opposite corners of the room when engaged? * * They saw all the mobs leading up to them being AoE'd down and made a judgment call. */ cBoss->AI()->DoAction(ACTION_BEGIN_MOVEMENT); } else { TC_LOG_WARN("scripts", "FourHorsemenAI: Encounter starting but horseman with id %u is not present", uint32(boss)); ResetEncounter(); return; } } }
void JustDied(Unit* /*killer*/) override { if (instance->GetBossState(BOSS_HORSEMEN) != IN_PROGRESS) // necessary in case a horseman gets one-shot { BeginEncounter(); return; } Talk(SAY_DEATH); _timeDied = getMSTime(); for (Horseman boss : horsemen) { if (Creature* cBoss = getHorsemanHandle(boss)) { if (cBoss->IsAlive()) { // in case a horseman dies while moving (unlikely but possible especially in non-335 branch) CheckIsMovementFinished(); return; } } else { TC_LOG_WARN("scripts", "FourHorsemenAI: %s died but horseman with id %u is not present", me->GetName().c_str(), uint32(boss)); ResetEncounter(); } } EncounterCleared(); }
void Reset() { _Reset(); RemoveSummons(); me->SetDisplayId(me->GetNativeDisplayId()); me->ClearUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED); Map* pMap = me->GetMap(); if (pMap && pMap->IsDungeon() && !bStartCombat) { bReset = true; Map::PlayerList const &players = pMap->GetPlayers(); for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) { if(itr->getSource() && itr->getSource()->isAlive() && !itr->getSource()->isGameMaster()) bReset = false; } } else bReset = true; ResetEncounter(); //me->SummonCreature(28859,me->GetPositionX(),me->GetPositionY(),me->GetPositionZ(),0,TEMsummon_CORPSE_DESPAWN); //uiState=IDLE; bEventInProgress = false; bEvent = false; bSummonArmy = false; bDeathArmyDone = false; uiPhase = PHASE_UNDEAD; uiIcyTouchTimer = urand(5000,9000); uiIcyTouch1Timer = urand(15000,15000); uiPlagueStrikeTimer = urand(10000,13000); uiPlagueStrike1Timer = urand(14000,14000); uiDeathRespiteTimer = urand(17000,17000); uiObliterateTimer = urand(17000,19000); uiObliterate1Timer = urand(15000,15000); uiDesecration = urand(15000,16000); uiDesecration1 = urand(22000,22000); uiDeathArmyCheckTimer = 7000; uiResurrectTimer = 4000; uiGhoulExplodeTimer = 8000; uiDeathBiteTimer = urand (2000,4000); uiMarkedDeathTimer = urand (5000,7000); }
void CheckIsMovementFinished() { for (Horseman boss : horsemen) { if (Creature* cBoss = getHorsemanHandle(boss)) { if (cBoss->IsAlive() && !cBoss->AI()->GetData(DATA_MOVEMENT_FINISHED)) return; } else { TC_LOG_WARN("scripts", "FourHorsemenAI: Checking if movement is finished but horseman with id %u is not present", uint32(boss)); ResetEncounter(); return; } } for (Horseman boss : horsemen) if (Creature* cBoss = getHorsemanHandle(boss)) cBoss->AI()->DoAction(ACTION_BEGIN_FIGHTING); }
void BeginFighting() override { SetCombatMovement(true); me->SetReactState(REACT_AGGRESSIVE); ThreatManager& threat = me->getThreatManager(); if (threat.isThreatListEmpty()) { if (Unit* nearest = me->SelectNearestPlayer(5000.0f)) { me->AddThreat(nearest, 1.0f); AttackStart(nearest); } else ResetEncounter(); } else AttackStart(threat.getHostilTarget()); events.ScheduleEvent(EVENT_BERSERK, Minutes(10)); events.ScheduleEvent(EVENT_MARK, Seconds(24)); events.ScheduleEvent(EVENT_METEOR, randtime(Seconds(10), Seconds(25))); }
void EnterEvadeMode(EvadeReason /*why*/) override { ResetEncounter(); }