Mercurial > hg > early-roguelike
comparison urogue/misc.c @ 256:c495a4f288c6
Import UltraRogue from the Roguelike Restoration Project (r1490)
| author | John "Elwin" Edwards |
|---|---|
| date | Tue, 31 Jan 2017 19:56:04 -0500 |
| parents | |
| children | e52a8a7ad4c5 |
comparison
equal
deleted
inserted
replaced
| 253:d9badb9c0179 | 256:c495a4f288c6 |
|---|---|
| 1 /* | |
| 2 misc.c - all sorts of miscellaneous routines | |
| 3 | |
| 4 UltraRogue: The Ultimate Adventure in the Dungeons of Doom | |
| 5 Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong | |
| 6 All rights reserved. | |
| 7 | |
| 8 Based on "Advanced Rogue" | |
| 9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka | |
| 10 All rights reserved. | |
| 11 | |
| 12 Based on "Rogue: Exploring the Dungeons of Doom" | |
| 13 Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman | |
| 14 All rights reserved. | |
| 15 | |
| 16 See the file LICENSE.TXT for full copyright and licensing information. | |
| 17 */ | |
| 18 | |
| 19 #include <stdlib.h> | |
| 20 #include <string.h> | |
| 21 #include <ctype.h> | |
| 22 #include "rogue.h" | |
| 23 | |
| 24 /* | |
| 25 tr_name() | |
| 26 print the name of a trap | |
| 27 */ | |
| 28 | |
| 29 char * | |
| 30 tr_name(char ch, char *trname) | |
| 31 { | |
| 32 const char *s = NULL; | |
| 33 | |
| 34 if (trname == NULL) | |
| 35 return(" Your found an error in UltraRogue #100."); | |
| 36 | |
| 37 switch(ch) | |
| 38 { | |
| 39 case TRAPDOOR: | |
| 40 s = "trapdoor."; | |
| 41 break; | |
| 42 case BEARTRAP: | |
| 43 s = "beartrap."; | |
| 44 break; | |
| 45 case SLEEPTRAP: | |
| 46 s = "sleeping gas trap."; | |
| 47 break; | |
| 48 case ARROWTRAP: | |
| 49 s = "arrow trap."; | |
| 50 break; | |
| 51 case TELTRAP: | |
| 52 s = "teleport trap."; | |
| 53 break; | |
| 54 case DARTTRAP: | |
| 55 s = "dart trap."; | |
| 56 break; | |
| 57 case POOL: | |
| 58 s = "shimmering pool."; | |
| 59 break; | |
| 60 case MAZETRAP: | |
| 61 s = "maze entrance."; | |
| 62 break; | |
| 63 case FIRETRAP: | |
| 64 s = "fire trap."; | |
| 65 break; | |
| 66 case POISONTRAP: | |
| 67 s = "poison pool trap."; | |
| 68 break; | |
| 69 case LAIR: | |
| 70 s = "monster lair."; | |
| 71 break; | |
| 72 case RUSTTRAP: | |
| 73 s = "rust trap."; | |
| 74 break; | |
| 75 default: | |
| 76 ; | |
| 77 } | |
| 78 | |
| 79 sprintf(trname, "You found a %s.", s); | |
| 80 | |
| 81 return(trname); | |
| 82 } | |
| 83 | |
| 84 /* | |
| 85 look() | |
| 86 A quick glance all around the player | |
| 87 */ | |
| 88 | |
| 89 void | |
| 90 look(int wakeup) | |
| 91 { | |
| 92 int x, y; | |
| 93 char ch, och; | |
| 94 int oldx, oldy; | |
| 95 int inpass, horizontal, vertical, do_light = FALSE, do_blank = FALSE; | |
| 96 int passcount = 0; | |
| 97 struct room *rp; | |
| 98 int ey, ex; | |
| 99 | |
| 100 /* Are we moving vertically or horizontally? */ | |
| 101 | |
| 102 if (runch == 'h' || runch == 'l') | |
| 103 horizontal = TRUE; | |
| 104 else | |
| 105 horizontal = FALSE; | |
| 106 | |
| 107 if (runch == 'j' || runch == 'k') | |
| 108 vertical = TRUE; | |
| 109 else | |
| 110 vertical = FALSE; | |
| 111 | |
| 112 getyx(cw, oldy, oldx); /* Save current position */ | |
| 113 | |
| 114 /* | |
| 115 * Blank out the floor around our last position and check for moving | |
| 116 * out of a corridor in a maze. | |
| 117 */ | |
| 118 | |
| 119 if (oldrp != NULL && (oldrp->r_flags & ISDARK) && | |
| 120 !(oldrp->r_flags & HASFIRE) && off(player, ISBLIND)) | |
| 121 do_blank = TRUE; | |
| 122 | |
| 123 for (x = player.t_oldpos.x - 1; x <= player.t_oldpos.x + 1; x++) | |
| 124 for (y = player.t_oldpos.y - 1; y <= player.t_oldpos.y + 1; | |
| 125 y++) | |
| 126 { | |
| 127 ch = show(y, x); | |
| 128 | |
| 129 if (do_blank && (y != hero.y || x != hero.x) && ch == FLOOR) | |
| 130 mvwaddch(cw, y, x, ' '); | |
| 131 | |
| 132 /* Moving out of a corridor? */ | |
| 133 | |
| 134 if (levtype == MAZELEV && | |
| 135 (ch != '|' && ch != '-') && /* Not a wall */ | |
| 136 ((vertical && x != player.t_oldpos.x && | |
| 137 y == player.t_oldpos.y) || | |
| 138 (horizontal && y != player.t_oldpos.y && | |
| 139 x == player.t_oldpos.x))) | |
| 140 do_light = TRUE; /* Just came to a turn */ | |
| 141 } | |
| 142 | |
| 143 inpass = ((rp = roomin(hero)) == NULL); /* Are we in a passage? */ | |
| 144 | |
| 145 /* Are we coming out of a wall into a corridor in a maze? */ | |
| 146 och = show(player.t_oldpos.y, player.t_oldpos.x); | |
| 147 ch = show(hero.y, hero.x); | |
| 148 | |
| 149 if (levtype == MAZELEV && (och == '|' || och == '-' || | |
| 150 och == SECRETDOOR) && (ch != '|' && ch != '-' && ch != SECRETDOOR)) | |
| 151 { | |
| 152 do_light = off(player, ISBLIND); /* Light it up if not blind */ | |
| 153 } | |
| 154 | |
| 155 /* Look around the player */ | |
| 156 | |
| 157 ey = hero.y + 1; | |
| 158 ex = hero.x + 1; | |
| 159 | |
| 160 for (x = hero.x - 1; x <= ex; x++) | |
| 161 if (x >= 0 && x < COLS) | |
| 162 for (y = hero.y - 1; y <= ey; y++) | |
| 163 { | |
| 164 if (y <= 0 || y >= LINES - 2) | |
| 165 continue; | |
| 166 | |
| 167 if (isalpha(mvwinch(mw, y, x))) | |
| 168 { | |
| 169 struct linked_list *it; | |
| 170 struct thing *tp; | |
| 171 | |
| 172 if (wakeup) | |
| 173 it = wake_monster(y, x); | |
| 174 else | |
| 175 it = find_mons(y, x); | |
| 176 | |
| 177 if (it == NULL) | |
| 178 continue; | |
| 179 | |
| 180 tp = THINGPTR(it); | |
| 181 tp->t_oldch = CCHAR( mvinch(y, x) ); | |
| 182 | |
| 183 if (isatrap(tp->t_oldch)) | |
| 184 { | |
| 185 struct trap *trp = trap_at(y, x); | |
| 186 | |
| 187 tp->t_oldch = (trp->tr_flags & ISFOUND) ? tp->t_oldch | |
| 188 : trp->tr_show; | |
| 189 } | |
| 190 | |
| 191 if (tp->t_oldch == FLOOR && | |
| 192 (rp->r_flags & ISDARK) | |
| 193 && !(rp->r_flags & HASFIRE) && | |
| 194 off(player, ISBLIND)) | |
| 195 tp->t_oldch = ' '; | |
| 196 } | |
| 197 | |
| 198 /* Secret doors show as walls */ | |
| 199 | |
| 200 if ((ch = show(y, x)) == SECRETDOOR) | |
| 201 ch = secretdoor(y, x); | |
| 202 | |
| 203 /* | |
| 204 * Don't show room walls if he is in a | |
| 205 * passage and check for maze turns | |
| 206 */ | |
| 207 | |
| 208 if (off(player, ISBLIND)) | |
| 209 { | |
| 210 if (y == hero.y && x == hero.x || (inpass && (ch == '-' || | |
| 211 ch == '|'))) | |
| 212 continue; | |
| 213 | |
| 214 /* Are we at a crossroads in a maze? */ | |
| 215 | |
| 216 if (levtype == MAZELEV && (ch != '|' && ch != '-') && | |
| 217 /* Not a wall */ | |
| 218 ((vertical && x != hero.x && y == hero.y) || | |
| 219 (horizontal && y != hero.y && x == hero.x))) | |
| 220 do_light = TRUE; | |
| 221 /* Just came to a turn */ | |
| 222 } | |
| 223 else if (y != hero.y || x != hero.x) | |
| 224 continue; | |
| 225 | |
| 226 wmove(cw, y, x); | |
| 227 waddch(cw, ch); | |
| 228 | |
| 229 if (door_stop && !firstmove && running) | |
| 230 { | |
| 231 switch (runch) | |
| 232 { | |
| 233 case 'h': | |
| 234 if (x == ex) | |
| 235 continue; | |
| 236 break; | |
| 237 case 'j': | |
| 238 if (y == hero.y - 1) | |
| 239 continue; | |
| 240 break; | |
| 241 case 'k': | |
| 242 if (y == ey) | |
| 243 continue; | |
| 244 break; | |
| 245 case 'l': | |
| 246 if (x == hero.x - 1) | |
| 247 continue; | |
| 248 break; | |
| 249 case 'y': | |
| 250 if ((x + y) - (hero.x + hero.y) >= 1) | |
| 251 continue; | |
| 252 break; | |
| 253 case 'u': | |
| 254 if ((y - x) - (hero.y - hero.x) >= 1) | |
| 255 continue; | |
| 256 break; | |
| 257 case 'n': | |
| 258 if ((x + y) - (hero.x + hero.y) <= -1) | |
| 259 continue; | |
| 260 break; | |
| 261 case 'b': | |
| 262 if ((y - x) - (hero.y - hero.x) <= -1) | |
| 263 continue; | |
| 264 break; | |
| 265 } | |
| 266 | |
| 267 switch (ch) | |
| 268 { | |
| 269 case DOOR: | |
| 270 if (x == hero.x || y == hero.y) | |
| 271 running = FALSE; | |
| 272 break; | |
| 273 case PASSAGE: | |
| 274 if (x == hero.x || y == hero.y) | |
| 275 passcount++; | |
| 276 break; | |
| 277 case FLOOR: | |
| 278 | |
| 279 /* | |
| 280 * Stop by new passages in a | |
| 281 * maze (floor next to us) | |
| 282 */ | |
| 283 if ((levtype == MAZELEV) && | |
| 284 ((horizontal && x == hero.x && y != hero.y) || | |
| 285 (vertical && y == hero.y && x != hero.x))) | |
| 286 running = FALSE; | |
| 287 | |
| 288 case '|': | |
| 289 case '-': | |
| 290 case ' ': | |
| 291 break; | |
| 292 | |
| 293 default: | |
| 294 running = FALSE; | |
| 295 break; | |
| 296 } | |
| 297 } | |
| 298 } | |
| 299 | |
| 300 if (door_stop && !firstmove && passcount > 1) | |
| 301 running = FALSE; | |
| 302 | |
| 303 /* | |
| 304 * Do we have to light up the area (just stepped into a new | |
| 305 * corridor)? | |
| 306 */ | |
| 307 | |
| 308 if (do_light && wakeup && /* wakeup will be true on a normal move */ | |
| 309 !(rp->r_flags & ISDARK) && /* We have some light */ | |
| 310 !ce(hero, player.t_oldpos)) /* Don't do anything if we didn't move */ | |
| 311 light(&hero); | |
| 312 | |
| 313 mvwaddch(cw, hero.y, hero.x, PLAYER); | |
| 314 wmove(cw, oldy, oldx); | |
| 315 | |
| 316 if (wakeup) | |
| 317 { | |
| 318 player.t_oldpos = hero; /* Don't change if we didn't move */ | |
| 319 oldrp = rp; | |
| 320 } | |
| 321 } | |
| 322 | |
| 323 /* | |
| 324 secret_door() | |
| 325 Figure out what a secret door looks like. | |
| 326 */ | |
| 327 | |
| 328 char | |
| 329 secretdoor(int y, int x) | |
| 330 { | |
| 331 struct room *rp; | |
| 332 coord cp; | |
| 333 | |
| 334 cp.x = x; | |
| 335 cp.y = y; | |
| 336 | |
| 337 if ((rp = roomin(cp)) != NULL) | |
| 338 { | |
| 339 if (y == rp->r_pos.y || y == rp->r_pos.y + rp->r_max.y - 1) | |
| 340 return ('-'); | |
| 341 else | |
| 342 return ('|'); | |
| 343 } | |
| 344 return ('p'); | |
| 345 } | |
| 346 | |
| 347 /* | |
| 348 find_obj() | |
| 349 find the unclaimed object at y, x | |
| 350 */ | |
| 351 | |
| 352 struct linked_list * | |
| 353 find_obj(int y, int x) | |
| 354 { | |
| 355 struct linked_list *obj, *sobj; | |
| 356 struct object *op; | |
| 357 | |
| 358 sobj = lvl_obj; | |
| 359 | |
| 360 for (obj = sobj; obj != NULL; obj = next(obj)) | |
| 361 { | |
| 362 op = OBJPTR(obj); | |
| 363 | |
| 364 if (op && op->o_pos.y == y && op->o_pos.x == x) | |
| 365 return(obj); | |
| 366 } | |
| 367 | |
