ackfuss-4.3.2/area/boards/
ackfuss-4.3.2/npcs/a/
ackfuss-4.3.2/npcs/b/
ackfuss-4.3.2/npcs/c/
ackfuss-4.3.2/npcs/d/
ackfuss-4.3.2/npcs/e/
ackfuss-4.3.2/npcs/f/
ackfuss-4.3.2/npcs/h/
ackfuss-4.3.2/npcs/i/
ackfuss-4.3.2/npcs/k/
ackfuss-4.3.2/npcs/l/
ackfuss-4.3.2/npcs/n/
ackfuss-4.3.2/npcs/o/
ackfuss-4.3.2/npcs/p/
ackfuss-4.3.2/npcs/r/
ackfuss-4.3.2/npcs/s/
ackfuss-4.3.2/npcs/w/
ackfuss-4.3.2/player/c/
ackfuss-4.3.2/reports/
/***************************************************************************
 *  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
 *  Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.   *
 *                                                                         *
 *  Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael          *
 *  Chastain, Michael Quan, and Mitchell Tse.                              *
 *                                                                         *
 *  Ack 2.2 improvements copyright (C) 1994 by Stephen Dooley              *
 *                                                                         *
 *  In order to use any part of this Merc Diku Mud, you must comply with   *
 *  both the original Diku license in 'license.doc' as well the Merc       *
 *  license in 'license.txt'.  In particular, you may not remove either of *
 *  these copyright notices.                                               *
 *                                                                         *
 *       _/          _/_/_/     _/    _/     _/    ACK! MUD is modified    *
 *      _/_/        _/          _/  _/       _/    Merc2.0/2.1/2.2 code    *
 *     _/  _/      _/           _/_/         _/    (c)Stephen Zepp 1998    *
 *    _/_/_/_/      _/          _/  _/             Version #: 4.3          *
 *   _/      _/      _/_/_/     _/    _/     _/                            *
 *                                                                         *
 *                                                                         *
 *  Much time and thought has gone into this software and you are          *
 *  benefitting.  We hope that you share your changes too.  What goes      *
 *  around, comes around.                                                  *
 ***************************************************************************/

#define DEC_UTILS_H 1

#ifndef DEC_TYPEDEFS_H
#include "typedefs.h"
#endif

#ifndef DEC_CONFIG_H
#include "config.h"
#endif

#if 0
#ifndef DEC_ACK_H
#include "ack.h"
#endif

#endif
/* Use these for bitvectors..saves having to recalculate each time :) Zen */

#define		BIT_0		0
#define		BIT_1		1
#define		BIT_2		2
#define		BIT_3		4
#define		BIT_4		8
#define		BIT_5		16
#define		BIT_6		32
#define		BIT_7		64
#define		BIT_8		128
#define		BIT_9		256
#define		BIT_10		512
#define		BIT_11		1024
#define		BIT_12		2048
#define		BIT_13		4096
#define		BIT_14		8192
#define		BIT_15		16384
#define		BIT_16		32768
#define		BIT_17		65536
#define		BIT_18		131072
#define		BIT_19		262144
#define		BIT_20		524288
#define		BIT_21		1048576
#define		BIT_22		2097152
#define		BIT_23		4194304
#define		BIT_24		8388608
#define		BIT_25		16777216
#define		BIT_26		33554432
#define		BIT_27		67108864
#define		BIT_28		134217728
#define		BIT_29		268435456
#define		BIT_30		536870912
#define		BIT_31		1073741824
#define		BIT_32		2147483648




/*
 *  SSM stuff
 */

#define STR(x) #x
#define SX(x) STR(x)
#define _caller __FILE__ ":" SX(__LINE__)

#define fread_string(x) _fread_string((x), _caller)
char *_fread_string args( ( FILE * fp, const char *caller ) );
#define str_dup(x) _str_dup((x), _caller)
char *_str_dup args( ( const char *str, const char *caller ) );
#define fread_string_eol(x) _fread_string_eol((x), _caller)
char *_fread_string_eol args( ( FILE * fp, const char *caller ) );
#define free_string(x) _free_string((x), _caller)
void _free_string args( ( char *pstr, const char *caller ) );

