/
roa/
roa/lib/boards/
roa/lib/config/
roa/lib/edits/
roa/lib/help/
roa/lib/misc/
roa/lib/plrobjs/
roa/lib/quests/
roa/lib/socials/
roa/lib/www/
roa/lib/www/LEDSign/
roa/lib/www/LEDSign/fonts/
roa/lib/www/LEDSign/scripts/
roa/src/s_inc/
roa/src/sclient/
roa/src/sclient/binary/
roa/src/sclient/text/
roa/src/util/
/************************************************************************
	Realms of Aurealis 		James Rhone aka Vall of RoA

utils.h					Oh macros, messy function protos
					should be cleaned up sometime...

		******** Heavily modified and expanded ********
		*** BE AWARE OF ALL RIGHTS AND RESERVATIONS ***
		******** Heavily modified and expanded ********
		        All rights reserved henceforth. 

    Please note that no guarantees are associated with any code from
Realms of Aurealis.  All code which has been released to the general
public has been done so with an 'as is' pretense.  RoA is based on both
Diku and CircleMUD and ALL licenses from both *MUST* be adhered to as well
as the RoA license.   *** Read, Learn, Understand, Improve ***
*************************************************************************/
#ifndef ROA_UTILS_H
#define ROA_UTILS_H

/* from weather.c / db.c sometime soon */
extern struct global_weather_type global_weather;

/* public functions */
int	str_cmp(char *arg1, char *arg2);
char*	str_add(char *arg1, char *arg2);
int	strn_cmp(char *arg1, char *arg2, int n);
char *padding(int i);
int get_pdata_filename(char *orig_name, char *ext, char *filename);

void free_log(void *ptr, char *txt);
char *str_cpy(char *dest, char *src, int max, char *fname);
char *str_cat(char *dest, char *src, int max, char *fname);

void	log(char *str);
void	mudlog(char *str, char type, sbyte level, byte file);
void	log_death_trap(struct char_data *ch);
int	number(int from, int to);
int	dice(int number, int size);
void	sprintbit(long vektor, char *names[], char *result);
void	sprinttype(int type, char *names[], char *result);
struct  time_info_data age(struct char_data *ch);
void 	send_to_room_not_busy(char *str, int rm);
int	get_command(char *comm);

/* in utils.c */
int 	MAX(int a, int b);
int 	MIN(int a, int b);
void	skip_spaces(char **str);
char   	*scan_past_eol(char *pt);
char   	*scan_past_eol_and_spaces(char *pt);
char   	*skip_block(char *pt);
int   	chars_in_block(char *pt);
void   	die_follower(chdata *ch);
void   	add_follower(chdata *ch, chdata *leader);
void   	stop_follower(chdata *ch);
BOOL   	circle_follow(chdata *ch, chdata *vict);
void 	underline(char *buf);
chdata  *group_member(chdata *ch, BOOL inroom);
chdata  *group_leader(chdata *ch);
int	num_in_group(chdata *ch);
int	InRange(int value, int low, int high);
int   	get_class_num(char *name);
BOOL	InSameGroup(CharData *ch, CharData *sch);
BOOL	MaxSummons(chdata *ch);

/* in info.c */
void do_look_at_room(chdata *ch, int cmd, int subcmd);
int can_see(chdata *ch, chdata *i);

BOOL	circle_follow(struct char_data *ch, struct char_data * victim);

/* from fight.c */
BOOL	check_mortal_combat(chdata *ch, chdata *vict);

/* from screen.c */
void	clrscr(chdata *ch);
void	topscreen(chdata *ch);
void	botscreen(chdata *ch);
void	updatescr(chdata *ch);
void	resetscr(chdata *ch);

/* db.c */
int	real_zone(int target_zone);
extern int top_of_world;
extern void remove_room_snooper(rmdata *r, dsdata *d);
extern void send_to_room_snoopers(char *x, int room, chdata *ch, int type);
extern void wax_room_snoopers(rmdata *r);
extern void add_room_snooper(rmdata *r, dsdata *d);

/* for misc.c */
void damage_object(obdata *ob, chdata *ch);
BOOL check_death_trap(chdata *ch, chdata *mount);

// from skills.c
int get_skill(chdata *ch, int skl);
int set_skill(chdata *ch, int skl, int perc);
int get_gskill(chdata *ch, int skl);
int set_gskill(chdata *ch, int skl, int perc);

/* defines for fseek */
#ifndef SEEK_SET
#define SEEK_SET	0
#define SEEK_CUR	1
#define SEEK_END	2
#endif

/* defines for mudlog() */
#define OFF	0
#define BRF	1
#define NRM	2
#define CMP	3
#define BUG	4

#define TRUE  1
#define YES   1
#define FALSE 0
#define NO    0

#define YESNO(a) ((a) ? "YES" : "NO")
#define ONOFF(a) ((a) ? "ON" : "OFF")

#define LOWER(c) (((c)>='A'  && (c) <= 'Z') ? ((c)+('a'-'A')) : (c))

#define UPPER(c) (((c)>='a'  && (c) <= 'z') ? ((c)+('A'-'a')) : (c) )

#define S2C()	send_to_char(buf, ch)
#define S2C2()	send_to_char(buf2, ch)
#define S2Q()	send_to_q(buf, d)

#define ISNEWL(ch) ((ch) == '\n' || (ch) == '\r') 
#define ISSPACE(ch) ((ch) == ' ' || (ch) == '\t') 

#define IF_STR(st) ((st) ? (st) : "\0")

