/******************************************************************
  
  Module:  RulePacket.h
  
  Author: Sean Craig
  
  Description:  Handles queries and
  calculations which use the game rules.  For example, the rule 
  packets are responsble for determing a character's post-buff 
  strength, for applying damage, decrementing hit points, etc.

  This file contains the format for the events.  A CALC_ packet just
  calculates a value, like strength or movement speed.  An EVENT_
  packet provides a hook for events to occur.  For example, a
  barrel can explode in response to an EVENT_APPLY_DAMAGE packet. 
  
  Rule packets are processed by game objects through their cStats
  class.  The cStats class contains a list of all the rules applicable
  to that object.  Each rule operates one at a time on the packet as
  it's processed.

  Formerly called RuleEvents, name changed to avoid semantic overlap
  and because "events" in network code implies latency.

  If speed becomes an issue, commonly calculated values can be 
  cashed, and/or rules can be registered for specific packet types.

  
  Copyright 2005 Sony Online Entertainment.  All rights reserved.
  
*******************************************************************/

#ifndef RULEPACKET_H
#define RULEPACKET_H

//-------------------------------------------------------- Includes
#include "gameobj.h"
#include "animdefs.h"
//-------------------------------------------------------- Typedefs
//---------------------------------------------- Class Declarations

class cRulePacket
{
public:
  typedef enum
  {
    CLASS_BASE,
    CLASS_CALC,
    CLASS_HIT,
    CLASS_DAMAGE,
    CLASS_FLAG
  } tPacketClass;

  typedef enum 
  {
    CALC_HEALTH_MAX,
    CALC_HEALTH_REGEN,
    CALC_MANA_MAX,
    CALC_MANA_REGEN,
    CALC_DAMAGE_INITIAL, // called on Attacker
    CALC_DAMAGE_RAW,     // called on Attacker
    CALC_DAMAGE_REDUCED, // called on Defender
    CALC_BLOCK_MAX,      // called on Defender
    CALC_BLOCK_REGEN,
    CALC_STRIKETHROUGH,  // called on Attacker

    CALC_CRITICAL_CHANCE,

    CALC_DEFENSE,

    CALC_CARRYING_CAPACITY,
    CALC_EXPERIENCE_GAIN,

    QUERY_FLAG,

    EVENT_HIT,               // hit someone else (called on Attacker)
    EVENT_APPLY_DAMAGE,      // took damage (called on Defender)
    NUM_PACKET_TYPES
  } tPacketType;


  cRulePacket()
  {
    mClass = CLASS_BASE;
  }
protected:
  tPacketClass      mClass;
public:
  tPacketClass      GetClass(){return mClass;};
  tPacketType       mPacketType;
  tGameObjectID     mObjectID; // this object
};


class cFlagPacket : public cRulePacket
{
public:
  cFlagPacket()
  {
    mClass = CLASS_FLAG;
  }

  void          SetFlag(const char *name);
  void          SetFlag(int32 flag){mFlagID = flag;};
  int32         GetFlag(){return mFlagID;};
  bool          IsFlag(const char *name);

  bool          Get(){return mSet;};
  void          Set(bool value){mSet = value;};

protected:
  uint32         mFlagID;
  bool          mSet;
};                

class cCalcPacket :public cRulePacket
{
public:
  cCalcPacket() : mTotal(0)
  {
    mClass = CLASS_CALC;
  };

  int                       GetTotal(){return mTotal;};
  void                      AddTotal(int newtotal,const char *description, const char *modifier); // strings for reporting
  void                      MultiplyTotal(float multiplier,const char *description, const char *modifier); // strings for reporting
  void                      SetTotal(int newtotal,const char *description, const char *modifier); // strings for reporting
  void                      Reset(){mTotal = 0;};

protected:
  int                   mTotal;

};


class cHitPacket : public cCalcPacket
{
public:
  cHitPacket() : 
    mbRanged(false),
    mbCritical(false),
    mbBlocked(false),
    mbCriticalBlocked(false),
    mCombo(COMBO_L)
  {
    mClass = CLASS_HIT;
  };

  tGameObjectID             mAttackerID;
  tGameObjectID             mDefenderID;
  bool                      mbRanged;
  bool                      mbCritical;
  bool                      mbBlocked;
  bool                      mbCriticalBlocked;
  eComboType                mCombo;
};

typedef enum
{
  NDT_NONE, // for attacks that are all fire, etc.
  NDT_PIERCING,
  NDT_BLUNT,
  NDT_SLASHING,
  NUM_NORMAL_DAMAGE_TYPES
} eNormalDamageType;

typedef enum
{
  MDT_NONE,
  MDT_FIRE,
  MDT_ICE,
  MDT_ELECTRICAL, 
  MDT_POISON, 
  MDT_MAGIC, 
  NUM_MAGIC_DAMAGE_TYPES
    // ...,
} eMagicDamageType;

class cDamagePacket : public cHitPacket 
{
public:
                            cDamagePacket();
                            ~cDamagePacket();
  void                      SetNormalDamageType(eNormalDamageType type){mNormalType = type;};
  void                      SetMagicDamageType(eMagicDamageType type){mMagicType = type;};


protected:

  eNormalDamageType               mNormalType;
  eMagicDamageType                mMagicType;
};

//------------------------------------------- Function Declarations
//--------------------------------------------------------- Globals
//------------------------------------------------ Inline Functions

#endif
