/******************************************************************
  
  Module:  debris.h
  
  Author: Borut Pfeifer
  
  Description: 

    spell/ability system
  
  Copyright 2005 Sony Online Entertainment.  All rights reserved.
  
*******************************************************************/

#ifndef SPELL_H
#define SPELL_H

//-------------------------------------------------------- Includes
#include "rulepacket.h"
#include "animdefs.h"
#include "surfacetype.h"

//-------------------------------------------------------- Typedefs
//---------------------------------------------- Class Declarations

class cGameEffect;
class Titan;
class SyCollRay;
class SySceneFilter;

class cSpellEffectMaster
{
public:
  cSpellEffectMaster();
  ~cSpellEffectMaster();

  enum EffectType
  {
    SPELLEFFECT_DAMAGE,
    SPELLEFFECT_DAMAGE_OVER_TIME,
    SPELLEFFECT_HEAL,
    SPELLEFFECT_DECREASE_MANA,
    SPELLEFFECT_DECREASE_MANA_OVER_TIME,
    SPELLEFFECT_INCREASE_MANA,
    SPELLEFFECT_HEALTH_DRAIN,
    SPELLEFFECT_MANA_DRAIN,
    SPELLEFFECT_HEALTH_REGEN,
    SPELLEFFECT_MANA_REGEN,
    SPELLEFFECT_ATTACK_SPEED,
    SPELLEFFECT_MOVEMENT_SPEED,
    SPELLEFFECT_ATTACK_POWER,
    SPELLEFFECT_SPELL_POWER,
    SPELLEFFECT_BLOCK_POWER,
    SPELLEFFECT_MELEE_CRITICAL_CHANCE,
    SPELLEFFECT_RANGED_CRITICAL_CHANCE,
    SPELLEFFECT_MELEE_DODGE_CHANCE,
    SPELLEFFECT_RANGED_DODGE_CHANCE,
    SPELLEFFECT_DEFENSE,
    SPELLEFFECT_DAMAGE_DONE,
    SPELLEFFECT_DAMAGE_TAKEN,
    SPELLEFFECT_SIZE,
    SPELLEFFECT_STUN,
    SPELLEFFECT_STUN_IMMUNITY,
    SPELLEFFECT_SLEEP,
    SPELLEFFECT_SLEEP_IMMUNITY,
    SPELLEFFECT_CONFUSE,
    SPELLEFFECT_CONFUSE_IMMUNITY,
    SPELLEFFECT_CHARM,
    SPELLEFFECT_CHARM_IMMUNITY,
    SPELLEFFECT_INVISIBILITY,
    SPELLEFFECT_SEE_INVISIBILITY,
    SPELLEFFECT_KNOCKBACK,
    SPELLEFFECT_KNOCKDOWN,
    SPELLEFFECT_KNOCKBACK_IMMUNITY,
    SPELLEFFECT_KNOCKDOWN_IMMUNITY,
    SPELLEFFECT_VORTEX,
    SPELLEFFECT_VORTEX_IMMUNITY,
    SPELLEFFECT_FREEZE,
    SPELLEFFECT_FREEZE_IMMUNITY,
    SPELLEFFECT_SPREAD_FIRE,
    SPELLEFFECT_KILL,
    SPELLEFFECT_KILL_IMMUNITY,
    SPELLEFFECT_BIND,
    SPELLEFFECT_BIND_IMMUNITY,
    SPELLEFFECT_SILENCE,
    SPELLEFFECT_SILENCE_IMMUNITY,
    SPELLEFFECT_FEAR,
    SPELLEFFECT_FEAR_IMMUNITY,
    SPELLEFFECT_FORCE_FIELD,
    SPELLEFFECT_DAMAGE_FIELD,
    SPELLEFFECT_TELEPORT,
    SPELLEFFECT_ILLUSION,
    SPELLEFFECT_RESURRECT,
    SPELLEFFECT_DUMMY_TARGET,
    SPELLEFFECT_SUMMON_PET,
    SPELLEFFECT_TRIGGER_SPELL,
    SPELLEFFECT_TRIGGER_TARGET_SPELL,
    SPELLEFFECT_TRIGGER_SPELL_ON_ATTACK,
    SPELLEFFECT_TRIGGER_SPELL_ON_DEFEND,
    SPELLEFFECT_TRIGGER_SPELL_ON_DEATH,
    SPELLEFFECT_SHOW_MAP_ENEMIES,
    SPELLEFFECT_SHOW_MAP_TREASURE,
    SPELLEFFECT_HEALTH_ABSORB,
    SPELLEFFECT_MANA_ABSORB,
    SPELLEFFECT_ESSENCE_ABSORB,
    SPELLEFFECT_HEALTH_DROP_CHANCE,
    SPELLEFFECT_MANA_DROP_CHANCE,
    SPELLEFFECT_ESSENCE_DROP_CHANCE,
    SPELLEFFECT_ITEM_DROP_CHANCE,
    SPELLEFFECT_EXPERIENCE_GAIN,
    SPELLEFFECT_SPAWN_TREASURE,

    SPELLEFFECT_NUM_TYPES
  };

  tGameID                   mSpellOwnerID;
  EffectType                mType;
  int                       mBaseAmount;
  float                     mMultAmount;
  float                     mDuration;
  int                       mPercentChance;