#define STR_DUP(st) ((st) ? strdup(st) : (char *) NULL)

#define CAP(st)  (*(st) = UPPER(*(st)), st)
#define UNCAP(st)  (*(st) = LOWER(*(st)), st)

#define CCAP(st)   do { \
			char *jtrtmp; \
			for (jtrtmp = (st); *jtrtmp; jtrtmp++) \
			  if (isalpha(*jtrtmp)) \
			  { \
			    CAP(jtrtmp); \
			    break; \
			  } \
		      } \
		   while (0)

#define CREATE(result, type, number)  do {\
\
        if ( (sizeof(type) * number) <= 0 )\
        { perror("malloc attempt <= 0"); abort();}\
\
        if (!((result) = (type *) calloc ((number), sizeof(type))))\
                { perror("malloc failure"); abort(); } } while(0)

#define RECREATE(result,type,number) do {\
  if (!((result) = (type *) realloc ((result), sizeof(type) * (number))))\
                { perror("realloc failure"); abort(); } } while(0)

#define IS_SET(flag,bit)  ((flag) & (bit))
#define SET_BIT(var,bit)  ((var) |= (bit))
#define REMOVE_BIT(var,bit)  ((var) &= ~(bit))
#define TOGGLE_BIT(var,bit) ((var) = (var) ^ (bit))

#define MOB_FLAGS(ch)  ((ch)->npc_specials.mob_bits)
#define MOB2_FLAGS(ch) ((ch)->npc_specials.mob2_bits)
#define SPC_FLAGS(ch)  ((ch)->npc_specials.spc_bits)
#define MOB_CLASS_FLAGS(ch)  ((ch)->npc_specials.mob_class)

#define PLR_FLAGS(ch)  ((ch)->pc_specials->saved.player_flags)
#define PLR2_FLAGS(ch) ((ch)->pc_specials->saved.plr2_flags)
#define PRF_FLAGS(ch)  ((ch)->pc_specials->saved.pref_flags)
#define PRF2_FLAGS(ch) ((ch)->pc_specials->saved.pref2_flags)
#define GRNT_FLAGS(ch) ((ch)->pc_specials->saved.grants)

#define SEND_OK(ch)	(!PLR_FLAGGED((ch), PLR_BUILDING) &&\
			 !PLR_FLAGGED((ch), PLR_WRITING) &&\
			 !PLR_FLAGGED((ch), PLR_MAILING))

#define IS_NPC(ch)  (IS_SET(MOB_FLAGS((ch)), MOB_ISNPC))
#define IS_MOB(ch)  (IS_NPC(ch) && ((ch)->nr > -1))
#define IS_PC(ch)   (!IS_NPC((ch)))
#define IS_SWITCHED(ch)	((ch)->desc && (ch)->desc->original)
#define TRUE_CHAR(ch)	((ch->desc->original) ? ch->desc->original : ch)

// descriptor defines for most descriptor loops
#define D_INGAME(d)  (!d->connected)
#define D_HASCHAR(d) (d->character)
#define D_CHECK(d)   (D_INGAME(d) && D_HASCHAR(d))
#define HAS_CLIENT(d) (d->cdesc > 0)

#define ZONE_FLAGS(zon) (zone_table[(zon)].bitvector)
#define REAL_ZONE(zon)	((real_zone((zon)) >= 0))
#define ROOM_FLAGS(room) (world[(room)].room_flags)
#define ROOM_FLAGS2(room) (world[(room)].room_flags2)
#define ROOM_VNUM(room)  (world[(room)].number)
#define ROOM_NAME(room)  (world[(room)].name)
#define ROOM_TEMP(room)  (world[(room)].room_temp)
#define ROOM_FLAGGED(room, flag) (IS_SET(ROOM_FLAGS((room)), flag))
#define ROOM_FLAGGED2(room, flag) (IS_SET(ROOM_FLAGS2((room)), flag))

#define INVALID_ROOM(r)	((r) <= NOWHERE || (r) >= top_of_world)

#define RPORTAL(room, num)	(world[(room)].portals[num])
#define RSNOOPER(room)		((room)->snooper)
#define DROPTO(room)		((room)->drop_to)
#define DRIFTTO(room)		((room)->drift_to)
#define FLOATTO(room)		((room)->float_to)
#define TRANS_KEYWORDS(room)	((room)->randoms[0])
#define TRANS_SHDESC(room)	((room)->randoms[1])
#define TRANS_LDESC(room)	((room)->randoms[2])
#define TRANS_MOVE_MESG(room)	((room)->randoms[3])
#define TRANS_ARRIVE_MESG(room)	((room)->randoms[4])
#define RPROC_BEG(r)            ((r)->rproc)
#define RPROC_CUR(r)            ((r)->rproc_cur)
#define RPROC_WAIT(r)           ((r)->rproc_wait)
#define RTRIGS(r)	        ((r)->trigs)
#define RTRIG_WAITING(r) 	((r)->trig_waiting)
#define RTRIG_IGNORE(r) 	((r)->trig_ignore)
#define RTARGET_CHAR(r)         ((r)->target_char)
#define RTARGET_OBJ(r)          ((r)->target_obj)
#define REMOTE(r)		((r)->remote)

#define MOB_FLAGGED(ch, flag)         (IS_NPC(ch) && IS_SET(MOB_FLAGS(ch), (flag)))
#define MOB2_FLAGGED(ch, flag)        (IS_NPC(ch) && IS_SET(MOB2_FLAGS(ch), (flag)))
#define MOB_CLASS_FLAGGED(ch, flag)   (IS_NPC(ch) && IS_SET(MOB_CLASS_FLAGS(ch), (flag)))

