/**************************************************************
 * FFTacticsMUD : ch.h                                        *
 **************************************************************
 * (c) 2002 Damien Dailidenas (Trenton). All rights reserved. *
 **************************************************************/

#include "desc.h"
#include "status.h"
#include "group.h"

typedef class AREA AREA;
typedef class ROOM ROOM;
typedef class BATTLE_AREA BATTLE_AREA;
typedef class BATTLE_ROOM BATTLE_ROOM;
typedef class OBJ OBJ;
typedef class BATTLE BATTLE;

#define PLR_LOG         (A)
#define PLR_OMNIPOTENT  (B)
#define PLR_INVIS       (C)
#define PLR_FROZEN	(D)
  
#define WIZ_ON          (A)
#define WIZ_LINKS       (B)
#define WIZ_DEATHS      (C)
#define WIZ_SECURE      (D)
#define WIZ_SPAM        (E)
#define WIZ_MEMORY      (F)
  
#define MAX_EQ_SLOTS 	10
#define MAX_SKILLS      100
#define MAX_NPC_SKILLS  5
#define MAX_IGNORE      99
#define MAX_JOBS        70

#define MAX_QUEUES	50

#define MAX_BATTLES	50

class CH {
public:
  CH *next, *next_in_room, *next_in_battle, *next_in_group, *following;
  DESC *desc;
  string name, pwd, email, ignore[MAX_IGNORE], socket, login, commands, queue[MAX_QUEUES];
  unsigned long mins_total;
  unsigned int pks, pdeaths, mins_login, mins_ave;
  AREA *area;
  ROOM *room;
  BATTLE_ROOM *battle_room, *orig_room, *to_room;
  OBJ *objects, *eq[5];   
  STATUS *status_list;
  BATTLE *battle;
  GROUP *group;
  bool acted, moved, skill[MAX_SKILLS], confirm_delete, snooping, admin, disabled, PK, npc, battles[MAX_BATTLES];
  float HPP, MPP, SpP, MAP, PAP;
  long act, wiznet, money, strengthen, weakness, imm, absorb, half;
  int timer;
  short sex, cjob, CT, wait, HP[2], MP[2], PA, MA, Sp, Br, Mv, Ju, Ev, Fa, lvl, exp, moves, id, birthday[2];

  struct {
    short lvl, JP, exp, subjob, reaction, support, move;
  } job[MAX_JOBS];

  struct {
    BATTLE_ROOM *target;   
    short ctr, id;  
    DO_ACT *action;
  } action;

  struct {
    DO_FUN *action;
    short range;
  } temp_action;

  CH();
  ~CH();

  void interpret(string argument);
  void printf(const string str, const bool sleeping=false);
  void printf(char *txt, ...);
  void restore();
  void leave_battle();
  void die(CH *killer=NULL);
  void join_group(CH *leader);
  void leave_group();
  void map_area(const bool quiet);
  void print_map(const bool quiet);
  void to(ROOM *room);
  void to(BATTLE_ROOM *room);
  void from_room();
  void from_battle_room();
  void remove(OBJ *obj);
  void remove(STATUS *status, const bool announce = true);
  void clear_status(const bool announce=true);
  void cancel(STATUSTYPE *type, const bool announce=true);
  void status_update();
  void stat(CH *ch);
  void copy(const CH *ch);
  void look(CH *ch);
  void damage(CH *victim, const short dam);
  void resolve_action();
  void end_turn();
  void retreat();
  void advance();
  void announce_action();
  void gain_exp();
  void gain_jp();
  void level_up(const bool quiet=false);
  void equip(OBJ *obj, const short loc);
  void init_stats();
  void print_status(CH *ch);
  void set_job(const short id);
  void restore_hp(const short x);
  void load_battle();
  void prompt();
  void print_MOTD();
  void save_objects();
  void save_ignored();
  void save();
  void load_jobs();
  void load_skills();
  void load_ignored();
  void load_objects();
  void ignore_add(const string name);
  void ignore_remove(const string name);
  void ignore_list();
  void npc_turn();
  void add_queue(const string str);
  void update_queue();
  void check_battle();

  string his_her();
  string he_she();
  string print_sector(BATTLE_ROOM *prev_room, BATTLE_ROOM *room, const bool color);
  string male_female();
  string idle();
  
  CH *get_ch_room(const string name);
  CH *get_nearest_target(const bool ally);

  bool physical_attack(CH *victim, short dam);
  bool can_see(const CH *ch);
  bool can_move(const ROOM *room);
  bool can_see(const OBJ *obj);
  bool move(const short dir);
  bool can_group(const CH *ch);
  bool check_evade();
  bool has_skill(const string skill_name, const bool jobonly=true);
  bool check_reaction(CH *victim, const short trigger);
  bool check_ok(const bool act=false);
  bool move_within_range(CH *victim);
  bool can_be_job(const short id);
  bool can_equip(const OBJ *obj, const short loc);
  bool is_admin();
  bool ignoring(const string name);

  short get_group_cnt();
  short calculate_dam(const short K, const short loc);
  short distance(const CH *ch);
  short dir(const CH *ch);
  short dir(const BATTLE_ROOM *room);
  short get_weap_loc();
  short get_hitpercent();
  short get_act_range(const short id);
  short get_move_range();
  short get_skill_id(const string name, const bool learned);

  OBJ *obj(const string name, const bool equipped = false);
  OBJ *obj(const short id, const bool equipped = false);

  BATTLE_ROOM *get_room_by_loc(const string str);
  BATTLE_ROOM *random_room(const short distance);

  STATUS *add(STATUSTYPE *status_type, const short ctr = 0, const short chance = 0, const bool announce = true);
  STATUS *status(STATUSTYPE *type);
};

struct statpoint_type {
  long SpP, PAPlow, PAPhigh, MAPlow, MAPhigh, HPPlow, HPPhigh, MPPlow, MPPhigh;
};

extern  const   struct  statpoint_type  statpoint_table[];
extern 	CH *ch_list;

CH *get_ch args((const string name));