|
|
|
@@ -87,23 +87,36 @@ public:
|
|
|
|
|
// Remove summons if player abandons or rewards a quest
|
|
|
|
|
if (player->GetMapId() == MAP_NPE)
|
|
|
|
|
{
|
|
|
|
|
if (player->GetQuestStatus(questId) == QUEST_STATUS_NONE || player->GetQuestStatus(questId) == QUEST_STATUS_REWARDED)
|
|
|
|
|
QuestStatus const status = player->GetQuestStatus(questId);
|
|
|
|
|
// The copter scene summons a second Lindie on top of the camp. Once the quest is
|
|
|
|
|
// ready to turn in she has to go, or she stands beside the phase copy and the follower.
|
|
|
|
|
bool const copterSceneDone = status == QUEST_STATUS_COMPLETE
|
|
|
|
|
&& (questId == QUEST_THE_SCOUT_O_MATIC_5000 || questId == QUEST_H_THE_CHOPPY_BOOSTER_MK5);
|
|
|
|
|
if (status == QUEST_STATUS_NONE || status == QUEST_STATUS_REWARDED || copterSceneDone)
|
|
|
|
|
{
|
|
|
|
|
std::vector<uint32> activeSummons;
|
|
|
|
|
switch (questId)
|
|
|
|
|
{
|
|
|
|
|
case QUEST_H_THE_CHOPPY_BOOSTER_MK5:
|
|
|
|
|
activeSummons.push_back(NPC_DARKMAUL_PLAINS_CHOPPYBOOSTER_SUMMONER);
|
|
|
|
|
if (!copterSceneDone)
|
|
|
|
|
activeSummons.push_back(NPC_DARKMAUL_PLAINS_CHOPPYBOOSTER_OBSERVER);
|
|
|
|
|
activeSummons.push_back(NPC_DARKMAUL_PLAINS_FIZZLEPOP);
|
|
|
|
|
break;
|
|
|
|
|
case QUEST_THE_SCOUT_O_MATIC_5000:
|
|
|
|
|
activeSummons.push_back(NPC_DARKMAUL_PLAINS_SCOUTOMATIC_SUMMONER);
|
|
|
|
|
if (!copterSceneDone)
|
|
|
|
|
activeSummons.push_back(NPC_DARKMAUL_PLAINS_SCOUTOMATIC_OBSERVER);
|
|
|
|
|
activeSummons.push_back(NPC_DARKMAUL_PLAINS_SPRINGSTOCK);
|
|
|
|
|
break;
|
|
|
|
|
case QUEST_RE_SIZING_THE_SITUATION:
|
|
|
|
|
activeSummons.push_back(NPC_DARKMAUL_PLAINS_WANDERING_BOAR_SUMMON);
|
|
|
|
|
activeSummons.push_back(NPC_DARKMAUL_PLAINS_RESIZED_BOAR);
|
|
|
|
|
activeSummons.push_back(NPC_DARKMAUL_PLAINS_SPRINGSTOCK_RESIZING_SUMMON);
|
|
|
|
|
break;
|
|
|
|
|
case QUEST_H_RE_SIZING_THE_SITUATION:
|
|
|
|
|
activeSummons.push_back(NPC_DARKMAUL_PLAINS_RESIZED_BOAR);
|
|
|
|
|
activeSummons.push_back(NPC_DARKMAUL_PLAINS_FIZZLEPOP_RESIZING_SUMMON);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -267,7 +280,8 @@ struct npc_exiles_reach_darkmaul_plains_167905_156526 : public VehicleAI
|
|
|
|
|
{
|
|
|
|
|
if (timer <= diff)
|
|
|
|
|
{
|
|
|
|
|
if (Unit* passenger = me->GetVehicleKit()->GetPassenger(0))
|
|
|
|
|
Vehicle* kit = me->GetVehicleKit();
|
|
|
|
|
if (Unit* passenger = kit ? kit->GetPassenger(0) : nullptr)
|
|
|
|
|
{
|
|
|
|
|
if (Player* player = passenger->ToPlayer())
|
|
|
|
|
{
|
|
|
|
@@ -353,15 +367,13 @@ struct npc_exiles_reach_darkmaul_plains_156267 : public VehicleAI
|
|
|
|
|
{
|
|
|
|
|
if (Player* player = summoner->ToPlayer())
|
|
|
|
|
{
|
|
|
|
|
if (me->GetAreaId() == AREA_DARKMAUL_PLAINS)
|
|
|
|
|
if (me->GetAreaId() == AREA_DARKMAUL_PLAINS && me->GetVehicleKit())
|
|
|
|
|
{
|
|
|
|
|
if (Creature* garrick = player->GetSummonedCreatureByEntry(NPC_OGRE_RUINS_TORGOK_FIGHTER_A))
|
|
|
|
|
{
|
|
|
|
|
garrick->EnterVehicle(me, 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Cork Fizzlepop, Lindie Springstock (Darkmaul Plains) (Re-Sizing the Situation)
|
|
|
|
@@ -382,19 +394,45 @@ struct npc_exiles_reach_darkmaul_plains_167915_156749 : public ScriptedAI
|
|
|
|
|
me->FollowTarget(player);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
|
|
|
|
|
{
|
|
|
|
|
// 305754 is the ping the third Re-Sizer test sends. She runs back to camp once.
|
|
|
|
|
if (!spellInfo || spellInfo->Id != SPELL_PING_LINDIE)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
_events.ScheduleEvent(EVENT_RESIZING_RUN_HOME, 2s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MovementInform(uint32 type, uint32 id) override
|
|
|
|
|
{
|
|
|
|
|
if (type != POINT_MOTION_TYPE || id != POINT_RESIZING_HOME)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (Unit* owner = me->GetCharmerOrOwnerPlayerOrPlayerItself())
|
|
|
|
|
me->CastSpell(owner, SPELL_LINDIE_DESUMMON, true);
|
|
|
|
|
else
|
|
|
|
|
me->DespawnOrUnsummon();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UpdateAI(uint32 diff) override
|
|
|
|
|
{
|
|
|
|
|
if (timer <= diff)
|
|
|
|
|
_events.Update(diff);
|
|
|
|
|
|
|
|
|
|
while (uint32 eventId = _events.ExecuteEvent())
|
|
|
|
|
{
|
|
|
|
|
if (me->GetPosition().IsInDist(ResizingTheSituationPositions[1], 1.f))
|
|
|
|
|
me->CastSpell(me->GetCharmerOrOwnerPlayerOrPlayerItself(), SPELL_LINDIE_DESUMMON, true);
|
|
|
|
|
if (eventId == EVENT_RESIZING_RUN_HOME)
|
|
|
|
|
me->GetMotionMaster()->MovePoint(POINT_RESIZING_HOME, ResizingTheSituationPositions[1]);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
timer -= diff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
uint32 timer = 1000;
|
|
|
|
|
enum ResizingGuardianEvents
|
|
|
|
|
{
|
|
|
|
|
EVENT_RESIZING_RUN_HOME = 1,
|
|
|
|
|
POINT_RESIZING_HOME = 0
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
EventMap _events;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Wandering Boar (Darkmaul Plains) (Re-Sizing the Situation)
|
|
|
|
@@ -402,20 +440,51 @@ struct npc_exiles_reach_darkmaul_plains_156736_156716 : public ScriptedAI
|
|
|
|
|
{
|
|
|
|
|
npc_exiles_reach_darkmaul_plains_156736_156716(Creature* creature) : ScriptedAI(creature) {}
|
|
|
|
|
|
|
|
|
|
bool IsResizedBoar() const
|
|
|
|
|
{
|
|
|
|
|
return me->GetEntry() == NPC_DARKMAUL_PLAINS_RESIZED_BOAR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Reset() override
|
|
|
|
|
{
|
|
|
|
|
if (IsResizedBoar())
|
|
|
|
|
{
|
|
|
|
|
me->SetReactState(REACT_PASSIVE);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_events.Reset();
|
|
|
|
|
_events.ScheduleEvent(1, 3s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JustAppeared() override
|
|
|
|
|
{
|
|
|
|
|
if (!IsResizedBoar())
|
|
|
|
|
{
|
|
|
|
|
CreatureAI::JustAppeared();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Do not follow the player. The boar grows, then walks to the camp and despawns.
|
|
|
|
|
me->SetReactState(REACT_PASSIVE);
|
|
|
|
|
_events.Reset();
|
|
|
|
|
_events.ScheduleEvent(EVENT_RESIZED_BOAR_GROW, 1s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JustEngagedWith(Unit* who) override
|
|
|
|
|
{
|
|
|
|
|
if (IsResizedBoar())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
me->CastSpell(who, SPELL_WANDERING_BOAR_MOB_CHARGE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// creature shouldn't die at resizing the situation quest otherwise killcredit doubled
|
|
|
|
|
void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
|
|
|
|
|
{
|
|
|
|
|
if (IsResizedBoar())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (Player* player = attacker->ToPlayer())
|
|
|
|
|
{
|
|
|
|
|
if (damage > me->GetHealth() && (player->GetQuestStatus(QUEST_RE_SIZING_THE_SITUATION) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(QUEST_H_RE_SIZING_THE_SITUATION) == QUEST_STATUS_INCOMPLETE))
|
|
|
|
@@ -426,32 +495,51 @@ struct npc_exiles_reach_darkmaul_plains_156736_156716 : public ScriptedAI
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void IsSummonedBy(WorldObject* summoner) override
|
|
|
|
|
void MovementInform(uint32 type, uint32 id) override
|
|
|
|
|
{
|
|
|
|
|
Player* player = summoner->ToPlayer();
|
|
|
|
|
if (!player)
|
|
|
|
|
if (!IsResizedBoar() || type != POINT_MOTION_TYPE || id != POINT_RESIZED_BOAR_CAMP)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
me->CastSpell(me, SPELL_GROW_1);
|
|
|
|
|
me->GetMotionMaster()->MovePoint(0, ResizingTheSituationPositions[0].GetPositionX(), ResizingTheSituationPositions[0].GetPositionY(), ResizingTheSituationPositions[0].GetPositionZ(), true, 0.7f);
|
|
|
|
|
player->KilledMonsterCredit(156722);
|
|
|
|
|
me->SetFacingTo(0.785398f);
|
|
|
|
|
|
|
|
|
|
if (Creature* springstock = player->GetSummonedCreatureByEntry(NPC_DARKMAUL_PLAINS_SPRINGSTOCK_RESIZING_SUMMON))
|
|
|
|
|
springstock->GetMotionMaster()->MovePoint(0, ResizingTheSituationPositions[1].GetPositionX(), ResizingTheSituationPositions[1].GetPositionY(), ResizingTheSituationPositions[1].GetPositionZ(), true, 4.f);
|
|
|
|
|
Unit* summoner = nullptr;
|
|
|
|
|
if (TempSummon* summoned = me->ToTempSummon())
|
|
|
|
|
summoner = summoned->GetSummonerUnit();
|
|
|
|
|
if (!summoner)
|
|
|
|
|
summoner = me->GetOwner();
|
|
|
|
|
|
|
|
|
|
if (Creature* fizzlepop = player->GetSummonedCreatureByEntry(NPC_DARKMAUL_PLAINS_FIZZLEPOP_RESIZING_SUMMON))
|
|
|
|
|
fizzlepop->GetMotionMaster()->MovePoint(0, ResizingTheSituationPositions[1].GetPositionX(), ResizingTheSituationPositions[1].GetPositionY(), ResizingTheSituationPositions[1].GetPositionZ(), true, 4.f);
|
|
|
|
|
if (summoner)
|
|
|
|
|
if (Player* player = summoner->ToPlayer())
|
|
|
|
|
player->CastSpell(player, SPELL_UPDATE_PHASESHIFT, true);
|
|
|
|
|
|
|
|
|
|
me->DespawnOrUnsummon();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UpdateAI(uint32 diff) override
|
|
|
|
|
{
|
|
|
|
|
if (timer <= diff)
|
|
|
|
|
if (IsResizedBoar())
|
|
|
|
|
{
|
|
|
|
|
if (me->GetPosition().IsInDist(ResizingTheSituationPositions[0], 1.f))
|
|
|
|
|
me->DespawnOrUnsummon();
|
|
|
|
|
_events.Update(diff);
|
|
|
|
|
|
|
|
|
|
while (uint32 eventId = _events.ExecuteEvent())
|
|
|
|
|
{
|
|
|
|
|
switch (eventId)
|
|
|
|
|
{
|
|
|
|
|
case EVENT_RESIZED_BOAR_GROW:
|
|
|
|
|
me->CastSpell(me, SPELL_GROW_1, true);
|
|
|
|
|
me->PlayDirectSound(SOUND_RESIZED_BOAR_GROW);
|
|
|
|
|
_events.ScheduleEvent(EVENT_RESIZED_BOAR_MOVE, 1s);
|
|
|
|
|
break;
|
|
|
|
|
case EVENT_RESIZED_BOAR_MOVE:
|
|
|
|
|
me->SetWalk(false);
|
|
|
|
|
me->GetMotionMaster()->MovePoint(POINT_RESIZED_BOAR_CAMP, ResizingTheSituationPositions[0]);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
timer -= diff;
|
|
|
|
|
|
|
|
|
|
if (!UpdateVictim())
|
|
|
|
|
return;
|
|
|
|
@@ -476,8 +564,14 @@ struct npc_exiles_reach_darkmaul_plains_156736_156716 : public ScriptedAI
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
enum ResizedBoarEvents
|
|
|
|
|
{
|
|
|
|
|
EVENT_RESIZED_BOAR_GROW = 2,
|
|
|
|
|
EVENT_RESIZED_BOAR_MOVE = 3,
|
|
|
|
|
POINT_RESIZED_BOAR_CAMP = 1
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
EventMap _events;
|
|
|
|
|
uint32 timer = 1000;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Lightspawn (Darkmaul Plains)
|
|
|
|
@@ -700,20 +794,6 @@ public:
|
|
|
|
|
|
|
|
|
|
class spell_re_sizing_305716_AuraScript : public AuraScript
|
|
|
|
|
{
|
|
|
|
|
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
|
|
|
|
{
|
|
|
|
|
Unit* caster = GetCaster();
|
|
|
|
|
Unit* target = GetUnitOwner();
|
|
|
|
|
|
|
|
|
|
if (!caster || !target || !target->IsCreature())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
Creature* creature = caster->ToCreature();
|
|
|
|
|
|
|
|
|
|
if (creature->GetEntry() != NPC_DARKMAUL_PLAINS_WANDERING_BOAR)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
|
|
|
|
{
|
|
|
|
|
Unit* caster = GetCaster();
|
|
|
|
@@ -730,30 +810,47 @@ public:
|
|
|
|
|
caster->SetChannelSpellId(0);
|
|
|
|
|
caster->SetChannelVisual({});
|
|
|
|
|
|
|
|
|
|
uint32 hitVariants[3] = { SPELL_RESIZER_HIT_TOSMALL, SPELL_RESIZER_HIT_EXPLODE, SPELL_RESIZER_OVERCHARGE };
|
|
|
|
|
uint32 selectedFailedSpell = hitVariants[rand() % 3];
|
|
|
|
|
// GetQuestStatus is an enum. Any non-zero status, including already turned in, used to count as "on the quest".
|
|
|
|
|
uint32 questId = 0;
|
|
|
|
|
if (player->GetQuestStatus(QUEST_RE_SIZING_THE_SITUATION) == QUEST_STATUS_INCOMPLETE)
|
|
|
|
|
questId = QUEST_RE_SIZING_THE_SITUATION;
|
|
|
|
|
else if (player->GetQuestStatus(QUEST_H_RE_SIZING_THE_SITUATION) == QUEST_STATUS_INCOMPLETE)
|
|
|
|
|
questId = QUEST_H_RE_SIZING_THE_SITUATION;
|
|
|
|
|
|
|
|
|
|
if (player->GetQuestStatus(QUEST_RE_SIZING_THE_SITUATION) || player->GetQuestStatus(QUEST_H_RE_SIZING_THE_SITUATION))
|
|
|
|
|
{
|
|
|
|
|
if (selectedFailedSpell == SPELL_RESIZER_HIT_EXPLODE && QuestAccepted(player, QUEST_H_THE_REDEATHER))
|
|
|
|
|
PlayExileConversation(player, CONVERSATION_REDEATHER_EXPLODE);
|
|
|
|
|
if (!questId)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (player->GetQuestObjectiveProgress(QUEST_RE_SIZING_THE_SITUATION, 0) < 2)
|
|
|
|
|
// 0 shrinks the boar, 1 bursts it, 2 grows the re-sized boar and sends Lindie home.
|
|
|
|
|
// Despawn is delayed so the aura owner is not deleted inside this hook. The old
|
|
|
|
|
// immediate despawn, plus a kill credit from the boar script, crashed the worldserver.
|
|
|
|
|
int32 const tests = player->GetQuestObjectiveProgress(questId, 0);
|
|
|
|
|
if (tests <= 0)
|
|
|
|
|
{
|
|
|
|
|
player->CastSpell(target, selectedFailedSpell, true);
|
|
|
|
|
player->CastSpell(creature, SPELL_RESIZER_HIT_TOSMALL, true);
|
|
|
|
|
creature->DespawnOrUnsummon(2s);
|
|
|
|
|
}
|
|
|
|
|
else if (tests == 1)
|
|
|
|
|
{
|
|
|
|
|
player->CastSpell(creature, SPELL_RESIZER_HIT_EXPLODE, true);
|
|
|
|
|
creature->DespawnOrUnsummon(2s);
|
|
|
|
|
}
|
|
|
|
|
else if (questId == QUEST_H_RE_SIZING_THE_SITUATION)
|
|
|
|
|
{
|
|
|
|
|
player->CastSpell(creature, SPELL_RESIZER_OVERCHARGE, true);
|
|
|
|
|
player->CastSpell(player, SPELL_PING_LINDIE, true);
|
|
|
|
|
creature->DespawnOrUnsummon(3s);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
player->CastSpell(target, SPELL_RESIZER_SPARKS_AND_BOAR_SUMMON, true);
|
|
|
|
|
creature->DespawnOrUnsummon();
|
|
|
|
|
}
|
|
|
|
|
player->CastSpell(creature, SPELL_RESIZER_SPARKS_AND_BOAR_SUMMON, true);
|
|
|
|
|
player->CastSpell(player, SPELL_PING_LINDIE, true);
|
|
|
|
|
creature->DespawnOrUnsummon(2s);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Register() override
|
|
|
|
|
{
|
|
|
|
|
OnEffectApply += AuraEffectApplyFn(spell_re_sizing_305716_AuraScript::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
|
|
|
|
OnEffectRemove += AuraEffectRemoveFn(spell_re_sizing_305716_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
|
|
|
|
AfterEffectRemove += AuraEffectRemoveFn(spell_re_sizing_305716_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
@@ -941,12 +1038,27 @@ public:
|
|
|
|
|
{
|
|
|
|
|
PreventHitDefaultEffect(effIndex);
|
|
|
|
|
|
|
|
|
|
WorldLocation const* loc = GetExplTargetDest();
|
|
|
|
|
Unit* caster = GetCaster();
|
|
|
|
|
if (!caster)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
caster->GetMotionMaster()->MoveCharge(loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ());
|
|
|
|
|
// The ride scene casts this at the boar with no destination. A null dest crashed the worldserver.
|
|
|
|
|
float x, y, z;
|
|
|
|
|
if (WorldLocation const* loc = GetExplTargetDest())
|
|
|
|
|
{
|
|
|
|
|
x = loc->GetPositionX();
|
|
|
|
|
y = loc->GetPositionY();
|
|
|
|
|
z = loc->GetPositionZ();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Position dest = caster->GetFirstCollisionPosition(20.f, 0.f);
|
|
|
|
|
x = dest.GetPositionX();
|
|
|
|
|
y = dest.GetPositionY();
|
|
|
|
|
z = dest.GetPositionZ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
caster->GetMotionMaster()->MoveCharge(x, y, z);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Register()
|
|
|
|
|