#define SPC_FLAGGED(ch, flag) (IS_NPC(ch) && IS_SET(SPC_FLAGS(ch), (flag)))
#define PLR_FLAGGED(ch, flag) (IS_PC((ch)) && IS_SET(PLR_FLAGS((ch)), (flag)))
#define PLR2_FLAGGED(ch, flag) (IS_PC((ch)) && IS_SET(PLR2_FLAGS((ch)), (flag)))
#define PRF_FLAGGED(ch, flag) (IS_PC((ch)) && IS_SET(PRF_FLAGS((ch)), (flag)))
#define PRF2_FLAGGED(ch, flag) (IS_PC((ch)) && IS_SET(PRF2_FLAGS((ch)), (flag)))
#define GRNT_FLAGGED(ch, flag) (IS_PC(ch) && IS_SET(GRNT_FLAGS(ch), (flag)))

#define ZONE_FLAGGED(zon, flag) (IS_SET(ZONE_FLAGS((zon)), (flag)))
#define ZONE_FREED(zon) (ZONE_FLAGGED((zon), Z_FREED))
#define ZONE_IDLE(zon)  (ZONE_FLAGGED((zon), Z_IDLE))
#define ZONE_CLOSED(zon)  (ZONE_FLAGGED((zon), Z_CLOSED))
#define ZONE_LOCKED(zon)  (ZONE_FLAGGED((zon), Z_LOCKED))
#define SET_ZONE_FREED(zon) (SET_BIT(ZONE_FLAGS((zon)), Z_FREED))
#define UNSET_ZONE_FREED(zon) (REMOVE_BIT(ZONE_FLAGS((zon)), Z_FREED))
#define SET_ZONE_IDLE(zon) (SET_BIT(ZONE_FLAGS((zon)), Z_IDLE))
#define UNSET_ZONE_IDLE(zon) (REMOVE_BIT(ZONE_FLAGS((zon)), Z_IDLE))

#define ZONE_TEMP(zon) 		(zone_table[(zon)].current_gtemp)
#define ZONE_ACCUM(zon)		(zone_table[(zon)].accum)
#define ZONE_ACCUM_TYPE(zon)	(zone_table[(zon)].accum_type)

#define HOUSE_FLAGGED(i, f) (IS_SET(house_control[i].bitvector, f))

#define CMD_NAME(cmd)    (cmd_info[(cmd)].comm)
#define CMD_IS(num, str) (!str_cmp((str), CMD_NAME((num))))
#define CMD_FLAGS(cmd) 	(cmd_info[(cmd)].bitvector)
#define CMD_GFLAGS(cmd) (cmd_info[(cmd)].gbitvector)
#define CMD_FLAGGED(c, f) (IS_SET(CMD_FLAGS(c), (f)))
#define CMD_GFLAGGED(c, f) (IS_SET(CMD_GFLAGS(c), (f)))
#define FLAG_CMD(c, f) (SET_BIT(CMD_FLAGS(c), (f)))
#define GFLAG_CMD(c, f) (SET_BIT(CMD_GFLAGS(c), (f)))
#define UNFLAG_CMD(c, f) (REMOVE_BIT(CMD_FLAGS(c), (f)))
#define GUNFLAG_CMD(c, f) (REMOVE_BIT(CMD_GFLAGS(c), (f)))

// for char and obj where vectors
#define WV_FLAGS(ob)	     ((ob)->wvector)
#define WV_FLAGGED(o, f)     (IS_SET(WV_FLAGS(o), (f)))

/* olc macs */
#define OBJ_SLOTS_LEFT ((top_of_sorted_objt + OBJ_PADDING - top_of_objt) > 0)
#define MOB_SLOTS_LEFT ((top_of_sorted_mobt + MOB_PADDING - top_of_mobt) > 0)
#define WLD_SLOTS_LEFT ((top_of_sorted_world + WLD_PADDING - top_of_world) > 0)

#define PLR_TOG_CHK(ch,flag) ((TOGGLE_BIT(PLR_FLAGS(ch), (flag))) & (flag))
#define PLR2_TOG_CHK(ch,flag) ((TOGGLE_BIT(PLR2_FLAGS(ch), (flag))) & (flag))
#define PRF_TOG_CHK(ch,flag) ((TOGGLE_BIT(PRF_FLAGS(ch), (flag))) & (flag))
#define PRF2_TOG_CHK(ch,flag) ((TOGGLE_BIT(PRF2_FLAGS(ch), (flag))) & (flag))

#define SWITCH(a,b) { (a) ^= (b); \
                      (b) ^= (a); \
                      (a) ^= (b); }

#define AFF_FLAGS(ch)  ((ch)->specials.affected_by)
#define AFF2_FLAGS(ch) ((ch)->specials.affected2_by)
#define CHAR_FLAGS(ch) ((ch)->specials.charvector)

#define IS_AFFECTED(ch,skill)  (IS_SET( AFF_FLAGS(ch), (skill)) )
#define IS_AFFECTED2(ch,skill) (IS_SET(AFF2_FLAGS(ch), (skill)) )
#define CHAR_FLAGGED(ch, flag) (IS_SET(CHAR_FLAGS(ch), (flag)) )

#define SUNLIGHT     (global_weather.sunlight)
#define DARK_OUTSIDE (SUNLIGHT == SUN_SET || SUNLIGHT == SUN_DARK)

