text: /**
   * ScriptDev2 is an extension for mangos providing enhanced features for
   * area triggers, creatures, game objects, instances, items, and spells beyond
   * the default database scripting in mangos.
   *
   * Copyright (C) 2006-2013  ScriptDev2 <http://www.scriptdev2.com/>
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   *
   * World of Warcraft, and all World of Warcraft or Warcraft art, images,
   * and lore are copyrighted by Blizzard Entertainment, Inc.
   */
  
  /**
   * ScriptData
   * SDName:      Ungoro_Crater
   * SD%Complete: 100
   * SDComment:   Quest support: 4245, 4491
   * SDCategory:  Un'Goro Crater
   * EndScriptData
   */
  
  /**
   * ContentData
   * npc_ringo
   * EndContentData
   */
  
  #include "precompiled.h"
  #include "escort_ai.h"
  #include "follower_ai.h"
  
  /*######
  ## npc_ame01
  ######*/
  
  enum
  {
      SAY_AME_START           = -1000446,
      SAY_AME_PROGRESS        = -1000447,
      SAY_AME_END             = -1000448,
      SAY_AME_AGGRO1          = -1000449,
      SAY_AME_AGGRO2          = -1000450,
      SAY_AME_AGGRO3          = -1000451,
  
      QUEST_CHASING_AME       = 4245
  };
  
  struct npc_ame01AI : public npc_escortAI
  {
      npc_ame01AI(Creature* pCreature) : npc_escortAI(pCreature) { Reset(); }
  
      void Reset() override {}
  
      void WaypointReached(uint32 uiPointId) override
      {
          switch (uiPointId)
          {
              case 0:
                  DoScriptText(SAY_AME_START, m_creature);
                  break;
              case 19:
                  DoScriptText(SAY_AME_PROGRESS, m_creature);
                  break;
              case 37:
                  DoScriptText(SAY_AME_END, m_creature);
                  if (Player* pPlayer = GetPlayerForEscort())
                  {
                      pPlayer->GroupEventHappens(QUEST_CHASING_AME, m_creature);
                  }
                  break;
          }
      }
  
      void Aggro(Unit* pWho) override
      {
          if (pWho->GetTypeId() == TYPEID_PLAYER)
          {
              return;
          }
  
          if (Player* pPlayer = GetPlayerForEscort())
          {
              if (pPlayer->getVictim() && pPlayer->getVictim() == pWho)
              {
                  return;
              }
  
              switch (urand(0, 2))
              {
                  case 0:
                      DoScriptText(SAY_AME_AGGRO1, m_creature, pWho);
                      break;
                  case 1:
                      DoScriptText(SAY_AME_AGGRO2, m_creature, pWho);
                      break;
                  case 2:
                      DoScriptText(SAY_AME_AGGRO3, m_creature, pWho);
                      break;
              }
          }
      }
  };
  
  bool QuestAccept_npc_ame01(Player* pPlayer, Creature* pCreature, const Quest* pQuest)
  {
      if (pQuest->GetQuestId() == QUEST_CHASING_AME)
      {
          if (npc_ame01AI* pAmeAI = dynamic_cast<npc_ame01AI*>(pCreature->AI()))
          {
              pCreature->SetStandState(UNIT_STAND_STATE_STAND);
  
              if (pPlayer->GetTeam() == ALLIANCE)
              {
                  pCreature->SetFactionTemporary(FACTION_ESCORT_A_PASSIVE, TEMPFACTION_RESTORE_RESPAWN);
              }
              else if (pPlayer->GetTeam() == HORDE)
              {
                  pCreature->SetFactionTemporary(FACTION_ESCORT_H_PASSIVE, TEMPFACTION_RESTORE_RESPAWN);
              }
  
              pAmeAI->Start(false, pPlayer, pQuest);
          }
      }
      return true;
  }
  
  CreatureAI* GetAI_npc_ame01(Creature* pCreature)
  {
      return new npc_ame01AI(pCreature);
  }
  
  /*####
  # npc_ringo
  ####*/
  
  enum
  {
      SAY_RIN_START_1             = -1000416,
      SAY_RIN_START_2             = -1000417,
  
      SAY_FAINT_1                 = -1000418,
      SAY_FAINT_2                 = -1000419,
      SAY_FAINT_3                 = -1000420,
      SAY_FAINT_4                 = -1000421,
  
      SAY_WAKE_1                  = -1000422,
      SAY_WAKE_2                  = -1000423,
      SAY_WAKE_3                  = -1000424,
      SAY_WAKE_4                  = -1000425,
  
      SAY_RIN_END_1               = -1000426,
      SAY_SPR_END_2               = -1000427,
      SAY_RIN_END_3               = -1000428,
      EMOTE_RIN_END_4             = -1000429,
      EMOTE_RIN_END_5             = -1000430,
      SAY_RIN_END_6               = -1000431,
      SAY_SPR_END_7               = -1000432,
      EMOTE_RIN_END_8             = -1000433,
  
      SPELL_REVIVE_RINGO          = 15591,
      QUEST_A_LITTLE_HELP         = 4491,
      NPC_SPRAGGLE                = 9997
  };
  
  struct npc_ringoAI : public FollowerAI
  {
      npc_ringoAI(Creature* pCreature) : FollowerAI(pCreature) { Reset(); }
  
      uint32 m_uiFaintTimer;
      uint32 m_uiEndEventProgress;
      uint32 m_uiEndEventTimer;
  
      Unit* pSpraggle;
  
      void Reset() override
      {
          m_uiFaintTimer = urand(30000, 60000);
          m_uiEndEventProgress = 0;
          m_uiEndEventTimer = 1000;
          pSpraggle = NULL;
      }
  
      void MoveInLineOfSight(Unit* pWho) override
      {
          FollowerAI::MoveInLineOfSight(pWho);
  
          if (!m_creature->getVictim() && !HasFollowState(STATE_FOLLOW_COMPLETE) && pWho->GetEntry() == NPC_SPRAGGLE)
          {
              if (m_creature->IsWithinDistInMap(pWho, INTERACTION_DISTANCE))
              {
                  if (Player* pPlayer = GetLeaderForFollower())
                  {
                      if (pPlayer->GetQuestStatus(QUEST_A_LITTLE_HELP) == QUEST_STATUS_INCOMPLETE)
                      {
                          pPlayer->GroupEventHappens(QUEST_A_LITTLE_HELP, m_creature);
                      }
                  }
  
                  pSpraggle = pWho;
                  SetFollowComplete(true);
              }
          }
      }
  
      void SpellHit(Unit* /*pCaster*/, const SpellEntry* pSpell) override
      {
          if (HasFollowState(STATE_FOLLOW_INPROGRESS | STATE_FOLLOW_PAUSED) && pSpell->Id == SPELL_REVIVE_RINGO)
          {
              ClearFaint();
          }
      }
  
      void SetFaint()
      {
          if (!HasFollowState(STATE_FOLLOW_POSTEVENT))
          {
              SetFollowPaused(true);
  
              switch (urand(0, 3))
              {
                  case 0:
                      DoScriptText(SAY_FAINT_1, m_creature);
                      break;
                  case 1:
                      DoScriptText(SAY_FAINT_2, m_creature);
                      break;
                  case 2:
                      DoScriptText(SAY_FAINT_3, m_creature);
                      break;
                  case 3:
                      DoScriptText(SAY_FAINT_4, m_creature);
                      break;
              }
          }
  
          // what does actually happen here? Emote? Aura?
          m_creature->SetStandState(UNIT_STAND_STATE_SLEEP);
      }
  
      void ClearFaint()
      {
          m_creature->SetStandState(UNIT_STAND_STATE_STAND);
  
          if (HasFollowState(STATE_FOLLOW_POSTEVENT))
          {
              return;
          }
  
          switch (urand(0, 3))
          {
              case 0:
                  DoScriptText(SAY_WAKE_1, m_creature);
                  break;
              case 1:
                  DoScriptText(SAY_WAKE_2, m_creature);
                  break;
              case 2:
                  DoScriptText(SAY_WAKE_3, m_creature);
                  break;
              case 3:
                  DoScriptText(SAY_WAKE_4, m_creature);
                  break;
          }
  
          SetFollowPaused(false);
      }
  
      void UpdateFollowerAI(const uint32 uiDiff) override
      {
          if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
          {
              if (HasFollowState(STATE_FOLLOW_POSTEVENT))
              {
                  if (m_uiEndEventTimer < uiDiff)
                  {
                      if (!pSpraggle || !pSpraggle->IsAlive())
                      {
                          SetFollowComplete();
                          return;
                      }
  
                      switch (m_uiEndEventProgress)
                      {
                          case 1:
                              DoScriptText(SAY_RIN_END_1, m_creature);
                              m_uiEndEventTimer = 3000;
                              break;
                          case 2:
                              DoScriptText(SAY_SPR_END_2, pSpraggle);
                              m_uiEndEventTimer = 5000;
                              break;
                          case 3:
                              DoScriptText(SAY_RIN_END_3, m_creature);
                              m_uiEndEventTimer = 1000;
                              break;
                          case 4:
                              DoScriptText(EMOTE_RIN_END_4, m_creature);
                              SetFaint();
                              m_uiEndEventTimer = 9000;
                              break;
                          case 5:
                              DoScriptText(EMOTE_RIN_END_5, m_creature);
                              ClearFaint();
                              m_uiEndEventTimer = 1000;
                              break;
                          case 6:
                              DoScriptText(SAY_RIN_END_6, m_creature);
                              m_uiEndEventTimer = 3000;
                              break;
                          case 7:
                              DoScriptText(SAY_SPR_END_7, pSpraggle);
                              m_uiEndEventTimer = 10000;
                              break;
                          case 8:
                              DoScriptText(EMOTE_RIN_END_8, m_creature);
                              m_uiEndEventTimer = 5000;
                              break;
                          case 9:
                              SetFollowComplete();
                              break;
                      }
  
                      ++m_uiEndEventProgress;
                  }
                  else
                  {
                      m_uiEndEventTimer -= uiDiff;
                  }
              }
              else if (HasFollowState(STATE_FOLLOW_INPROGRESS))
              {
                  if (!HasFollowState(STATE_FOLLOW_PAUSED))
                  {
                      if (m_uiFaintTimer < uiDiff)
                      {
                          SetFaint();
                          m_uiFaintTimer = urand(60000, 120000);
                      }
                      else
                      {
                          m_uiFaintTimer -= uiDiff;
                      }
                  }
              }
  
              return;
          }
  
          DoMeleeAttackIfReady();
      }
  };
  
  CreatureAI* GetAI_npc_ringo(Creature* pCreature)
  {
      return new npc_ringoAI(pCreature);
  }
  
  bool QuestAccept_npc_ringo(Player* pPlayer, Creature* pCreature, const Quest* pQuest)
  {
      if (pQuest->GetQuestId() == QUEST_A_LITTLE_HELP)
      {
          if (npc_ringoAI* pRingoAI = dynamic_cast<npc_ringoAI*>(pCreature->AI()))
          {
              pCreature->SetStandState(UNIT_STAND_STATE_STAND);
              pRingoAI->StartFollow(pPlayer, FACTION_ESCORT_N_FRIEND_PASSIVE, pQuest);
          }
      }
  
      return true;
  }
  
  void AddSC_ungoro_crater()
  {
      Script* pNewScript;
  
      pNewScript = new Script;
      pNewScript->Name = "npc_ame01";
      pNewScript->GetAI = &GetAI_npc_ame01;
      pNewScript->pQuestAcceptNPC = &QuestAccept_npc_ame01;
      pNewScript->RegisterSelf();
  
      pNewScript = new Script;
      pNewScript->Name = "npc_ringo";
      pNewScript->GetAI = &GetAI_npc_ringo;
      pNewScript->pQuestAcceptNPC = &QuestAccept_npc_ringo;
      pNewScript->RegisterSelf();
  }
  