/*
 * Updated pointer referencing, curtesy of Spectrum, from Beyond the Veil
 *
 */

#define OBJ_NEXT          1
#define OBJ_NEXTCONTENT   2
#define OBJ_NULL          3

struct obj_ref_type
{
   bool inuse;
   struct obj_ref_type *next;
   OBJ_DATA **var;
   int type;   /* OBJ_xxxx */
};

#define CHAR_NEXT         1
#define CHAR_NEXTROOM     2
#define CHAR_NULL         3

struct char_ref_type
{
   bool inuse;
   struct char_ref_type *next;
   CHAR_DATA **var;
   int type;
};

#define OREF(v, type) do { \
static struct obj_ref_type s={FALSE,NULL,NULL,type}; s.var=&v; \
obj_reference(&s); } while(0)
#define OUREF(var) obj_unreference(&var);

#define CREF(v, type) do { \
static struct char_ref_type s={FALSE,NULL,NULL,type}; s.var=&v; \
char_reference(&s); } while(0)
#define CUREF(var) char_unreference(&var);




/*
 * Utility macros.
 */
#define UMIN(a, b)              ((a) < (b) ? (a) : (b))
#define UMAX(a, b)              ((a) > (b) ? (a) : (b))
#define URANGE(a, b, c)         ((b) < (a) ? (a) : ((b) > (c) ? (c) : (b)))
#define LOWER(c)                ((c) >= 'A' && (c) <= 'Z' ? (c)+'a'-'A' : (c))
#define UPPER(c)                ((c) >= 'a' && (c) <= 'z' ? (c)+'A'-'a' : (c))
#define IS_SET(flag, bit)       ((flag) & (bit))
#define SET_BIT(var, bit)       ((var) |= (bit))
#define REMOVE_BIT(var, bit)    ((var) &= ~(bit))
#define IS_LETTER(c)            ( ((c) >= 'A' && (c) <= 'Z' ) \
                                ||((c) >= 'a' && (c) <= 'z' ) )


/*
 * Character macros.
 */
#define IS_VAMP(ch) (IS_NPC(ch) ? IS_SET(ch->act, ACT_VAMPIRE) : IS_SET(ch->pcdata->pflags,PFLAG_VAMP) )
#define IS_UNDEAD(ch) (IS_NPC(ch) ? IS_SET(ch->act, ACT_UNDEAD ) : FALSE )
#define IS_NPC(ch)              (IS_SET((ch)->act, ACT_IS_NPC))
#define IS_IMMORTAL(ch)         (get_trust(ch) >= LEVEL_IMMORTAL)
#define IS_HERO(ch)             (get_trust(ch) >= LEVEL_HERO)
#define IS_AFFECTED(ch, sn)     (IS_SET((ch)->affected_by, (sn)))
/* #define IS_WERE(ch) (IS_NPC(ch) ? IS_SET(ch->act, ACT_WEREWOLF) : IS_SET(ch->pcdata->pflags,PFLAG_WEREWOLF) )
*/
#define IS_GOOD(ch)             (ch->alignment >= 350)
#define IS_EVIL(ch)             (ch->alignment <= -350)
#define IS_NEUTRAL(ch)          (!IS_GOOD(ch) && !IS_EVIL(ch))

#define IS_AWAKE(ch)            (ch->position > POS_SLEEPING)

#define GET_AC(ch)              ( IS_NPC(ch) ? (REAL_AC( ch ) + ch->ac_mod) : REAL_AC( ch ) + ch->stance_ac_mod )

#define REAL_AC(ch)             ((ch)->armor  + ( IS_AWAKE(ch) \
                                                ? ( IS_NPC( ch ) \
                                                ? ( dex_app[get_curr_dex(ch)].defensive * get_psuedo_level( ch )/20 ) \
                                                : ( dex_app[get_curr_dex(ch)].defensive * get_psuedo_level( ch )/10 ) ): 0 ))
#define IS_WOLF(ch) (IS_NPC(ch) ? FALSE : IS_SET(ch->pcdata->pflags, PFLAG_WEREWOLF) )
#define IS_SHIFTED(ch) (IS_NPC(ch) ? FALSE : IS_SET( ch->pcdata->pflags, PFLAG_SHIFTED ) ? TRUE : FALSE )
#define IS_RAGED(ch) (IS_NPC(ch) ? FALSE : IS_SET( ch->pcdata->pflags, PFLAG_RAGED ) ? TRUE : FALSE )

/* Added bonus to hit and dam for higher levl players */
/* High level naked players should still be able to fight ok */

#define GET_HITROLL(ch)         ( IS_NPC(ch) ? (REAL_HITROLL(ch) + ch->hr_mod + (get_psuedo_level( ch ) / 4 )) : REAL_HITROLL(ch)+(ch->level/8) + ch->stance_hr_mod )

#define REAL_HITROLL(ch)        ((ch)->hitroll+ (str_app[get_curr_str(ch)].tohit * get_psuedo_level( ch )/10) )

#define GET_DAMROLL(ch)         ( IS_NPC(ch) ? (REAL_DAMROLL(ch) + ch->dr_mod + (ch->level / 3 ))  : REAL_DAMROLL(ch)+(ch->level/10) + ch->stance_dr_mod )

#define REAL_DAMROLL(ch)        ((ch)->damroll+( str_app[get_curr_str(ch)].todam * get_psuedo_level( ch ) /10 ) )

#define IS_OUTSIDE(ch)          (!IS_SET( (ch)->in_room->room_flags, ROOM_INDOORS))

#define WAIT_STATE(ch, npulse)  ((ch)->wait = UMAX((ch)->wait, (npulse)))

#define MANA_COST(ch, sn)       (IS_NPC(ch) ? 0 : UMAX ( skill_table[sn].min_mana, 100 / (2 + ch->level - skill_table[sn].skill_level[ch->class] ) ) )

#define IS_RIDING(ch)           (!IS_NPC(ch) && ((ch)->riding))

#define ADEPT_LEVEL(ch)         (IS_NPC(ch) ? (ch)->level/7 : (ch)->adept_level )

#define MAGIC_STANCE(ch)        ( IS_NPC(ch) ? FALSE : \
                                   ( (ch)->stance == STANCE_CASTER ) \
                                || ( (ch)->stance == STANCE_WIZARD ) \
                                || ( (ch)->stance == STANCE_MAGI ) )

#define PLAYTESTER(ch)          ( !IS_NPC(ch) && IS_SET((ch)->pcdata->pflags, PFLAG_TESTER )  )
#define HAS_BODY(ch)            ( !IS_NPC(ch) || !IS_SET((ch)->act, ACT_NO_BODY ) )
#define HAS_MIND(ch)            ( !IS_NPC(ch) || !IS_SET((ch)->act, ACT_NOMIND ) )
#define IS_WEAPON(eq)           ( (eq) != NULL ? (eq)->item_type == ITEM_WEAPON : FALSE )
#define IS_SHIELD(eq)           ( (eq) != NULL ? (eq)->item_type == ITEM_ARMOR : FALSE )

/*
 * Object macros.
 */
#define CAN_WEAR(obj, part)     (IS_SET((obj)->wear_flags,  (part)))
#define IS_OBJ_STAT(obj, stat)  (IS_SET((obj)->extra_flags, (stat)))



/*
 * Description macros.
 */
#define PERS(ch, looker) ( can_see( looker, (ch) ) ? ( IS_NPC(ch) ? (ch)->short_descr : (IS_WOLF(ch) && (IS_SHIFTED(ch) || IS_RAGED(ch))) ? "A Large @@bWolf@@N" :(ch)->name ) : IS_IMMORTAL( ch ) ? "A Mystical Being" : "Someone" )
#define NAME(ch)		( IS_NPC(ch) ? (ch)->short_descr : (ch)->name )


