/
Archipelago/
Archipelago/doc/
Archipelago/lib/misc/
Archipelago/lib/plrobjs/
Archipelago/lib/plrobjs/P-T/
Archipelago/lib/world/mob/
Archipelago/lib/world/obj/
Archipelago/lib/world/shp/
Archipelago/lib/world/wld/
Archipelago/lib/world/zon/
Archipelago/slave/
/* ************************************************************************
*   File: utils.h                                       Part of CircleMUD *
*  Usage: header file: utility macros and prototypes of utility funcs     *
*                                                                         *
*  All rights reserved.  See license.doc for complete information.        *
*                                                                         *
*  Copyright (C) 1993 by the Trustees of the Johns Hopkins University     *
*  CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991.               *
************************************************************************ */
/* Archipelago changes by Alastair J. Neil Copyright (C) 1993, 94, 95, 96 */

/*Linux does not have a SIGBUS 
#ifdef LINUX
#define SIGBUS SIGUNUSED
#endif
*/

extern struct weather_data weather_info;

/* public functions */
char	*str_dup(const char *source);
int	str_cmp(char *arg1, char *arg2);
int	strn_cmp(char *arg1, char *arg2, int n);
void	logg(char *str);
void	mudlog(char *str, char type, ubyte level, byte file);
void	log_death_trap(struct char_data *ch);
int	MAX(int a, int b);
int	MIN(int a, int b);
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 assertmsg(char *file, unsigned int line, char *messg);

/* in magic.c */
bool	circle_follow(struct char_data *ch, struct char_data * victim);

/* defines for fseek */
#ifndef SEEK_SET
#define SEEK_SET	0
#define SEEK_CUR	1
#define SEEK_END	2
#endif
/*my ASSERT macro */
#ifdef DEBUG
#define ASSERT(f, message) ((f) ? NULL: assertmsg(__FILE__,__LINE__,message))
#else
#define ASSERT(f, message)  NULL
#endif
/* defines for mudlog() */
    
#define OFF	0
#define BRF	1
#define NRM	2

#define CMP	3

#define TRUE  1

#define FALSE 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) )

/* Functions in utility.c                     */
/* #define MAX(a,b) (((a) > (b)) ? (a) : (b)) */
/* #define MIN(a,b) (((a) < (b)) ? (a) : (b)) */

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

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

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

#define CREATE(result, type, number)  do {\
	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 IS_NPC(ch)  ((ch) && IS_SET((ch)->specials2.act, MOB_ISNPC))
#define CAN_SPEAK(ch) ( !IS_MOB((ch)) || GET_INT((ch)) > 10 || \
			IS_SET((ch)->specials2.act, MOB_CAN_SPEAK))
#define IS_MOB(ch)  (IS_NPC((ch)) && ((ch)->nr >-1))
#define HASROOM(obj) ((GET_ITEM_TYPE((obj)) == ITEM_CONTAINER) && \
		       ((obj)->obj_flags.value[3] > 0)) && \
                       (real_room((obj)->obj_flags.value[3]) != -1)
#define MOB_FLAGS(ch) ((ch)->specials2.act)
#define PLR_FLAGS(ch) ((ch)->specials2.act)
#define PRF_FLAGS(ch) ((ch)->specials2.pref)

#define MOB_FLAGGED(ch, flag) (IS_NPC((ch)) && IS_SET(MOB_FLAGS((ch)), (flag)))
#define PLR_FLAGGED(ch, flag) (!IS_NPC((ch)) && IS_SET(PLR_FLAGS((ch)), (flag)))
#define PRF_FLAGGED(ch, flag) (IS_SET(PRF_FLAGS((ch)), (flag)))

#define PLR_TOG_CHK(ch,flag) ((TOGGLE_BIT(PLR_FLAGS(ch), (flag))) & (flag))
#define PRF_TOG_CHK(ch,flag) ((TOGGLE_BIT(PRF_FLAGS(ch), (flag))) & (flag))
#define IS_GODITEM(item) (IS_SET((item)->obj_flags.extra_flags, ITEM_GODONLY))
#define IS_CART(item) (IS_SET((item)->obj_flags.extra_flags, ITEM_PULLABLE))   
#define IS_TWOHANDED(ch,weapon) ((IS_SET((weapon)->obj_flags.extra_flags,ITEM_2HANDED)\
				  && !(GET_SIZE(ch) < GET_OBJ_SIZE(weapon)-1)\
				 || ((GET_SIZE(ch) > GET_OBJ_SIZE(weapon)+1))\
				     && !IS_SET((weapon)->obj_flags.extra_flags,ITEM_2HANDED)))
    
