#define ROOMS_C #include "kernel.h" #include <stdlib.h> #include <string.h> #include <strings.h> #include "exitnames.h" #include "lflags.h" #include "rooms.h" #include "mobile.h" #include "sendsys.h" #include "sflags.h" #include "pflags.h" #include "cflags.h" #include "oflags.h" #include "calendar.h" #include "objsys.h" #include "zones.h" #include "bprintf.h" #include "parse.h" #include "fight.h" #include "uaf.h" #include "special.h" /* A room's short description (title) */ char *sdesc (int room) { return exists (room) ? lshort (room) : "Where no man has gone before"; } /* A room's long description */ char *ldesc (int room) { return exists (room) ? llong (room) : ""; } int getexit (int room, int ex) { return lexit (room, ex); } /* Set the <dir>-most exit in <room> to <dest>. * Return False if the new exit was a room which didn't exist. */ void setexit (int room, int dir, int dest) { int i, n; if (exists (lexit (room, dir))) { for (i = n = 0; i < NEXITS && n <= 1; i++) if (lexit (room, i) == lexit (room, dir)) ++n; /* If we are removing the only exit to that room from this: */ if (n == 1) remove_int (room, lexits_to_me (lexit (room, dir))); } if (exists (dest)) add_int (room, lexits_to_me (dest)); lexit (room, dir) = dest; ltouched (room) = True; } /* * return the room number an object is in * even if it is carried by someone or in something * [code by Twizzly, July 1995] */ int roomobjin(int o) { int i; i = oloc(o); while( ocarrf(o) == IN_CONTAINER) /* work our way out of the container */ { o = i; i = oloc(o); } if( ocarrf(o) != IN_ROOM){ return(ploc(i)); } return i; } /* Get a random exit direction from a location, or -1 if none exists. * Used in things like moving mobiles and flee-code */ int get_rand_exit_dir (int room) { int i, ex[NEXITS], newch, n_exits = 0; for (i = 0; i < NEXITS; i++) { if (!exists (lexit (room, i)) && (lexit (room, i) < DOOR || lexit (room, i) >= EDOOR)) continue; if (!exists (newch = lexit (room, i))) { if (state (newch -= DOOR) > 0) continue; else newch = obj_loc (olinked (newch)); } ex[n_exits++] = i; } return n_exits == 0 ? -1 : ex[MY_RANDOM () % n_exits]; } void get_exit_locs_from(int loc, int *loctable, Boolean through_doors) { int i, newch,drnum,droff; for (i = 0; i < NEXITS; i++) { newch = getexit (loc, i); if (newch >= DOOR && newch < EDOOR) { /* look through special exits */ drnum = newch - DOOR; droff = olinked (drnum); /*other side */ if (!state (drnum) || through_doors) newch = obj_loc (droff); } loctable[i] = newch; } } Boolean checklevel (int player, int room) { if (ltstflg(room, LFL_WIZONLY) && (plev(player) < LVL_APPREN)) { sendf(player, "I'm sorry, that room is reserved for Immortals.\n"); return False; } if (ltstflg(room, LFL_AWIZONLY) && (plev(player) < LVL_ARCHWIZARD)) { sendf(player, "I'm sorry, that room is reserved for Powers.\n"); return False; } if (ltstflg(room, LFL_DGODONLY) && (plev(player) < LVL_DEMI)) { sendf(player, "I'm sorry, that room is reserved for Dgod and up.\n"); return False; } if (ltstflg(room, LFL_GODONLY) && (plev(player) < LVL_GOD)) { sendf(player, "I'm sorry, that room is reserved for God and up.\n"); return False; } return True; } /* Get a random exit (the room itself) from a location, or 0 if none exists. * Note: This differs from get_rand_exit_dir in that this already returns the * exit location, while get_rand_exit_dir return the direction. */ int get_rand_exit (int room) { int newch; int i = get_rand_exit_dir (room); if (i == -1) return 0; newch = lexit (room, i); return !exists (newch) ? obj_loc (olinked (newch - DOOR)) : newch; } int count_players (int loc, int min_lvl, int max_lvl, int flags) { /* Count number of players in a room */ /* loc == 0 is legal and signify all rooms */ int plx; int count = 0; int pla, plb; Boolean i; pla = ((flags & COUNT_PLAYERS) != 0) ? 0 : max_players; plb = ((flags & COUNT_MOBILES) != 0) ? numchars : max_players; i = ((flags & INVERT_LEVELS) != 0); for (plx = pla; plx < plb; plx++) { if ((loc == 0 || ploc (plx) == loc) && !EMPTY (pname (plx))) { if (plx >= max_players || ((plev (plx) >= min_lvl && plev (plx) < max_lvl) != i)) { ++count; } } } return count; } void gotocom (Boolean tiptoe) { char xx[SETIN_MAX+100]; int a, pc; if (!ptstflg (mynum, PFL_GOTO)) { erreval (); return; } if (ltstflg(ploc(mynum),LFL_JAIL) && (plev(mynum) < LVL_ARCHWIZARD) ) { bprintf("Just where do you think you are going??\n"); erreval(); return; } if (brkword () == -1) { if (!exists (a = find_loc_by_id (phome (mynum)))) { bprintf("Goto where?\n"); return; } } else if ((a = findroomnum (wordbuf)) == 0) { bprintf ("Unknown Player, object or room\n"); return; } if (ltstflg(a,LFL_JAIL) && (plev(mynum) < LVL_ARCHWIZARD) ) { bprintf("I don't think that will be a good idea.\n"); return; } if (!checklevel(mynum,a)) return; if (!has_access_to(mynum,a,-1)) { bprintf("You can't transport to unknown grounds.\n"); return; } if (plev (mynum) < LVL_GOD) { if (ltstflg (a, LFL_PRIVATE)) { pc = count_players (a, LVL_MIN, LVL_MAX, COUNT_PLAYERS | COUNT_MOBILES); if (pc > 1) { bprintf ("I'm sorry. There's a private conference in that location.\n"); return; } } } if (rom_fun(a) != NULL) { param_s.plx = mynum; param_s.loc = a; param_s.ret = 1; rom_fun(a)(E_ONENTRY); if (param_s.ret != 1) return; } if (!tiptoe) send_msg (ploc (mynum), 0, pvis (mynum), LVL_MAX, mynum, NOBODY, "%s\n", build_setin (mynum,xx, cur_player->setmout, pname (mynum), NULL)); setploc (mynum, a); trapch (a); if (!tiptoe) send_msg (ploc (mynum), 0, pvis (mynum), LVL_MAX, mynum, NOBODY, "%s\n", build_setin (mynum,xx, cur_player->setmin, pname (mynum), NULL)); } int exists (int room) { return (room < 0 && convroom (room) < numloc); } /* The EXITS command */ A_COMMAND(exitcom) { show_exits(True); } void show_exits(Boolean check_line) { int a, v, newch; /* int drnum, droff;*/ int b = 0; char st[120]; int e[NEXITS]; Boolean shortexits; int room, exit = 0; Boolean gotroom = False, gotexit = False, gotarg; if (!check_line) { gotarg = False; room = ploc(mynum); } else { room = !(gotarg = (brkword () != -1)) ? ploc (mynum) : find_loc_by_name (wordbuf); } if (gotarg && !ptstflg (mynum, PFL_GOTO)) { bprintf ("You aren't powerful enough to give arguments to EXITS.\n"); return; } gotroom = exists (room); if (!gotroom && !(gotexit = ((exit = tlookup (wordbuf, Exits)) != -1))) { bprintf ("Non-existant room or exit.\n"); return; } if (!gotexit && brkword () == -1) { if (r_isdark (room, mynum)) { bprintf ("It is dark.....\n"); return; } shortexits = ststflg(mynum,SFL_SHORTEXIT); get_exit_locs_from(room,e,False); b = 0; bprintf ("&+wObvious exits are: &*"); for (a = 0; a < NEXITS; a++) { if (e[a] >= 0) continue; if (shortexits) bprintf("&+w%s ",Exits[a]); else if (plev (mynum) < LVL_APPREN || (ltstflg(ploc(mynum), LFL_MAZE) && plev(mynum) < LVL_ARCHWIZARD)) bprintf ("\n&+w[&+w%-9.9s&+w] &+w: &+w%s", Exits[a], sdesc (e[a])); else { v = findzone (e[a], st); bprintf ("\n&+w[&+w%-9.9s&+w] &+w%-50s : %s%d", Exits[a], sdesc (e[a]), st, v); } b = 1; } if (b == 0) { if (!shortexits) bprintf("\n"); bprintf ("None...."); } bprintf("\n"); return; } if (!gotroom) room = ploc (mynum); if (ltstflg(room,LFL_JAIL) && plev(mynum) < LVL_ARCHWIZARD) { bprintf ("If only that was true...\n"); return; } if (lpermanent (room) && !ptstflg (mynum, PFL_ROOM)) { bprintf ("Your are only powerful enough to change exits on\n" "non-permanent (wizard-created) rooms.\n"); return; } if (!gotexit && (exit = tlookup (wordbuf, Exits)) == -1) { bprintf ("Illegal exit-name, use north, east, etc...\n"); return; } if (brkword () == -1) newch = 0; else if (!exists (newch = find_loc_by_name (wordbuf))) { bprintf ("I don't know that destination.\n"); return; } setexit (room, exit, newch); bprintf ("Exit %s from %s is now %s.\n", Exits[exit], sdesc (room), (newch == 0) ? "removed" : sdesc (newch)); } /* Is a room dark or not? It's dark if the Lflag DARK is set but * not if there is someone in the room carrying somthing lit. */ Boolean roomdark (int room) { int i, j; /* if there is a lit wiz in the room, it is light */ for (i=0; i< lnumchars(room); i++) if (ststflg( lmob_nr(i,room), SFL_GLOWING)) return False; /* if LFL_LIGHT, it is never dark */ if (check_light(room) == LFL_LIGHT) /* if (lmaskflg(room,LFL_L_MASK) == LFL_LIGHT) */ return False; /* if REALTIME and not night, it is light */ if (ltstflg (room, LFL_REALTIME) && !is_real_dark ()) return False; for (i = 0; i < lnumobs (room); i++) { if ((otstbit (lobj_nr (i, room), OFL_LIT) || otstbit (lobj_nr (i, room), OFL_MAGICLIT)) && !otstbit (lobj_nr (i, room), OFL_DESTROYED)) return False; } for (i = 0; i < lnumchars (room); i++) { for (j = 0; j < pnumobs (lmob_nr (i, room)); j++) { if ((otstbit (pobj_nr (j, lmob_nr (i, room)), OFL_LIT) || otstbit (pobj_nr (j, lmob_nr (i, room)), OFL_MAGICLIT)) && !otstbit (pobj_nr (j, lmob_nr (i, room)), OFL_DESTROYED)) return False; } } return True; } /* Determine if a player can see in a room or not. Same as above with the * difference that if they are wiz, they will allways be able to see. */ Boolean r_isdark (int room, int plr) { return roomdark (room) && plev (plr) < LVL_APPREN; } Boolean isdark () { return r_isdark (ploc (mynum), mynum); } void teletrap (int newch) { if (ltstflg(ploc(mynum),LFL_JAIL) && (plev(mynum) < LVL_ARCHWIZARD)) { bprintf("For some reason, you are still in jail.\n"); return; } send_msg (ploc (mynum), 0, pvis (mynum), LVL_MAX, mynum, NOBODY, "%s has left.\n", pname (mynum)); send_msg (newch, 0, pvis (mynum), LVL_MAX, mynum, NOBODY, "%s has arrived.\n", pname (mynum)); stp = 0; strbuf[stp] = '\0'; trapch (newch); } Boolean trapch (int loc) { stp = 0; strbuf[stp] = '\0' ; /* Exits bug fix */ setploc (mynum, loc); lookin (loc, 0); if (ltstflg (loc, LFL_DEATH)) { if (plev (mynum) < LVL_APPREN) { send_msg(DEST_ALL,MODE_QUIET|MODE_BRACKET,Max(pvis(mynum),LVL_APPREN),LVL_MAX, mynum,NOBODY,"%s has found a death room", pname(mynum)); up_pdied(mynum); crapup ("\t\tYou seem to have died...", CRAP_SAVE); return False; } } if (pfighting (mynum) >= 0 && ploc (mynum) != ploc (pfighting (mynum))) setpfighting (mynum, -1); return True; } void lookin (int loc, int showfl) { int dark = isdark(); if (ststflg (mynum, SFL_BLIND)) bprintf ("You're blind, you can't see a thing!\n"); else { if (ptstflg (mynum, PFL_GOTO) || plev (mynum) >= LVL_APPREN) { bprintf ("Location: %s - %s", showname (loc), ststflg(mynum,SFL_BRIEF) ? "\n" : ""); if (roomdark (loc) && plev (mynum) >= LVL_APPREN) bprintf ("(Dark)"); } if (dark) { bprintf ("It's dark. Be careful or you may be eaten by a Grue!\n"); return; } else { if (!ststflg (mynum, SFL_BRIEF) && plev (mynum) >= LVL_APPREN) bprintf ("%s - %s\n%s\n", real_light_state (loc), real_temp_state (loc), sdesc(loc)); else bprintf("%s\n",sdesc(loc)); } } if (ltstflg (loc, LFL_DEATH) && plev (mynum) >= LVL_APPREN) bprintf ("(DEATH) "); if (plev (mynum) >= LVL_APPREN && ltstflg (loc, LFL_PRIVATE)) bprintf ("(PRIVATE) "); if (plev (mynum) >= LVL_APPREN && ltstflg (loc, LFL_PARTY)) bprintf ("(PARTY) "); if (!dark && !ststflg (mynum, SFL_BLIND)) { if ((showfl & SHOW_LONG) != 0 || ststflg (mynum, SFL_BRIEF) == 0) bprintf ("\n%s", ldesc (loc)); list_objects(OFL_NOGET,True); show_weather (); list_objects (MAX_OFLAG,True); list_people (); } bprintf ("\n"); if (ststflg(mynum, SFL_AUTOEXIT)) { show_exits(False); bprintf("\n"); } } char *showname (int loc) { static char a[255]; return xshowname (a, loc); } char *xshowname (char *b, int loc) { char v[255]; sprintf (b, "%s", buildname (v, loc)); return b; } char *buildname (char *b, int loc) { int k; char n[255]; k = findzone (loc, n); sprintf (b, "%s%d", n, k); return b; } /* Find Location By Name * * Name is either <zonename/abbrev><offsett> (for instance "cat44") * or <absolute room number> (for instance "-233") * * Return location, or 0 on error, or 1 if correct zonename (only) was given. */ int find_loc_by_name (char *name) { int y; char buff[MAX_COM_LEN], *b = buff; char *p = name; int n; while (isalpha (*p)) *b++ = *p++; *b = '\0'; n = atoi (p); if (*buff == '\0') return exists (n) ? n : 0; if ((y = get_zone_by_name (buff)) != -1) return n == 0 ? 1 : getlocid (y, n); else return 0; } /* * Basic function to find a room number from: 1) zonename<offset>, * or 2) mobile/player * or 3) object * or 4) zonaname (no offset, assumes1) * Return room number, or 0 on error. */ int findroomnum (char *w) { int loc, a; while (*w != 0 && *w != '-' && !isalnum (*w)) ++w; if ((loc = find_loc_by_name (w)) < 0) return loc; else if ((a = fpbn (w)) != -1) return ploc (a); else if ((a = fobn (w)) != -1) return obj_loc (a); else if (loc == 1) return getlocnum (w, 1); else return 0; } /* Same as findroomnum(), but use brkword() and wordbuf. */ int getroomnum () { return (brkword () == -1) ? 0 : findroomnum (wordbuf); } /* Find location's in-game index from its ID. * Return 0 if not found. */ int find_loc_by_id (long int id) { long int x; if (id < 0 && convroom (id) < num_const_locs) return id; return (x = lookup_entry (id, &id_table)) == NOT_IN_TABLE || !exists (x) ? 0 : x; } Boolean cango (int d) { if (getexit (ploc (mynum), d) == 0) return False; if (getexit (ploc (mynum), d) < 0) return True; if (getexit (ploc (mynum), d) < DOOR) return False; if (state (getexit (ploc (mynum), d) - DOOR) == 0) return True; return False; } Boolean reset_location (int loc) { Boolean missing_exit = False; /* xlflags (loc) = xlflags_reset (loc); */ xlflags(loc).b1 = xlflags_reset(loc).b1; xlflags(loc).b2 = xlflags_reset(loc).b2; xlflags(loc).b3 = xlflags_reset(loc).b3; if (ltouched (loc)) { int i, x; for (i = 0; i < NEXITS; i++) { missing_exit |= (x = lexit_reset (loc, i)) != 0 && (x < DOOR || x > EX_MAX) && (x = find_loc_by_id (x)) == 0; setexit (loc, i, x); } ltouched (loc) = False; } return !missing_exit; } int check_light(int loc) { if (ltstflg(loc,LFL_LIGHT)) return LFL_LIGHT; else if (ltstflg(loc,LFL_DARK)) return LFL_DARK; else if (ltstflg(loc,LFL_L_REAL)) return LFL_L_REAL; return LFL_LIGHT; } int check_temp(int loc) { if (ltstflg(loc,LFL_T_ORDINARY)) return LFL_T_ORDINARY; else if (ltstflg(loc,LFL_HOT)) return LFL_HOT; else if (ltstflg(loc,LFL_COLD)) return LFL_COLD; else if (ltstflg(loc,LFL_T_REAL)) return LFL_T_REAL; return LFL_T_ORDINARY; }