/**************************************************************************
* Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, *
* Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. *
* *
* Merc Diku Mud improvements copyright (C) 1992, 1993 by Michael *
* Chastain, Michael Quan, and Mitchell Tse. *
* *
* 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. *
* *
* Much time and thought has gone into this software and you are *
* benefiting. We hope that you share your changes too. What goes *
* around, comes around. *
***************************************************************************
* ROM 2.4 is copyright 1993-1998 Russ Taylor *
* ROM has been brought to you by the ROM consortium *
* Russ Taylor (rtaylor@hypercube.org) *
* Gabrielle Taylor (gtaylor@hypercube.org) *
* Brian Moore (zump@rom.org) *
* By using this code, you have agreed to follow the terms of the *
* ROM license, in the file Rom24/doc/rom.license *
***************************************************************************
* 1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings *
* http://1stmud.dlmud.com/ <r-jenn@shaw.ca> *
***************************************************************************/
#if !defined(MACRO_H)
#define MACRO_H
#define init_cols(ch, cols) \
int column_pos = 0; \
bool done_newline = FALSE; \
int line_length = get_scr_cols(ch); \
int line_pos = 0; \
int column_count = (cols); \
int column_length = line_length / column_count
#define reset_cols \
column_pos = 0; \
done_newline = FALSE; \
line_pos = 0
#define print_cols(pfunc, out, buf) \
do { \
int buf_len = strlen_color(buf); \
line_pos += buf_len; \
if(!done_newline && line_pos >= line_length) { \
pfunc##ln((out), ""); \
done_newline = TRUE; \
column_pos = 0; \
line_pos = buf_len; \
} \
pfunc((out), buf); \
column_pos++; \
if(column_pos >= column_count) { \
pfunc##ln((out), ""); \
done_newline = TRUE; \
column_pos = line_pos = 0; \
} else { \
int col_diff = 0; \
if(column_length > buf_len) { \
col_diff = column_length - buf_len; \
} else if(buf_len > column_length) { \
int diff_count = 0; \
while(buf_len > column_length) \
++diff_count, buf_len -= column_length; \
col_diff = (column_length * diff_count) - buf_len; \
column_pos += diff_count; \
} \
if (line_pos + col_diff < line_length) { \
line_pos += col_diff; \
if(col_diff > 0) \
pfunc##f((out), FORMATF("%%%d.%ds", col_diff, col_diff), " "); \
} \
done_newline = FALSE; \
} \
} while(0)
#define alloc_mem(result, type, number) \
do \
{ \
if (!((result) = (type *) calloc ((number), sizeof(type)))) \
{ \
log_error("malloc failure"); \
logf( "Malloc failure @ %s:%d\n", __FILE__, __LINE__ ); \
abort(); \
} \
} while(0)
#define realloc_mem(result,type,number) \
do \
{ \
if (!((result) = (type *) realloc ((void *)(result), sizeof(type) * (number)))) \
{ \
log_error("realloc failure"); \
logf( "Realloc failure @ %s:%d\n", __FILE__, __LINE__ ); \
abort(); \
} \
} while(0)
#define free_mem(point) \
do \
{ \
if (!(point)) \
bugf("Freeing null pointer %s:%d", __FILE__, __LINE__ ); \
else free((void *)(point)); \
(point) = NULL; \
} while(0)
/*
* Utility macros.
*/
#define IS_VALID(data) ((data) != NULL && (data)->valid)
#define VALIDATE(data) ((data)->valid = TRUE)
#define INVALIDATE(data) ((data)->valid = FALSE)
#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))
/* bit string operation macro. */
#define STR_IS_SET(var, bit) ((((char *)(var))[((bit)/8)]) & ((1<<((bit)%8))))
#define STR_SET_BIT(var, bit) ((((char *)(var))[((bit)/8)]) |= ((1<<((bit)%8))))
#define STR_REMOVE_BIT(var, bit) ((((char *)(var))[((bit)/8)]) &= ~((1<<((bit)%8))))
#define STR_TOGGLE_BIT(var, bit) ((((char *)(var))[((bit)/8)]) ^= ((1<<((bit)%8))))
#define IS_NULLSTR(str) ((str) == NULL || (str)[0] == '\0')
#define ENTRE(min,num,max) ( ((min) < (num)) && ((num) < (max)) )
#define CHECK_POS(a, b, c) { \
(a) = (b); \
if ( (a) < 0 ) \
bug( "CHECK_POS : " c " == < 0"); \
}
#define SET_STAT(ch, pos, val) ((ch)->pcdata->gamestat[pos] = val)
#define GET_STAT(ch, pos) ((ch)->pcdata->gamestat[pos])
#define ADD_STAT(ch, pos, val) ((ch)->pcdata->gamestat[pos] += val)
#define IS_VALID_STANCE(st) ((st) > STANCE_NONE && (st) < STANCE_CURRENT)
#define GET_STANCE(ch, st) ((ch)->stance[(st)])
#define IS_STANCE(ch, sn) (GET_STANCE((ch), STANCE_CURRENT) == (sn))
#define SET_STANCE(ch, pos, st) ((ch)->stance[(pos)] = (st))
#define UNLINK_SINGLE(pdata,pnext,type,list) \
do \
{ \
if (list == pdata) \
{ \
list = pdata->pnext; \
} \
else \
{ \
type *prev; \
for (prev = list; prev != NULL; prev = prev->pnext) \
{ \
if (prev->pnext == pdata) \
{ \
prev->pnext = pdata->pnext; \
break; \
} \
} \
if (prev == NULL) \
{ \
bugf (#pdata " not found in " #list "."); \
} \
} \
} while(0)
#define LINK_SINGLE(pdata,pnext,list) \
do \
{ \
pdata->pnext = list; \
list = pdata; \
} \
while (0)
#define LINK_LAST(pdata,pnext,type,list) \
do \
{ \
type *tmp; \
if((tmp = list) == NULL) \
{ \
pdata->pnext = list; \
list = pdata; \
break; \
} \
for(; tmp; tmp = tmp->pnext) \
{ \
if(!tmp->pnext) \
{ \
tmp->pnext = pdata; \
pdata->pnext = NULL; \
break; \
} \
} \
} \
while (0)
#define LINK(link, first, last, next, prev) \
do \
{ \
if ( !(first) ) \
{ \
(first) = (link); \
(last) = (link); \
} \
else \
(last)->next = (link); \
(link)->next = NULL; \
if (first == link) \
(link)->prev = NULL; \
else \
(link)->prev = (last); \
(last) = (link); \
} while(0)
#define INSERT(link, insert, first, next, prev) \
do \
{ \
(link)->prev = (insert)->prev; \
if ( !(insert)->prev ) \
(first) = (link); \
else \
(insert)->prev->next = (link); \
(insert)->prev = (link); \
(link)->next = (insert); \
} while(0)
#define UNLINK(link, first, last, next, prev) \
do \
{ \
if ( !(link)->prev ) \
{ \
(first) = (link)->next; \
if ((first)) \
(first)->prev = NULL; \
} \
else \
{ \
(link)->prev->next = (link)->next; \
} \
if ( !(link)->next ) \
{ \
(last) = (link)->prev; \
if ((last)) \
(last)->next = NULL; \
} \
else \
{ \
(link)->next->prev = (link)->prev; \
} \
} while(0)
#define CHECK_LINKS(first, last, next, prev, type) \
do { \
type *ptr, *pptr = NULL; \
if ( !(first) && !(last) ) \
break; \
if ( !(first) ) \
{ \
bugf( "CHECK_LINKS: last with NULL first! %s.", \
#first ); \
for ( ptr = (last); ptr->prev; ptr = ptr->prev ); \
(first) = ptr; \
} \
else if ( !(last) ) \
{ \
bugf( "CHECK_LINKS: first with NULL last! %s.", \
#first ); \
for ( ptr = (first); ptr->next; ptr = ptr->next ); \
(last) = ptr; \
} \
if ( (first) ) \
{ \
for ( ptr = (first); ptr; ptr = ptr->next ) \
{ \
if ( ptr->prev != pptr ) \
{ \
bugf( "CHECK_LINKS(%s): %p:->prev != %p. Fixing.", \
#first, ptr, pptr ); \
ptr->prev = pptr; \
} \
if ( ptr->prev && ptr->prev->next != ptr ) \
{ \
bugf( "CHECK_LINKS(%s): %p:->prev->next != %p. Fixing.",\
#first, ptr, ptr ); \
ptr->prev->next = ptr; \
} \
pptr = ptr; \
} \
pptr = NULL; \
} \
if ( (last) ) \
{ \
for ( ptr = (last); ptr; ptr = ptr->prev ) \
{ \
if ( ptr->next != pptr ) \
{ \
bugf( "CHECK_LINKS (%s): %p:->next != %p. Fixing.", \
#first, ptr, pptr ); \
ptr->next = pptr; \
} \
if ( ptr->next && ptr->next->prev != ptr ) \
{ \
bugf( "CHECK_LINKS(%s): %p:->next->prev != %p. Fixing.",\
#first, ptr, ptr ); \
ptr->next->prev = ptr; \
} \
pptr = ptr; \
} \
} \
} while(0)
#define replace_string(astr, bstr) do{ free_string(astr); astr = str_dup(bstr); }while(0)
#define free_string(pstr) _free_string(pstr), pstr = NULL
#define NUL '\0'
#define IS_STRSET(str) (IS_NULLSTR(str) ? "Not set." : (str))
/*
* Character macros.
*/
#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_TRUSTED(ch,level) (get_trust((ch)) >= (level))
#define IS_AFFECTED(ch, sn) (IS_SET((ch)->affected_by, (sn)))
#define GET_AGE(ch) ((int) (17 + ((ch)->played \
+ current_time - (ch)->logon )/72000))
#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,type) ((ch)->armor[type] \
+ ( IS_AWAKE(ch) \
? dex_app[get_curr_stat(ch,STAT_DEX)].defensive : 0 ))
#define GET_HITROLL(ch) \
((ch)->hitroll+str_app[get_curr_stat(ch,STAT_STR)].tohit)
#define GET_DAMROLL(ch) \
((ch)->damroll+str_app[get_curr_stat(ch,STAT_STR)].todam)
#define IS_OUTSIDE(ch) (!IS_SET( \
(ch)->in_room->room_flags, \
ROOM_INDOORS))
#define IS_IN_WAR(ch) (ch->war != NULL \
&& IS_SET((ch)->in_room->room_flags, ROOM_ARENA))
#define WAIT_STATE(ch, npulse) ((ch)->wait = UMAX((ch)->wait, (npulse)))
#define DAZE_STATE(ch, npulse) ((ch)->daze = UMAX((ch)->daze, (npulse)))
#define get_carry_weight(ch) ((ch)->carry_weight + (ch)->silver/10 + \
(ch)->gold * 2 / 5)
#define act(format,ch,arg1,arg2,type)\
act_new((format),(ch),(arg1),(arg2),(type),POS_RESTING)
#define log_wiznet(ch, flag, level, fmt) \
do { log_string(fmt); wiznet(fmt, NULL, NULL, flag, 0, 0); } while(0)
#define wiznet(string, ch, obj, flag, skip, level) \
new_wiznet((ch),(obj),(flag),(skip),(level),(string))
#define HAS_TRIGGER_MOB(ch,trig) (IS_SET((ch)->pIndexData->mprog_flags,(trig)))
#define HAS_TRIGGER_OBJ(obj,trig) (IS_SET((obj)->pIndexData->oprog_flags,(trig)))
#define HAS_TRIGGER_ROOM(room,trig) (IS_SET((room)->rprog_flags,(trig)))
#define IS_SWITCHED( ch ) ( ch->desc && ch->desc->original )
#define IS_BUILDER(ch, Area) ( !IS_NPC(ch) && !IS_SWITCHED( ch ) && \
( ch->pcdata->security >= Area->security \
|| strstr( Area->builders, ch->name ) \
|| strstr( Area->builders, "All" ) ) )
#define DESC_FLAGGED(d, flag) (IS_SET((d)->d_flags, (flag)))
#define CH(descriptor) ((descriptor)->original ? \
(descriptor)->original : (descriptor)->character)
#define IS_REMORT(ch) (!IS_NPC(ch) && ( IS_SET((ch)->act, PLR_REMORT) \
|| number_classes(ch) > 1))
#define ON_GQUEST(ch) (gquest_info.running != GQUEST_OFF && ch->gquest)
#define STR_EDIT_KEY(ch) (IS_NPC(ch) ? '.' : ch->pcdata->str_ed_key)
#define GET_TZONE(ch) (IS_NPC(ch) ? -1 : ch->pcdata->timezone)
#define IS_PORTAL(d) ((d) && IS_SET((d)->d_flags, DESC_PORTAL))
#define IS_FIRECL(d) ((d) && IS_SET((d)->d_flags, DESC_IMP))
#define IS_MXP(d) ((d) && IS_SET((d)->d_flags, DESC_MXP) \
&& ((d)->mxp.mxp_ver * 10) >= 4)
#define IS_MSP(d) ((d) && IS_SET((d)->d_flags, DESC_MSP))
#define IS_COMPRESSED(d) (d && d->out_compress)
#define IS_PUEBLO(d) ((d) && IS_SET((d)->d_flags, DESC_PUEBLO))
#define SCR_WIDTH(d) (!(d) ? DEFAULT_SCR_WIDTH - 2 : (d)->scr_width)
#define SCR_HEIGHT(d) (!(d) ? DEFAULT_SCR_HEIGHT - 2 : (d)->scr_height)
/*
* 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)))
#define IS_WEAPON_STAT(obj,stat)(IS_SET((obj)->value[4],(stat)))
#define WEIGHT_MULT(obj) ((obj)->item_type == ITEM_CONTAINER ? \
(obj)->value[4] : 100)
#define IS_QUESTOR(ch) (!IS_NPC(ch) && IS_SET((ch)->act, PLR_QUESTOR) && \
(ch)->pcdata->questgiver != 0 )
/*
* Description macros.
*/
#define PERS(ch, looker) ( can_see( looker, (ch) ) ? \
( IS_NPC(ch) ? (ch)->short_descr \
: (ch)->name ) : IS_IMMORTAL(ch) ? "an Immortal" : "someone" )
#endif