1 1.14 mrg /* $NetBSD: room.c,v 1.14 2019/02/03 03:19:25 mrg Exp $ */ 2 1.3 cgd 3 1.1 cgd /* 4 1.3 cgd * Copyright (c) 1988, 1993 5 1.3 cgd * The Regents of the University of California. All rights reserved. 6 1.1 cgd * 7 1.1 cgd * This code is derived from software contributed to Berkeley by 8 1.1 cgd * Timothy C. Stoehr. 9 1.1 cgd * 10 1.1 cgd * Redistribution and use in source and binary forms, with or without 11 1.1 cgd * modification, are permitted provided that the following conditions 12 1.1 cgd * are met: 13 1.1 cgd * 1. Redistributions of source code must retain the above copyright 14 1.1 cgd * notice, this list of conditions and the following disclaimer. 15 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 cgd * notice, this list of conditions and the following disclaimer in the 17 1.1 cgd * documentation and/or other materials provided with the distribution. 18 1.7 agc * 3. Neither the name of the University nor the names of its contributors 19 1.1 cgd * may be used to endorse or promote products derived from this software 20 1.1 cgd * without specific prior written permission. 21 1.1 cgd * 22 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 1.1 cgd * SUCH DAMAGE. 33 1.1 cgd */ 34 1.1 cgd 35 1.4 lukem #include <sys/cdefs.h> 36 1.1 cgd #ifndef lint 37 1.3 cgd #if 0 38 1.3 cgd static char sccsid[] = "@(#)room.c 8.1 (Berkeley) 5/31/93"; 39 1.3 cgd #else 40 1.14 mrg __RCSID("$NetBSD: room.c,v 1.14 2019/02/03 03:19:25 mrg Exp $"); 41 1.3 cgd #endif 42 1.1 cgd #endif /* not lint */ 43 1.1 cgd 44 1.1 cgd /* 45 1.1 cgd * room.c 46 1.1 cgd * 47 1.1 cgd * This source herein may be modified and/or distributed by anybody who 48 1.1 cgd * so desires, with the following restrictions: 49 1.1 cgd * 1.) No portion of this notice shall be removed. 50 1.1 cgd * 2.) Credit shall not be taken for the creation of this source. 51 1.1 cgd * 3.) This code is not to be traded, sold, or used for personal 52 1.1 cgd * gain or profit. 53 1.1 cgd * 54 1.1 cgd */ 55 1.1 cgd 56 1.1 cgd #include "rogue.h" 57 1.1 cgd 58 1.1 cgd room rooms[MAXROOMS]; 59 1.12 dholland 60 1.12 dholland static boolean rooms_visited[MAXROOMS]; 61 1.1 cgd 62 1.1 cgd #define NOPTS 7 63 1.12 dholland static const struct option { 64 1.6 hubertf const char *prompt; 65 1.1 cgd boolean is_bool; 66 1.1 cgd char **strval; 67 1.1 cgd boolean *bval; 68 1.1 cgd } options[NOPTS] = { 69 1.1 cgd { 70 1.1 cgd "Show position only at end of run (\"jump\"): ", 71 1.12 dholland 1, NULL, &jump 72 1.1 cgd }, 73 1.1 cgd { 74 1.1 cgd "Follow turnings in passageways (\"passgo\"): ", 75 1.12 dholland 1, NULL, &passgo 76 1.1 cgd }, 77 1.1 cgd { 78 1.1 cgd "Don't print skull when killed (\"noskull\" or \"notombstone\"): ", 79 1.12 dholland 1, NULL, &no_skull 80 1.1 cgd }, 81 1.1 cgd { 82 1.1 cgd "Ask player before saying 'Okay, bye-bye!' (\"askquit\"): ", 83 1.12 dholland 1, NULL, &ask_quit 84 1.1 cgd }, 85 1.1 cgd { 86 1.1 cgd "Name (\"name\"): ", 87 1.12 dholland 0, &nick_name, NULL 88 1.1 cgd }, 89 1.1 cgd { 90 1.1 cgd "Fruit (\"fruit\"): ", 91 1.12 dholland 0, &fruit, NULL 92 1.1 cgd }, 93 1.1 cgd { 94 1.1 cgd "Save file (\"file\"): ", 95 1.12 dholland 0, &save_file, NULL 96 1.1 cgd } 97 1.1 cgd }; 98 1.1 cgd 99 1.13 dholland static boolean get_oth_room(short, short *, short *); 100 1.13 dholland static void opt_erase(int); 101 1.13 dholland static void opt_go(int); 102 1.13 dholland static void opt_show(int); 103 1.13 dholland static void visit_rooms(int); 104 1.13 dholland 105 1.4 lukem void 106 1.12 dholland light_up_room(int rn) 107 1.1 cgd { 108 1.1 cgd short i, j; 109 1.1 cgd 110 1.1 cgd if (!blind) { 111 1.1 cgd for (i = rooms[rn].top_row; 112 1.1 cgd i <= rooms[rn].bottom_row; i++) { 113 1.1 cgd for (j = rooms[rn].left_col; 114 1.1 cgd j <= rooms[rn].right_col; j++) { 115 1.1 cgd if (dungeon[i][j] & MONSTER) { 116 1.1 cgd object *monster; 117 1.1 cgd 118 1.4 lukem if ((monster = object_at( 119 1.4 lukem &level_monsters, i, j)) != NULL) { 120 1.1 cgd dungeon[monster->row][monster->col] &= (~MONSTER); 121 1.1 cgd monster->trail_char = 122 1.1 cgd get_dungeon_char(monster->row, monster->col); 123 1.1 cgd dungeon[monster->row][monster->col] |= MONSTER; 124 1.1 cgd } 125 1.1 cgd } 126 1.1 cgd mvaddch(i, j, get_dungeon_char(i, j)); 127 1.1 cgd } 128 1.1 cgd } 129 1.1 cgd mvaddch(rogue.row, rogue.col, rogue.fchar); 130 1.1 cgd } 131 1.1 cgd } 132 1.1 cgd 133 1.4 lukem void 134 1.12 dholland light_passage(int row, int col) 135 1.1 cgd { 136 1.1 cgd short i, j, i_end, j_end; 137 1.1 cgd 138 1.1 cgd if (blind) { 139 1.1 cgd return; 140 1.1 cgd } 141 1.1 cgd i_end = (row < (DROWS-2)) ? 1 : 0; 142 1.1 cgd j_end = (col < (DCOLS-1)) ? 1 : 0; 143 1.1 cgd 144 1.1 cgd for (i = ((row > MIN_ROW) ? -1 : 0); i <= i_end; i++) { 145 1.1 cgd for (j = ((col > 0) ? -1 : 0); j <= j_end; j++) { 146 1.1 cgd if (can_move(row, col, row+i, col+j)) { 147 1.1 cgd mvaddch(row+i, col+j, get_dungeon_char(row+i, col+j)); 148 1.1 cgd } 149 1.1 cgd } 150 1.1 cgd } 151 1.1 cgd } 152 1.1 cgd 153 1.4 lukem void 154 1.12 dholland darken_room(short rn) 155 1.1 cgd { 156 1.1 cgd short i, j; 157 1.1 cgd 158 1.1 cgd for (i = rooms[rn].top_row + 1; i < rooms[rn].bottom_row; i++) { 159 1.1 cgd for (j = rooms[rn].left_col + 1; j < rooms[rn].right_col; j++) { 160 1.1 cgd if (blind) { 161 1.1 cgd mvaddch(i, j, ' '); 162 1.1 cgd } else { 163 1.1 cgd if (!(dungeon[i][j] & (OBJECT | STAIRS)) && 164 1.1 cgd !(detect_monster && (dungeon[i][j] & MONSTER))) { 165 1.1 cgd if (!imitating(i, j)) { 166 1.1 cgd mvaddch(i, j, ' '); 167 1.1 cgd } 168 1.1 cgd if ((dungeon[i][j] & TRAP) && (!(dungeon[i][j] & HIDDEN))) { 169 1.1 cgd mvaddch(i, j, '^'); 170 1.1 cgd } 171 1.1 cgd } 172 1.1 cgd } 173 1.1 cgd } 174 1.1 cgd } 175 1.1 cgd } 176 1.1 cgd 177 1.4 lukem char 178 1.12 dholland get_dungeon_char(short row, short col) 179 1.1 cgd { 180 1.4 lukem unsigned short mask = dungeon[row][col]; 181 1.1 cgd 182 1.1 cgd if (mask & MONSTER) { 183 1.1 cgd return(gmc_row_col(row, col)); 184 1.1 cgd } 185 1.1 cgd if (mask & OBJECT) { 186 1.1 cgd object *obj; 187 1.1 cgd 188 1.1 cgd obj = object_at(&level_objects, row, col); 189 1.1 cgd return(get_mask_char(obj->what_is)); 190 1.1 cgd } 191 1.1 cgd if (mask & (TUNNEL | STAIRS | HORWALL | VERTWALL | FLOOR | DOOR)) { 192 1.1 cgd if ((mask & (TUNNEL| STAIRS)) && (!(mask & HIDDEN))) { 193 1.1 cgd return(((mask & STAIRS) ? '%' : '#')); 194 1.1 cgd } 195 1.1 cgd if (mask & HORWALL) { 196 1.1 cgd return('-'); 197 1.1 cgd } 198 1.1 cgd if (mask & VERTWALL) { 199 1.1 cgd return('|'); 200 1.1 cgd } 201 1.1 cgd if (mask & FLOOR) { 202 1.1 cgd if (mask & TRAP) { 203 1.1 cgd if (!(dungeon[row][col] & HIDDEN)) { 204 1.1 cgd return('^'); 205 1.1 cgd } 206 1.1 cgd } 207 1.1 cgd return('.'); 208 1.1 cgd } 209 1.1 cgd if (mask & DOOR) { 210 1.1 cgd if (mask & HIDDEN) { 211 1.1 cgd if (((col > 0) && (dungeon[row][col-1] & HORWALL)) || 212 1.1 cgd ((col < (DCOLS-1)) && (dungeon[row][col+1] & HORWALL))) { 213 1.1 cgd return('-'); 214 1.1 cgd } else { 215 1.1 cgd return('|'); 216 1.1 cgd } 217 1.1 cgd } else { 218 1.1 cgd return('+'); 219 1.1 cgd } 220 1.1 cgd } 221 1.1 cgd } 222 1.1 cgd return(' '); 223 1.1 cgd } 224 1.1 cgd 225 1.4 lukem char 226 1.12 dholland get_mask_char(unsigned short mask) 227 1.1 cgd { 228 1.1 cgd switch(mask) { 229 1.1 cgd case SCROL: 230 1.1 cgd return('?'); 231 1.1 cgd case POTION: 232 1.1 cgd return('!'); 233 1.1 cgd case GOLD: 234 1.1 cgd return('*'); 235 1.1 cgd case FOOD: 236 1.1 cgd return(':'); 237 1.1 cgd case WAND: 238 1.1 cgd return('/'); 239 1.1 cgd case ARMOR: 240 1.1 cgd return(']'); 241 1.1 cgd case WEAPON: 242 1.1 cgd return(')'); 243 1.1 cgd case RING: 244 1.1 cgd return('='); 245 1.1 cgd case AMULET: 246 1.1 cgd return(','); 247 1.1 cgd default: 248 1.1 cgd return('~'); /* unknown, something is wrong */ 249 1.1 cgd } 250 1.1 cgd } 251 1.1 cgd 252 1.4 lukem void 253 1.12 dholland gr_row_col(short *row, short *col, unsigned short mask) 254 1.1 cgd { 255 1.1 cgd short rn; 256 1.1 cgd short r, c; 257 1.1 cgd 258 1.1 cgd do { 259 1.1 cgd r = get_rand(MIN_ROW, DROWS-2); 260 1.1 cgd c = get_rand(0, DCOLS-1); 261 1.1 cgd rn = get_room_number(r, c); 262 1.1 cgd } while ((rn == NO_ROOM) || 263 1.1 cgd (!(dungeon[r][c] & mask)) || 264 1.1 cgd (dungeon[r][c] & (~mask)) || 265 1.1 cgd (!(rooms[rn].is_room & (R_ROOM | R_MAZE))) || 266 1.1 cgd ((r == rogue.row) && (c == rogue.col))); 267 1.1 cgd 268 1.1 cgd *row = r; 269 1.1 cgd *col = c; 270 1.1 cgd } 271 1.1 cgd 272 1.4 lukem short 273 1.12 dholland gr_room(void) 274 1.1 cgd { 275 1.1 cgd short i; 276 1.1 cgd 277 1.1 cgd do { 278 1.1 cgd i = get_rand(0, MAXROOMS-1); 279 1.1 cgd } while (!(rooms[i].is_room & (R_ROOM | R_MAZE))); 280 1.1 cgd 281 1.1 cgd return(i); 282 1.1 cgd } 283 1.1 cgd 284 1.4 lukem short 285 1.12 dholland party_objects(int rn) 286 1.1 cgd { 287 1.1 cgd short i, j, nf = 0; 288 1.1 cgd object *obj; 289 1.1 cgd short n, N, row, col; 290 1.1 cgd boolean found; 291 1.1 cgd 292 1.4 lukem row = col = 0; 293 1.1 cgd N = ((rooms[rn].bottom_row - rooms[rn].top_row) - 1) * 294 1.1 cgd ((rooms[rn].right_col - rooms[rn].left_col) - 1); 295 1.1 cgd n = get_rand(5, 10); 296 1.1 cgd if (n > N) { 297 1.1 cgd n = N - 2; 298 1.1 cgd } 299 1.1 cgd for (i = 0; i < n; i++) { 300 1.1 cgd for (j = found = 0; ((!found) && (j < 250)); j++) { 301 1.1 cgd row = get_rand(rooms[rn].top_row+1, 302 1.1 cgd rooms[rn].bottom_row-1); 303 1.1 cgd col = get_rand(rooms[rn].left_col+1, 304 1.1 cgd rooms[rn].right_col-1); 305 1.1 cgd if ((dungeon[row][col] == FLOOR) || (dungeon[row][col] == TUNNEL)) { 306 1.1 cgd found = 1; 307 1.1 cgd } 308 1.1 cgd } 309 1.1 cgd if (found) { 310 1.1 cgd obj = gr_object(); 311 1.1 cgd place_at(obj, row, col); 312 1.1 cgd nf++; 313 1.1 cgd } 314 1.1 cgd } 315 1.1 cgd return(nf); 316 1.1 cgd } 317 1.1 cgd 318 1.4 lukem short 319 1.12 dholland get_room_number(int row, int col) 320 1.1 cgd { 321 1.1 cgd short i; 322 1.1 cgd 323 1.1 cgd for (i = 0; i < MAXROOMS; i++) { 324 1.1 cgd if ((row >= rooms[i].top_row) && (row <= rooms[i].bottom_row) && 325 1.1 cgd (col >= rooms[i].left_col) && (col <= rooms[i].right_col)) { 326 1.1 cgd return(i); 327 1.1 cgd } 328 1.1 cgd } 329 1.1 cgd return(NO_ROOM); 330 1.1 cgd } 331 1.1 cgd 332 1.4 lukem boolean 333 1.12 dholland is_all_connected(void) 334 1.1 cgd { 335 1.1 cgd short i, starting_room; 336 1.1 cgd 337 1.4 lukem starting_room = 0; 338 1.1 cgd for (i = 0; i < MAXROOMS; i++) { 339 1.1 cgd rooms_visited[i] = 0; 340 1.1 cgd if (rooms[i].is_room & (R_ROOM | R_MAZE)) { 341 1.1 cgd starting_room = i; 342 1.1 cgd } 343 1.1 cgd } 344 1.1 cgd 345 1.1 cgd visit_rooms(starting_room); 346 1.1 cgd 347 1.1 cgd for (i = 0; i < MAXROOMS; i++) { 348 1.1 cgd if ((rooms[i].is_room & (R_ROOM | R_MAZE)) && (!rooms_visited[i])) { 349 1.1 cgd return(0); 350 1.1 cgd } 351 1.1 cgd } 352 1.1 cgd return(1); 353 1.1 cgd } 354 1.1 cgd 355 1.13 dholland static void 356 1.12 dholland visit_rooms(int rn) 357 1.1 cgd { 358 1.1 cgd short i; 359 1.1 cgd short oth_rn; 360 1.1 cgd 361 1.1 cgd rooms_visited[rn] = 1; 362 1.1 cgd 363 1.1 cgd for (i = 0; i < 4; i++) { 364 1.1 cgd oth_rn = rooms[rn].doors[i].oth_room; 365 1.1 cgd if ((oth_rn >= 0) && (!rooms_visited[oth_rn])) { 366 1.1 cgd visit_rooms(oth_rn); 367 1.1 cgd } 368 1.1 cgd } 369 1.1 cgd } 370 1.1 cgd 371 1.4 lukem void 372 1.12 dholland draw_magic_map(void) 373 1.1 cgd { 374 1.1 cgd short i, j, ch, och; 375 1.1 cgd unsigned short mask = (HORWALL | VERTWALL | DOOR | TUNNEL | TRAP | STAIRS | 376 1.1 cgd MONSTER); 377 1.1 cgd unsigned short s; 378 1.1 cgd 379 1.1 cgd for (i = 0; i < DROWS; i++) { 380 1.1 cgd for (j = 0; j < DCOLS; j++) { 381 1.1 cgd s = dungeon[i][j]; 382 1.1 cgd if (s & mask) { 383 1.1 cgd if (((ch = mvinch(i, j)) == ' ') || 384 1.1 cgd ((ch >= 'A') && (ch <= 'Z')) || (s & (TRAP | HIDDEN))) { 385 1.1 cgd och = ch; 386 1.1 cgd dungeon[i][j] &= (~HIDDEN); 387 1.1 cgd if (s & HORWALL) { 388 1.1 cgd ch = '-'; 389 1.1 cgd } else if (s & VERTWALL) { 390 1.1 cgd ch = '|'; 391 1.1 cgd } else if (s & DOOR) { 392 1.1 cgd ch = '+'; 393 1.1 cgd } else if (s & TRAP) { 394 1.1 cgd ch = '^'; 395 1.1 cgd } else if (s & STAIRS) { 396 1.1 cgd ch = '%'; 397 1.1 cgd } else if (s & TUNNEL) { 398 1.1 cgd ch = '#'; 399 1.1 cgd } else { 400 1.1 cgd continue; 401 1.1 cgd } 402 1.1 cgd if ((!(s & MONSTER)) || (och == ' ')) { 403 1.1 cgd addch(ch); 404 1.1 cgd } 405 1.1 cgd if (s & MONSTER) { 406 1.1 cgd object *monster; 407 1.1 cgd 408 1.4 lukem if ((monster = object_at( 409 1.4 lukem &level_monsters, i, j)) 410 1.4 lukem != NULL) { 411 1.4 lukem monster->trail_char = 412 1.4 lukem ch; 413 1.1 cgd } 414 1.1 cgd } 415 1.1 cgd } 416 1.1 cgd } 417 1.1 cgd } 418 1.1 cgd } 419 1.1 cgd } 420 1.1 cgd 421 1.4 lukem void 422 1.12 dholland dr_course(object *monster, boolean entering, short row, short col) 423 1.1 cgd { 424 1.1 cgd short i, j, k, rn; 425 1.1 cgd short r, rr; 426 1.1 cgd 427 1.1 cgd monster->row = row; 428 1.1 cgd monster->col = col; 429 1.1 cgd 430 1.1 cgd if (mon_sees(monster, rogue.row, rogue.col)) { 431 1.1 cgd monster->trow = NO_ROOM; 432 1.1 cgd return; 433 1.1 cgd } 434 1.1 cgd rn = get_room_number(row, col); 435 1.1 cgd 436 1.1 cgd if (entering) { /* entering room */ 437 1.1 cgd /* look for door to some other room */ 438 1.1 cgd r = get_rand(0, MAXROOMS-1); 439 1.1 cgd for (i = 0; i < MAXROOMS; i++) { 440 1.1 cgd rr = (r + i) % MAXROOMS; 441 1.1 cgd if ((!(rooms[rr].is_room & (R_ROOM | R_MAZE))) || (rr == rn)) { 442 1.1 cgd continue; 443 1.1 cgd } 444 1.1 cgd for (k = 0; k < 4; k++) { 445 1.1 cgd if (rooms[rr].doors[k].oth_room == rn) { 446 1.1 cgd monster->trow = rooms[rr].doors[k].oth_row; 447 1.1 cgd monster->tcol = rooms[rr].doors[k].oth_col; 448 1.1 cgd if ((monster->trow == row) && 449 1.1 cgd (monster->tcol == col)) { 450 1.1 cgd continue; 451 1.1 cgd } 452 1.1 cgd return; 453 1.1 cgd } 454 1.1 cgd } 455 1.1 cgd } 456 1.1 cgd /* look for door to dead end */ 457 1.8 jnemeth if (rn == NO_ROOM) 458 1.8 jnemeth clean_up("dr_course: monster not in room"); 459 1.1 cgd for (i = rooms[rn].top_row; i <= rooms[rn].bottom_row; i++) { 460 1.1 cgd for (j = rooms[rn].left_col; j <= rooms[rn].right_col; j++) { 461 1.1 cgd if ((i != monster->row) && (j != monster->col) && 462 1.1 cgd (dungeon[i][j] & DOOR)) { 463 1.1 cgd monster->trow = i; 464 1.1 cgd monster->tcol = j; 465 1.1 cgd return; 466 1.1 cgd } 467 1.1 cgd } 468 1.1 cgd } 469 1.1 cgd /* return monster to room that he came from */ 470 1.1 cgd for (i = 0; i < MAXROOMS; i++) { 471 1.1 cgd for (j = 0; j < 4; j++) { 472 1.1 cgd if (rooms[i].doors[j].oth_room == rn) { 473 1.1 cgd for (k = 0; k < 4; k++) { 474 1.1 cgd if (rooms[rn].doors[k].oth_room == i) { 475 1.1 cgd monster->trow = rooms[rn].doors[k].oth_row; 476 1.1 cgd monster->tcol = rooms[rn].doors[k].oth_col; 477 1.1 cgd return; 478 1.1 cgd } 479 1.1 cgd } 480 1.1 cgd } 481 1.1 cgd } 482 1.1 cgd } 483 1.1 cgd /* no place to send monster */ 484 1.1 cgd monster->trow = NO_ROOM; 485 1.1 cgd } else { /* exiting room */ 486 1.9 christos if (rn == NO_ROOM || !get_oth_room(rn, &row, &col)) { 487 1.1 cgd monster->trow = NO_ROOM; 488 1.1 cgd } else { 489 1.1 cgd monster->trow = row; 490 1.1 cgd monster->tcol = col; 491 1.1 cgd } 492 1.1 cgd } 493 1.1 cgd } 494 1.1 cgd 495 1.13 dholland static boolean 496 1.12 dholland get_oth_room(short rn, short *row, short *col) 497 1.1 cgd { 498 1.1 cgd short d = -1; 499 1.1 cgd 500 1.1 cgd if (*row == rooms[rn].top_row) { 501 1.1 cgd d = UPWARD/2; 502 1.1 cgd } else if (*row == rooms[rn].bottom_row) { 503 1.1 cgd d = DOWN/2; 504 1.1 cgd } else if (*col == rooms[rn].left_col) { 505 1.1 cgd d = LEFT/2; 506 1.1 cgd } else if (*col == rooms[rn].right_col) { 507 1.1 cgd d = RIGHT/2; 508 1.1 cgd } 509 1.1 cgd if ((d != -1) && (rooms[rn].doors[d].oth_room >= 0)) { 510 1.1 cgd *row = rooms[rn].doors[d].oth_row; 511 1.1 cgd *col = rooms[rn].doors[d].oth_col; 512 1.1 cgd return(1); 513 1.1 cgd } 514 1.1 cgd return(0); 515 1.1 cgd } 516 1.1 cgd 517 1.4 lukem void 518 1.12 dholland edit_opts(void) 519 1.1 cgd { 520 1.1 cgd char save[NOPTS+1][DCOLS]; 521 1.1 cgd short i, j; 522 1.1 cgd short ch; 523 1.1 cgd boolean done = 0; 524 1.1 cgd char buf[MAX_OPT_LEN + 2]; 525 1.1 cgd 526 1.1 cgd for (i = 0; i < NOPTS+1; i++) { 527 1.1 cgd for (j = 0; j < DCOLS; j++) { 528 1.1 cgd save[i][j] = mvinch(i, j); 529 1.1 cgd } 530 1.1 cgd if (i < NOPTS) { 531 1.1 cgd opt_show(i); 532 1.1 cgd } 533 1.1 cgd } 534 1.1 cgd opt_go(0); 535 1.1 cgd i = 0; 536 1.1 cgd 537 1.1 cgd while (!done) { 538 1.1 cgd refresh(); 539 1.1 cgd ch = rgetchar(); 540 1.1 cgd CH: 541 1.1 cgd switch(ch) { 542 1.1 cgd case '\033': 543 1.1 cgd done = 1; 544 1.1 cgd break; 545 1.1 cgd case '\012': 546 1.1 cgd case '\015': 547 1.1 cgd if (i == (NOPTS - 1)) { 548 1.1 cgd mvaddstr(NOPTS, 0, press_space); 549 1.1 cgd refresh(); 550 1.1 cgd wait_for_ack(); 551 1.1 cgd done = 1; 552 1.1 cgd } else { 553 1.1 cgd i++; 554 1.1 cgd opt_go(i); 555 1.1 cgd } 556 1.1 cgd break; 557 1.1 cgd case '-': 558 1.1 cgd if (i > 0) { 559 1.1 cgd opt_go(--i); 560 1.1 cgd } else { 561 1.1 cgd sound_bell(); 562 1.1 cgd } 563 1.1 cgd break; 564 1.1 cgd case 't': 565 1.1 cgd case 'T': 566 1.1 cgd case 'f': 567 1.1 cgd case 'F': 568 1.1 cgd if (options[i].is_bool) { 569 1.1 cgd *(options[i].bval) = (((ch == 't') || (ch == 'T')) ? 1 : 0); 570 1.1 cgd opt_show(i); 571 1.1 cgd opt_go(++i); 572 1.1 cgd break; 573 1.1 cgd } 574 1.14 mrg /* FALLTHROUGH */ 575 1.1 cgd default: 576 1.1 cgd if (options[i].is_bool) { 577 1.1 cgd sound_bell(); 578 1.1 cgd break; 579 1.1 cgd } 580 1.1 cgd j = 0; 581 1.1 cgd if ((ch == '\010') || ((ch >= ' ') && (ch <= '~'))) { 582 1.1 cgd opt_erase(i); 583 1.1 cgd do { 584 1.1 cgd if ((ch >= ' ') && (ch <= '~') && (j < MAX_OPT_LEN)) { 585 1.1 cgd buf[j++] = ch; 586 1.1 cgd buf[j] = '\0'; 587 1.1 cgd addch(ch); 588 1.1 cgd } else if ((ch == '\010') && (j > 0)) { 589 1.1 cgd buf[--j] = '\0'; 590 1.1 cgd move(i, j + strlen(options[i].prompt)); 591 1.1 cgd addch(' '); 592 1.1 cgd move(i, j + strlen(options[i].prompt)); 593 1.1 cgd } 594 1.1 cgd refresh(); 595 1.1 cgd ch = rgetchar(); 596 1.1 cgd } while ((ch != '\012') && (ch != '\015') && (ch != '\033')); 597 1.1 cgd if (j != 0) { 598 1.10 dholland /* 599 1.10 dholland * We rely on the option string being 600 1.11 dholland * allocated to hold MAX_OPT_LEN+2 601 1.10 dholland * bytes. This is arranged in init.c. 602 1.10 dholland */ 603 1.11 dholland (void)strcpy(*(options[i].strval), buf); 604 1.1 cgd } 605 1.1 cgd opt_show(i); 606 1.1 cgd goto CH; 607 1.1 cgd } else { 608 1.1 cgd sound_bell(); 609 1.1 cgd } 610 1.1 cgd break; 611 1.1 cgd } 612 1.1 cgd } 613 1.1 cgd 614 1.1 cgd for (i = 0; i < NOPTS+1; i++) { 615 1.1 cgd move(i, 0); 616 1.1 cgd for (j = 0; j < DCOLS; j++) { 617 1.1 cgd addch(save[i][j]); 618 1.1 cgd } 619 1.1 cgd } 620 1.1 cgd } 621 1.1 cgd 622 1.13 dholland static void 623 1.12 dholland opt_show(int i) 624 1.1 cgd { 625 1.6 hubertf const char *s; 626 1.10 dholland const struct option *opt = &options[i]; 627 1.1 cgd 628 1.1 cgd opt_erase(i); 629 1.1 cgd 630 1.1 cgd if (opt->is_bool) { 631 1.1 cgd s = *(opt->bval) ? "True" : "False"; 632 1.1 cgd } else { 633 1.1 cgd s = *(opt->strval); 634 1.1 cgd } 635 1.1 cgd addstr(s); 636 1.1 cgd } 637 1.1 cgd 638 1.13 dholland static void 639 1.12 dholland opt_erase(int i) 640 1.1 cgd { 641 1.10 dholland const struct option *opt = &options[i]; 642 1.1 cgd 643 1.1 cgd mvaddstr(i, 0, opt->prompt); 644 1.1 cgd clrtoeol(); 645 1.1 cgd } 646 1.1 cgd 647 1.13 dholland static void 648 1.12 dholland opt_go(int i) 649 1.1 cgd { 650 1.1 cgd move(i, strlen(options[i].prompt)); 651 1.1 cgd } 652 1.1 cgd 653 1.4 lukem void 654 1.12 dholland do_shell(void) 655 1.1 cgd { 656 1.1 cgd #ifdef UNIX 657 1.6 hubertf const char *sh; 658 1.1 cgd 659 1.1 cgd md_ignore_signals(); 660 1.1 cgd if (!(sh = md_getenv("SHELL"))) { 661 1.1 cgd sh = "/bin/sh"; 662 1.1 cgd } 663 1.1 cgd move(LINES-1, 0); 664 1.1 cgd refresh(); 665 1.1 cgd stop_window(); 666 1.1 cgd printf("\nCreating new shell...\n"); 667 1.1 cgd md_shell(sh); 668 1.1 cgd start_window(); 669 1.1 cgd wrefresh(curscr); 670 1.1 cgd md_heed_signals(); 671 1.1 cgd #endif 672 1.1 cgd } 673