aboutsummaryrefslogtreecommitdiff
path: root/src/server/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/scripts')
-rw-r--r--src/server/scripts/CMakeLists.txt1
-rw-r--r--src/server/scripts/World/guards.cpp363
2 files changed, 252 insertions, 112 deletions
diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt
index 17d4bfc91e5..9fd63fdde8f 100644
--- a/src/server/scripts/CMakeLists.txt
+++ b/src/server/scripts/CMakeLists.txt
@@ -34,7 +34,6 @@ set(scripts_STAT_SRCS
../game/AI/ScriptedAI/ScriptedEscortAI.cpp
../game/AI/ScriptedAI/ScriptedCreature.cpp
../game/AI/ScriptedAI/ScriptedFollowerAI.cpp
- ../game/AI/ScriptedAI/ScriptedGuardAI.cpp
../game/AI/ScriptedAI/ScriptedSimpleAI.cpp
)
diff --git a/src/server/scripts/World/guards.cpp b/src/server/scripts/World/guards.cpp
index c7c91fed3e9..107ada81863 100644
--- a/src/server/scripts/World/guards.cpp
+++ b/src/server/scripts/World/guards.cpp
@@ -19,220 +19,361 @@
/* ScriptData
SDName: Guards
SD%Complete: 100
-SDComment: All Guard gossip data, quite some npc_text-id's still missing, adding constantly as new id's are known. CombatAI should be organized better for future.
+SDComment:
SDCategory: Guards
EndScriptData */
/* ContentData
guard_generic
-guard_orgrimmar
guard_shattrath_aldor
guard_shattrath_scryer
-guard_stormwind
EndContentData */
#include "ScriptPCH.h"
-#include "ScriptedGuardAI.h"
+#include "GuardAI.h"
-/*******************************************************
- * guard_generic
- *******************************************************/
+enum GuardGeneric
+{
+ GENERIC_CREATURE_COOLDOWN = 5000,
+
+ SAY_GUARD_SIL_AGGRO1 = -1070001,
+ SAY_GUARD_SIL_AGGRO2 = -1070002,
+ SAY_GUARD_SIL_AGGRO3 = -1070003,
+
+ NPC_CENARION_HOLD_INFANTRY = 15184,
+ NPC_STORMWIND_CITY_GUARD = 68,
+ NPC_STORMWIND_CITY_PATROLLER = 1976,
+ NPC_ORGRIMMAR_GRUNT = 3296
+};
class guard_generic : public CreatureScript
{
public:
guard_generic() : CreatureScript("guard_generic") { }
- CreatureAI *GetAI(Creature *creature) const
+ struct guard_genericAI : public GuardAI
{
- return new guardAI(creature);
- }
-};
+ guard_genericAI(Creature* creature) : GuardAI(creature) {}
-/*******************************************************
- * guard_orgrimmar
- *******************************************************/
+ void Reset()
+ {
+ globalCooldown = 0;
+ buffTimer = 0;
+ }
-class guard_orgrimmar : public CreatureScript
-{
-public:
- guard_orgrimmar() : CreatureScript("guard_orgrimmar") { }
+ void EnterCombat(Unit* who)
+ {
+ if (me->GetEntry() == NPC_CENARION_HOLD_INFANTRY)
+ DoScriptText(RAND(SAY_GUARD_SIL_AGGRO1,SAY_GUARD_SIL_AGGRO2,SAY_GUARD_SIL_AGGRO3), me, who);
+ if (SpellEntry const* spell = me->reachWithSpellAttack(who))
+ DoCast(who, spell->Id);
+ }
- CreatureAI *GetAI(Creature *creature) const
+ void UpdateAI(const uint32 diff)
+ {
+ //Always decrease our global cooldown first
+ if (globalCooldown > diff)
+ globalCooldown -= diff;
+ else
+ globalCooldown = 0;
+
+ //Buff timer (only buff when we are alive and not in combat
+ if (me->isAlive() && !me->isInCombat())
+ {
+ if (buffTimer <= diff)
+ {
+ //Find a spell that targets friendly and applies an aura (these are generally buffs)
+ SpellEntry const *info = SelectSpell(me, 0, 0, SELECT_TARGET_ANY_FRIEND, 0, 0, 0, 0, SELECT_EFFECT_AURA);
+
+ if (info && !globalCooldown)
+ {
+ //Cast the buff spell
+ DoCast(me, info->Id);
+
+ //Set our global cooldown
+ globalCooldown = GENERIC_CREATURE_COOLDOWN;
+
+ //Set our timer to 10 minutes before rebuff
+ buffTimer = 600000;
+ } //Try again in 30 seconds
+ else buffTimer = 30000;
+ } else buffTimer -= diff;
+ }
+
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ // Make sure our attack is ready and we arn't currently casting
+ if (me->isAttackReady() && !me->IsNonMeleeSpellCasted(false))
+ {
+ //If we are within range melee the target
+ if (me->IsWithinMeleeRange(me->getVictim()))
+ {
+ bool healing = false;
+ SpellEntry const *info = NULL;
+
+ //Select a healing spell if less than 30% hp
+ if (me->HealthBelowPct(30))
+ info = SelectSpell(me, 0, 0, SELECT_TARGET_ANY_FRIEND, 0, 0, 0, 0, SELECT_EFFECT_HEALING);
+
+ //No healing spell available, select a hostile spell
+ if (info)
+ healing = true;
+ else
+ info = SelectSpell(me->getVictim(), 0, 0, SELECT_TARGET_ANY_ENEMY, 0, 0, 0, 0, SELECT_EFFECT_DONTCARE);
+
+ //20% chance to replace our white hit with a spell
+ if (info && urand(0,99) < 20 && !globalCooldown)
+ {
+ //Cast the spell
+ if (healing)
+ DoCast(me, info->Id);
+ else
+ DoCast(me->getVictim(), info->Id);
+
+ //Set our global cooldown
+ globalCooldown = GENERIC_CREATURE_COOLDOWN;
+ }
+ else
+ me->AttackerStateUpdate(me->getVictim());
+
+ me->resetAttackTimer();
+ }
+ }
+ else
+ {
+ //Only run this code if we arn't already casting
+ if (!me->IsNonMeleeSpellCasted(false))
+ {
+ bool healing = false;
+ SpellEntry const *info = NULL;
+
+ //Select a healing spell if less than 30% hp ONLY 33% of the time
+ if (me->HealthBelowPct(30) && 33 > urand(0, 99))
+ info = SelectSpell(me, 0, 0, SELECT_TARGET_ANY_FRIEND, 0, 0, 0, 0, SELECT_EFFECT_HEALING);
+
+ //No healing spell available, See if we can cast a ranged spell (Range must be greater than ATTACK_DISTANCE)
+ if (info)
+ healing = true;
+ else
+ info = SelectSpell(me->getVictim(), 0, 0, SELECT_TARGET_ANY_ENEMY, 0, 0, NOMINAL_MELEE_RANGE, 0, SELECT_EFFECT_DONTCARE);
+
+ //Found a spell, check if we arn't on cooldown
+ if (info && !globalCooldown)
+ {
+ //If we are currently moving stop us and set the movement generator
+ if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != IDLE_MOTION_TYPE)
+ {
+ me->GetMotionMaster()->Clear(false);
+ me->GetMotionMaster()->MoveIdle();
+ }
+
+ //Cast spell
+ if (healing)
+ DoCast(me,info->Id);
+ else
+ DoCast(me->getVictim(),info->Id);
+
+ //Set our global cooldown
+ globalCooldown = GENERIC_CREATURE_COOLDOWN;
+
+ } //If no spells available and we arn't moving run to target
+ else if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != TARGETED_MOTION_TYPE)
+ {
+ //Cancel our current spell and then mutate new movement generator
+ me->InterruptNonMeleeSpells(false);
+ me->GetMotionMaster()->Clear(false);
+ me->GetMotionMaster()->MoveChase(me->getVictim());
+ }
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ void DoReplyToTextEmote(uint32 emote)
+ {
+ switch(emote)
+ {
+ case TEXTEMOTE_KISS: me->HandleEmoteCommand(EMOTE_ONESHOT_BOW); break;
+ case TEXTEMOTE_WAVE: me->HandleEmoteCommand(EMOTE_ONESHOT_WAVE); break;
+ case TEXTEMOTE_SALUTE: me->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE); break;
+ case TEXTEMOTE_SHY: me->HandleEmoteCommand(EMOTE_ONESHOT_FLEX); break;
+ case TEXTEMOTE_RUDE:
+ case TEXTEMOTE_CHICKEN: me->HandleEmoteCommand(EMOTE_ONESHOT_POINT); break;
+ }
+ }
+
+ void ReceiveEmote(Player* player, uint32 textEmote)
+ {
+ switch(me->GetEntry())
+ {
+ case NPC_STORMWIND_CITY_GUARD:
+ case NPC_STORMWIND_CITY_PATROLLER:
+ case NPC_ORGRIMMAR_GRUNT:
+ break;
+ default:
+ return;
+ }
+
+ if (!me->IsFriendlyTo(player))
+ return;
+
+ DoReplyToTextEmote(textEmote);
+ }
+
+ private:
+ uint32 globalCooldown;
+ uint32 buffTimer;
+ };
+
+ CreatureAI *GetAI(Creature* creature) const
{
- return new guardAI_orgrimmar(creature);
+ return new guard_genericAI(creature);
}
};
-/*******************************************************
- * guard_shattrath_aldor
- *******************************************************/
-
-#define SPELL_BANISHED_SHATTRATH_A 36642
-#define SPELL_BANISHED_SHATTRATH_S 36671
-#define SPELL_BANISH_TELEPORT 36643
-#define SPELL_EXILE 39533
+enum GuardShattrath
+{
+ SPELL_BANISHED_SHATTRATH_A = 36642,
+ SPELL_BANISHED_SHATTRATH_S = 36671,
+ SPELL_BANISH_TELEPORT = 36643,
+ SPELL_EXILE = 39533
+};
-class guard_shattrath_aldor : public CreatureScript
+class guard_shattrath_scryer : public CreatureScript
{
public:
- guard_shattrath_aldor() : CreatureScript("guard_shattrath_aldor") { }
+ guard_shattrath_scryer() : CreatureScript("guard_shattrath_scryer") { }
- struct guard_shattrath_aldorAI : public guardAI
+ struct guard_shattrath_scryerAI : public GuardAI
{
- guard_shattrath_aldorAI(Creature *c) : guardAI(c) {}
-
- uint32 Exile_Timer;
- uint32 Banish_Timer;
- uint64 PlayerGUID;
- bool CanTeleport;
+ guard_shattrath_scryerAI(Creature* creature) : GuardAI(creature) {}
void Reset()
{
- Banish_Timer = 5000;
- Exile_Timer = 8500;
- PlayerGUID = 0;
- CanTeleport = false;
+ banishTimer = 5000;
+ exileTimer = 8500;
+ playerGUID = 0;
+ canTeleport = false;
}
- void EnterCombat(Unit * /*who*/) {}
-
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
- if (CanTeleport)
+ if (canTeleport)
{
- if (Exile_Timer <= diff)
+ if (exileTimer <= diff)
{
- if (Unit* temp = Unit::GetUnit(*me,PlayerGUID))
+ if (Unit* temp = Unit::GetUnit(*me,playerGUID))
{
temp->CastSpell(temp,SPELL_EXILE,true);
temp->CastSpell(temp,SPELL_BANISH_TELEPORT,true);
}
- PlayerGUID = 0;
- Exile_Timer = 8500;
- CanTeleport = false;
- } else Exile_Timer -= diff;
+ playerGUID = 0;
+ exileTimer = 8500;
+ canTeleport = false;
+ } else exileTimer -= diff;
}
- else if (Banish_Timer <= diff)
+ else if (banishTimer <= diff)
{
Unit* temp = me->getVictim();
if (temp && temp->GetTypeId() == TYPEID_PLAYER)
{
DoCast(temp, SPELL_BANISHED_SHATTRATH_A);
- Banish_Timer = 9000;
- PlayerGUID = temp->GetGUID();
- if (PlayerGUID)
- CanTeleport = true;
+ banishTimer = 9000;
+ playerGUID = temp->GetGUID();
+ if (playerGUID)
+ canTeleport = true;
}
- } else Banish_Timer -= diff;
+ } else banishTimer -= diff;
DoMeleeAttackIfReady();
}
+
+ private:
+ uint32 exileTimer;
+ uint32 banishTimer;
+ uint64 playerGUID;
+ bool canTeleport;
};
CreatureAI *GetAI(Creature *creature) const
{
- return new guard_shattrath_aldorAI(creature);
+ return new guard_shattrath_scryerAI(creature);
}
};
-/*******************************************************
- * guard_shattrath_scryer
- *******************************************************/
-
-class guard_shattrath_scryer : public CreatureScript
+class guard_shattrath_aldor : public CreatureScript
{
public:
- guard_shattrath_scryer() : CreatureScript("guard_shattrath_scryer") { }
+ guard_shattrath_aldor() : CreatureScript("guard_shattrath_aldor") { }
- struct guard_shattrath_scryerAI : public guardAI
+ struct guard_shattrath_aldorAI : public GuardAI
{
- guard_shattrath_scryerAI(Creature *c) : guardAI(c) {}
-
- uint32 Exile_Timer;
- uint32 Banish_Timer;
- uint64 PlayerGUID;
- bool CanTeleport;
+ guard_shattrath_aldorAI(Creature* creature) : GuardAI(creature) {}
void Reset()
{
- Banish_Timer = 5000;
- Exile_Timer = 8500;
- PlayerGUID = 0;
- CanTeleport = false;
+ banishTimer = 5000;
+ exileTimer = 8500;
+ playerGUID = 0;
+ canTeleport = false;
}
- void EnterCombat(Unit * /*who*/) {}
-
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
- if (CanTeleport)
+ if (canTeleport)
{
- if (Exile_Timer <= diff)
+ if (exileTimer <= diff)
{
- if (Unit* temp = Unit::GetUnit(*me,PlayerGUID))
+ if (Unit* temp = Unit::GetUnit(*me,playerGUID))
{
temp->CastSpell(temp,SPELL_EXILE,true);
temp->CastSpell(temp,SPELL_BANISH_TELEPORT,true);
}
- PlayerGUID = 0;
- Exile_Timer = 8500;
- CanTeleport = false;
- } else Exile_Timer -= diff;
+ playerGUID = 0;
+ exileTimer = 8500;
+ canTeleport = false;
+ } else exileTimer -= diff;
}
- else if (Banish_Timer <= diff)
+ else if (banishTimer <= diff)
{
Unit* temp = me->getVictim();
if (temp && temp->GetTypeId() == TYPEID_PLAYER)
{
DoCast(temp, SPELL_BANISHED_SHATTRATH_S);
- Banish_Timer = 9000;
- PlayerGUID = temp->GetGUID();
- if (PlayerGUID)
- CanTeleport = true;
+ banishTimer = 9000;
+ playerGUID = temp->GetGUID();
+ if (playerGUID)
+ canTeleport = true;
}
- } else Banish_Timer -= diff;
+ } else banishTimer -= diff;
DoMeleeAttackIfReady();
}
+ private:
+ uint32 exileTimer;
+ uint32 banishTimer;
+ uint64 playerGUID;
+ bool canTeleport;
};
CreatureAI *GetAI(Creature *creature) const
{
- return new guard_shattrath_scryerAI(creature);
- }
-};
-
-/*******************************************************
- * guard_stormwind
- *******************************************************/
-
-class guard_stormwind : public CreatureScript
-{
-public:
- guard_stormwind() : CreatureScript("guard_stormwind") { }
-
- CreatureAI *GetAI(Creature *creature) const
- {
- return new guardAI_stormwind(creature);
+ return new guard_shattrath_aldorAI(creature);
}
};
-/*******************************************************
- * AddSC
- *******************************************************/
-
void AddSC_guards()
{
new guard_generic;
- new guard_orgrimmar;
new guard_shattrath_aldor;
new guard_shattrath_scryer;
- new guard_stormwind;
}