/******************************************************************
  
  Module:  aigoal_cast.cpp
  
  Author: Borut Pfeifer
  
  Copyright 2005 Sony Online Entertainment.  All rights reserved.
  
*******************************************************************/

//-------------------------------------------------------- Includes
#include "aigoal_cast.h"

#include "../intel.h"
#include "../stats.h"
#include "../graphic.h"
#include "../registry.h"
#include "../titan.h"
#include "../database.h"
#include "../areaeffect.h"
#include "../spell.h"

#include "../debugoverlay.h"
#include "aiblackboard.h"
#include "aigoal_attack.h"

#include <vector>

//-------------------------------------------------------- cGoalCast
cGoal_Cast::cGoal_Cast()
{
}

cGoal_Cast::cGoal_Cast(tGameID spellID, tGameObjectID targetID)
: cAiGoal(),
  mSpellID(spellID)
{
  SyAssert(mSpellID != ID_NONE);
  
  mSpellTargetLOS.SetTarget(targetID);
  mSpellTargetLOS.AllowDeadTarget(true);
}

cGoal_Cast::cGoal_Cast(tGameID spellID, const SyVect3& targetLocation)
: cAiGoal(),
  mSpellID(spellID)
{
  SyAssert(mSpellID !=ID_NONE);

  mSpellTargetLOS.SetTargetPosition(targetLocation);
}


void cGoal_Cast::Update(float time)
{
  cGameObject* pObj = GetGameObject();
  cGameObject* pTarget = mSpellTargetLOS.GetTarget(pObj);
  float speed = ((cStatsCharacter*)pObj->GetStats())->GetAIMovementSpeed();

  mSpellTargetLOS.Update(pObj, time);

  bool bDoneMoving = MoveToCastPosition(speed);

  if (bDoneMoving)
  {
    if (Cast(time))
    {
      const cSpellMaster* pSpell = pObj->GetTitan()->GetDatabaseSys()->GetSpellMaster(mSpellID);
      if (pSpell)
      {
        pSpell->CastSpell(GetGameObject(), pTarget, mSpellTargetLOS.mbUseTargetPos ? &mSpellTargetLOS.mTargetPos : NULL);
      }

      mpOwner->Pop(this);
    }
  }
}

bool cGoal_Cast::MoveToCastPosition(float speed)
{
  cGameObject* pObj = GetGameObject();
  cIntelNPC* pIntel = GetIntel();

  const cSpellMaster* pSpell = pObj->GetTitan()->GetDatabaseSys()->GetSpellMaster(mSpellID);
  if (!pSpell || pSpell->mRange < 0.00001f)
  {
    pIntel->Stop();
    return true;
  }
    
  SyVect3 targetLoc;

  if (mSpellTargetLOS.mbUseTargetPos)
  {
    targetLoc = mSpellTargetLOS.mTargetPos;
  }
  else
  {
    cGameObject* pTarget = mSpellTargetLOS.GetTarget(pObj);

    if (pTarget)
    {
      targetLoc = pTarget->GetLocation();
    }
    else
    {
      pIntel->Stop();
      return true;
    }
  }

  float dist = GetGameObject()->GetDistance(targetLoc);

  if (dist <= pSpell->mRange)
  {
    pIntel->Stop();
    pIntel->TurnTo(targetLoc);
    return true;
  }
  else
  {
    if (!pIntel->IsAvoiding())
    {
      pIntel->GoTo(targetLoc, speed);
    }

    return false;
  }
}

bool cGoal_Cast::Cast(float time)
{
  bool bDone = GetAnimInterface()->IsIdle();

  if (bDone)
  {
    mpOwner->Pop(this);
  }

  return bDone;
}

// EOF