#define SWITCH(a,b) { (a) ^= (b); \
                      (b) ^= (a); \
                      (a) ^= (b); }

#define IS_ANIMAL(ch) (IS_NPC(ch) && ((GET_RACE(ch) == CLASS_ANIMAL || \
				       !CAN_SPEAK(ch))))
#define IS_UNDEAD(ch) (IS_NPC(ch) && ((GET_RACE(ch) == CLASS_UNDEAD)))
				       
#define IS_AFFECTED(ch,skill) ( IS_SET((ch)->specials.affected_by, (skill)) )

#define IS_DARK(room)  ( !world[(room)].light && \
                         (IS_SET(world[(room)].room_flags, DARK) || \
                          ( ( world[(room)].sector_type != SECT_INSIDE && \
                              world[(room)].sector_type != SECT_CITY ) && \
                            (weather_info.sunlight == SUN_SET || \
			     weather_info.sunlight == SUN_DARK)) ) )

#define IS_LIGHT(room)  (!IS_DARK(room))
#define GET_MOOD(ch) ((ch)->specials.mood)
#define GET_INVIS_LEV(ch) ((ch)->specials2.invis_level)
#define IS_LIMITED(obj)  ((obj)->obj_flags.value[6] >0 ? 1: 0)

/* Can subject see character "obj"? */

#define CAN_SEE(sub, obj) ( ((sub) == (obj)) || ( \
      ( (GET_LEVEL(sub) >= GET_INVIS_LEV(obj)) && \
      ( (PRF_FLAGGED((sub), PRF_HOLYLIGHT)) ||    \
           ((!IS_AFFECTED((sub), AFF_BLIND)) &&   \
           (can_see_char((sub), (obj))))))))

#define WIMP_LEVEL(ch) ((ch)->specials2.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 SIZE(i) (((i)==0) ?"Normal":(((i)==1) ? "Huge":(((i)==2)  ? "Large" :\
(((i)==3) ? "Normal":(((i)==4) ? "Small":(((i)==5) ? "Very Small": \
       (((i)==6) ? "Tiny" :  "Error" )))))))
#define GET_SIZE(ch) (GET_HEIGHT(ch) < 100 ? 6 :(GET_HEIGHT(ch) < 135 ? 5\
    :(GET_HEIGHT(ch) < 170 ? 4 :(GET_HEIGHT(ch) < 190 ? 3\
				 :(GET_HEIGHT(ch) < 220 ? 2: 1)))))
#define  GET_OBJ_SIZE(obj) ((obj)->obj_flags.value[5] == 0 ? 3 :\
                                                (obj)->obj_flags.value[5])
    
#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)->specials2.conditions[(i)])

#define GET_LOADROOM(ch) ((ch)->specials2.load_room)

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

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


#define GET_LEVEL(ch)   ((ch)->player.level)
#define GET_SUB_LEVEL(ch)   ((ch)->points.sub_level)
#define GET_SPELL_LEVEL(ch,sn) (spell_info[(sn)].min_level*(calc_difficulty((ch),(sn))+1))    

#define GET_CLASS(ch)   ((ch)->player.race)
#define GET_RACE(ch)   ((ch)->player.race)

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

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

#define GET_STR(ch)     ((ch)->tmpabilities.str)
#define GET_RAW_STR(ch)     ((ch)->abilities.str)

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

#define GET_DEX(ch)     ((ch)->tmpabilities.dex)
#define GET_RAW_DEX(ch)     ((ch)->abilities.dex)

#define GET_INT(ch)     ((ch)->tmpabilities.intel)
#define GET_RAW_INT(ch)     ((ch)->abilities.intel)

#define GET_WIS(ch)     ((ch)->tmpabilities.wis)
#define GET_RAW_WIS(ch)     ((ch)->abilities.wis)

#define GET_CON(ch)     ((ch)->tmpabilities.con)
#define GET_RAW_CON(ch)     ((ch)->abilities.con)

#define GET_CHR(ch)     ((ch)->tmpabilities.chr)
#define GET_RAW_CHR(ch)     ((ch)->abilities.chr)

#define GET_PER(ch)     ((ch)->tmpabilities.per)
#define GET_RAW_PER(ch)     ((ch)->abilities.per)

#define GET_GUI(ch)     ((ch)->tmpabilities.gui)
#define GET_RAW_GUI(ch)     ((ch)->abilities.gui)

#define GET_FOC(ch)     ((ch)->tmpabilities.foc)
#define GET_RAW_FOC(ch)     ((ch)->abilities.foc)

#define GET_DEV(ch)     ((ch)->tmpabilities.dev)
#define GET_RAW_DEV(ch)     ((ch)->abilities.dev)    

#define GET_LUC(ch)     ((ch)->tmpabilities.luc)
#define GET_RAW_LUC(ch)     ((ch)->abilities.luc)

#define STRENGTH_APPLY_INDEX(ch) ((ch)->tmpabilities.str)

#define GET_AC(ch)      ((ch)->points.armor[0])
#define GET_BODY_AC(ch)      ((ch)->points.armor[0])
#define GET_LEGS_AC(ch)      ((ch)->points.armor[1])
#define GET_ARMS_AC(ch)      ((ch)->points.armor[2])
#define GET_HEAD_AC(ch)      ((ch)->points.armor[3])
#define GET_BODY_STOPPING(ch)      ((ch)->points.stopping[0])
#define GET_LEGS_STOPPING(ch)      ((ch)->points.stopping[1])
#define GET_ARMS_STOPPING(ch)      ((ch)->points.stopping[2])
#define GET_HEAD_STOPPING(ch)      ((ch)->points.stopping[3])



/* The hit_limit, move_limit, and mana_limit functions are gone.  See
   limits.c for details.
*/

#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 GET_HITROLL2(ch) ((ch)->specials.hitroll)
#define GET_DAMROLL2(ch) ((ch)->specials.damroll)

#define SPELLS_TO_LEARN(ch) ((ch)->specials2.spells_to_learn)

#define GET_IDNUM(ch) (IS_NPC(ch) ? -1 : (ch)->specials2.idnum)
#define GET_LAST_TELL(ch) (IS_NPC(ch) ? -1 : (ch)->specials2.last_tell_id)
#define AWAKE(ch) (GET_POS(ch) > POSITION_SLEEPING)

#define GET_SKILL(ch, i) ((ch)->skills ? (((ch)->skills)[i]) : 24)

#define SET_SKILL(ch, i, pct) { if ((ch)->skills) (ch)->skills[i] = pct; }

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


/* Object And Carry related macros */

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


#define GET_ITEM_TYPE(obj) ((obj)->obj_flags.type_flag)

#define CAN_WEAR(obj, part) (IS_SET((obj)->obj_flags.wear_flags,part))

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

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

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

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

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

#define IS_PULLING(ch) (((ch)->specials.cart) ? (ch)->specials.cart : 0)    
#define IS_RIDING(ch) (((ch)->specials.mount) ? (ch)->specials.mount: 0)
    
#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_OBJ_STAT(obj,stat) (IS_SET((obj)->obj_flags.extra_flags,stat))



/* char name/short_desc(for mobs) or someone?  */

#define PERS(ch, vict)   (CAN_SEE(vict, ch) ? GET_NAME(ch) : ((GET_INT(ch) > 10) ? ((GET_LEVEL(ch) >= LEVEL_BUILDER) ? "someone" : "somebody") : "something"))

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

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

#define OUTSIDE(ch) (!IS_SET(world[(ch)->in_room].room_flags,INDOORS))

#define EXIT(ch, door)  (world[(ch)->in_room].dir_option[door])

#define CAN_GO(ch, door) (EXIT(ch,door)  &&  (EXIT(ch,door)->to_room != NOWHERE) \
                          && !IS_SET(EXIT(ch, door)->exit_info, EX_CLOSED))

#define TO_RM(ch, cmd) (real_room(EXIT(ch,cmd)->to_room))
	
#define IS_CLIMB(ch,cmd) ((cmd == 4 || cmd == 5) &&  \
	(CAN_GO(ch,cmd)) &&  \
	(CLIMB_ROOM(TO_RM(ch,cmd)) || CLIMB_ROOM((ch)->in_room)))
    
#define CLIMB_ROOM(room) (IS_SET(world[room].room_flags,CLIMB_EASY) || \
	IS_SET(world[room].room_flags,CLIMB_MODERATE) || \
	IS_SET(world[room].room_flags,CLIMB_HARD) || \
	IS_SET(world[room].room_flags,CLIMB_SEVERE) || \
	IS_SET(world[room].room_flags,CLIMB_EXTREME))
    
#define GET_ALIGNMENT(ch) ((ch)->specials2.alignment)
#define GET_FAME(ch) ((ch)->specials2.fame)

#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) ? "--" : race_abbrevs[(int)GET_RACE(ch)])
#define RACE_ABBR(ch) (IS_NPC(ch) ? "--" : race_abbrevs[(int)GET_RACE(ch)])