#define WEATHER_ROOM(room) ((world[room].terrain_type != TERRAIN_INSIDE && \
                            world[room].terrain_type != TERRAIN_CITY  && \
			    world[room].terrain_type != TERRAIN_UWATER && \
			    !ROOM_FLAGGED(room, NO_WEATHER)))

#define IS_DARK(room)  (!world[(room)].light && \
			(ROOM_FLAGGED((room), DARK) || \
			 (WEATHER_ROOM((room)) && DARK_OUTSIDE)))

#define IS_LIGHT(room)  (!IS_DARK(room))

#define WILDERNESS(stype) (((stype) == TERRAIN_FOREST) || \
			   ((stype) == TERRAIN_HILLS) || \
			   ((stype) == TERRAIN_MOUNTAIN) || \
			   ((stype) == TERRAIN_FIELD))

#define IS_PRECIPPING(zone) (zone_table[(zone)].current_status > CLOUDY)

#define GET_INVIS_LEV(ch) ((ch)->pc_specials->invis_level)

#define TELL_LEV(ch) ((ch)->pc_specials->tell_level)

#define CAN_SEE_IN_DARK(ch) ((IS_PC((ch)) && PRF_FLAGGED(ch, PRF_HOLYLIGHT)) || \
                             IS_AFFECTED(ch, AFF_INFRARED))

#define WIMP_LEVEL(ch) ((ch)->pc_specials->saved.wimp_level)

#define GET_REQ(i) (i<2  ? "Awful" :(i<4  ? "Bad"     :(i<7  ? "Poor"      :\
(i<10 ? "Average" :(i<14 ? "Fair"    :(i<20 ? "Good"    :(i<24 ? "Very good" :\
        "Superb" )))))))

#define HSHR(ch) ((ch)->player.sex ?					\
	(((ch)->player.sex == 1) ? "his" : "her") : "its")

#define HSSH(ch) ((ch)->player.sex ?					\
	(((ch)->player.sex == 1) ? "he" : "she") : "it")

#define HMHR(ch) ((ch)->player.sex ? 					\
	(((ch)->player.sex == 1) ? "him" : "her") : "it")	

#define AN(string) (strchr("aeiouAEIOU", *string) ? "an" : "a")

#define ANA(obj) (strchr("aeiouyAEIOUY", *(obj)->name) ? "An" : "A")

#define SANA(obj) (strchr("aeiouyAEIOUY", *(obj)->name) ? "an" : "a")

#define GET_POS(ch)     ((ch)->specials.position)

#define GET_COND(ch, i) ((ch)->pc_specials->saved.conditions[(i)])

#define GET_HTOWN(ch)	((ch)->player.hometown)
#define GET_LOADROOM(ch) ((ch)->pc_specials->saved.load_room)

#define GET_NAME(ch)    (IS_NPC(ch) ? (ch)->player.short_descr : (ch)->player.name)

#define GET_PRENAME(ch) ((ch)->pc_specials->saved.prename)

#define GET_TITLE(ch)   ((ch)->player.title)

#define GET_LEVEL(ch)   ((ch)->player.level)
#define GET_WLEVEL(ch)   ((ch)->pc_specials->saved.warlock_level)

#define GET_CLASS(ch)   ((ch)->player.cls)

#define GET_RACE(ch)	((IS_PC((ch)))?(ch)->pc_specials->saved.race:0)

#define GET_HOME(ch)	((ch)->player.hometown)

#define GET_AGE(ch)     (age(ch).year)

#define GET_STR(ch)     ((ch)->aff_abils.str)

#define GET_ADD(ch)     ((ch)->aff_abils.str_add)

#define GET_DEX(ch)     ((ch)->aff_abils.dex)

#define GET_INT(ch)     ((ch)->aff_abils.intel)

#define GET_WIS(ch)     ((ch)->aff_abils.wis)

#define GET_CON(ch)     ((ch)->aff_abils.con)

#define GET_CHA(ch)	((ch)->aff_abils.cha)

#define GET_RSNOOPING(ch)	((ch)->desc->room_snooping)

/* returns a number 1-30 of true strength */
#define TRUE_STRENGTH(ch) \
        ( ((GET_ADD(ch)==0) || (GET_STR(ch) != 18)) ? GET_STR(ch) :\
          (GET_ADD(ch) <= 50) ? 26 :( \
          (GET_ADD(ch) <= 75) ? 27 :( \
          (GET_ADD(ch) <= 90) ? 28 :( \
          (GET_ADD(ch) <= 99) ? 29 :  30 ) ) )                   \
        )

#define GET_AC(ch)      ((ch)->points.armor)
#define GET_HIT(ch)	((ch)->points.hit)
#define GET_MAX_HIT(ch)	((ch)->points.max_hit)

#define GET_MOVE(ch)	((ch)->points.move)
#define GET_MAX_MOVE(ch) ((ch)->points.max_move)

#define GET_MANA(ch)	((ch)->points.mana)
#define GET_MAX_MANA(ch) ((ch)->points.max_mana)

#define GET_GOLD(ch)	((ch)->points.gold)
#define GET_BANK_GOLD(ch) ((ch)->points.bank_gold)

#define GET_EXP(ch)	((ch)->points.exp)

#define GET_HEIGHT(ch)	((ch)->player.height)

#define GET_WEIGHT(ch)	((ch)->player.weight)

#define GET_SEX(ch)	((ch)->player.sex)

#define GET_HITROLL(ch) ((ch)->points.hitroll)

#define GET_DAMROLL(ch) ((ch)->points.damroll)

#define SPELLS_TO_LEARN(ch) ((ch)->pc_specials->saved.spells_to_learn)

