/* ************************************************************************ * File: utils.h EmpireMUD AD 1.0 * * Usage: header file: utility macros and prototypes of utility funcs * * * * All rights reserved. See license.doc for complete information. * * * * Code base by Paul Clarke. EmpireMUD Project, a tbgMUD Production. * * Based upon CircleMUD 3.0, beta patch level 17, by Jeremy Elson. * * * * Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University * * CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991. * ************************************************************************ */ /* external declarations and prototypes **********************************/ /* Log information */ extern FILE *logfile; #define log basic_mud_log /* public functions in utils.c */ char *str_dup(const char *source); int str_cmp(const char *arg1, const char *arg2); extern bool str_str(const char *arg1, const char *arg2); int strn_cmp(const char *arg1, const char *arg2, int n); void basic_mud_log(const char *format, ...) __attribute__ ((format (printf, 1, 2))); int touch(const char *path); void syslog(int level, bool file, const char *str, ...); void mortlog(Creature ch, const char *str, ...); int number(int from, int to); int dice(int number, int size); int ww_dice(int num, int diff); void sprintbit(bitvector_t vektor, const char *names[], char *result, bool space); void sprinttype(int type, const char *names[], char *result); int get_line(FILE *fl, char *buf); int get_filename(char *orig_name, char *filename, int mode); struct time_info_data *age(Creature ch); int num_pc_in_room(Room room); void save_char(Creature ch, room_rnum load_room); #define SAVE_CHAR(ch) save_char((ch), (ch)->in_room != NOWHERE ? (ch)->in_room : GET_LOADROOM(ch) != NOWHERE ? GET_LOADROOM(ch) : NOWHERE) extern struct reboot_data reboot; /* resources */ void extract_resources(Creature ch, Resource list[], bool ground); void give_resources(Creature ch, Resource list[], bool split); extern int get_total_resources(Resource list[]); extern int get_amount_of_resource(Resource list[], obj_vnum vnum); extern bool has_resources(Creature ch, Resource list[], bool ground); /* undefine MAX and MIN so that our macros are used instead */ #ifdef MAX #undef MAX #endif #define MAX(a, b) (a > b ? a : b) #ifdef MIN #undef MIN #endif #define MIN(a, b) (a < b ? a : b) extern char *CAP(char *txt); /* in act.informative.c */ void look_at_room_by_rnum(Creature ch, room_rnum room); #define look_at_room(ch) look_at_room_by_rnum((ch), (ch)->in_room) /* various constants *****************************************************/ /* get_filename() */ #define CRASH_FILE 0 #define ETEXT_FILE 1 #define ALIAS_FILE 2 #define REC_FILE 3 #define LORE_FILE 4 /* * XXX: These constants should be configurable. See act.informative.c * and utils.c for other places to change. */ /* mud-life time */ #define SECS_PER_MUD_HOUR 75 #define SECS_PER_MUD_DAY (24 * SECS_PER_MUD_HOUR) #define SECS_PER_MUD_MONTH (30 * SECS_PER_MUD_DAY) #define SECS_PER_MUD_YEAR (12 * SECS_PER_MUD_MONTH) /* real-life time (remember Real Life?) */ #define SECS_PER_REAL_MIN 60 #define SECS_PER_REAL_HOUR (60 * SECS_PER_REAL_MIN) #define SECS_PER_REAL_DAY (24 * SECS_PER_REAL_HOUR) #define SECS_PER_REAL_YEAR (365 * SECS_PER_REAL_DAY) /* string utils **********************************************************/ #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) ) #define ISNEWL(ch) ((ch) == '\n' || (ch) == '\r') #define IF_STR(st) ((st) ? (st) : "\0") #define AN(string) (strchr("aeiouAEIOU", *string) ? "an" : "a") /* memory utils **********************************************************/ #define CREATE(result, type, number) do {\ if ((number) * sizeof(type) <= 0) \ log("SYSERR: Zero bytes or less requested at %s:%d.", __FILE__, __LINE__); \ if (!((result) = (type *) calloc ((number), sizeof(type)))) \ { log("SYSERR: malloc failure: %s: %d", __FILE__, __LINE__); abort(); } } while(0) #define RECREATE(result, type, number) do {\ if (!((result) = (type *) realloc ((result), sizeof(type) * (number))))\ { log("SYSERR: realloc failure: %s: %d", __FILE__, __LINE__); abort(); } } while(0) /* * the source previously used the same code in many places to remove an item * from a list: if it's the list head, change the head, else traverse the * list looking for the item before the one to be removed. Now, we have a * macro to do this. To use, just make sure that there is a variable 'temp' * declared as the same type as the list to be manipulated. */ #define REMOVE_FROM_LIST(item, head, next) \ if ((item) == (head)) \ head = (item)->next; \ else { \ temp = head; \ while (temp && (temp->next != (item))) \ temp = temp->next; \ if (temp) \ temp->next = (item)->next; \ } \ /* npc safeguard ********************************************************* * * Accessing player specific data structures on a mobile is a very bad thing * to do. Consider that changing these variables for a single mob will change * it for every other single mob in the game. If we didn't specifically check * for it, 'wimpy' would be an extremely bad thing for a mob to do, as an * example. If you really couldn't care less, change this to a '#if 0'. */ #if 1 #define CHECK_PLAYER_SPECIAL(ch, var) (*(((ch)->player_specials == &dummy_mob) ? (log("SYSERR: Mob using '"#var"' at %s:%d.", __FILE__, __LINE__), &(var)) : &(var))) #else #define CHECK_PLAYER_SPECIAL(ch, var) (var) #endif #define REAL_CHAR(ch) (((ch)->desc && (ch)->desc->original) ? (ch)->desc->original : (ch)) /* basic bitvector utils *************************************************/ #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 MOB_FLAGS(ch) ((ch)->char_specials.saved.act) #define PLR_FLAGS(ch) (REAL_CHAR(ch)->char_specials.saved.act) #define PRF_FLAGS(ch) CHECK_PLAYER_SPECIAL(REAL_CHAR(ch), (REAL_CHAR(ch)->player_specials->saved.pref)) #define AFF_FLAGS(ch) ((ch)->char_specials.saved.affected_by) #define DSC_FLAGS(ch) ((ch)->char_specials.saved.dsc_flags) #define ROOM_AFF_FLAGS(r) (world[HOME_ROOM(r)].affects) #define INJURY_FLAGS(ch) ((ch)->char_specials.saved.injuries) #define IS_NPC(ch) (IS_SET(MOB_FLAGS(ch), MOB_ISNPC)) #define REAL_NPC(ch) (IS_NPC(REAL_CHAR(ch))) #define IS_MOB(ch) (IS_NPC(ch) && GET_MOB_RNUM(ch) >= 0) #define MOB_FLAGGED(ch, flag) (IS_NPC(ch) && IS_SET(MOB_FLAGS(ch), (flag))) #define PLR_FLAGGED(ch, flag) (!REAL_NPC(ch) && IS_SET(PLR_FLAGS(ch), (flag))) #define AFF_FLAGGED(ch, flag) (IS_SET(AFF_FLAGS(ch), (flag))) #define DSC_FLAGGED(ch, flag) (IS_SET(DSC_FLAGS(ch), (flag))) #define ROOM_AFF_FLAGGED(r, flag) (IS_SET(world[(r)].affects, (flag))) #define PRF_FLAGGED(ch, flag) (!REAL_NPC(ch) && IS_SET(PRF_FLAGS(ch), (flag))) #define IS_INJURED(ch, flag) (IS_SET(INJURY_FLAGS(ch), (flag))) #define EXIT_FLAGGED(exit, flag) (IS_SET((exit)->exit_info, (flag))) #define OBJVAL_FLAGGED(obj, flag) (IS_SET(GET_OBJ_VAL((obj), 1), (flag))) #define OBJ_FLAGGED(obj, flag) (IS_SET(GET_OBJ_EXTRA(obj), (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_WRITING(ch) (PLR_FLAGGED(ch, PLR_WRITING) || PLR_FLAGGED(ch, PLR_MAILING)) /* room utils ************************************************************/ extern struct weather_data weather_info; extern bool adjacent_room_is_light(room_rnum room); extern int shift_dir[][2]; extern int shift_room(int origin, int x, int y); int get_season(); #define SECT(room) (world[(room)].sector_type) #define BUILDING_TYPE(room) (SECT(room) == SECT_BUILDING ? world[(room)].type : NOWHERE) #define ROOM_TYPE(room) (SECT(room) == SECT_INSIDE ? world[(room)].type : NOWHERE) #define OPEN_MONUMENT_TYPE(room) (SECT(room) == SECT_MONUMENT_OPEN ? world[(room)].type : NOWHERE) #define CLOSED_MONUMENT_TYPE(room) (SECT(room) == SECT_MONUMENT_CLOSED ? world[(room)].type : NOWHERE) #define IS_DARK(room) ((SECT(room) != SECT_BUILDING && SECT(room) != SECT_MULTI && SECT(room) != SECT_INSIDE && !world[room].light && weather_info.sunlight == SUN_DARK) || ROOM_AFF_FLAGGED((room), ROOM_AFF_DARK)) #define IS_REAL_LIGHT(room) ((!IS_DARK(room) || SECT(room) == SECT_BUILDING || SECT(room) == SECT_MULTI || SECT(room) == SECT_INSIDE) && !ROOM_AFF_FLAGGED((room), ROOM_AFF_DARK)) #define IS_LIGHT(room) ((!IS_DARK(room) || adjacent_room_is_light(room) || SECT(room) == SECT_BUILDING || SECT(room) == SECT_MULTI || SECT(room) == SECT_INSIDE) && !ROOM_AFF_FLAGGED((room), ROOM_AFF_DARK)) #define VALID_RNUM(rnum) ((rnum) >= 0 && (rnum) <= top_of_world) #define GET_ROOM_VNUM(rnum) ((room_vnum)(VALID_RNUM(rnum) ? world[(rnum)].number : NOWHERE)) #define EXIT(ch, door) (world[(ch)->in_room].dir_option[door]) #define HOME_ROOM(room) (world[(room)].home_room != NOWHERE && real_room(world[(room)].home_room) != NOWHERE ? real_room(world[(room)].home_room) : (room)) #define ROOM_WEIGHT(room) (world[(room)].weight) #define ALWAYS_CLOSED(room) (SECT(room) == SECT_MONUMENT_CLOSED || BUILDING_TYPE(room) == BUILDING_MINE || BUILDING_TYPE(room) == BUILDING_MINE_COMPLEX || BUILDING_TYPE(room) == BUILDING_MOUNTAIN_OUTPOST || BUILDING_TYPE(room) == BUILDING_CLIFF_DWELLING || BUILDING_TYPE(room) == BUILDING_TUNNEL || BUILDING_TYPE(room) == BUILDING_TUNNEL2) #define IS_HAVEN(room) (BUILDING_TYPE(room) == BUILDING_HAVEN_HOUSE || BUILDING_TYPE(room) == BUILDING_HAVEN_BURROW || BUILDING_TYPE(room) == BUILDING_HAVEN_PUEBLO || BUILDING_TYPE(room) == BUILDING_HAVEN_CAVE) #define BUILDING_CAN_BURN(room) (BUILDING_TYPE(room) == BUILDING_HUT || BUILDING_TYPE(room) == BUILDING_TREE_HOUSE || BUILDING_TYPE(room) == BUILDING_WATCH_TOWER || BUILDING_TYPE(room) == BUILDING_TREE_COMPLEX || BUILDING_TYPE(room) == BUILDING_CABIN || BUILDING_TYPE(room) == BUILDING_HOUSE || (SECT(room) == SECT_BARRIER && !world[room].type) || BUILDING_TYPE(room) == BUILDING_GUARD_TOWER || BUILDING_TYPE(room) == BUILDING_GUARD_TOWER2) extern bool STORE_BUILDING(room_rnum room); extern bool CAN_USE_ROOM(Creature ch, room_rnum room, bool mode); #define real_shift(a, b, c) (real_room(shift_room(world[a].number, b, c))) #define shift_nw(room) real_shift(room, -1, 1) #define shift_n(room) real_shift(room, 0, 1) #define shift_ne(room) real_shift(room, 1, 1) #define shift_e(room) real_shift(room, 1, 0) #define shift_se(room) real_shift(room, 1, -1) #define shift_s(room) real_shift(room, 0, -1) #define shift_sw(room) real_shift(room, -1, -1) #define shift_w(room) real_shift(room, -1, 0) #define IS_OUTDOORS(ch) (SECT(ch->in_room) != SECT_BUILDING && SECT(ch->in_room) != SECT_INSIDE && SECT(ch->in_room) != SECT_MULTI && SECT(ch->in_room) != SECT_MONUMENT_CLOSED) #define GET_BOAT(room) (world[HOME_ROOM(room)].boat) #define BOAT_ROOM(room) (world[HOME_ROOM(room)].boat ? world[HOME_ROOM(room)].boat->in_room : room) #define X_COORD(room) (world[HOME_ROOM(BOAT_ROOM(room))].number % MAP_WIDTH) #define Y_COORD(room) (world[HOME_ROOM(BOAT_ROOM(room))].number / MAP_HEIGHT) #define FLAT_X_COORD(room) (world[BOAT_ROOM(room)].number % MAP_WIDTH) #define FLAT_Y_COORD(room) (world[BOAT_ROOM(room)].number / MAP_HEIGHT) #define GET_BUILD_VALUE(room) (world[room].build_value) #define IS_COMPLETE(room) (!world[room].res.logs && !world[room].res.sticks && !world[room].res.rocks && !world[room].res.iron) #define IS_DISMANTLING(room) (world[room].dismantling) #define CAN_GO(ch, door) (EXIT(ch,door) && \ (EXIT(ch,door)->to_room != NOWHERE) && \ !IS_SET(EXIT(ch, door)->exit_info, EX_CLOSED)) /* char utils ************************************************************/ /* ch */ #define GET_PFILEPOS(ch) ((ch)->pfilepos) #define IN_ROOM(ch) ((ch)->in_room) #define GET_WAS_IN(ch) ((ch)->was_in_room) #define GET_AGE(ch) (IS_VAMPIRE(ch) ? GET_APPARENT_AGE(ch) : age(ch)->year) #define GET_REAL_AGE(ch) (age(ch)->year) #define GET_EQ(ch, i) ((ch)->equipment[i]) /* ch->player */ #define GET_PC_NAME(ch) ((ch)->player.name) #define GET_NAME(ch) (IS_NPC(ch) ? (ch)->player.short_descr : GET_PC_NAME(ch)) #define GET_TITLE(ch) ((ch)->player.title) #define GET_PROMPT(ch) ((ch)->player.prompt) #define POOFIN(ch) ((ch)->player.poofin) #define POOFOUT(ch) ((ch)->player.poofout) #define GET_EMAIL(ch) ((ch)->player.email) #define GET_LASTNAME(ch) ((ch)->player.lastname) #define GET_LEVEL(ch) ((ch)->player.level) #define GET_REAL_LEVEL(ch) (ch->desc && ch->desc->original ? GET_LEVEL(ch->desc->original) : GET_LEVEL(ch)) #define IS_IMMORTAL(ch) (GET_LEVEL(ch) >= LVL_START_IMM) #define IS_GOD(ch) (GET_LEVEL(ch) == LVL_GOD) #define GET_PASSWD(ch) ((ch)->player.passwd) #define GET_HEIGHT(ch) ((ch)->player.height) #define GET_WEIGHT(ch) ((ch)->player.weight) #define GET_SEX(ch) ((ch)->player.sex) #define GET_LORE(ch) ((ch)->player.lore) /* ch->aff_abils */ #define GET_STRENGTH(ch) ((ch)->aff_abils.strength) #define GET_DEXTERITY(ch) ((ch)->aff_abils.dexterity) #define GET_STAMINA(ch) ((ch)->aff_abils.stamina) #define GET_CHARISMA(ch) ((ch)->aff_abils.charisma) #define GET_MANIPULATION(ch) ((ch)->aff_abils.manipulation) #define GET_APPEARANCE(ch) ((ch)->aff_abils.appearance) #define GET_PERCEPTION(ch) ((ch)->aff_abils.perception) #define GET_INTELLIGENCE(ch) ((ch)->aff_abils.intelligence) #define GET_WITS(ch) ((ch)->aff_abils.wits) #define GET_CONSCIENCE(ch) ((ch)->points.conscience) #define GET_SELF_CONTROL(ch) ((ch)->points.self_control) #define GET_COURAGE(ch) ((ch)->points.courage) #define GET_HUMANITY(ch) ((ch)->points.humanity) #define GET_WILLPOWER(ch) ((ch)->points.willpower) #define GET_MAX_WILLPOWER(ch) ((ch)->points.max_willpower) #define GET_RAGE(ch) ((ch)->points.rage) #define GET_MAX_RAGE(ch) ((ch)->points.max_rage) #define GET_GNOSIS(ch) ((ch)->points.gnosis) #define GET_MAX_GNOSIS(ch) ((ch)->points.max_gnosis) #define GET_SOAK(ch) ((ch)->points.soak) #define GET_BLOCK(ch) ((ch)->points.block) #define GET_BLOOD(ch) ((ch)->points.blood) #define GET_VAMP_BLOOD(ch) ((ch)->points.vamp_blood) extern byte GET_MAX_BLOOD(Creature ch); /* ch->points */ #define GET_DAMAGE(ch) ((ch)->points.damage) #define GET_AGG_DAMAGE(ch) ((ch)->points.agg_damage) #define GET_MOVE(ch) ((ch)->points.move) #define GET_MAX_MOVE(ch) ((ch)->points.max_move) #define GET_EXPERIENCE(ch) ((ch)->points.experience) /* ch->char_specials */ #define GET_POS(ch) ((ch)->char_specials.position) #define GET_IDNUM(ch) (REAL_CHAR(ch)->char_specials.saved.idnum) #define IS_CARRYING_W(ch) ((ch)->char_specials.carry_weight) #define IS_CARRYING_N(ch) ((ch)->char_specials.carry_items) #define HUNTING(ch) ((ch)->char_specials.hunting) #define ON_CHAIR(ch) ((ch)->char_specials.chair) #define GET_RIDING(ch) ((ch)->char_specials.riding) #define GET_RIDDEN_BY(ch) ((ch)->char_specials.ridden_by) #define GET_FEEDING_FROM(ch) ((ch)->char_specials.feeding_from) #define GET_FED_ON_BY(ch) ((ch)->char_specials.fed_on_by) #define GET_LEADING(ch) ((ch)->char_specials.leading) #define GET_LED_BY(ch) ((ch)->char_specials.led_by) #define GET_PULLING(ch) ((ch)->char_specials.pulling) #define FIGHTING(ch) ((ch)->char_specials.fighting.victim) #define FIGHT_MODE(ch) ((ch)->char_specials.fighting.mode) #define FIGHT_WAIT(ch) ((ch)->char_specials.fighting.wait) #define ATTACK_BONUS(ch) ((ch)->char_specials.fighting.attack_bonus) /* ch->player_specials->saved */ #define GET_DAYS_SINCE_BATHING(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.days_since_bathing)) #define GET_APPARENT_AGE(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.apparent_age)) #define GET_EXP_TODAY(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.exp_today)) #define GET_LANGUAGES(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.languages)) #define SET_SPEAKING(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.speaking)) #define GET_SPEAKING(ch) (GET_MORPH(ch) == MORPH_NONE || CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.speaking)) == LANG_HIGH_TONGUE ? CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.speaking)) : LANG_FERAL_SPEECH) #define GET_EXP_CYCLE(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.exp_cycle)) #define GET_MORPH(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.morph)) #define GET_LOYALTY(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.loyalty)) #define GET_DEFECT_TIMER(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.defect_timer)) #define GET_LAST_DIR(ch) CHECK_PLAYER_SPECIAL(REAL_CHAR(ch), (REAL_CHAR(ch)->player_specials->saved.last_direction)) #define GET_RANK(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.rank)) #define GET_PLEDGE(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.pledge)) #define GET_IMM_LEV(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.imm_lev)) #define GET_COND(ch, i) CHECK_PLAYER_SPECIAL(REAL_CHAR(ch), (REAL_CHAR(ch)->player_specials->saved.conditions[(i)])) #define GET_LOADROOM(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.load_room)) #define GET_SPARE_ROOM(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.spare_room)) #define GET_INVIS_LEV(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.invis_level)) #define GET_BAD_PWS(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.bad_pws)) #define GET_ACTION(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.action)) #define GET_ACTION_TIMER(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.action_timer)) #define GET_ACTION_ROOM(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.action_room)) #define GET_ACTION_ROTATION(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.action_rotation)) #define GET_ACTION_VNUM(ch, n) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.action_vnum[(n)])) #define GET_SKIN(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.skin)) #define GET_HAIR(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.hair)) #define GET_EYES(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.eyes)) #define GET_RESOURCE(ch, i) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.res[i])) #define GET_MEMORY(ch, i) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.memory[i])) #define GET_CLAN(ch) (IS_VAMPIRE(ch) ? GET_REAL_CLAN(ch) : -1) #define GET_REAL_CLAN(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.clan)) #define GET_GENERATION(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.generation)) #define GET_TALENT(ch, i) (REAL_NPC(ch) ? 1 : CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.talents[i]))) #define GET_SKILL(ch, i) (REAL_NPC(ch) ? 1 : CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.skills[i]))) #define GET_KNOWLEDGE(ch, i) (IS_NPC(ch) ? 1 : CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.knowledges[i]))) #define GET_TRIBE(ch) (IS_WEREWOLF(ch) ? GET_REAL_TRIBE(ch) : -1) #define GET_REAL_TRIBE(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.tribe)) #define GET_BREED(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.breed)) #define GET_AUSPICE(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.auspice)) /* Disciplines */ #define GET_DISC(ch, disc) ((IS_VAMPIRE(ch) || IS_GHOUL(ch)) ? (ch)->player_specials->saved.discs[(disc)] : 0) #define GET_REAL_DISC(ch, disc) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.discs[(disc)])) #define GET_ANIMALISM(ch) ((IS_VAMPIRE(ch) || IS_GHOUL(ch)) ? (ch)->player_specials->saved.discs[DISC_ANIMALISM] : 0) #define GET_AUSPEX(ch) ((IS_VAMPIRE(ch) || IS_GHOUL(ch)) ? (ch)->player_specials->saved.discs[DISC_AUSPEX] : 0) #define GET_CELERITY(ch) ((IS_VAMPIRE(ch) || IS_GHOUL(ch)) ? (ch)->player_specials->saved.discs[DISC_CELERITY] : 0) #define GET_CHIMERSTRY(ch) ((IS_VAMPIRE(ch) || IS_GHOUL(ch)) ? (ch)->player_specials->saved.discs[DISC_CHIMERSTRY] : 0) #define GET_DEMENTATION(ch) ((IS_VAMPIRE(ch) || IS_GHOUL(ch)) ? (ch)->player_specials->saved.discs[DISC_DEMENTATION] : 0) #define GET_DOMINATE(ch) ((IS_VAMPIRE(ch) || IS_GHOUL(ch)) ? (ch)->player_specials->saved.discs[DISC_DOMINATE] : 0) #define GET_FORTITUDE(ch) ((IS_VAMPIRE(ch) || IS_GHOUL(ch)) ? (ch)->player_specials->saved.discs[DISC_FORTITUDE] : 0) #define GET_MORTIS(ch) ((IS_VAMPIRE(ch) || IS_GHOUL(ch)) ? (ch)->player_specials->saved.discs[DISC_MORTIS] : 0) #define GET_OBFUSCATE(ch) ((IS_VAMPIRE(ch) || IS_GHOUL(ch)) ? (ch)->player_specials->saved.discs[DISC_OBFUSCATE] : 0) #define GET_OBTENEBRATION(ch) ((IS_VAMPIRE(ch) || IS_GHOUL(ch)) ? (ch)->player_specials->saved.discs[DISC_OBTENEBRATION] : 0) #define GET_POTENCE(ch) ((IS_VAMPIRE(ch) || IS_GHOUL(ch)) ? (ch)->player_specials->saved.discs[DISC_POTENCE] : 0) #define GET_PRESENCE(ch) ((IS_VAMPIRE(ch) || IS_GHOUL(ch)) ? (ch)->player_specials->saved.discs[DISC_PRESENCE] : 0) #define GET_PROTEAN(ch) ((IS_VAMPIRE(ch) || IS_GHOUL(ch)) ? (ch)->player_specials->saved.discs[DISC_PROTEAN] : 0) #define GET_QUIETUS(ch) ((IS_VAMPIRE(ch) || IS_GHOUL(ch)) ? (ch)->player_specials->saved.discs[DISC_QUIETUS] : 0) #define GET_SERPENTIS(ch) ((IS_VAMPIRE(ch) || IS_GHOUL(ch)) ? (ch)->player_specials->saved.discs[DISC_SERPENTIS] : 0) #define GET_THAUMATURGY(ch) ((IS_VAMPIRE(ch) || IS_GHOUL(ch)) ? (ch)->player_specials->saved.discs[DISC_THAUMATURGY] : 0) #define GET_VICISSITUDE(ch) ((IS_VAMPIRE(ch) || IS_GHOUL(ch)) ? (ch)->player_specials->saved.discs[DISC_VICISSITUDE] : 0) #define GET_PATH(ch, path) ((IS_VAMPIRE(ch) || IS_GHOUL(ch)) ? (ch)->player_specials->saved.paths[(path)] : 0) #define GET_REAL_PATH(ch, path) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.paths[(path)])) #define GET_PRIMARY_PATH(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.primary_path)) #define GET_REAL_PRIMARY_PATH(ch) ((ch)->player_specials->saved.primary_path) #define GET_REGO_VITAE(ch) GET_PATH(ch, PATH_REGO_VITAE) #define GET_CREO_IGNEM(ch) GET_PATH(ch, PATH_CREO_IGNEM) #define GET_REGO_MOTUS(ch) GET_PATH(ch, PATH_REGO_MOTUS) #define GET_REGO_TEMPESTAS(ch) GET_PATH(ch, PATH_REGO_TEMPESTAS) #define GET_REGO_AQUAM(ch) GET_PATH(ch, PATH_REGO_AQUAM) #define GET_REGO_ELEMENTUM(ch) GET_PATH(ch, PATH_REGO_ELEMENTUM) #define GET_WAY_OF_LEVINBOLT(ch) GET_PATH(ch, PATH_WAY_OF_LEVINBOLT) #define GET_PATH_OF_WARDING(ch) GET_PATH(ch, PATH_PATH_OF_WARDING) #define IS_VAMPIRE(ch) (!IS_NPC(ch) && PLR_FLAGGED((ch), PLR_VAMPIRE)) #define IS_WEREWOLF(ch) (!IS_NPC(ch) && PLR_FLAGGED((ch), PLR_WEREWOLF)) #define IS_GHOUL(ch) (!IS_NPC(ch) && PLR_FLAGGED((ch), PLR_GHOUL)) #define IS_HUMAN(ch) (!IS_VAMPIRE(ch) && !IS_GHOUL(ch)) #define IS_HARDCORE(ch) (!IS_NPC(ch) && PLR_FLAGGED(ch, PLR_HARDCORE)) /* ch->player_specials */ #define GET_QUIT_TIMER(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->quit_timer)) #define GET_SLIT_WRIST(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->slit_wrist)) #define GET_ALIASES(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->aliases)) #define GET_LAST_TELL(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->last_tell)) #define IS_AFK(ch) (IS_NPC(ch) ? 0 : ((ch)->player_specials->isafk || ((ch->char_specials.timer * SECS_PER_MUD_HOUR / SECS_PER_REAL_MIN) >= 10))) #define AFK_MSG(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->afk_msg)) #define AFK_MSGS(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->afk_msgs)) #define REBOOT_CONF(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->reboot_conf)) #define GET_MOVE_REGEN(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->move_regen)) #define GET_NEW_EQ_SET(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->eq_set)) #define GET_VC(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->vc)) #define GET_VC_NAME(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->vc_name)) /* ch->mob_specials */ #define MOB_TO_HIT(ch) ((ch)->mob_specials.to_hit) #define MOB_TO_DODGE(ch) ((ch)->mob_specials.to_dodge) #define MOB_SECTS(ch) ((ch)->mob_specials.sects) #define MOB_ATTACK_TYPE(ch) ((ch)->mob_specials.attack_type) #define MOB_DAMAGE(ch) ((ch)->mob_specials.damage) #define MOB_LAST_DIR(ch) ((ch)->mob_specials.last_direction) #define MOB_MILK_TIMER(ch) ((ch)->mob_specials.milk_timer) #define MOB_TYPE(ch) ((ch)->mob_specials.type) #define MOB_SKIN(ch) ((ch)->mob_specials.skin) extern Creature mob_proto; #define GET_MOB_NAME_BY_PROTO(rnum) mob_proto[(rnum)].player.short_descr #define GET_MOB_RNUM(mob) ((mob)->nr) #define GET_MOB_VNUM(mob) (IS_MOB(mob) ? mob_index[GET_MOB_RNUM(mob)].vnum : NOBODY) /* Strength Data */ extern const struct str_app_type str_app[]; #define CAN_CARRY_W(ch) (str_app[GET_STRENGTH(ch)].carry_w) #define CAN_CARRY_N(ch) (15 * GET_DEXTERITY(ch)) #define AWAKE(ch) (GET_POS(ch) > POS_SLEEPING) #define HAS_INFRA(ch) (AFF_FLAGGED(ch, AFF_INFRAVISION) || DSC_FLAGGED(ch, DSC_WITNESS_OF_DARKNESS)) #define CAN_SEE_IN_DARK(ch) (HAS_INFRA(ch) || (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_HOLYLIGHT))) #define NOCTURNE_DARK(room) (ROOM_AFF_FLAGGED((room), ROOM_AFF_DARK)) #define CAN_SEE_IN_NOCTURNE(ch) (GET_OBTENEBRATION(ch) >= 2) #define CAN_SEE_IN_DARK_ROOM(ch, room) ((IS_LIGHT(room) || CAN_SEE_IN_DARK(ch)) && (!NOCTURNE_DARK(room) || CAN_SEE_IN_NOCTURNE(ch))) /* These three deprecated. */ #define WAIT_STATE(ch, cycle) do { GET_WAIT_STATE(ch) = (cycle); } while(0) #define CHECK_WAIT(ch) ((ch)->wait > 0) #define GET_MOB_WAIT(ch) GET_WAIT_STATE(ch) /* New, preferred macro. */ #define GET_WAIT_STATE(ch) ((ch)->wait) /* descriptor-based utils ************************************************/ #define STATE(d) ((d)->connected) /* object utils **********************************************************/ extern char *get_obj_desc(Object obj, Creature ch, int mode); extern Object obj_proto; #define GET_OBJ_NAME_BY_PROTO(rnum) obj_proto[(rnum)].short_description #define GET_OBJ_DESC(obj, ch, mode) get_obj_desc((obj), (ch), (mode)) #define GET_OBJ_TYPE(obj) ((obj)->obj_flags.type_flag) #define GET_OBJ_COST(obj) ((obj)->obj_flags.cost) #define GET_OBJ_RENT(obj) ((obj)->obj_flags.cost_per_day) #define GET_OBJ_EXTRA(obj) ((obj)->obj_flags.extra_flags) #define GET_OBJ_WEAR(obj) ((obj)->obj_flags.wear_flags) #define GET_OBJ_VAL(obj, val) ((obj)->obj_flags.value[(val)]) #define GET_OBJ_WEIGHT(obj) ((obj)->obj_flags.weight) #define GET_OBJ_TIMER(obj) ((obj)->obj_flags.timer) #define GET_OBJ_MATERIAL(obj) ((obj)->obj_flags.material) #define GET_OBJ_RNUM(obj) ((obj)->item_number) #define GET_OBJ_VNUM(obj) (GET_OBJ_RNUM(obj) >= 0 ? obj_index[GET_OBJ_RNUM(obj)].vnum : NOTHING) #define IS_OBJ_STAT(obj,stat) (IS_SET((obj)->obj_flags.extra_flags,stat)) #define IS_CORPSE(obj) (GET_OBJ_TYPE(obj) == ITEM_CORPSE) #define CAN_WEAR(obj, part) (IS_SET((obj)->obj_flags.wear_flags, (part))) #define IN_CHAIR(obj) ((obj)->sitting) #define GET_PULLED_BY(obj, i) (i == 0 ? (obj)->pulled_by1 : (obj)->pulled_by2) /* Sight notes */ #define NIGHTVIS(ch) (AFF_FLAGGED((ch), AFF_NIGHTVISION)) /* Is anyone carrying this object and if so, are they visible? */ #define CAN_SEE_OBJ_CARRIER(sub, obj) \ ((!obj->carried_by || CAN_SEE(sub, obj->carried_by)) && \ (!obj->worn_by || CAN_SEE(sub, obj->worn_by))) #define MORT_CAN_SEE_OBJ(sub, obj) \ ((LIGHT_OK(sub) || (SENSES_BONUS(sub) && obj->in_room == sub->in_room) || obj->worn_by == sub || obj->carried_by == sub) && CAN_SEE_OBJ_CARRIER(sub, obj)) #define CAN_SEE_OBJ(sub, obj) \ (MORT_CAN_SEE_OBJ(sub, obj) || (!IS_NPC(sub) && PRF_FLAGGED((sub), PRF_HOLYLIGHT))) #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_WEAR_TAKE) && CAN_CARRY_OBJ((ch),(obj)) && \ CAN_SEE_OBJ((ch),(obj))) #define OBJS(obj, vict) (CAN_SEE_OBJ((vict), (obj)) ? GET_OBJ_DESC((obj), vict, 1) : "something") /* personal utilities ***************************************************/ extern char *PERS(Creature ch, Creature vict, bool real); #define HSHR(ch) (MOB_FLAGGED((ch), MOB_PLURAL) ? "their" : (GET_SEX(ch) ? (GET_SEX(ch) == SEX_MALE ? "his":"her") :"its")) #define HSSH(ch) (MOB_FLAGGED((ch), MOB_PLURAL) ? "they" : (GET_SEX(ch) ? (GET_SEX(ch) == SEX_MALE ? "he" :"she") : "it")) #define HMHR(ch) (MOB_FLAGGED((ch), MOB_PLURAL) ? "them" : (GET_SEX(ch) ? (GET_SEX(ch) == SEX_MALE ? "him":"her") : "it")) #define ANA(obj) (strchr("aeiouyAEIOUY", *(obj)->name) ? "An" : "A") #define SANA(obj) (strchr("aeiouyAEIOUY", *(obj)->name) ? "an" : "a") /* Various macros building up to CAN_SEE ********************************/ #define LIGHT_OK(sub) (!AFF_FLAGGED(sub, AFF_BLIND) && \ (IS_LIGHT((sub)->in_room) || HAS_INFRA(sub))) #define INVIS_OK(sub, obj) ((!AFF_FLAGGED(obj, AFF_INVISIBLE)) && \ (!AFF_FLAGGED((obj), AFF_HIDE) || AFF_FLAGGED((sub), AFF_SENSE_HIDE))) #define CAN_SEE_UNSEEN(sub, obj) (DSC_FLAGGED(obj, DSC_UNSEEN_PRESENCE) ? (DSC_FLAGGED(sub, DSC_HEIGHTENED_SENSES) ? (GET_AUSPEX(sub) > GET_OBFUSCATE(obj) ? 1 : (GET_AUSPEX(sub) == GET_OBFUSCATE(obj) ? (ww_dice(GET_PERCEPTION(sub) + GET_TALENT(sub, TALENT_SUBTERFUGE), 7) > ww_dice(GET_MANIPULATION(obj) + GET_TALENT(obj, TALENT_SUBTERFUGE), 7) ? 1 : 0) : 0)) : 0) : 1) #define MORT_CAN_SEE(sub, obj) (((LIGHT_OK(sub) || (SENSES_BONUS(sub) && obj->in_room == sub->in_room)) && CAN_SEE_UNSEEN(sub, obj) && INVIS_OK(sub, obj)) && !AFF_FLAGGED(sub, AFF_BLIND)) #define MORT_CAN_SEE_NO_DARK(sub, obj) ((INVIS_OK(sub, obj)) && !AFF_FLAGGED(sub, AFF_BLIND)) #define IMM_CAN_SEE(sub, obj) \ (MORT_CAN_SEE(sub, obj) || (!IS_NPC(sub) && PRF_FLAGGED(sub, PRF_HOLYLIGHT))) #define IMM_CAN_SEE_NO_DARK(sub, obj) \ (MORT_CAN_SEE_NO_DARK(sub, obj) || (!IS_NPC(sub) && PRF_FLAGGED(sub, PRF_HOLYLIGHT))) #define SELF(sub, obj) ((sub) == (obj)) /* Can subject see character "obj"? */ #define CAN_SEE_DARK(sub, obj) (SELF(sub, obj) || \ ((GET_REAL_LEVEL(sub) >= (IS_NPC(obj) ? 0 : GET_INVIS_LEV(obj))) && \ IMM_CAN_SEE(sub, obj))) #define CAN_SEE_NO_DARK(sub, obj) (SELF(sub, obj) || \ ((GET_REAL_LEVEL(sub) >= (IS_NPC(obj) ? 0 : GET_INVIS_LEV(obj))) && \ IMM_CAN_SEE_NO_DARK(sub, obj))) #define CAN_SEE(sub, obj) (Global_ignore_dark ? CAN_SEE_NO_DARK(sub, obj) : CAN_SEE_DARK(sub, obj)) /* OS compatibility *****************************************************/ /* there could be some strange OS which doesn't have NULL... */ #ifndef NULL #define NULL (void *)0 #endif #if !defined(FALSE) #define FALSE 0 #endif #if !defined(TRUE) #define TRUE (!FALSE) #endif /* defines for fseek */ #ifndef SEEK_SET #define SEEK_SET 0 #define SEEK_CUR 1 #define SEEK_END 2 #endif /* * NOCRYPT can be defined by an implementor manually in sysdep.h. * EMPIRE_CRYPT is a variable that the 'configure' script * automatically sets when it determines whether or not the system is * capable of encrypting. */ #if defined(NOCRYPT) || !defined(EMPIRE_CRYPT) #define CRYPT(a, b) (a) #else #define CRYPT(a, b) ((char *) crypt((a),(b))) #endif #define ABSOLUTE(x) ((x < 0) ? (x * -1) : (x)) #define BOTCHED < 0 /* a result on a ww_dice roll was < 0 */ #define FAILED == 0 /* a result on a ww_dice roll was == 0 */ extern struct clan_data clan[]; extern struct discipline_data disc[]; /* Vampire related bonuses */ #define SENSES_BONUS(ch) (DSC_FLAGGED(ch, DSC_HEIGHTENED_SENSES) ? 2 : 0) #define CAN_SPEND_BLOOD(ch) (!DSC_FLAGGED(ch, DSC_CANT_SPEND_BLOOD)) #define CAN_SPEND_WILLPOWER(ch) (!DSC_FLAGGED(ch, DSC_CANT_SPEND_WILLPOWER)) /* Werewolf related stuff */ #define GET_BREED_FORM(ch) (GET_BREED(ch) == BREED_HOMID ? MORPH_NONE : (GET_BREED(ch) == BREED_METIS ? MORPH_CRINOS : MORPH_LUPUS)) /* Other */ #define SHOULD_APPEAR(ch) (AFF_FLAGGED(ch, AFF_HIDE | AFF_INVISIBLE) || DSC_FLAGGED(ch, DSC_UNSEEN_PRESENCE))