/**************************************************************************/ // macros.h - most of the compiler macros are defined in here /*************************************************************************** * The Dawn of Time v1.69r (c)1997-2004 Michael Garratt * * >> A number of people have contributed to the Dawn codebase, with the * * majority of code written by Michael Garratt - www.dawnoftime.org * * >> To use this source code, you must fully comply with all the licenses * * in licenses.txt... In particular, you may not remove this copyright * * notice. * *************************************************************************** * >> Original Diku Mud copyright (c)1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, & Katja Nyboe. * * >> Merc Diku Mud improvements copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * >> ROM 2.4 is copyright 1993-1995 Russ Taylor and has been brought to * * you by the ROM consortium: Russ Taylor(rtaylor@pacinfo.com), * * Gabrielle Taylor(gtaylor@pacinfo.com) & Brian Moore(rom@rom.efn.org) * * >> Oblivion 1.2 is copyright 1996 Wes Wagner * **************************************************************************/ #ifndef MACROS_H #define MACROS_H /**************************************************************************/ // disable minor printf optimisation macro used in versions of GCC >= 2.97 // this macro creates problems when you have member functions called // printf() - such as in the char_data class #ifdef __GNUC__ # ifdef printf # if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97) # undef printf // macro is defined normally as below //#ifdef __GNUC_PREREQ (2,97) //# define printf(fmt, args...) fprintf (stdout, fmt, ##args) # endif # endif #endif /**************************************************************************/ // a assert pointer macro, used to make shorthand asserts // compatible with gcc 3.3.1+ #define assertp(pointer) assert( (pointer) !=NULL) /**************************************************************************/ #define alloc_mem(sz) malloc((size_t)sz) #define free_mem(mem, sz) free(mem) /**************************************************************************/ /* * 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) (tolower(c)) /* (c) >= 'A' && (c) <= 'Z' ? (c)+'a'-'A' : (c))*/ #define UPPER(c) ((c) >= 'a' && (c) <= 'z' ? (c)+'A'-'a' : (c)) #define IS_LOWER(c) ((c) >= 'a' && (c) <= 'a' ? true: false) #define IS_UPPER(c) ((c) >= 'A' && (c) <= 'Z' ? true: false) /* used by ident system */ #define replace_string( pstr, nstr ) \ { free_string( (pstr) ); pstr=str_dup( (nstr) ); } #define IS_NULLSTR(str) ((str)==NULL || (str)[0]=='\0') #define IS_HEALER(mob) (IS_NPC(mob) && IS_SET(mob->act, ACT_IS_HEALER)) #define IS_WATER_SECTOR(sect) (sect==SECT_WATER_SWIM \ || sect==SECT_WATER_NOSWIM \ || sect==SECT_UNDERWATER) #define HAS_CLASSFLAG(ch, flag) (IS_SET(class_table[(ch)->clss].flags, flag)) /**************************************************************************/ /* * OLC Macros */ #define HAS_AREA_SECURITY(ch, Area) (\ IS_SET(Area->area_flags, AREA_LOCKED)? \ HAS_SECURITY(ch,9):HAS_SECURITY(ch, UMAX(6,Area->security) ) ) #define IS_BUILDER_WHEN_NOT_RESTRICTED(ch, Area) (\ HAS_AREA_SECURITY(ch, Area) \ || is_exact_name(ch->name, Area->builders) ) #define IS_BUILDER_WHEN_RESTRICTED(ch, Area, type) (\ HAS_SECURITY(ch,9) \ ||is_exact_name("all", \ Area->build_restricts[type]) \ ||is_exact_name(ch->name, \ Area->build_restricts[type]) \ ||is_exact_name("all", \ Area->build_restricts[BUILDRESTRICT_ALL]) \ ||is_exact_name(ch->name, \ Area->build_restricts[BUILDRESTRICT_ALL]) ) #define IS_BUILDER(ch, Area, type) (\ IS_SET(Area->area_flags, AREA_LOCKED)? \ HAS_SECURITY(ch,9): \ HAS_SECURITY(ch,1) && \ (IS_SET(Area->area_flags, AREA_USE_BUILDRESTRICTS) \ ?IS_BUILDER_WHEN_RESTRICTED(ch, Area, type) \ :IS_BUILDER_WHEN_NOT_RESTRICTED(ch, Area)) ) #define GET_SECURITY(ch) ( IS_NPC((ch))? 0 : (ch)->pcdata->security ) #define HAS_SECURITY(cha, value) (GET_SECURITY( (cha) ) >= (value) ) #define TOGGLE_BIT(var, bit) ((var) ^= (bit)) // macro used in reading in character files #define IS_OLD_CHVER(ch) ( ch->version<9 || \ ( ch->version==9 && ch->subversion<2)) /**************************************************************************/ /* * Character macros. */ #define IS_OOC(ch) ( (ch)->in_room!=NULL && IS_SET((ch)->in_room->room_flags, ROOM_OOC)) #define IS_OLC(ch) ( (ch)->in_room && IS_SET((ch)->in_room->area->area_flags, AREA_OLCONLY)) #define IS_IC(ch) ( (ch)->in_room!=NULL \ && !IS_SET((ch)->in_room->room_flags, ROOM_OOC) \ && !IS_SET((ch)->in_room->area->area_flags, AREA_OLCONLY) ) #define IS_OLCAREA(area) (IS_SET( (area)->area_flags, AREA_OLCONLY) ) #define IS_NEWBIE(ch) ((ch->level) <= (10) && !IS_LETGAINED(ch)) #define IS_NEWBIE_SUPPORT(ch) (IS_SET((ch)->comm,COMM_NEWBIE_SUPPORT)) #define HAS_IMMTALK_NAME(ch) (ch && TRUE_CH(ch)->pcdata && !IS_NULLSTR(TRUE_CH(ch)->pcdata->immtalk_name)) #define IS_RP_SUPPORT(ch) (HAS_CONFIG((ch), CONFIG_RP_SUPPORT )) #define IS_SPELL(sn) ((sn >= FIRST_SPELL) && (sn <= LAST_SPELL)) #define IS_REALM(sn) ((sn >= gsn_abjuration) && (sn <= gsn_time )) #define IS_SKILL(sn) ((sn >= gsn_claw) && (sn <= gsn_kobold )) #define IS_SKILL_VALID_FOR_CLASS(sn, class_index) \ (skill_table[sn].rating[class_index] > 0 \ && skill_table[sn].skill_level[class_index] < LEVEL_IMMORTAL \ && skill_table[sn].skill_level[class_index] >= 0 ) #define IS_SKILLGROUP_SELECTABLE_FOR_CHAR(gn, ch) \ (ch && (skillgroup_table[gn].rating[ch->clss] >= 0 || IS_SET(skillgroup_table[gn].flags, SKILLGROUP_FREE_FOR_ALL)) \ && ch->remort>= skillgroup_table[gn].remort \ && IS_SET(skillgroup_table[gn].flags, SKILLGROUP_CREATION_SELECTABLE)) #define IS_SWITCHED(ch) ((ch)->desc && (ch)->desc->original) #define IS_CONTROLLED(victim) (IS_NPC(victim) && (victim)->desc != NULL) #define HAS_DESC(ch) ((ch)->desc) #define SAFE_DESC_CHARACTER(ch) (ch->desc->character? ch->desc->character: ch) #define TRUE_CH(ch) (ch->desc ? \ (ch->desc->original ? ch->desc->original : SAFE_DESC_CHARACTER(ch)):ch) #define TCH(ch) TRUE_CH(ch) #define TRUE_CH_PCDATA(ch) (TRUE_CH(ch)?TRUE_CH(ch)->pcdata:NULL) #define ACTIVE_CH(ch) (ch->desc ? ch: \ (ch->controlling? (ch->controlling->desc?ch->controlling:ch):ch)) #define ACH(ch) ACTIVE_CH(ch) #define CH(descriptor) ((descriptor)->original ? \ (descriptor)->original : (descriptor)->character) #define IS_IN_EDITMODE(ch) ((ch)->desc && (ch)->desc->pString) #define IS_IN_REDIT(ch) (ch->desc && ch->desc->editor==ED_ROOM) #define IS_NPC(ch) ((ch)->pcdata==NULL) #define IS_KEEPER(ch) (IS_NPC((ch)) && (ch)->pIndexData && (ch)->pIndexData->pShop) #define IS_UNSWITCHED_MOB(ch) (IS_NPC(ch) && !IS_CONTROLLED(ch)) #define IS_IRCCON(connection) ((connection)->contype==CONTYPE_IRC) #define IS_IRC(ch) (!IS_SWITCHED(ch) && (ch)->desc && IS_IRCCON((ch)->desc) ) #define IS_IMMORTAL(ch) (get_trust(ch) >= LEVEL_IMMORTAL) #define IS_ICIMMORTAL(ch) (!IS_NPC(ch) && ch->level >=LEVEL_IMMORTAL) #define IS_HERO(ch) (get_trust(ch) == LEVEL_HERO) #define IS_TRUSTED(ch,level) (get_trust((ch)) >= (level)) #define IS_AFFECTED(ch, bit) (IS_SET((ch)->affected_by, (bit))) #define IS_AFFECTED2(ch, bit) (IS_SET((ch)->affected_by2, (bit))) #define IS_ADMIN(ch) (TRUE_CH(ch)->level>=ADMIN) #define IS_NOBLE(ch) (TRUE_CH(ch)->pcdata && ((TRUE_CH(ch))->pcdata->diplomacy>0) ) #define IS_SILENT(ch) (IS_SET((ch)->dyn, DYN_SILENTLY)) #define IS_QUESTER(ch) (IS_SET(TRUE_CH(ch)->act, PLR_QUESTER)) #define IS_JAILED(ch) (!IS_NPC(ch) && (ch)->level<LEVEL_IMMORTAL \ && (ch)->in_room_vnum()==ROOM_VNUM_JAIL) #define IS_THIEF(ch) (!IS_NPC(ch) && TRUE_CH_PCDATA(ch)->thief_until>current_time) #define IS_KILLER(ch) (!IS_NPC(ch) && TRUE_CH_PCDATA(ch)->killer_until>current_time) #define IS_LINKDEAD(ch) ( !IS_NPC(ch) && !ch->desc \ && (ch->controlling? !ch->controlling->desc:true)) #define IS_ACTIVE(ch) (HAS_CONFIG(ch, CONFIG_ACTIVE) \ && !GAMESETTING(GAMESET_PEACEFUL_MUD) \ && !GAMESETTING2(GAMESET2_NO_DUEL_REQUIRED)) #define IS_PEACEFUL(ch) (!IS_ACTIVE(ch)) #define USING_AUTOMAP(ch) (HAS_CONFIG(ch, CONFIG_AUTOMAP)) // CONFIG MACROS #define HAS_HOLYLIGHT(ch) (TRUE_CH(ch)->pcdata \ && IS_SET(TRUE_CH(ch)->act,PLR_HOLYLIGHT)) #define HAS_AUTOSELF(ch) (IS_SET(TRUE_CH(ch)->comm,COMM_AUTOSELF)) #define GET_AGE(ch) ((int) (17 + ((ch)->played \ + current_time - (ch)->logon )/72000)) #define GET_NEW_KARN_COUNTER(ch) (IS_NPC(ch)?0:((ch->pcdata->karns*1000)+400)\ * ((ch)->level<40 ? 1 : (1 + ((ch)->level-40)/10))) #define GET_NEW_LAY_COUNTER(ch) (IS_NPC(ch)?0:8) #define GET_MAX_KARN(ch) (IS_NPC(ch)?0: \ (IS_SET(ch->act, PLR_NOREDUCING_MAXKARN) \ || GAMESETTING3(GAMESET3_NO_DECREASING_MAX_KARN)? \ 5 : UMAX(0, 5-( (ch->pkkills-(ch->pkdefeats/2)) /5) ) ) ) #define IS_GOOD(ch) (ch->alliance >= 2) #define IS_EVIL(ch) (ch->alliance <= -2) #define IS_NEUTRAL(ch) (!IS_GOOD(ch) && !IS_EVIL(ch)) #define IS_TEND_CHAOTIC(ch) (ch->tendency < -1) #define IS_TEND_LAWFUL(ch) (ch->tendency > 1) #define IS_TEND_NEUTRAL(ch) (!IS_TEND_CHAOTIC(ch) && !IS_TEND_LAWFUL(ch)) #define IS_AWAKE(ch) (ch->position > POS_SLEEPING) #define IS_MOUNTED(ch) ((ch)->ridden_by) #define IS_RIDING(ch) ((ch)->mounted_on) #define IS_TETHERED(ch) (IS_NPC((ch)) && ((ch)->tethered)) #define DAMTYPE(sn) (skill_table[sn].damtype) #define IS_SUBDUED(ch) ((ch)->subdued) #define GET_AC(ch,type)\ ((ch)->armor[type] + \ ( IS_AWAKE(ch) ? - (ch)->modifiers[STAT_QU] : 0 )) #define GET_HITROLL(ch) \ ((ch)->hitroll+ (ch)->modifiers[STAT_ST]/10 ) #define GET_DAMROLL(ch) \ ((ch)->damroll+ (ch)->modifiers[STAT_ST]/5 ) #define XP_PAST_LEVEL(ch) \ (IS_NPC(ch)?0:(ch->exp- (ch->level *exp_per_level(ch, ch->pcdata->points)))) #define IS_LETGAINED(ch) (IS_NPC(ch)?true:IS_SET(ch->act,PLR_CAN_ADVANCE)) #define GAMESETTING_LETGAINING_IS_REQUIRED (!GAMESETTING(GAMESET_NO_LETGAINING_REQUIRED)) #define IS_OUTSIDE(ch) \ ( !IS_SET(ch->in_room->room_flags, ROOM_INDOORS) \ && ch->in_room->sector_type != SECT_UNDERWATER \ && ch->in_room->sector_type != SECT_CAVE ) #define WIZI_LOOKUP(ch) (IS_OOC(ch)?ch->owizi:IS_OLC(ch)?ch->olcwizi:ch->iwizi) #define INVIS_LEVEL(ch) (WIZI_LOOKUP(ch)?WIZI_LOOKUP(ch):ch->invis_level) #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 HAS_TRIGGER(ch,trig) (IS_SET((ch)->pIndexData->mprog_flags,(trig))) #define GET_SECONDS_PLAYED(ch) \ (ch->played + (int) (current_time - ch->logon)) // config macros #define HAS_CONFIG(ch, value) ( IS_SET (TRUE_CH(ch)->config, value )) #define SET_CONFIG(ch, value) ( SET_BIT(TRUE_CH(ch)->config, value )) #define REMOVE_CONFIG(ch, value) (REMOVE_BIT(TRUE_CH(ch)->config, value )) #define TOGGLE_CONFIG(ch, value) (TOGGLE_BIT(TRUE_CH(ch)->config, value )) // config2 macros #define HAS_CONFIG2(ch, value) ( IS_SET (TRUE_CH(ch)->config2, value )) #define SET_CONFIG2(ch, value) ( SET_BIT(TRUE_CH(ch)->config2, value )) #define REMOVE_CONFIG2(ch, value) (REMOVE_BIT(TRUE_CH(ch)->config2, value )) #define TOGGLE_CONFIG2(ch, value) (TOGGLE_BIT(TRUE_CH(ch)->config2, value )) // pconfig macros - player configs, stored in pcdata #define HAS_PCONFIG(ch, value) ( IS_SET (TRUE_CH_PCDATA->config, value )) #define SET_PCONFIG(ch, value) ( SET_BIT(TRUE_CH_PCDATA->config, value )) #define REMOVE_PCONFIG(ch, value) (REMOVE_BIT(TRUE_CH_PCDATA->config, value )) #define TOGGLE_PCONFIG(ch, value) (TOGGLE_BIT(TRUE_CH_PCDATA->config, value )) // channel macros #define __CHAN_VALUE(ch) (TRUE_CH(ch)->pcdata?TRUE_CH(ch)->pcdata->channeloff:__CHANNEL_OFF_CRASH_PROTECTOR_VARIABLE) #define HAS_CHANNELOFF(ch, value) ( IS_SET(__CHAN_VALUE(ch), value )) #define SET_CHANNELOFF(ch, value) ( SET_BIT(__CHAN_VALUE(ch), value )) #define REMOVE_CHANNELOFF(ch, value) (REMOVE_BIT(__CHAN_VALUE(ch), value )) #define TOGGLE_CHANNELOFF(ch, value) (TOGGLE_BIT(__CHAN_VALUE(ch), value )) #define HAS_MSP(ch) (ch && TRUE_CH(ch)->pcdata && TRUE_CH(ch)->pcdata->msp_enabled) #define HAS_MXP(ch) (ch && TRUE_CH(ch)->pcdata && TRUE_CH(ch)->pcdata->mxp_enabled) #define HAS_MXPDESC(d) (d && d->mxp_enabled) #define MXP_DETECTED_OR_ON(ch) ( ch && TRUE_CH(ch)->pcdata \ && (TRUE_CH(ch)->pcdata->preference_mxp==PREF_ON \ || \ (TRUE_CH(ch)->pcdata->preference_mxp==PREF_AUTOSENSE && \ TRUE_CH(ch)->desc && \ IS_SET(TRUE_CH(ch)->desc->flags, CONNECTFLAG_MXP_DETECTED)) ) ) #define IS_COURT(ch) IS_SET((ch)->config, CONFIG_COURTMEMBER) #define HAS_HOLYSPEECH(ch) IS_SET((ch)->config, CONFIG_HOLYSPEECH) #define CAN_HEAR_MSP(ch) ( !IS_NPC(TRUE_CH(ch)) && \ HAS_MSP(ch) && \ !is_affected(ch, gsn_deafness) ) #define CAN_SEE_EXIT(ch, exit) (!IS_SET(exit->exit_info, EX_CLOSED) \ || HAS_HOLYLIGHT(ch) \ || IS_SET(TRUE_CH(ch)->act, PLR_HOLYWALK) \ || IS_SET(exit->exit_info, EX_OBVIOUS)) // capitalized person #define CPERS(ch, looker) (capitalize(PERS(ch,looker))) /**************************************************************************/ /* * Object macros. */ #define OBJECT_AFFECTS(obj) \ (obj->affected? obj->affected: (obj->no_affects?NULL:obj->pIndexData->affected)) // if an object is disenchanted (failed enchant etc), then it gets the // obj->no_affects flag set. // this flag is only checked if obj->affects is NULL... if obj->affects is NULL // and obj->no_affects is not set then the olc templates affects // (obj->pIndexData->affected) are used. #define CAN_WEAR(obj, part) (IS_SET((obj)->wear_flags, (part))) #define DISALLOWED_OBJECT_FOR_CHAR(obj, ch) \ (!IS_NPC(ch) && (obj)->pIndexData->class_allowances \ && !IS_SET((obj)->pIndexData->class_allowances, 1<<(ch)->clss) ) #define IS_OBJ_STAT(obj, stat) (IS_SET((obj)->extra_flags, (stat))) #define IS_OBJ2_STAT(obj, stat) (IS_SET((obj)->extra2_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 get_gold_weight(gold) ((gold)*2/5) #define get_silver_weight(silv) ((silv)/10) #define trim_string(str) (ltrim_string(rtrim_string(str))) #define IS_TRAPPED(obj) (IS_SET((obj)->extra2_flags, (OBJEXTRA2_TRAP))) /**************************************************************************/ /**************************************************************************/ // reading in a a defined datatype macro #if defined(KEY) #undef KEY #endif #define KEY( literal, field, value ) \ if ( !str_cmp( word, literal ) ) \ { \ field = value; \ fMatch = true; \ break; \ } /**************************************************************************/ // reading in a string from a file macro #if defined(SKEY) #undef SKEY #endif #define SKEY( string, field ) \ if ( !str_cmp( word, string ) ) \ { \ free_string( field ); \ field = fread_string( fp ); \ fMatch = true; \ break; \ } /**************************************************************************/ #define channel_colour_disabled(ch, channel) \ (TRUE_CH(ch)?(TRUE_CH(ch)->pcdata? IS_SET( \ TRUE_CH(ch)->pcdata->strip_colour_on_channel,channel):false):false) /**************************************************************************/ // iSpell Related stuff below #define Stringify(x) Str(x) #define Str(x) #x #ifdef WIN32 // compatiblity macros #define vsnprintf(buf, len, fmt, args) _vsnprintf(buf, len, fmt, args) #define snprintf _snprintf #define popen(command, mode) _popen(command,mode) #define pclose(fp) _pclose(fp) #define getcwd(dir, size) _getcwd(dir, size) #define chdir(dir) _chdir(dir) #define mkdir(dir) _mkdir(dir) #endif #endif // MACROS_H