#define GET_IDNUM(ch) (IS_NPC(ch) ? -1 : (ch)->pc_specials->saved.idnum)

#define AWAKE(ch) (GET_POS(ch) > POS_SLEEPING)

#define FIGHTING(ch)	((ch)->specials.fighting)

#define HOLDER(ch)	((ch)->specials.holder)

#define GET_TRAP_LEVEL(ch)   (IS_IMMORTAL(ch) ? (ch)->specials.traplevel : (ch)->player.level)

/* npc only huntin */
#define HUNTING(ch)	((ch)->npc_specials.hunting)

#define CHARMED(ch)	(IS_AFFECTED((ch), AFF_CHARM))

#define IS_ASSASSIN(ch) (IS_PC((ch)) && PRF_FLAGGED((ch), PRF_ASSASSIN))
#define INCOG(ch) 	(IS_PC((ch)) && PRF_FLAGGED((ch), PRF_INCOGNITO))
#define IN_ARENA(ch)	(IS_PC((ch)) && PLR_FLAGGED((ch), PLR_ARENA))
#define SUMMONED(ch)	(CHAR_FLAGGED((ch), CH_SUMMONED))
#define SUMMONER(ch)	((ch)->npc_specials.summoner)
#define TEMP_FLAGGED(ch) (CHAR_FLAGGED((ch), CH_TEMP))
#define UNTEMP_FLAG(ch)	(REMOVE_BIT(CHAR_FLAGS((ch), CH_TEMP)))
#define TEMP_FLAG(ch)	(SET_BIT(CHAR_FLAGS((ch), CH_TEMP)))

#define GET_WAS_IN(ch)	((ch)->specials.was_in_room)

#define GET_SKILL(ch, i) get_skill(ch, i)
#define SET_SKILL(ch, i, pct) set_skill(ch, i, pct)

#define GET_GSKILL(ch, i) get_gskill(ch, i)
#define SET_GSKILL(ch, i, pct) set_gskill(ch, i, pct)
#define GSKILL_LEVEL(s)    (gs_array[(s)].level)
#define GSKILL_MAXPERC(s)  (gs_array[(s)].max_perc)
#define GSKILL_FLAGS(s)    (gs_array[(s)].bitv)
#define GSKILL_RCFLAGS(s)  (gs_array[(s)].rcbitv)
#define GSKILL_FLAGGED(s, f)    (IS_SET(GSKILL_FLAGS(s), (f)))
#define GSKILL_RCFLAGGED(s, f)  (IS_SET(GSKILL_RCFLAGS(s), (f)))

#define WAIT_STATE(ch, cycle)  (((ch)->desc) ? (ch)->desc->wait = (cycle) : 0)

#define CHECK_WAIT(ch) (((ch)->desc) ? ((ch)->desc->wait > 1) : 0)

// works for objs and chars
#define SAME_ROOM(ch, vict)  ((ch)->in_room == (vict)->in_room)

/* Object And Carry related macros */
/* for objects */

#define CAN_SEE_OBJ(sub, obj)                                    \
	(( (( !IS_SET((obj)->extras, ITEM_INVISIBLE) ||   \
	     IS_AFFECTED((sub),AFF_DETECT_INVISIBLE) ) &&               \
	     !IS_AFFECTED((sub),AFF_BLIND)) && IS_LIGHT(sub->in_room) ) \
	     || PRF_FLAGGED((sub), PRF_HOLYLIGHT))

#define ITEM_TYPE(obj) ((obj)->type_flag)

#define OBJ_WEARS(ob)		((ob)->wear_flags)
#define OBJ_EXTRAS(ob)		((ob)->extras)

#define OBJ_HITS(ob)		((ob)->obj_hits)
#define MAX_OBJ_HITS(ob)	((ob)->max_obj_hits)
#define OBJ_EXTRAS2(ob)		((ob)->extras2)
#define MADE_OF(ob)             ((ob)->made_of)
#define SUCCESS_RATE(ob)        ((ob)->success_rate)
#define OWNER_OF(ob)		((ob)->owner_of)
#define OBJ_ID(ob)		((ob)->obj_id)
#define OBJ_LIGHT(ob)		(ITEM_TYPE((ob)) == ITEM_LIGHT)
#define IS_WEAPON(ob)		(ITEM_TYPE((ob)) == ITEM_WEAPON)
#define IS_ARMOR(ob)		(ITEM_TYPE((ob)) == ITEM_ARMOR)
#define LIGHT_TIME(ob)		((ob)->value[2])
#define MAX_CHARGES(ob)		((ob)->value[1])
#define CHARGES_LEFT(ob)	((ob)->value[2])
#define LIT(ob)			((ob)->lit && LIGHT_TIME((ob)))

#define OBJ_FLAGGED(obj,stat) 	(IS_SET(OBJ_EXTRAS((obj)),stat))
#define OBJ_FLAGGED2(obj,stat) 	(IS_SET(OBJ_EXTRAS2((obj)),stat))

#define THROWABLE(ob)		(OBJ_FLAGGED2((ob), ITEM_THROWABLE))

#define BROKE(ob)	((OBJ_HITS((ob)) <= 0) && (MAX_OBJ_HITS((ob)) != -1))

#define CAN_WEAR(obj, part) (IS_SET(OBJ_WEARS((obj)),part))

#define EQ(ch, pos)	   ((ch)->equipment[(pos)])

#define GET_OBJ_WEIGHT(obj) ((obj)->weight)

#define GET_OBJ_RNUM(obj) ((obj)->item_number)

