utils.h
1 /* ************************************************************************ 2 * File: utils.h Part of CircleMUD * 3 * Usage: header file: utility macros and prototypes of utility funcs * 4 * * 5 * All rights reserved. See license.doc for complete information. * 6 * * 7 * Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University * 8 * CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991. * 9 ************************************************************************ */ 10 11 12 /* external declarations and prototypes **********************************/ 13 14 extern struct weather_data weather_info; 15 extern FILE *logfile; 16 17 #define log basic_mud_log 18 19 #define READ_SIZE 256 20 21 /* public functions in utils.c */ 22 void basic_mud_log(const char *format, ...) __attribute__ ((format (printf, 1, 2))); 23 void basic_mud_vlog(const char *format, va_list args); 24 int touch(const char *path); 25 void mudlog(int type, int level, int file, const char *str, ...) __attribute__ ((format (printf, 4, 5))); 26 void log_death_trap(struct char_data *ch); 27 int rand_number(int from, int to); 28 int dice(int number, int size); 29 size_t sprintbit(bitvector_t vektor, const char *names[], char *result, size_t reslen); 30 size_t sprinttype(int type, const char *names[], char *result, size_t reslen); 31 int get_line(FILE *fl, char *buf); 32 int get_filename(char *filename, size_t fbufsize, int mode, const char *orig_name); 33 time_t mud_time_to_secs(struct time_info_data *now); 34 struct time_info_data *age(struct char_data *ch); 35 int num_pc_in_room(struct room_data *room); 36 void core_dump_real(const char *, int); 37 int room_is_dark(room_rnum room); 38 39 #define core_dump() core_dump_real(__FILE__, __LINE__) 40 41 /* 42 * Only provide our versions if one isn't in the C library. These macro names 43 * will be defined by sysdep.h if a strcasecmp or stricmp exists. 44 */ 45 #ifndef str_cmp 46 int str_cmp(const char *arg1, const char *arg2); 47 #endif 48 #ifndef strn_cmp 49 int strn_cmp(const char *arg1, const char *arg2, int n); 50 #endif 51 52 /* random functions in random.c */ 53 void circle_srandom(unsigned long initial_seed); 54 unsigned long circle_random(void); 55 56 /* undefine MAX and MIN so that our functions are used instead */ 57 #ifdef MAX 58 #undef MAX 59 #endif 60 61 #ifdef MIN 62 #undef MIN 63 #endif 64 65 int MAX(int a, int b); 66 int MIN(int a, int b); 67 char *CAP(char *txt); 68 69 /* Followers */ 70 int num_followers_charmed(struct char_data *ch); 71 void die_follower(struct char_data *ch); 72 void add_follower(struct char_data *ch, struct char_data *leader); 73 void stop_follower(struct char_data *ch); 74 bool circle_follow(struct char_data *ch, struct char_data *victim); 75 76 /* in act.informative.c */ 77 void look_at_room(struct char_data *ch, int mode); 78 79 /* in act.movmement.c */ 80 int do_simple_move(struct char_data *ch, int dir, int following); 81 int perform_move(struct char_data *ch, int dir, int following); 82 83 /* in limits.c */ 84 int mana_gain(struct char_data *ch); 85 int hit_gain(struct char_data *ch); 86 int move_gain(struct char_data *ch); 87 void advance_level(struct char_data *ch); 88 void set_title(struct char_data *ch, char *title); 89 void gain_exp(struct char_data *ch, int gain); 90 void gain_exp_regardless(struct char_data *ch, int gain); 91 void gain_condition(struct char_data *ch, int condition, int value); 92 void check_idling(struct char_data *ch); 93 void point_update(void); 94 void update_pos(struct char_data *victim); 95 96 97 /* various constants *****************************************************/ 98 99 /* defines for mudlog() */ 100 #define OFF 0 101 #define BRF 1 102 #define NRM 2 103 #define CMP 3 104 105 /* get_filename() */ 106 #define CRASH_FILE 0 107 #define ETEXT_FILE 1 108 #define ALIAS_FILE 2 109 110 /* breadth-first searching */ 111 #define BFS_ERROR (-1) 112 #define BFS_ALREADY_THERE (-2) 113 #define BFS_NO_PATH (-3) 114 115 /* 116 * XXX: These constants should be configurable. See act.informative.c 117 * and utils.c for other places to change. 118 */ 119 /* mud-life time */ 120 #define SECS_PER_MUD_HOUR 75 121 #define SECS_PER_MUD_DAY (24*SECS_PER_MUD_HOUR) 122 #define SECS_PER_MUD_MONTH (35*SECS_PER_MUD_DAY) 123 #define SECS_PER_MUD_YEAR (17*SECS_PER_MUD_MONTH) 124 125 /* real-life time (remember Real Life?) */ 126 #define SECS_PER_REAL_MIN 60 127 #define SECS_PER_REAL_HOUR (60*SECS_PER_REAL_MIN) 128 #define SECS_PER_REAL_DAY (24*SECS_PER_REAL_HOUR) 129 #define SECS_PER_REAL_YEAR (365*SECS_PER_REAL_DAY) 130 131 132 /* string utils **********************************************************/ 133 134 135 #define YESNO(a) ((a) ? "YES" : "NO") 136 #define ONOFF(a) ((a) ? "ON" : "OFF") 137 138 #define LOWER(c) (((c)>='A' && (c) <= 'Z') ? ((c)+('a'-'A')) : (c)) 139 #define UPPER(c) (((c)>='a' && (c) <= 'z') ? ((c)+('A'-'a')) : (c) ) 140 141 #define ISNEWL(ch) ((ch) == '\n' || (ch) == '\r') 142 143 /* See also: ANA, SANA */ 144 #define AN(string) (strchr("aeiouAEIOU", *string) ? "an" : "a") 145 146 147 /* memory utils **********************************************************/ 148 149 150 #define CREATE(result, type, number) do {\ 151 if ((number) * sizeof(type) <= 0) \ 152 log("SYSERR: Zero bytes or less requested at %s:%d.", __FILE__, __LINE__); \ 153 if (!((result) = (type *) calloc ((number), sizeof(type)))) \ 154 { perror("SYSERR: malloc failure"); abort(); } } while(0) 155 156 #define RECREATE(result,type,number) do {\ 157 if (!((result) = (type *) realloc ((result), sizeof(type) * (number))))\ 158 { perror("SYSERR: realloc failure"); abort(); } } while(0) 159 160 /* 161 * the source previously used the same code in many places to remove an item 162 * from a list: if it's the list head, change the head, else traverse the 163 * list looking for the item before the one to be removed. Now, we have a 164 * macro to do this. To use, just make sure that there is a variable 'temp' 165 * declared as the same type as the list to be manipulated. BTW, this is 166 * a great application for C++ templates but, alas, this is not C++. Maybe 167 * CircleMUD 4.0 will be... 168 */ 169 #define REMOVE_FROM_LIST(item, head, next) \ 170 if ((item) == (head)) \ 171 head = (item)->next; \ 172 else { \ 173 temp = head; \ 174 while (temp && (temp->next != (item))) \ 175 temp = temp->next; \ 176 if (temp) \ 177 temp->next = (item)->next; \ 178 } \ 179 180 181 /* basic bitvector utils *************************************************/ 182 183 184 #define IS_SET(flag,bit) ((flag) & (bit)) 185 #define SET_BIT(var,bit) ((var) |= (bit)) 186 #define REMOVE_BIT(var,bit) ((var) &= ~(bit)) 187 #define TOGGLE_BIT(var,bit) ((var) ^= (bit)) 188 189 /* 190 * Accessing player specific data structures on a mobile is a very bad thing 191 * to do. Consider that changing these variables for a single mob will change 192 * it for every other single mob in the game. If we didn't specifically check 193 * for it, 'wimpy' would be an extremely bad thing for a mob to do, as an 194 * example. If you really couldn't care less, change this to a '#if 0'. 195 */ 196 #if 1 197 /* Subtle bug in the '#var', but works well for now. */ 198 #define CHECK_PLAYER_SPECIAL(ch, var) \ 199 (*(((ch)->player_specials == &dummy_mob) ? (log("SYSERR: Mob using '"#var"' at %s:%d.", __FILE__, __LINE__), &(var)) : &(var))) 200 #else 201 #define CHECK_PLAYER_SPECIAL(ch, var) (var) 202 #endif 203 204 #define MOB_FLAGS(ch) ((ch)->char_specials.saved.act) 205 #define PLR_FLAGS(ch) ((ch)->char_specials.saved.act) 206 #define PRF_FLAGS(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.pref)) 207 #define AFF_FLAGS(ch) ((ch)->char_specials.saved.affected_by) 208 #define ROOM_FLAGS(loc) (world[(loc)].room_flags) 209 #define SPELL_ROUTINES(spl) (spell_info[spl].routines) 210 211 /* 212 * See http://www.circlemud.org/~greerga/todo/todo.009 to eliminate MOB_ISNPC. 213 * IS_MOB() acts as a VALID_MOB_RNUM()-like function. 214 */ 215 #define IS_NPC(ch) (IS_SET(MOB_FLAGS(ch), MOB_ISNPC)) 216 #define IS_MOB(ch) (IS_NPC(ch) && GET_MOB_RNUM(ch) <= top_of_mobt && \ 217 GET_MOB_RNUM(ch) != NOBODY) 218 219 #define MOB_FLAGGED(ch, flag) (IS_NPC(ch) && IS_SET(MOB_FLAGS(ch), (flag))) 220 #define PLR_FLAGGED(ch, flag) (!IS_NPC(ch) && IS_SET(PLR_FLAGS(ch), (flag))) 221 #define AFF_FLAGGED(ch, flag) (IS_SET(AFF_FLAGS(ch), (flag))) 222 #define PRF_FLAGGED(ch, flag) (IS_SET(PRF_FLAGS(ch), (flag))) 223 #define ROOM_FLAGGED(loc, flag) (IS_SET(ROOM_FLAGS(loc), (flag))) 224 #define EXIT_FLAGGED(exit, flag) (IS_SET((exit)->exit_info, (flag))) 225 #define OBJAFF_FLAGGED(obj, flag) (IS_SET(GET_OBJ_AFFECT(obj), (flag))) 226 #define OBJVAL_FLAGGED(obj, flag) (IS_SET(GET_OBJ_VAL((obj), 1), (flag))) 227 #define OBJWEAR_FLAGGED(obj, flag) (IS_SET(GET_OBJ_WEAR(obj), (flag))) 228 #define OBJ_FLAGGED(obj, flag) (IS_SET(GET_OBJ_EXTRA(obj), (flag))) 229 #define HAS_SPELL_ROUTINE(spl, flag) (IS_SET(SPELL_ROUTINES(spl), (flag))) 230 231 /* IS_AFFECTED for backwards compatibility */ 232 #define IS_AFFECTED(ch, skill) (AFF_FLAGGED((ch), (skill))) 233 234 #define PLR_TOG_CHK(ch,flag) ((TOGGLE_BIT(PLR_FLAGS(ch), (flag))) & (flag)) 235 #define PRF_TOG_CHK(ch,flag) ((TOGGLE_BIT(PRF_FLAGS(ch), (flag))) & (flag)) 236 237 238 /* room utils ************************************************************/ 239 240 241 #define SECT(room) (VALID_ROOM_RNUM(room) ? \ 242 world[(room)].sector_type : SECT_INSIDE) 243 244 #define IS_DARK(room) room_is_dark((room)) 245 #define IS_LIGHT(room) (!IS_DARK(room)) 246 247 #define VALID_ROOM_RNUM(rnum) ((rnum) != NOWHERE && (rnum) <= top_of_world) 248 #define GET_ROOM_VNUM(rnum) \ 249 ((room_vnum)(VALID_ROOM_RNUM(rnum) ? world[(rnum)].number : NOWHERE)) 250 #define GET_ROOM_SPEC(room) \ 251 (VALID_ROOM_RNUM(room) ? world[(room)].func : NULL) 252 253 254 /* char utils ************************************************************/ 255 256 257 #define IN_ROOM(ch) ((ch)->in_room) 258 #define GET_WAS_IN(ch) ((ch)->was_in_room) 259 #define GET_AGE(ch) (age(ch)->year) 260 261 #define GET_PC_NAME(ch) ((ch)->player.name) 262 #define GET_NAME(ch) (IS_NPC(ch) ? \ 263 (ch)->player.short_descr : GET_PC_NAME(ch)) 264 #define GET_TITLE(ch) ((ch)->player.title) 265 #define GET_LEVEL(ch) ((ch)->player.level) 266 #define GET_PASSWD(ch) ((ch)->player.passwd) 267 #define GET_PFILEPOS(ch)((ch)->pfilepos) 268 269 /* 270 * I wonder if this definition of GET_REAL_LEVEL should be the definition 271 * of GET_LEVEL? JE 272 */ 273 #define GET_REAL_LEVEL(ch) \ 274 (ch->desc && ch->desc->original ? GET_LEVEL(ch->desc->original) : \ 275 GET_LEVEL(ch)) 276 277 #define GET_CLASS(ch) ((ch)->player.chclass) 278 #define GET_HOME(ch) ((ch)->player.hometown) 279 #define GET_HEIGHT(ch) ((ch)->player.height) 280 #define GET_WEIGHT(ch) ((ch)->player.weight) 281 #define GET_SEX(ch) ((ch)->player.sex) 282 283 #define GET_STR(ch) ((ch)->aff_abils.str) 284 #define GET_ADD(ch) ((ch)->aff_abils.str_add) 285 #define GET_DEX(ch) ((ch)->aff_abils.dex) 286 #define GET_INT(ch) ((ch)->aff_abils.intel) 287 #define GET_WIS(ch) ((ch)->aff_abils.wis) 288 #define GET_CON(ch) ((ch)->aff_abils.con) 289 #define GET_CHA(ch) ((ch)->aff_abils.cha) 290 291 #define GET_EXP(ch) ((ch)->points.exp) 292 #define GET_AC(ch) ((ch)->points.armor) 293 #define GET_HIT(ch) ((ch)->points.hit) 294 #define GET_MAX_HIT(ch) ((ch)->points.max_hit) 295 #define GET_MOVE(ch) ((ch)->points.move) 296 #define GET_MAX_MOVE(ch) ((ch)->points.max_move) 297 #define GET_MANA(ch) ((ch)->points.mana) 298 #define GET_MAX_MANA(ch) ((ch)->points.max_mana) 299 #define GET_GOLD(ch) ((ch)->points.gold) 300 #define GET_BANK_GOLD(ch) ((ch)->points.bank_gold) 301 #define GET_HITROLL(ch) ((ch)->points.hitroll) 302 #define GET_DAMROLL(ch) ((ch)->points.damroll) 303 304 #define GET_POS(ch) ((ch)->char_specials.position) 305 #define GET_IDNUM(ch) ((ch)->char_specials.saved.idnum) 306 #define IS_CARRYING_W(ch) ((ch)->char_specials.carry_weight) 307 #define IS_CARRYING_N(ch) ((ch)->char_specials.carry_items) 308 #define FIGHTING(ch) ((ch)->char_specials.fighting) 309 #define HUNTING(ch) ((ch)->char_specials.hunting) 310 #define GET_SAVE(ch, i) ((ch)->char_specials.saved.apply_saving_throw[i]) 311 #define GET_ALIGNMENT(ch) ((ch)->char_specials.saved.alignment) 312 313 #define GET_COND(ch, i) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.conditions[(i)])) 314 #define GET_LOADROOM(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.load_room)) 315 #define GET_PRACTICES(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.spells_to_learn)) 316 #define GET_INVIS_LEV(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.invis_level)) 317 #define GET_WIMP_LEV(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.wimp_level)) 318 #define GET_FREEZE_LEV(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.freeze_level)) 319 #define GET_BAD_PWS(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.bad_pws)) 320 #define GET_TALK(ch, i) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.talks[i])) 321 #define POOFIN(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->poofin)) 322 #define POOFOUT(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->poofout)) 323 #define GET_LAST_OLC_TARG(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->last_olc_targ)) 324 #define GET_LAST_OLC_MODE(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->last_olc_mode)) 325 #define GET_ALIASES(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->aliases)) 326 #define GET_LAST_TELL(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->last_tell)) 327 328 #define GET_SKILL(ch, i) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.skills[i])) 329 #define SET_SKILL(ch, i, pct) do { CHECK_PLAYER_SPECIAL((ch), (ch)->player_specials->saved.skills[i]) = pct; } while(0) 330 331 #define GET_EQ(ch, i) ((ch)->equipment[i]) 332 333 #define GET_MOB_SPEC(ch) (IS_MOB(ch) ? mob_index[(ch)->nr].func : NULL) 334 #define GET_MOB_RNUM(mob) ((mob)->nr) 335 #define GET_MOB_VNUM(mob) (IS_MOB(mob) ? \ 336 mob_index[GET_MOB_RNUM(mob)].vnum : NOBODY) 337 338 #define GET_DEFAULT_POS(ch) ((ch)->mob_specials.default_pos) 339 #define MEMORY(ch) ((ch)->mob_specials.memory) 340 341 #define STRENGTH_APPLY_INDEX(ch) \ 342 ( ((GET_ADD(ch)==0) || (GET_STR(ch) != 18)) ? GET_STR(ch) :\ 343 (GET_ADD(ch) <= 50) ? 26 :( \ 344 (GET_ADD(ch) <= 75) ? 27 :( \ 345 (GET_ADD(ch) <= 90) ? 28 :( \ 346 (GET_ADD(ch) <= 99) ? 29 : 30 ) ) ) \ 347 ) 348 349 #define CAN_CARRY_W(ch) (str_app[STRENGTH_APPLY_INDEX(ch)].carry_w) 350 #define CAN_CARRY_N(ch) (5 + (GET_DEX(ch) >> 1) + (GET_LEVEL(ch) >> 1)) 351 #define AWAKE(ch) (GET_POS(ch) > POS_SLEEPING) 352 #define CAN_SEE_IN_DARK(ch) \ 353 (AFF_FLAGGED(ch, AFF_INFRAVISION) || (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_HOLYLIGHT))) 354 355 #define IS_GOOD(ch) (GET_ALIGNMENT(ch) >= 350) 356 #define IS_EVIL(ch) (GET_ALIGNMENT(ch) <= -350) 357 #define IS_NEUTRAL(ch) (!IS_GOOD(ch) && !IS_EVIL(ch)) 358 359 360 /* These three deprecated. */ 361 #define WAIT_STATE(ch, cycle) do { GET_WAIT_STATE(ch) = (cycle); } while(0) 362 #define CHECK_WAIT(ch) ((ch)->wait > 0) 363 #define GET_MOB_WAIT(ch) GET_WAIT_STATE(ch) 364 /* New, preferred macro. */ 365 #define GET_WAIT_STATE(ch) ((ch)->wait) 366 367 368 /* descriptor-based utils ************************************************/ 369 370 /* Hrm, not many. We should make more. -gg 3/4/99 */ 371 #define STATE(d) ((d)->connected) 372 373 374 /* object utils **********************************************************/ 375 376 /* 377 * Check for NOWHERE or the top array index? 378 * If using unsigned types, the top array index will catch everything. 379 * If using signed types, NOTHING will catch the majority of bad accesses. 380 */ 381 #define VALID_OBJ_RNUM(obj) (GET_OBJ_RNUM(obj) <= top_of_objt && \ 382 GET_OBJ_RNUM(obj) != NOTHING) 383 384 #define GET_OBJ_TYPE(obj) ((obj)->obj_flags.type_flag) 385 #define GET_OBJ_COST(obj) ((obj)->obj_flags.cost) 386 #define GET_OBJ_RENT(obj) ((obj)->obj_flags.cost_per_day) 387 #define GET_OBJ_AFFECT(obj) ((obj)->obj_flags.bitvector) 388 #define GET_OBJ_EXTRA(obj) ((obj)->obj_flags.extra_flags) 389 #define GET_OBJ_WEAR(obj) ((obj)->obj_flags.wear_flags) 390 #define GET_OBJ_VAL(obj, val) ((obj)->obj_flags.value[(val)]) 391 #define GET_OBJ_WEIGHT(obj) ((obj)->obj_flags.weight) 392 #define GET_OBJ_TIMER(obj) ((obj)->obj_flags.timer) 393 #define GET_OBJ_RNUM(obj) ((obj)->item_number) 394 #define GET_OBJ_VNUM(obj) (VALID_OBJ_RNUM(obj) ? \ 395 obj_index[GET_OBJ_RNUM(obj)].vnum : NOTHING) 396 #define GET_OBJ_SPEC(obj) (VALID_OBJ_RNUM(obj) ? \ 397 obj_index[GET_OBJ_RNUM(obj)].func : NULL) 398 399 #define IS_CORPSE(obj) (GET_OBJ_TYPE(obj) == ITEM_CONTAINER && \ 400 GET_OBJ_VAL((obj), 3) == 1) 401 402 #define CAN_WEAR(obj, part) OBJWEAR_FLAGGED((obj), (part)) 403 404 405 /* compound utilities and other macros **********************************/ 406 407 /* 408 * Used to compute CircleMUD version. To see if the code running is newer 409 * than 3.0pl13, you would use: #if _CIRCLEMUD > CIRCLEMUD_VERSION(3,0,13) 410 */ 411 #define CIRCLEMUD_VERSION(major, minor, patchlevel) \ 412 (((major) << 16) + ((minor) << 8) + (patchlevel)) 413 414 #define HSHR(ch) (GET_SEX(ch) ? (GET_SEX(ch)==SEX_MALE ? "his":"her") :"its") 415 #define HSSH(ch) (GET_SEX(ch) ? (GET_SEX(ch)==SEX_MALE ? "he" :"she") : "it") 416 #define HMHR(ch) (GET_SEX(ch) ? (GET_SEX(ch)==SEX_MALE ? "him":"her") : "it") 417 418 #define ANA(obj) (strchr("aeiouAEIOU", *(obj)->name) ? "An" : "A") 419 #define SANA(obj) (strchr("aeiouAEIOU", *(obj)->name) ? "an" : "a") 420 421 422 /* Various macros building up to CAN_SEE */ 423 424 #define LIGHT_OK(sub) (!AFF_FLAGGED(sub, AFF_BLIND) && \ 425 (IS_LIGHT(IN_ROOM(sub)) || AFF_FLAGGED((sub), AFF_INFRAVISION))) 426 427 #define INVIS_OK(sub, obj) \ 428 ((!AFF_FLAGGED((obj),AFF_INVISIBLE) || AFF_FLAGGED(sub,AFF_DETECT_INVIS)) && \ 429 (!AFF_FLAGGED((obj), AFF_HIDE) || AFF_FLAGGED(sub, AFF_SENSE_LIFE))) 430 431 #define MORT_CAN_SEE(sub, obj) (LIGHT_OK(sub) && INVIS_OK(sub, obj)) 432 433 #define IMM_CAN_SEE(sub, obj) \ 434 (MORT_CAN_SEE(sub, obj) || (!IS_NPC(sub) && PRF_FLAGGED(sub, PRF_HOLYLIGHT))) 435 436 #define SELF(sub, obj) ((sub) == (obj)) 437 438 /* Can subject see character "obj"? */ 439 #define CAN_SEE(sub, obj) (SELF(sub, obj) || \ 440 ((GET_REAL_LEVEL(sub) >= (IS_NPC(obj) ? 0 : GET_INVIS_LEV(obj))) && \ 441 IMM_CAN_SEE(sub, obj))) 442 443 /* End of CAN_SEE */ 444 445 446 #define INVIS_OK_OBJ(sub, obj) \ 447 (!OBJ_FLAGGED((obj), ITEM_INVISIBLE) || AFF_FLAGGED((sub), AFF_DETECT_INVIS)) 448 449 /* Is anyone carrying this object and if so, are they visible? */ 450 #define CAN_SEE_OBJ_CARRIER(sub, obj) \ 451 ((!obj->carried_by || CAN_SEE(sub, obj->carried_by)) && \ 452 (!obj->worn_by || CAN_SEE(sub, obj->worn_by))) 453 454 #define MORT_CAN_SEE_OBJ(sub, obj) \ 455 (LIGHT_OK(sub) && INVIS_OK_OBJ(sub, obj) && CAN_SEE_OBJ_CARRIER(sub, obj)) 456 457 #define CAN_SEE_OBJ(sub, obj) \ 458 (MORT_CAN_SEE_OBJ(sub, obj) || (!IS_NPC(sub) && PRF_FLAGGED((sub), PRF_HOLYLIGHT))) 459 460 #define CAN_CARRY_OBJ(ch,obj) \ 461 (((IS_CARRYING_W(ch) + GET_OBJ_WEIGHT(obj)) <= CAN_CARRY_W(ch)) && \ 462 ((IS_CARRYING_N(ch) + 1) <= CAN_CARRY_N(ch))) 463 464 #define CAN_GET_OBJ(ch, obj) \ 465 (CAN_WEAR((obj), ITEM_WEAR_TAKE) && CAN_CARRY_OBJ((ch),(obj)) && \ 466 CAN_SEE_OBJ((ch),(obj))) 467 468 #define PERS(ch, vict) (CAN_SEE(vict, ch) ? GET_NAME(ch) : "someone") 469 470 #define OBJS(obj, vict) (CAN_SEE_OBJ((vict), (obj)) ? \ 471 (obj)->short_description : "something") 472 473 #define OBJN(obj, vict) (CAN_SEE_OBJ((vict), (obj)) ? \ 474 fname((obj)->name) : "something") 475 476 477 #define EXIT(ch, door) (world[IN_ROOM(ch)].dir_option[door]) 478 479 #define CAN_GO(ch, door) (EXIT(ch,door) && \ 480 (EXIT(ch,door)->to_room != NOWHERE) && \ 481 !IS_SET(EXIT(ch, door)->exit_info, EX_CLOSED)) 482 483 484 #define CLASS_ABBR(ch) (IS_NPC(ch) ? "--" : class_abbrevs[(int)GET_CLASS(ch)]) 485 486 #define IS_MAGIC_USER(ch) (!IS_NPC(ch) && \ 487 (GET_CLASS(ch) == CLASS_MAGIC_USER)) 488 #define IS_CLERIC(ch) (!IS_NPC(ch) && \ 489 (GET_CLASS(ch) == CLASS_CLERIC)) 490 #define IS_THIEF(ch) (!IS_NPC(ch) && \ 491 (GET_CLASS(ch) == CLASS_THIEF)) 492 #define IS_WARRIOR(ch) (!IS_NPC(ch) && \ 493 (GET_CLASS(ch) == CLASS_WARRIOR)) 494 495 #define OUTSIDE(ch) (!ROOM_FLAGGED(IN_ROOM(ch), ROOM_INDOORS)) 496 497 498 /* OS compatibility ******************************************************/ 499 500 501 /* there could be some strange OS which doesn't have NULL... */ 502 #ifndef NULL 503 #define NULL (void *)0 504 #endif 505 506 #if !defined(FALSE) 507 #define FALSE 0 508 #endif 509 510 #if !defined(TRUE) 511 #define TRUE (!FALSE) 512 #endif 513 514 /* defines for fseek */ 515 #ifndef SEEK_SET 516 #define SEEK_SET 0 517 #define SEEK_CUR 1 518 #define SEEK_END 2 519 #endif 520 521 /* 522 * NOCRYPT can be defined by an implementor manually in sysdep.h. 523 * CIRCLE_CRYPT is a variable that the 'configure' script 524 * automatically sets when it determines whether or not the system is 525 * capable of encrypting. 526 */ 527 #if defined(NOCRYPT) || !defined(CIRCLE_CRYPT) 528 #define CRYPT(a,b) (a) 529 #else 530 #define CRYPT(a,b) ((char *) crypt((a),(b))) 531 #endif 532