/* Added stuff - Flar */
#define CH(descriptor)  ((descriptor)->original ? \
(descriptor)->original : (descriptor)->character)

/*
 * Linked list macros, -- Altrag
 */
/* Regular linking of double-linked list */
#define LINK(link, first, last, next, prev) \
do { \
  if ( (link)->is_free == TRUE ) hang("LINK: link is FREE!"); \
  if ( (link)->is_free != FALSE ) hang("LINK: link is corrupted!"); \
  if ( (link)->prev || (link)->next ) hang("LINK: link already in list?"); \
  if ( (last) && (last)->next ) hang("LINK: last->next NON-NULL!"); \
  if ( !(first) ) \
    (first) = (link); \
  else \
    (last)->next = (link); \
  (link)->next = NULL; \
  (link)->prev = (last); \
  (last) = (link); \
} while(0)

/* Link at the head of the list rather than the tail.  Double linked */
#define TOPLINK(link, first, last, next, prev) \
do { \
  if ( (link)->is_free == TRUE ) hang("TOPLINK: link is FREE!"); \
  if ( (link)->is_free != FALSE ) hang("TOPLINK: link is corrupted!"); \
  if ( (link)->prev || (link)->next ) hang("TOPLINK: link already in list?"); \
  if ( (first) && (first)->prev ) hang("TOPLINK: first->prev NON-NULL!"); \
  if ( !(last) ) \
    (last) = (link); \
  else \
    (first)->prev = (link); \
  (link)->prev = NULL; \
  (link)->next = (first); \
  (first) = (link); \
} while(0)

/* Insert link before ref link */
#define LINK_BEFORE(link, ref, first, last, next, prev) \
do { \
  if ( (link)->is_free == TRUE ) hang("LINK_BEFORE: link is FREE!"); \
  if ( (link)->is_free != FALSE ) hang("LINK_BEFORE: link is corrupted!"); \
  if ( (link)->prev || (link)->next ) hang("LINK_BEFORE: link already in list?"); \
  if ( !(ref) ) hang("LINK_BEFORE: ref is NULL!"); \
  if ( (ref)->is_free == TRUE ) hang("LINK_BEFORE: ref is FREE!"); \
  if ( (ref)->is_free != FALSE ) hang("LINK_BEFORE: ref is corrupted!"); \
  (link)->next = (ref); \
  (link)->prev = (ref)->prev; \
  if ( !(ref)->prev ) \
    (first) = (link); \
  else \
    ((ref)->prev)->next = (link); \
  (ref)->prev = (link); \
} while (0)

/* Insert link after ref link */
#define LINK_AFTER(link, ref, first, last, next, prev) \
do { \
  if ( (link)->is_free == TRUE ) hang("LINK_AFTER: link is FREE!"); \
  if ( (link)->is_free != FALSE ) hang("LINK_AFTER: link is corrupted!"); \
  if ( (link)->prev || (link)->next ) hang("LINK_AFTER: link already in list?"); \
  if ( !(ref) ) hang("LINK_AFTER: ref is NULL!"); \
  if ( (ref)->is_free == TRUE ) hang("LINK_AFTER: ref is FREE!"); \
  if ( (ref)->is_free != FALSE ) hang("LINK_AFTER: ref is corrupted!"); \
  (link)->prev = (ref); \
  (link)->next = (ref)->next; \
  if ( !(ref)->next ) \
    (last) = (link); \
  else \
    ((ref)->next)->prev = (link); \
  (ref)->next = (link); \
} while (0)

/* Unlink a double linked list */
#define UNLINK(link, first, last, next, prev) \
do { \
  if ( (link)->is_free == TRUE ) hang("UNLINK: link is FREE!"); \
  if ( (link)->is_free != FALSE ) hang("UNLINK: link is corrupted!"); \
  if ( (link)->prev && (((link)->prev)->next != (link)) ) \
    hang("UNLINK: link->prev->next corrupted!"); \
  if ( (link)->next && (((link)->next)->prev != (link)) ) \
    hang("UNLINK: link->next->prev corrupted!"); \
  if ( !(link)->next ) \
    (last) = (link)->prev; \
  else \
    (link)->next->prev = (link)->prev; \
  if ( !(link)->prev ) \
    (first) = (link)->next; \
  else \
    (link)->prev->next = (link)->next; \
  (link)->prev = NULL; \
  (link)->next = NULL; \
} while(0)

/* Link to the end of a single-linked list */
#define SING_LINK(link, first, next, DATA_TYPE) \
do { \
  if ( !(first) ) \
    (first) = (link); \
  else \
  { \
    DATA_TYPE *last; \
    for ( last = (first); last->next; last = last->next ) \
      ; \
    last->next = (link); \
  } \
  (link)->next = NULL; \
} while(0)

/* Link to head of a single-linked list (normal linking) */
#define SING_TOPLINK(link, first, next) \
do { \
  (link)->next = (first); \
  (first) = (link); \
} while(0)

/* Unlink a single linked list */
#define SING_UNLINK(link, first, next, DATA_TYPE) \
do { \
  if ( (link) == (first) ) \
    (first) = (link)->next; \
  else \
  { \
    DATA_TYPE *prev; \
    for ( prev = (first); prev; prev = prev->next ) \
      if ( prev->next == (link) ) \
        break; \
    if ( prev != NULL ) \
      prev->next = (link)->next; \
    else \
      bug("Sing_unlink: link not in list.", 0); \
  } \
} while(0)

/* Link to end of a half-linked list */
/* Half linked lists have a LAST pointer, but not a PREV pointer, making
   them approximately halfway between a single linked list and a double
   linked list. -- Altrag */
#define HALF_LINK(link, first, last, next) \
do { \
  if ( !(last) ) \
    (first) = (link); \
  else \
    (last)->next = (link); \
  (link)->next = NULL; \
  (last) = (link); \
} while(0)

/* Link to head of a half-linked list. */
#define HALF_TOPLINK(link, first, last, next) \
do { \
  if ( (last) == (first) ) \
    (last) = (link); \
  (link)->next = (first); \
  (first) = (link); \
} while(0)

/* Unlink a half-linked list. */
#define HALF_UNLINK(link, first, last, next, DATA_TYPE) \
do { \
  if ( (link) == (first) ) \
  { \
    (first) = (link)->next; \
    if ( (link) == (last) ) \
      (last) = NULL; \
  } \
  else \
  { \
    DATA_TYPE *prev; \
    for ( prev = (first); prev; prev = prev->next ) \
      if ( prev->next == (link) ) \
        break; \
    if ( prev != NULL ) \
    { \
      prev->next = (link)->next; \
      if ( (link) == (last) ) \
        (last) = prev; \
    } \
    else \
      bug("Half_unlink: link not in list.", 0); \
  } \
} while(0)

/*
 * Miscellaneous macros.
 */

/* spec: macro-ised getmem as a wrapper around _getmem for mem_log handling */
#define getmem(size) _getmem(size,_caller,1)
#define qgetmem(size) _getmem(size,_caller,0)

/* This one goes as a #define in merc.h.. dont worry.. itll work.. :) */
/* spec: log all dispose's if mem_log==TRUE - also nuke trailing ; */
/* spec: add dispose override, too */
#define _dispose(mem,size,log) \
do { \
  if ( ! (mem) ) \
  { \
    bug("Disposing NULL memory",0); \
    return; \
  } \
  if (log&&mem_log) log_f("dispose(%p) from %s:%d", (mem), __FILE__, __LINE__); \
  free((mem)); \
  (mem) = NULL; \
} while(0)

#define dispose(mem,size) _dispose(mem,size,1)
#define qdispose(mem,size) _dispose(mem,size,0)

/*
 * Miscellaneous macros.
 */