#define GET_MOB_RNUM(mob) ((mob)->nr)

#define GET_OBJ_VNUM(obj) ((GET_OBJ_RNUM((obj)) >= 0) ? (obj_index[GET_OBJ_RNUM((obj))].vnum) : -1)

#define GET_MOB_VNUM(mob) ((GET_MOB_RNUM((mob)) >= 0) ? (mob_index[GET_MOB_RNUM((mob))].vnum) : -1)

#define CAN_CARRY_W(ch) (str_app[TRUE_STRENGTH(ch)].carry_w)

#define CAN_CARRY_N(ch) (5+GET_DEX(ch)/2+GET_LEVEL(ch)/2)

#define IS_CARRYING_W(ch) ((ch)->specials.carry_weight)

#define IS_CARRYING_N(ch) ((ch)->specials.carry_items)

#define CAN_CARRY_OBJ(ch,obj)  \
   (((IS_CARRYING_W(ch) + GET_OBJ_WEIGHT(obj)) <= CAN_CARRY_W(ch)) &&   \
    ((IS_CARRYING_N(ch) + 1) <= CAN_CARRY_N(ch)))

#define CAN_GET_OBJ(ch, obj)   \
   (CAN_WEAR((obj), ITEM_TAKE) && CAN_CARRY_OBJ((ch),(obj)) && CAN_SEE_OBJ((ch),(obj)))


#define IS_CORPSE(ob)   ((ITEM_TYPE((ob)) == ITEM_CONTAINER) && ((ob))->value[3])

#define DRINKS_LEFT(ob) ((ob)->value[1])
#define DRINK_TYPE(ob)  ((ob)->value[2])
#define DRINK_POISONED(ob)  ((ob)->value[3])
#define POISON_LEVEL(ob)  ((ob)->value[3])

#define IS_LIQCONT(ob)      (ITEM_TYPE((ob)) == ITEM_DRINKCON)
#define IS_PUREPOISON(ob)   (IS_LIQCONT(ob) && DRINK_TYPE((ob)) == LIQ_POISON)
#define IS_ALCOHOL(ob)      (IS_LIQCONT((ob)) && ( \
                             DRINK_TYPE(ob) == LIQ_BEER || \
                             DRINK_TYPE(ob) == LIQ_WINE || \
                             DRINK_TYPE(ob) == LIQ_ALE || \
                             DRINK_TYPE(ob) == LIQ_DARKALE || \
                             DRINK_TYPE(ob) == LIQ_WHISKY || \
                             DRINK_TYPE(ob) == LIQ_FIREBRT || \
                             DRINK_TYPE(ob) == LIQ_LOCALSPC ))

#define PERS(ch, vict)   (can_see(vict, ch) ? GET_NAME(ch) : "someone")

#define OBJS(obj, vict) (CAN_SEE_OBJ((vict), (obj)) ? (obj)->shdesc : "something")

#define OBJN(obj, vict) (CAN_SEE_OBJ((vict), (obj)) ? \
	fname((obj)->name) : "something")

#define OUTSIDE(ch) (world[ch->in_room].terrain_type != TERRAIN_INSIDE && \
		     world[ch->in_room].terrain_type != TERRAIN_UWATER && \
		     !ROOM_FLAGGED(ch->in_room, NO_WEATHER))

#define DIR(room, door) (world[(room)].dir_option[(door)])
#define EXIT(ch, door)  (DIR((ch)->in_room, (door)))
#define EXIT_FLAGGED(dir, flag) (IS_SET(dir->exinfo, (flag)))
#define EXIT_ISDOOR(dir) (EXIT_FLAGGED((dir), EX_ISDOOR))
#define EXIT_CLOSED(dir) (EXIT_FLAGGED((dir), EX_CLOSED))
#define EXIT_OPEN(dir)   (!EXIT_CLOSED((dir)))
#define EXIT_LOCKED(dir) (EXIT_FLAGGED((dir), EX_LOCKED))
#define EXIT_JAMMED(dir) (EXIT_FLAGGED((dir), EX_JAMMED))
#define EXIT_SECRET(dir) (EXIT_FLAGGED((dir), EX_SECRET))
#define EXIT_UNLOCKED(dir) (!EXIT_LOCKED((dir)))
#define FLAG_EXIT(dir, flag) (SET_BIT((dir)->exinfo, (flag)))
#define UNFLAG_EXIT(dir, flag) (REMOVE_BIT((dir)->exinfo, (flag)))

#define CAN_GO(ch, door) (EXIT(ch,door) && (EXIT(ch,door)->to_room != NOWHERE) \
                          && EXIT_OPEN(EXIT(ch, door)) && !EXIT_SECRET(EXIT(ch, door)))

#define GET_ALIGNMENT(ch) ((IS_PC(ch))?(ch)->pc_specials->saved.alignment :\
			      (ch)->npc_specials.alignment)

#define SAVING_THROW(ch, i) ((IS_PC(ch)) \
			?(ch)->pc_specials->saved.saving_throws[(i)] : \
			 (ch)->npc_specials.saving_throws[(i)])

#define IS_GOOD(ch)    (GET_ALIGNMENT(ch) >= 350)
#define IS_EVIL(ch)    (GET_ALIGNMENT(ch) <= -350)
#define IS_NEUTRAL(ch) (!IS_GOOD(ch) && !IS_EVIL(ch))

#define CLASS_ABBR(ch) (IS_NPC(ch) ? "---" : clarray[(int)GET_CLASS(ch)].class_abbrev)

