Mercurial > hg > early-roguelike
comparison srogue/move.c @ 36:2128c7dc8a40
Import Super-Rogue 9.0 from the Roguelike Restoration Project (r1490)
| author | elwin |
|---|---|
| date | Thu, 25 Nov 2010 12:21:41 +0000 |
| parents | |
| children | 94a0d9dd5ce1 |
comparison
equal
deleted
inserted
replaced
| 35:05018c63a721 | 36:2128c7dc8a40 |
|---|---|
| 1 /* | |
| 2 * Hero movement commands | |
| 3 * | |
| 4 * @(#)move.c 9.0 (rdk) 7/17/84 | |
| 5 * | |
| 6 * Super-Rogue | |
| 7 * Copyright (C) 1984 Robert D. Kindelberger | |
| 8 * All rights reserved. | |
| 9 * | |
| 10 * Based on "Rogue: Exploring the Dungeons of Doom" | |
| 11 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman | |
| 12 * All rights reserved. | |
| 13 * | |
| 14 * See the file LICENSE.TXT for full copyright and licensing information. | |
| 15 */ | |
| 16 | |
| 17 #include <ctype.h> | |
| 18 #include "rogue.h" | |
| 19 #include "rogue.ext" | |
| 20 | |
| 21 /* | |
| 22 * Used to hold the new hero position | |
| 23 */ | |
| 24 | |
| 25 struct coord nh; | |
| 26 | |
| 27 /* | |
| 28 * do_run: | |
| 29 * Start the hero running | |
| 30 */ | |
| 31 | |
| 32 do_run(ch) | |
| 33 char ch; | |
| 34 { | |
| 35 running = TRUE; | |
| 36 after = FALSE; | |
| 37 runch = ch; | |
| 38 } | |
| 39 | |
| 40 /* | |
| 41 * do_move: | |
| 42 * Check to see that a move is legal. If it is handle the | |
| 43 * consequences (fighting, picking up, etc.) | |
| 44 */ | |
| 45 | |
| 46 do_move(dy, dx) | |
| 47 int dy, dx; | |
| 48 { | |
| 49 reg int ch; | |
| 50 reg struct room *rp; | |
| 51 | |
| 52 firstmove = FALSE; | |
| 53 curprice = -1; | |
| 54 inpool = FALSE; | |
| 55 | |
| 56 if (player.t_nomove > 0) { | |
| 57 player.t_nomove -= 1; | |
| 58 msg("You are still stuck in the bear trap."); | |
| 59 return; | |
| 60 } | |
| 61 /* | |
| 62 * Do a confused move (maybe) | |
| 63 */ | |
| 64 if ((rnd(100) < 80 && pl_on(ISHUH)) || | |
| 65 (iswearing(R_DELUS) && rnd(100) < 25)) | |
| 66 nh = *rndmove(&player); | |
| 67 else { | |
| 68 nh.y = hero.y + dy; | |
| 69 nh.x = hero.x + dx; | |
| 70 } | |
| 71 /* | |
| 72 * Check if he tried to move off the screen or make | |
| 73 * an illegal diagonal move, and stop him if he did. | |
| 74 */ | |
| 75 if (!cordok(nh.y, nh.x) || | |
| 76 (pl_off(ISETHER) && !diag_ok(&hero, &nh))) { | |
| 77 after = running = FALSE; | |
| 78 return; | |
| 79 } | |
| 80 if (running) { | |
| 81 ch = winat(nh.y, nh.x); | |
| 82 if (dead_end(ch)) { | |
| 83 reg int gox, goy, apsg, whichway; | |
| 84 | |
| 85 gox = goy = apsg = 0; | |
| 86 if (dy == 0) { | |
| 87 ch = show(hero.y+1,hero.x); | |
| 88 if (ch == PASSAGE) { | |
| 89 apsg += 1; | |
| 90 goy = 1; | |
| 91 } | |
| 92 ch = show(hero.y-1,hero.x); | |
| 93 if (ch == PASSAGE) { | |
| 94 apsg += 1; | |
| 95 goy = -1; | |
| 96 } | |
| 97 } | |
| 98 else if (dx == 0) { | |
| 99 ch = show(hero.y,hero.x+1); | |
| 100 if (ch == PASSAGE) { | |
| 101 gox = 1; | |
| 102 apsg += 1; | |
| 103 } | |
| 104 ch = show(hero.y,hero.x-1); | |
| 105 if (ch == PASSAGE) { | |
| 106 gox = -1; | |
| 107 apsg += 1; | |
| 108 } | |
| 109 } | |
| 110 if (apsg != 1) { | |
| 111 running = after = FALSE; | |
| 112 return; | |
| 113 } | |
| 114 else { /* can still run here */ | |
| 115 nh.y = hero.y + goy; | |
| 116 nh.x = hero.x + gox; | |
| 117 whichway = (goy + 1) * 3 + gox + 1; | |
| 118 switch(whichway) { | |
| 119 case 0: runch = 'y'; | |
| 120 when 1: runch = 'k'; | |
| 121 when 2: runch = 'u'; | |
| 122 when 3: runch = 'h'; | |
| 123 when 4: runch = '.'; /* shouldn't do */ | |
| 124 when 5: runch = 'l'; | |
| 125 when 6: runch = 'b'; | |
| 126 when 7: runch = 'j'; | |
| 127 when 8: runch = 'n'; | |
| 128 } | |
| 129 } | |
| 130 } | |
| 131 } | |
| 132 if (running && ce(hero, nh)) | |
| 133 after = running = FALSE; | |
| 134 ch = winat(nh.y, nh.x); | |
| 135 if (pl_on(ISHELD) && ch != 'F' && ch != 'd') { | |
| 136 msg("You are being held."); | |
| 137 return; | |
| 138 } | |
| 139 if (pl_off(ISETHER)) { | |
| 140 if (isatrap(ch)) { | |
| 141 ch = be_trapped(&nh, &player); | |
| 142 if (nlmove) { | |
| 143 nlmove = FALSE; | |
| 144 return; | |
| 145 } | |
| 146 else if (ch == POOL) | |
| 147 inpool = TRUE; | |
| 148 } | |
| 149 else if (dead_end(ch)) { | |
| 150 after = running = FALSE; | |
| 151 return; | |
| 152 } | |
| 153 else { | |
| 154 switch(ch) { | |
| 155 case GOLD: case POTION: case SCROLL: | |
| 156 case FOOD: case WEAPON: case ARMOR: | |
| 157 case RING: case AMULET: case STICK: | |
| 158 running = FALSE; | |
| 159 take = ch; | |
| 160 default: | |
| 161 if (illeg_ch(ch)) { | |
| 162 running = FALSE; | |
| 163 mvaddch(nh.y, nh.x, FLOOR); | |
| 164 teleport(rndspot, &player); | |
| 165 light(&nh); | |
| 166 msg("The spatial warp disappears !"); | |
| 167 return; | |
| 168 } | |
| 169 } | |
| 170 } | |
| 171 } | |
| 172 rp = roomin(&nh); | |
| 173 if (ch == DOOR) { /* just stepped on a door */ | |
| 174 running = FALSE; | |
| 175 if (rp != NULL && rf_on(rp, ISTREAS)) { | |
| 176 struct linked_list *item; | |
| 177 struct thing *tp; | |
| 178 | |
| 179 for (item = mlist; item != NULL; item = next(item)) { | |
| 180 tp = THINGPTR(item); | |
| 181 if (tp->t_room == rp) | |
| 182 runto(&tp->t_pos, &hero); | |
| 183 } | |
| 184 } | |
| 185 } | |
| 186 else if (ch == STAIRS && pl_off(ISETHER)) | |
| 187 running = FALSE; | |
| 188 else if (isalpha(ch) && pl_off(ISETHER)) { | |
| 189 running = FALSE; | |
| 190 fight(&nh, cur_weapon, FALSE); | |
| 191 return; | |
| 192 } | |
| 193 if (rp == NULL && player.t_room != NULL) | |
| 194 light(&hero); /* exiting a room */ | |
| 195 else if (rp != NULL && player.t_room == NULL) | |
| 196 light(&nh); /* just entering a room */ | |
| 197 if (pl_on(ISBLIND)) | |
| 198 ch = ' '; | |
| 199 else | |
| 200 ch = player.t_oldch; | |
| 201 mvwaddch(cw, hero.y, hero.x, ch); | |
| 202 mvwaddch(cw, nh.y, nh.x, PLAYER); | |
| 203 hero = nh; | |
| 204 player.t_room = rp; | |
| 205 player.t_oldch = mvinch(hero.y, hero.x); | |
| 206 } | |
| 207 | |
| 208 /* | |
| 209 * Called to illuminate a room. | |
| 210 * If it is dark, remove anything that might move. | |
| 211 */ | |
| 212 light(cp) | |
| 213 struct coord *cp; | |
| 214 { | |
| 215 reg struct room *rp; | |
| 216 reg int j, k, x, y; | |
| 217 reg char ch, rch; | |
| 218 reg struct linked_list *item; | |
| 219 | |
| 220 rp = roomin(cp); | |
| 221 if (rp == NULL) | |
| 222 return; | |
| 223 if (pl_on(ISBLIND)) { | |
| 224 for (j = 0; j < rp->r_max.y; j += 1) { | |
| 225 for (k = 0; k < rp->r_max.x; k += 1) { | |
| 226 y = rp->r_pos.y + j; | |
| 227 x = rp->r_pos.x + k; | |
| 228 mvwaddch(cw, y, x, ' '); | |
| 229 } | |
| 230 } | |
| 231 look(FALSE); | |
| 232 return; | |
| 233 } | |
| 234 if (iswearing(R_LIGHT)) | |
| 235 rp->r_flags &= ~ISDARK; | |
| 236 for (j = 0; j < rp->r_max.y; j += 1) { | |
| 237 for (k = 0; k < rp->r_max.x; k += 1) { | |
| 238 y = rp->r_pos.y + j; | |
| 239 x = rp->r_pos.x + k; | |
| 240 if (levtype == MAZELEV && !cansee(y, x)) | |
| 241 continue; | |
| 242 ch = show(y, x); | |
| 243 wmove(cw, y, x); | |
| 244 /* | |
| 245 * Figure out how to display a secret door | |
| 246 */ | |
| 247 if (ch == SECRETDOOR) { | |
| 248 if (j == 0 || j == rp->r_max.y - 1) | |
| 249 ch = '-'; | |
| 250 else | |
| 251 ch = '|'; | |
| 252 } | |
| 253 if (isalpha(ch)) { | |
| 254 struct thing *mit; | |
| 255 | |
| 256 item = wake_monster(y, x); | |
| 257 if (item == NULL) { | |
| 258 ch = FLOOR; | |
| 259 mvaddch(y, x, ch); | |
| 260 } | |
| 261 else { | |
| 262 mit = THINGPTR(item); | |
| 263 if (mit->t_oldch == ' ') | |
| 264 if (!rf_on(rp,ISDARK)) | |
| 265 mit->t_oldch = mvinch(y, x); | |
| 266 if (levtype == MAZELEV) | |
| 267 ch = mvinch(y, x); | |
| 268 } | |
| 269 } | |
| 270 if (rf_on(rp,ISDARK)) { | |
| 271 rch = mvwinch(cw, y, x); | |
| 272 if (isatrap(rch)) { | |
| 273 ch = rch; /* if its a trap */ | |
| 274 } | |
| 275 else { /* try other things */ | |
| 276 switch (rch) { | |
| 277 case DOOR: case STAIRS: case '|': | |
| 278 case '-': | |
| 279 ch = rch; | |
| 280 otherwise: | |
| 281 ch = ' '; | |
| 282 } | |
| 283 } | |
| 284 } | |
| 285 mvwaddch(cw, y, x, ch); | |
| 286 } | |
| 287 } | |
| 288 } | |
| 289 | |
| 290 /* | |
| 291 * show: | |
| 292 * returns what a certain thing will display as to the un-initiated | |
| 293 */ | |
| 294 show(y, x) | |
| 295 int y, x; | |
| 296 { | |
| 297 reg char ch = winat(y, x); | |
| 298 reg struct linked_list *it; | |
| 299 reg struct thing *tp; | |
| 300 reg struct trap *ta; | |
| 301 | |
| 302 if (isatrap(ch)) { | |
| 303 if ((ta = trap_at(y, x)) == NULL) | |
| 304 return FLOOR; | |
| 305 if (iswearing(R_FTRAPS)) | |
| 306 ta->tr_flags |= ISFOUND; | |
| 307 return ((ta->tr_flags & ISFOUND) ? ta->tr_type : FLOOR); | |
| 308 } | |
| 309 if (ch == SECRETDOOR && iswearing(R_FTRAPS)) { | |
| 310 mvaddch(y,x,DOOR); | |
| 311 return DOOR; | |
| 312 } | |
| 313 if ((it = find_mons(y, x)) != NULL) { /* maybe a monster */ | |
| 314 tp = THINGPTR(it); | |
| 315 if (ch == 'M' || (tp->t_flags & ISINVIS)) { | |
| 316 if (ch == 'M') | |
| 317 ch = tp->t_disguise; | |
| 318 else if (pl_off(CANSEE)) { | |
| 319 if (ch == 's') | |
| 320 ch = ' '; /* shadows show as a blank */ | |
| 321 else | |
| 322 ch = mvinch(y, x); /* hide invisibles */ | |
| 323 } | |
| 324 } | |
| 325 } | |
| 326 return ch; | |
| 327 } | |
| 328 | |
| 329 /* | |
| 330 * be_trapped: | |
| 331 * Hero or monster stepped on a trap. | |
| 332 */ | |
| 333 be_trapped(tc, th) | |
| 334 struct thing *th; | |
| 335 struct coord *tc; | |
| 336 { | |
| 337 reg struct trap *trp; | |
| 338 reg int ch, ishero; | |
| 339 struct linked_list *mon; | |
| 340 char stuckee[35], seeit, sayso; | |
| 341 | |
| 342 if ((trp = trap_at(tc->y, tc->x)) == NULL) | |
| 343 return; | |
| 344 ishero = (th == &player); | |
| 345 if (ishero) { | |
| 346 strcpy(stuckee, "You"); | |
| 347 count = running = FALSE; | |
| 348 } | |
| 349 else { | |
| 350 sprintf(stuckee, "The %s", monsters[th->t_indx].m_name); | |
| 351 } | |
| 352 seeit = cansee(tc->y, tc->x); | |
| 353 if (seeit) | |
| 354 mvwaddch(cw, tc->y, tc->x, trp->tr_type); | |
| 355 trp->tr_flags |= ISFOUND; | |
| 356 sayso = TRUE; | |
| 357 switch (ch = trp->tr_type) { | |
| 358 case POST: | |
| 359 if (ishero) { | |
| 360 nlmove = TRUE; | |
| 361 new_level(POSTLEV); | |
| 362 } | |
| 363 else | |
| 364 goto goner; | |
| 365 when MAZETRAP: | |
| 366 if (ishero) { | |
| 367 nlmove = TRUE; | |
| 368 level += 1; | |
| 369 new_level(MAZELEV); | |
| 370 msg("You are surrounded by twisty passages!"); | |
| 371 } | |
| 372 else | |
| 373 goto goner; | |
| 374 when TELTRAP: | |
| 375 nlmove = TRUE; | |
| 376 teleport(trp->tr_goto, th); | |
| 377 when TRAPDOOR: | |
| 378 if (ishero) { | |
| 379 level += 1; | |
| 380 new_level(NORMLEV); | |
| 381 } | |
| 382 else { /* monsters get lost */ | |
| 383 goner: | |
| 384 ch = GONER; | |
| 385 } | |
| 386 nlmove = TRUE; | |
| 387 if (seeit && sayso) | |
| 388 msg("%s fell into a trap!", stuckee); |