  tGameID                   mTargetFXID;
  cNameID                   mObjectNameID;
  tGameID                   mTargetRace;

  cGameEffect* CreateGameEffect(cGameObject* pSource,
                                const SyVect3& loc,
                                eDamageType damageType,
                                bool bArea,
                                tGameID itemMasterID);

  void         AppendPropertyString(cGameObject *pObj,
                                    SyString &str,
                                    eDamageType damageType) const;
};

class cSpellMaster
{
public:
  cSpellMaster();
  ~cSpellMaster();

  enum OriginMechanism
  {
    SPELL_ORIGIN_CASTER,
    SPELL_ORIGIN_TARGET,
    SPELL_ORIGIN_CASTER_LOCATION,
    SPELL_ORIGIN_TARGET_LOCATION,
    SPELL_ORIGIN_RANDOM_LOCATION,
    SPELL_ORIGIN_WARD,
    SPELL_ORIGIN_NUM_TYPES
  };

  enum DeliveryMechanism
  {
    SPELL_DELIVERY_SINGLE,
    SPELL_DELIVERY_RADIUS,
    SPELL_DELIVERY_NOVA,
    SPELL_DELIVERY_CHAIN,
    SPELL_DELIVERY_WAVE_ANGLE,
    SPELL_DELIVERY_WAVE_LINE,
    SPELL_DELIVERY_BEAM,
    SPELL_DELIVERY_ARC,
    SPELL_DELIVERY_WALL,
    SPELL_DELIVERY_TRAIL,
    SPELL_DELIVERY_CONE,
    SPELL_DELIVERY_METEOR_SHOWER,
    SPELL_DELIVERY_NUM_TYPES
  };

  enum TargetingMechanism
  {
    SPELL_TARGETING_ANY,
    SPELL_TARGETING_ALLIES,
    SPELL_TARGETING_ENEMIES,
    SPELL_TARGETING_ENEMIES_AND_PROPS,
    SPELL_TARGETING_NUM_TYPES
  };

  cNameID                 mID;
  OriginMechanism         mOrigin;
  DeliveryMechanism       mDelivery;
  TargetingMechanism      mTargeting;
  SyVector<cSpellEffectMaster*>   mEffects;

  tGameID                 mProjectileTypeID;
  float                   mOffset;
  float                   mRange;
  float                   mWidth;
  float                   mAngleStart;
  float                   mAngleEnd;
  int                     mMaxTargets;
  int                     mManaCost;
  tGameID                 mWardPropID;
  int                     mCastAnimID;
  tGameID                 mCastFXID;
  tGameID                 mCastStartFXID;
  tGameID                 mAreaFXID;
  tGameID                 mCastLoopFXID;
  tGameID                 mParentSpellID;
  int                     mStackingCategory;
  float                   mDeliveryDuration;
  float                   mRefreshTime;
  float                   mNPCCastTime;
  bool                    mbBlockable;
  bool                    mbJumpable;

  tGameID                 mImpactFXSetID;
  tGameID                 mImpactSoundSetID;
  eDamageType             mDamageType;
  eElementalType          mElementalType;

  // Main external function to cast spell
  void CastSpell(cGameObject* pCaster,
                 cGameObject* pTarget = NULL,
                 SyVect3* pTargetPos = NULL,
                 eComboType combo = NUM_COMBOS,
                 tGameID itemMasterID = ID_NONE) const;

  // called when animation is done
  void CreateSpellDelivery(cGameObject* pCaster,
                           cGameObject* pTarget,
                           SyVect3* pTargetPos = NULL,
                           eComboType combo = NUM_COMBOS,
                           tGameID itemMasterID = ID_NONE) const;

  // called when delivery mechanism is finished (eg. projectile hits)
  void CreateSpellEffects(cGameObject* pCaster,
                          cGameObject* pTarget,
                          SyVect3* pTargetPos = NULL,
                          eComboType combo = NUM_COMBOS,
                          tGameID itemMasterID = ID_NONE) const;

  // if spell is ongoing (eg based on button press), this is called when it ends
  void EndSpellEffects(cGameObject* pCaster, cGameObject* pTarget, tGameID itemMasterID = ID_NONE) const;

  // adds description of this spell to the string
  void AppendPropertyString(cGameObject *obj, SyString &str) const; 

  void PlayImpact(cGameObject* pObj) const;

  void PlayImpact(Titan* pTitan, SyCollRay& ray, SySceneFilter& filter, int waterType) const;
};

// abilities are entries in the character class progession table
class cAbilityMaster
{
public:
  cAbilityMaster();

  enum Constants
  {
    MAX_PREREQS = 3
  };

  cNameID                 mID;
  int                     mRank;
  tGameID                 mClass;
  int                     mLevelMin;
  tGameID                 mAbilityPrereqs[MAX_PREREQS];
  tGameID                 mSpell;
  eComboType              mCombo;
  int                     mCost;
  uint32                  mNameString;
  uint32                  mDescString;
  tGameID                 mIconID;
};


//------------------------------------------- Function Declarations

//--------------------------------------------------------- Globals
//------------------------------------------------ Inline Functions

#endif
