/************************************************************************** * 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