Last active
February 21, 2018 03:56
-
-
Save sirikfoll/16c1d9f9f2ab856bb83f to your computer and use it in GitHub Desktop.
Quest The Balance of Light and Shadow support (npc eris havenfire, npc fleeing peasant/plagued peasant)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
enum ErisHavenfireSays | |
{ | |
SAY_DEATH = 0, | |
SAY_SPAWN = 1, | |
SAY_SAVED = 2, | |
SAY_EMPOWER = 0, | |
SAY_COMPLETE = 1, | |
SAY_FAILED1 = 2, | |
SAY_FAILED2 = 3 | |
}; | |
enum ErisHavenfireMisc | |
{ | |
QUEST_THE_BALANCE_OF_LIGHT_AND_SHADOW = 7622, | |
NPC_INJURED_PEASANT = 14484, | |
NPC_SCOURGE_ARCHER = 14489, | |
NPC_SCOURGE_FOOTSOLDIER = 14486, | |
NPC_PLAGUED_PEASANT = 14485, | |
SPELL_BLESSING_OF_NORDRASSIL = 23108, | |
SPELL_DEATH_DOOR = 23127, | |
SPELL_SEETHING_PLAGUE = 23072, | |
SPELL_ENTER_THE_LIGHT_DND = 23107, | |
SPELL_SHOOT = 23073, | |
ACTION_START_SPAWN = 0, | |
ACTION_SEARCH_TARGETS = 1, | |
SUCCESS = 50, | |
FAILED = 15, | |
MAX_PEASANTS = 12, | |
MAX_ARCHERS = 8, | |
}; | |
Position const ArcherPositions[11] = | |
{ | |
// Archers | |
{ 3327.42f, -3021.11f, 170.57f, 6.01f }, | |
{ 3335.4f, -3054.3f, 173.63f, 0.49f }, | |
{ 3351.3f, -3079.08f, 178.67f, 1.15f }, | |
{ 3358.93f, -3076.1f, 174.87f, 1.57f }, | |
{ 3371.58f, -3069.24f, 175.20f, 1.99f }, | |
{ 3369.46f, -3023.11f, 171.83f, 3.69f }, | |
{ 3383.25f, -3057.01f, 181.53f, 2.21f }, | |
{ 3380.03f, -3062.73f, 181.90f, 2.31f }, | |
// Footsoldiers | |
{ 3347.603271f, -3045.536377f, 164.029877f, 1.814429f }, | |
{ 3363.609131f, -3037.187256f, 163.541885f, 2.277649f }, | |
{ 3349.105469f, -3056.500977f, 168.079468f, 1.857460f }, | |
}; | |
Position const PeasantMoveLoc = { 3335.0f, -2994.04f, 161.14f }; | |
Position const PeasantsPos[12] = | |
{ | |
{ 3364.47f, -3048.50f, 165.17f, 1.86f }, | |
{ 3363.24f, -3052.06f, 165.26f, 2.095f }, | |
{ 3362.33f, -3049.37f, 165.23f, 1.54f }, | |
{ 3360.13f, -3052.63f, 165.31f, 1.88f }, | |
{ 3361.05f, -3055.49f, 165.31f, 2.041f }, | |
{ 3363.92f, -3046.96f, 165.09f, 2.13f }, | |
{ 3366.83f, -3052.23f, 165.41f, 2.044f }, | |
{ 3367.79f, -3047.80f, 165.16f, 2.08f }, | |
{ 3358.76f, -3050.37f, 165.21f, 2.05f }, | |
{ 3366.63f, -3045.29f, 164.99f, 2.19f }, | |
{ 3357.45f, -3052.82f, 165.50f, 2.006f }, | |
{ 3363.00f, -3044.21f, 164.80f, 2.182f } | |
}; | |
struct npc_eris_havenfire : public ScriptedAI | |
{ | |
npc_eris_havenfire(Creature* creature) : ScriptedAI(creature), _summons(me) { } | |
void Reset() | |
{ | |
_scheduler.CancelAll(); | |
_summons.DespawnAll(); | |
_failCounter = 0; | |
_winCounter = 0; | |
_eventActive = false; | |
} | |
void JustSummoned(Creature* summon) override | |
{ | |
_summons.Summon(summon); | |
} | |
void FinishQuest(bool success) | |
{ | |
if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID)) | |
{ | |
if (Group* group = player->GetGroup()) | |
{ | |
for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) | |
if (Player* member = itr->GetSource()) | |
{ | |
if (success) | |
member->CompleteQuest(QUEST_THE_BALANCE_OF_LIGHT_AND_SHADOW); | |
else if (player->GetQuestStatus(QUEST_THE_BALANCE_OF_LIGHT_AND_SHADOW) == QUEST_STATUS_INCOMPLETE) | |
member->FailQuest(QUEST_THE_BALANCE_OF_LIGHT_AND_SHADOW); | |
} | |
} | |
else if (success) | |
player->CompleteQuest(QUEST_THE_BALANCE_OF_LIGHT_AND_SHADOW); | |
else if (player->GetQuestStatus(QUEST_THE_BALANCE_OF_LIGHT_AND_SHADOW) == QUEST_STATUS_INCOMPLETE) | |
player->FailQuest(QUEST_THE_BALANCE_OF_LIGHT_AND_SHADOW); | |
} | |
if (success) | |
{ | |
Talk(SAY_COMPLETE); | |
Reset(); | |
} | |
else | |
{ | |
Talk(SAY_FAILED1); | |
Talk(SAY_FAILED2); | |
//me->DespawnOrUnsummon(Seconds(2)); | |
} | |
} | |
void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override | |
{ | |
if (summon->GetEntry() == NPC_INJURED_PEASANT || summon->GetEntry() == NPC_PLAGUED_PEASANT) | |
++_failCounter; | |
if (_failCounter >= FAILED) | |
FinishQuest(false); | |
} | |
void SetData(uint32 /*data*/, uint32 /*value*/) override | |
{ | |
++_winCounter; | |
if (_winCounter >= SUCCESS) | |
FinishQuest(true); | |
} | |
void DoAction(int32 action) override | |
{ | |
if (!_eventActive && action == ACTION_START_SPAWN) | |
{ | |
_eventActive = true; | |
for (uint8 i = 0; i < MAX_ARCHERS; i++) | |
if (Creature* archer = me->SummonCreature(NPC_SCOURGE_ARCHER, ArcherPositions[i], TEMPSUMMON_TIMED_DESPAWN, 5 * MINUTE * IN_MILLISECONDS)) | |
{ | |
archer->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_1); | |
} | |
_scheduler.Schedule(Seconds(10), [this](TaskContext waves) | |
{ | |
if (waves.GetRepeatCounter() > 5) | |
_scheduler.CancelAll(); | |
for (uint8 i = 0; i <= MAX_PEASANTS; i++) | |
if (Creature* peasant = me->SummonCreature(roll_chance_i(70) ? NPC_INJURED_PEASANT : NPC_PLAGUED_PEASANT, PeasantsPos[i], TEMPSUMMON_DEAD_DESPAWN)) | |
if (peasant->GetEntry() == NPC_PLAGUED_PEASANT) | |
peasant->CastSpell(peasant, roll_chance_i(70) ? SPELL_SEETHING_PLAGUE : SPELL_DEATH_DOOR, true); | |
if (Creature* peasant = me->FindNearestCreature(NPC_INJURED_PEASANT, 100.0f, true)) | |
peasant->AI()->Talk(SAY_SPAWN); | |
EntryCheckPredicate pred(NPC_SCOURGE_ARCHER); | |
_summons.DoAction(ACTION_SEARCH_TARGETS, pred); | |
waves.Repeat(Seconds(60)); | |
}); | |
_scheduler.Schedule(Seconds(72), [this](TaskContext soldiers) | |
{ | |
for (uint8 i = 0; i < urand(2, 3); ++i) | |
if (Creature* soldier = me->SummonCreature(NPC_SCOURGE_FOOTSOLDIER, PeasantsPos[urand(0, 11)], TEMPSUMMON_CORPSE_DESPAWN)) | |
{ | |
if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID)) | |
soldier->AI()->AttackStart(player); | |
} | |
soldiers.Repeat(Seconds(20), Seconds(40)); | |
}); | |
_scheduler.Schedule(Seconds(2), [this](TaskContext heal) | |
{ | |
heal.Repeat(); | |
if (Player* priest = ObjectAccessor::GetPlayer(*me, _playerGUID)) | |
if (priest->IsAlive()) | |
{ | |
if (!priest->HasAuraEffect(SPELL_BLESSING_OF_NORDRASSIL, EFFECT_0) && priest->GetMaxPower(POWER_MANA) && (100.0f * priest->GetPower(POWER_MANA) / priest->GetMaxPower(POWER_MANA)) < 35.0f) | |
{ | |
me->CastSpell(priest, SPELL_BLESSING_OF_NORDRASSIL, true); | |
Talk(SAY_EMPOWER); | |
} | |
} | |
else | |
FinishQuest(false); | |
}); | |
} | |
} | |
void UpdateAI(uint32 diff) override | |
{ | |
if (!_eventActive) | |
return; | |
_scheduler.Update(diff); | |
} | |
void QuestAccept(Player* player, Quest const* quest) override | |
{ | |
if (!_eventActive && quest->GetQuestId() == QUEST_THE_BALANCE_OF_LIGHT_AND_SHADOW) | |
{ | |
DoAction(ACTION_START_SPAWN); | |
_playerGUID = player->GetGUID(); | |
} | |
} | |
private: | |
SummonList _summons; | |
uint32 _failCounter; | |
uint32 _winCounter; | |
bool _eventActive; | |
TaskScheduler _scheduler; | |
ObjectGuid _playerGUID; | |
}; | |
class ArcherTargetSelector | |
{ | |
public: | |
ArcherTargetSelector() { } | |
bool operator()(WorldObject* target) const | |
{ | |
return target->GetTypeId() != TYPEID_PLAYER; | |
} | |
}; | |
struct npc_scourge_archer : public ScriptedAI | |
{ | |
npc_scourge_archer(Creature *creature) : ScriptedAI(creature) | |
{ | |
SetCombatMovement(false); | |
me->SetReactState(REACT_AGGRESSIVE); | |
} | |
void DoAction(int32 action) override | |
{ | |
if (action == ACTION_SEARCH_TARGETS) | |
{ | |
ResetThreatList(); | |
std::vector<Creature*> peasants; | |
me->GetCreatureListWithEntryInGrid(peasants, NPC_PLAGUED_PEASANT, 48.0f); | |
me->GetCreatureListWithEntryInGrid(peasants, NPC_INJURED_PEASANT, 48.0f); | |
for (Creature* peasant : peasants) | |
{ | |
me->GetThreatManager().AddThreat(peasant, 1.0f); | |
} | |
} | |
} | |
void Reset() override | |
{ | |
_scheduler.Schedule(Seconds(1), [this](TaskContext shoot) | |
{ | |
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, ArcherTargetSelector())) | |
{ | |
DoCast(target, SPELL_SHOOT, true); | |
} | |
shoot.Repeat(Milliseconds(1517)); | |
}); | |
} | |
void EnterEvadeMode(EvadeReason why) override | |
{ | |
std::cout << "\n Evade"; | |
} | |
void UpdateAI(uint32 diff) override | |
{ | |
UpdateVictim(); | |
_scheduler.Update(diff); | |
} | |
private: | |
TaskScheduler _scheduler; | |
}; | |
struct npc_fleeing_peasant : public ScriptedAI | |
{ | |
npc_fleeing_peasant(Creature *creature) : ScriptedAI(creature) { } | |
void Reset() | |
{ | |
me->SetWalk(true); | |
me->SetSpeed(MOVE_WALK, 0.45f); | |
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); | |
me->SetReactState(REACT_PASSIVE); | |
me->GetMotionMaster()->MovePoint(1, PeasantMoveLoc); | |
} | |
void MovementInform(uint32 type, uint32 point) override | |
{ | |
if (type != POINT_MOTION_TYPE && point != 1) | |
return; | |
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); | |
me->RemoveAllAuras(); | |
DoCastSelf(SPELL_ENTER_THE_LIGHT_DND); | |
Talk(SAY_SAVED); | |
me->DespawnOrUnsummon(Seconds(2)); | |
if (Creature* eris = me->FindNearestCreature(14494, 200.0f, true)) | |
eris->ToCreature()->AI()->SetData(1, 1); | |
} | |
void JustDied(Unit* /*killer*/) override | |
{ | |
Talk(SAY_DEATH); | |
} | |
}; |
Author
sirikfoll
commented
Feb 28, 2017
•
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment