text: /**
   * @file
   * @brief Spell miscast class.
  **/
  
  #pragma once
  
  #include "enum.h"
  #include "monster.h"
  #include "mpr.h"
  #include "spl-util.h"
  
  enum nothing_happens_when_type
  {
      NH_DEFAULT,
      NH_NEVER,
      NH_ALWAYS,
  };
  
  enum miscast_source
  {
      ZOT_TRAP_MISCAST,
      HELL_EFFECT_MISCAST,
      WIELD_MISCAST,
      MELEE_MISCAST,
      SPELL_MISCAST,
      ABIL_MISCAST,
      WIZARD_MISCAST,
      MUMMY_MISCAST,
      DECK_MISCAST,
      // This should always be last.
      GOD_MISCAST
  };
  
  class actor;
  // class monster;
  
  class MiscastEffect
  {
  public:
      MiscastEffect(actor* _target, actor* _act_source,
                    int _source, spell_type _spell, int _pow,
                    int _fail, string _cause = "",
                    nothing_happens_when_type _nothing_happens = NH_DEFAULT,
                    int _lethality_margin = 0,
                    string _hand_str = "", bool _can_plural_hand = true);
      MiscastEffect(actor* _target, actor* _act_source,
                    int _source, spschool_flag_type _school,
                    int _level, string _cause,
                    nothing_happens_when_type _nothing_happens = NH_DEFAULT,
                    int _lethality_margin = 0,
                    string _hand_str = "", bool _can_plural_hand = true);
      MiscastEffect(actor* _target, actor* _act_source,
                    int _source, spschool_flag_type _school,
                    int _pow, int _fail, string _cause,
                    nothing_happens_when_type _nothing_happens = NH_DEFAULT,
                    int _lethality_margin = 0,
                    string _hand_str = "", bool _can_plural_hand = true);
  
      ~MiscastEffect();
  
      void do_miscast();
  
  private:
      actor* target;
      // May be nullptr.
      actor* act_source;
      // Either a miscast_source, or GOD_MISCAST + god_type enum.
      int    special_source;
  
      string cause;
  
      spell_type         spell;
      spschool_flag_type school;
  
      int pow;
      int fail;
      int level;
  
  private:
      // init() sets this to a proper value
      killer_type kt = KILL_NONE;
  
      nothing_happens_when_type nothing_happens_when;
  
      int lethality_margin;
  
      string hand_str;
      bool        can_plural_hand;
  
      bool source_known;
      bool target_known;
  
      bolt beam;
  
      string all_msg;
      string you_msg;
      string mon_msg;
      string mon_msg_seen;
      string mon_msg_unseen;
  
      msg_channel_type msg_ch;
  
      int  sound_loudness;
  
      int  recursion_depth;
      bool did_msg;
  
  private:
      void init();
      string get_default_cause(bool attribute_to_user) const;
  
      bool neither_end_silenced();
  
      void do_msg(bool suppress_nothing_happens = false);
      bool _ouch(int dam, beam_type flavour = BEAM_NONE);
      bool _explosion();
      bool _big_cloud(cloud_type cl_type, int cloud_pow, int size,
                      int spread_rate = -1);
      bool _paralyse(int dur);
      bool _sleep(int dur);
      bool _create_monster(monster_type what, int abj_deg, bool alert = false);
      bool _send_to_abyss();
      bool _malign_gateway(bool hostile = true);
      void _do_poison(int amount);
      void _malmutate();
  
      bool avoid_lethal(int dam);
  
      void _conjuration(int severity);
      void _hexes(int severity);
      void _charms(int severity);
      void _translocation(int severity);
      void _summoning(int severity);
      void _necromancy(int severity);
      void _transmutation(int severity);
      void _fire(int severity);
      void _ice(int severity);
      void _earth(int severity);
      void _air(int severity);
      void _poison(int severity);
  
      void _zot();
  };
  