/* Remove from a linked list macro - 3.0 addition - SL */
#define REMOVE_FROM_LIST(item, head, next)	do\
  {\
   if ((item) == (head))		\
      head = (item)->next;		\
   else 				\
   {					\
      temp = head;			\
      while (temp && (temp->next != (item))) \
	 temp = temp->next;		\
      if (temp)				\
         temp->next = (item)->next;	\
   }					\
  } while(0)

// try to ease freeing of memory -roa
#define FREENULL(ptr) do {if ((ptr)) free((ptr)); (ptr) = NULL;} while(0)

/********/

/* following additions by JTRhone (Vall) ROA */
/* various NPC strings RoA */
#define MSTR1(ch)    ((ch)->npc_specials.strs[0])
#define MSTR2(ch)    ((ch)->npc_specials.strs[1])
#define MSTR3(ch)    ((ch)->npc_specials.strs[2])
#define MSTR4(ch)    ((ch)->npc_specials.strs[3])
#define MSTR5(ch)    ((ch)->npc_specials.strs[4])
#define MSTR6(ch)    ((ch)->npc_specials.strs[5])
#define TRIG1(ch)    (MSTR1(ch))
#define REAC1(ch)    (MSTR2(ch))
#define TRIG2(ch)    (MSTR3(ch))
#define REAC2(ch)    (MSTR4(ch))
#define MPROC_BEG(ch)    (MSTR5((ch)))
#define MPROC_CUR(ch)    (MSTR6((ch)))
#define MWALKIN(ch)	((ch)->npc_specials.walkIn)
#define MWALKOUT(ch)	((ch)->npc_specials.walkOut)

/* target mobproc strings RoA */
#define TARGET_CHAR(ch)    ((ch)->npc_specials.target_char)
#define TARGET_OBJ(ch)     ((ch)->npc_specials.target_obj)

/* various PC strings RoA */
#define PSTR1(ch)    ((ch)->npc_specials.strs[0])
#define PSTR2(ch)    ((ch)->npc_specials.strs[1])

#define WALKIN(ch)	((ch)->pc_specials->saved.walkIn)
#define WALKOUT(ch)	((ch)->pc_specials->saved.walkOut)

#define VT100(ch)	(IS_PC(ch) && (ch)->pc_specials->saved.vt100)
#define BARS(ch)	(IS_PC(ch) && (ch)->pc_specials->saved.bars)
#define PAGE_LENGTH(ch)	((ch)->pc_specials->saved.page_length)
#define VTSPLIT(ch)	((ch)->pc_specials->saved.vtsplit)
#define PSIZE(ch)	((ch)->pc_specials->saved.psize)

#define IN_A_RITUAL(ch)   (PLR_FLAGGED((ch), PLR_RITUAL))

#define DELAY_TYPE(ch)	  ((ch)->pc_specials->delay_type)

#define IS_IMPL(ch)     (IS_PC((ch)) && (GET_LEVEL((ch)) >= LEV_IMPL))
#define IS_CIMP(ch)     (IS_PC((ch)) && (GET_LEVEL((ch)) >= LEV_CIMP))
#define IS_AIMP(ch)     (IS_PC((ch)) && (GET_LEVEL((ch)) >= LEV_AIMP))
#define IS_IMMORTAL(ch) (!IS_NPC((ch)) && (GET_LEVEL((ch)) >= LEV_IMM))

#define IN_NOWHERE(ch) ((ch)->in_room <= NOWHERE)

#define IS_FLYING(ch)   (GET_POS((ch)) == POS_FLOATING || IS_AFFECTED((ch), AFF_WINGS))

#define HAS_GILLS(ch)	(MOB_FLAGGED((ch), MOB_GILLS) || IS_AFFECTED((ch), AFF_GILLS))

#define IS_HELD(ch)     (IS_AFFECTED((ch), AFF_HOLD))

#define VWAIT(ch)	((ch)->specials.violence_wait)

#define WAITING(ch)     (VWAIT(ch) || IS_HELD((ch)))

#define IS_PPL_LIMIT(rm)  ((rm).max_contains > -1 ? TRUE : FALSE)

#define HAS_LIGHT(ch)   (EQ((ch), W_HOLD) && LIT(EQ((ch), W_HOLD)) )

#define PC_MOUNTING(ch)   (GET_POS((ch)) == POS_MOUNTED)

#define TRIGS(ch)	        ((ch)->npc_specials.trigs)
#define TRIG_WAITING(ch) 	((ch)->npc_specials.trig_waiting)
#define TRIG_IGNORE(ch) 	((ch)->npc_specials.trig_ignore)

#define SHOPKEEP_OPEN(ch) (IS_SET(CHAR_FLAGS(ch), CH_SHOP_OPEN))

#define IS_MOUNTED(ch)	(IS_SET(CHAR_FLAGS(ch), CH_MOUNTED))

#define GET_SIZE(ch)   ((ch)->npc_specials.mob_size)

#define IS_AFK(ch) (PLR_FLAGGED(ch, PLR_AFK))

