text: /**
   * @file
   * @brief Spell casting functions.
  **/
  
  #ifndef SPL_CAST_H
  #define SPL_CAST_H
  
  #include "enum.h"
  
  enum spflag_type
  {
      SPFLAG_NONE                 = 0x000000,
      SPFLAG_DIR_OR_TARGET        = 0x000001,      // use DIR_NONE targeting
      SPFLAG_TARGET               = 0x000002,      // use DIR_TARGET targeting
                                  //0x000004,
      SPFLAG_DIR                  = 0x000008,      // use DIR_DIR targeting
      SPFLAG_TARGETING_MASK       = SPFLAG_DIR_OR_TARGET | SPFLAG_TARGET
                                     | SPFLAG_DIR , // used to test for targeting
      // TODO: we need a new flag if we want to target corpses too.
      SPFLAG_OBJ                  = 0x000010,      // TARG_MOVABLE_OBJECT used
      SPFLAG_HELPFUL              = 0x000020,      // TARG_FRIEND used
      SPFLAG_NEUTRAL              = 0x000040,      // TARG_ANY used
      SPFLAG_NOT_SELF             = 0x000080,      // aborts on isMe
      SPFLAG_UNHOLY               = 0x000100,      // counts as "unholy"
      SPFLAG_UNCLEAN              = 0x000200,      // counts as "unclean"
      SPFLAG_CHAOTIC              = 0x000400,      // counts as "chaotic"
      SPFLAG_HASTY                = 0x000800,      // counts as "hasty"
      SPFLAG_EMERGENCY            = 0x001000,      // monsters use in emergencies
      SPFLAG_ESCAPE               = 0x002000,      // useful for running away
      SPFLAG_RECOVERY             = 0x004000,      // healing or recovery spell
      SPFLAG_AREA                 = 0x008000,      // area affect
                              //  = 0x010000,      // was SPFLAG_BATTLE
      SPFLAG_SELFENCH             = 0x020000,      // monsters use as selfench
      SPFLAG_MONSTER              = 0x040000,      // monster-only spell
      SPFLAG_NEEDS_TRACER         = 0x080000,      // monster casting needs tracer
      SPFLAG_NOISY                = 0x100000,      // makes noise, even if innate
      SPFLAG_TESTING              = 0x200000,      // a testing/debugging spell
      SPFLAG_CORPSE_VIOLATING     = 0x400000,      // Conduct violation for Fedhas
                                 // 0x800000,      // was SPFLAG_ALLOW_SELF
      SPFLAG_UTILITY             = 0x1000000,      // usable no matter what foe is
      SPFLAG_NO_GHOST            = 0x2000000,      // ghosts can't get this spell
      SPFLAG_CLOUD               = 0x4000000,      // makes a cloud
      SPFLAG_MR_CHECK            = 0x8000000,      // spell that checks monster MR
      SPFLAG_MONS_ABJURE        = 0x10000000,      // monsters can cast abjuration
                                                   // instead of this spell
      SPFLAG_NOT_EVIL           = 0x20000000,      // not considered evil by the
                                                   // good gods
      SPFLAG_HOLY               = 0x40000000,      // considered holy (can't be
                                                   // used by Yred enslaved souls)
      SPFLAG_PERMABUFF          = 0x80000000,      // permabuff that reserves max mp
  };
  
  enum spret_type
  {
      SPRET_ABORT = 0,            // should be left as 0
      SPRET_FAIL,
      SPRET_SUCCESS,
      SPRET_NONE,                 // spell was not handled
  };
  
  #define IOOD_X "iood_x"
  #define IOOD_Y "iood_y"
  #define IOOD_VX "iood_vx"
  #define IOOD_VY "iood_vy"
  #define IOOD_KC "iood_kc"
  #define IOOD_POW "iood_pow"
  #define IOOD_CASTER "iood_caster"
  #define IOOD_REFLECTOR "iood_reflector"
  #define IOOD_DIST "iood_distance"
  #define IOOD_MID "iood_mid"
  #define IOOD_FLAWED "iood_flawed"
  #define IOOD_TPOS "iood_tpos"
  
  #define fail_check() if (fail) return SPRET_FAIL
  
  void surge_power(const int enhanced);
  
  typedef bool (*spell_selector)(spell_type spell);
  
  int list_spells(bool toggle_with_I = true, bool viewing = false,
                  bool allow_preselect = true,
                  const string &title = "Your Spells",
                  spell_selector selector = nullptr);
  int raw_spell_fail(spell_type spell);
  int stepdown_spellpower(int power, int scale = 1);
  int calc_spell_power(spell_type spell, bool apply_intel,
                       bool fail_rate_chk = false, bool cap_power = true,
                       int scale = 1);
  int calc_spell_range(spell_type spell, int power = 0);
  
  bool cast_a_spell(bool check_range, spell_type spell = SPELL_NO_SPELL);
  
  int apply_enhancement(const int initial_power, const int enhancer_levels);
  
  void inspect_spells();
  void do_cast_spell_cmd(bool force);
  
  int hex_success_chance(const int mr, int powc, int scale,
                         bool round_up = false);
  class targetter;
  vector<string> desc_success_chance(const monster_info& mi, int pow, bool evoked,
                                     targetter* hitfunc);
  spret_type your_spells(spell_type spell, int powc = 0, bool allow_fail = true,
                         const item_def* const evoked_item = nullptr);				   
  					   
  int spell_mp_freeze(spell_type spell);
  bool is_buff_spell (spell_type spell);
  extern const char *fail_severity_adjs[];
  
  double get_miscast_chance(spell_type spell, int severity = 2);
  int fail_severity(spell_type spell);
  int failure_rate_colour(spell_type spell);
  int failure_rate_to_int(int fail);
  string failure_rate_to_string(int fail);
  
  int power_to_barcount(int power);
  
  string spell_power_string(spell_type spell);
  string spell_reserved_mp_string(spell_type spell);
  string spell_range_string(spell_type spell);
  string range_string(int range, int maxrange, char32_t caster_char);
  string spell_schools_string(spell_type spell);
  string spell_failure_rate_string(spell_type spell);
  string spell_noise_string(spell_type spell, int chop_wiz_display_width = 0);
  
  void spell_skills(spell_type spell, set<skill_type> &skills);
  
  #endif
  