#define IS_NAT_MAGE(ch)			(GET_CLASS(ch) == CLASS_MAGE)
#define IS_NAT_CLERIC(ch)		(GET_CLASS(ch) == CLASS_CLERIC)
#define IS_NAT_THIEF(ch)		(GET_CLASS(ch) == CLASS_THIEF)
#define IS_NAT_WARRIOR(ch)		(GET_CLASS(ch) == CLASS_WARRIOR)
#define IS_NAT_RANGER(ch)		(GET_CLASS(ch) == CLASS_RANGER)
#define IS_NAT_SHAMAN(ch)		(GET_CLASS(ch) == CLASS_SHAMAN)
#define IS_NAT_MONK(ch)			(GET_CLASS(ch) == CLASS_MONK)
#define IS_NAT_WARLOCK(ch)		(GET_CLASS(ch) == CLASS_WARLOCK)
#define IS_NAT_BARD(ch)			(GET_CLASS(ch) == CLASS_BARD)
#define IS_NAT_MADEPT(ch)		(GET_CLASS(ch) == CLASS_MADEPT)
#define IS_NAT_DRUID(ch)		(GET_CLASS(ch) == CLASS_DRUID)

// NEW stuff for class, could be multiple classed (remort or whataver)
// has a natural class byte, and a bitvector multi class plr2
// begins with it
#define WAS_CLASS(ch, field)  (PLR2_FLAGGED(ch, (1 << (field - 1))))

#define IS_MAGE(ch)	        (IS_PC(ch) && (IS_IMMORTAL(ch) || \
				 GET_CLASS(ch) == CLASS_MAGE ||\
				 PLR2_FLAGGED(ch, PLR2_MAGE)))

#define IS_CLERIC(ch)		(IS_PC(ch) && (IS_IMMORTAL(ch) || \
				 GET_CLASS(ch) == CLASS_CLERIC ||\
				 PLR2_FLAGGED(ch, PLR2_CLERIC)))

#define IS_THIEF(ch)		(IS_PC(ch) && (IS_IMMORTAL(ch) || \
				 GET_CLASS(ch) == CLASS_THIEF ||\
				 PLR2_FLAGGED(ch, PLR2_THIEF)))

#define IS_WARRIOR(ch)          (IS_PC(ch) && (IS_IMMORTAL(ch) || \
				 GET_CLASS(ch) == CLASS_WARRIOR ||\
				 PLR2_FLAGGED(ch, PLR2_WARRIOR)))

#define IS_BARD(ch)		(IS_PC(ch) && (IS_IMMORTAL(ch) || \
				 GET_CLASS(ch) == CLASS_BARD ||\
				 PLR2_FLAGGED(ch, PLR2_BARD)))

#define IS_RANGER(ch)		(IS_PC(ch) && (IS_IMMORTAL(ch) || \
				 GET_CLASS(ch) == CLASS_RANGER ||\
				 PLR2_FLAGGED(ch, PLR2_RANGER)))

#define IS_WARLOCK(ch)		(IS_PC(ch) && (IS_IMMORTAL(ch) || \
				 GET_CLASS(ch) == CLASS_WARLOCK ||\
				 PLR2_FLAGGED(ch, PLR2_WARLOCK)))

#define IS_MONK(ch)		(IS_PC(ch) && (IS_IMMORTAL(ch) || \
				 GET_CLASS(ch) == CLASS_MONK ||\
				 PLR2_FLAGGED(ch, PLR2_MONK)))

#define IS_SHAMAN(ch)		(IS_PC(ch) && (IS_IMMORTAL(ch) || \
				 GET_CLASS(ch) == CLASS_SHAMAN ||\
				 PLR2_FLAGGED(ch, PLR2_SHAMAN)))

#define IS_MADEPT(ch)		(IS_PC(ch) && (IS_IMMORTAL(ch) || \
				 GET_CLASS(ch) == CLASS_MADEPT ||\
				 PLR2_FLAGGED(ch, PLR2_MADEPT)))

#define IS_DRUID(ch)		(IS_PC(ch) && (IS_IMMORTAL(ch) || \
				 GET_CLASS(ch) == CLASS_DRUID ||\
				 PLR2_FLAGGED(ch, PLR2_DRUID)))

#define IS_HUMAN(ch)	        (IS_PC(ch) && (GET_RACE(ch) == RACE_HUMAN))
#define IS_ELF(ch)	        (IS_PC(ch) && (GET_RACE(ch) == RACE_ELF))
#define IS_HALF_ELF(ch)	        (IS_PC(ch) && (GET_RACE(ch) == RACE_HALF_ELF))
#define IS_ORC(ch)	        (IS_PC(ch) && (GET_RACE(ch) == RACE_ORC))
#define IS_OGRE(ch)	        (IS_PC(ch) && (GET_RACE(ch) == RACE_OGRE))
#define IS_DROW(ch)	        (IS_PC(ch) && (GET_RACE(ch) == RACE_DROW))
#define IS_DWARF(ch)	        (IS_PC(ch) && (GET_RACE(ch) == RACE_DWARF))
#define IS_PIXIE(ch)	        (IS_PC(ch) && (GET_RACE(ch) == RACE_PIXIE))
#define IS_NIXIE(ch)	        (IS_PC(ch) && (GET_RACE(ch) == RACE_NIXIE))
#define IS_DRAGON(ch)	        (IS_PC(ch) && (GET_RACE(ch) == RACE_DRAGON))

#define SPEAKING(ch)		((ch)->specials.speaking)

#define SINGING(ch)		((ch)->pc_specials->singing)
#define SONG_TIME(ch)		((ch)->pc_specials->song_time)

#define PLAYING(ch)		((ch)->pc_specials->playing)
#define PLAY_TIME(ch)		((ch)->pc_specials->play_time)

#define PLSHOPS(ch)		((ch)->pc_specials->plshops)

#define GET_ALIASES(ch)		((ch)->aliases)

#define INCHAT(ch)		(CHAR_FLAGGED((ch), CH_CHAT))

#endif /* ROA_UTILS_H */