Mercurial > hg > early-roguelike
comparison arogue5/move.c @ 63:0ed67132cf10
Import Advanced Rogue 5.8 from the Roguelike Restoration Project (r1490)
| author | elwin |
|---|---|
| date | Thu, 09 Aug 2012 22:58:48 +0000 |
| parents | |
| children | a0a57cf42810 |
comparison
equal
deleted
inserted
replaced
| 62:0ef99244acb8 | 63:0ed67132cf10 |
|---|---|
| 1 /* | |
| 2 * Hero movement commands | |
| 3 * | |
| 4 * Advanced Rogue | |
| 5 * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T | |
| 6 * All rights reserved. | |
| 7 * | |
| 8 * Based on "Super-Rogue" | |
| 9 * Copyright (C) 1984 Robert D. Kindelberger | |
| 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 "curses.h" | |
| 20 #include <ctype.h> | |
| 21 #include "rogue.h" | |
| 22 | |
| 23 /* | |
| 24 * Used to hold the new hero position | |
| 25 */ | |
| 26 | |
| 27 static coord nh; | |
| 28 | |
| 29 static const char Moves[3][3] = { | |
| 30 { 'y', 'k', 'u' }, | |
| 31 { 'h', '\0', 'l' }, | |
| 32 { 'b', 'j', 'n' } | |
| 33 }; | |
| 34 | |
| 35 /* | |
| 36 * be_trapped: | |
| 37 * The guy stepped on a trap.... Make him pay. | |
| 38 */ | |
| 39 | |
| 40 be_trapped(th, tc) | |
| 41 register struct thing *th; | |
| 42 register coord *tc; | |
| 43 { | |
| 44 register struct trap *tp; | |
| 45 register char ch; | |
| 46 register const char *mname = NULL; | |
| 47 register bool is_player = (th == &player), | |
| 48 can_see; | |
| 49 register struct linked_list *mitem = NULL; | |
| 50 | |
| 51 | |
| 52 /* Can the player see the creature? */ | |
| 53 can_see = (cansee(tc->y, tc->x) && (is_player || !invisible(th))); | |
| 54 | |
| 55 tp = trap_at(tc->y, tc->x); | |
| 56 /* | |
| 57 * if he's wearing boots of elvenkind, he won't set off the trap | |
| 58 * unless its a magic pool (they're not really traps) | |
| 59 */ | |
| 60 if (is_player && | |
| 61 cur_misc[WEAR_BOOTS] != NULL && | |
| 62 cur_misc[WEAR_BOOTS]->o_which == MM_ELF_BOOTS && | |
| 63 tp->tr_type != POOL) | |
| 64 return '\0'; | |
| 65 | |
| 66 /* | |
| 67 * if the creature is flying then it won't set off the trap | |
| 68 */ | |
| 69 if (on(*th, ISFLY)) | |
| 70 return '\0'; | |
| 71 | |
| 72 tp->tr_flags |= ISFOUND; | |
| 73 | |
| 74 if (!is_player) { | |
| 75 mitem = find_mons(th->t_pos.y, th->t_pos.x); | |
| 76 mname = monsters[th->t_index].m_name; | |
| 77 } | |
| 78 else { | |
| 79 count = running = FALSE; | |
| 80 mvwaddch(cw, tp->tr_pos.y, tp->tr_pos.x, tp->tr_type); | |
| 81 } | |
| 82 switch (ch = tp->tr_type) { | |
| 83 case TRAPDOOR: | |
| 84 if (is_player) { | |
| 85 level++; | |
| 86 pstats.s_hpt -= roll(1, 10); | |
| 87 msg("You fell into a trap!"); | |
| 88 if (pstats.s_hpt <= 0) death(D_FALL); | |
| 89 new_level(NORMLEV); | |
| 90 } | |
| 91 else { | |
| 92 if (can_see) msg("The %s fell into a trap!", mname); | |
| 93 | |
| 94 /* See if the fall killed the monster */ | |
| 95 if ((th->t_stats.s_hpt -= roll(1, 10)) <= 0) { | |
| 96 killed(mitem, FALSE, FALSE); | |
| 97 } | |
| 98 else { /* Just move monster to next level */ | |
| 99 check_residue(th); | |
| 100 | |
| 101 /* Erase the monster from the old position */ | |
| 102 if (isalpha(mvwinch(cw, th->t_pos.y, th->t_pos.x))) | |
| 103 mvwaddch(cw, th->t_pos.y, th->t_pos.x, th->t_oldch); | |
| 104 mvwaddch(mw, th->t_pos.y, th->t_pos.x, ' '); | |
| 105 turn_on(*th, ISELSEWHERE); | |
| 106 detach(mlist, mitem); | |
| 107 attach(tlist, mitem); /* remember him next level */ | |
| 108 } | |
| 109 } | |
| 110 when BEARTRAP: | |
| 111 if (is_stealth(th)) { | |
| 112 if (is_player) msg("You pass a bear trap."); | |
| 113 else if (can_see) msg("The %s passes a bear trap.", mname); | |
| 114 } | |
| 115 else { | |
| 116 th->t_no_move += BEARTIME; | |
| 117 if (is_player) msg("You are caught in a bear trap."); | |
| 118 else if (can_see) msg("The %s is caught in a bear trap.", | |
| 119 mname); | |
| 120 } | |
| 121 when SLEEPTRAP: | |
| 122 if (is_player) { | |
| 123 msg("A strange white mist envelops you."); | |
| 124 if (!ISWEARING(R_ALERT)) { | |
| 125 msg("You fall asleep."); | |
| 126 no_command += SLEEPTIME; | |
| 127 } | |
| 128 } | |
| 129 else { | |
| 130 if (can_see) | |
| 131 msg("A strange white mist envelops the %s.",mname); | |
| 132 if (on(*th, ISUNDEAD)) { | |
| 133 if (can_see) | |
| 134 msg("The mist doesn't seem to affect the %s.",mname); | |
| 135 } | |
| 136 else { | |
| 137 th->t_no_move += SLEEPTIME; | |
| 138 } | |
| 139 } | |
| 140 when ARROWTRAP: | |
| 141 if (swing(th->t_ctype, th->t_stats.s_lvl-1, th->t_stats.s_arm, 1)) | |
| 142 { | |
| 143 if (is_player) { | |
| 144 msg("Oh no! An arrow shot you."); | |
| 145 if ((pstats.s_hpt -= roll(1, 6)) <= 0) { | |
| 146 msg("The arrow killed you."); | |
| 147 death(D_ARROW); | |
| 148 } | |
| 149 } | |
| 150 else { | |
| 151 if (can_see) msg("An arrow shot the %s.", mname); | |
| 152 if ((th->t_stats.s_hpt -= roll(1, 6)) <= 0) { | |
| 153 if (can_see) msg("The arrow killed the %s.", mname); | |
| 154 killed(mitem, FALSE, FALSE); | |
| 155 } | |
| 156 } | |
| 157 } | |
| 158 else | |
| 159 { | |
| 160 register struct linked_list *item; | |
| 161 register struct object *arrow; | |
| 162 | |
| 163 if (is_player) msg("An arrow shoots past you."); | |
| 164 else if (can_see) msg("An arrow shoots by the %s.", mname); | |
| 165 item = new_item(sizeof *arrow); | |
| 166 arrow = OBJPTR(item); | |
| 167 arrow->o_type = WEAPON; | |
| 168 arrow->contents = NULL; | |
| 169 arrow->o_which = ARROW; | |
| 170 arrow->o_hplus = rnd(3) - 1; | |
| 171 arrow->o_dplus = rnd(3) - 1; | |
| 172 init_weapon(arrow, ARROW); | |
| 173 arrow->o_count = 1; | |
| 174 arrow->o_pos = *tc; | |
| 175 arrow->o_mark[0] = '\0'; | |
| 176 fall(item, FALSE); | |
| 177 } | |
| 178 when TELTRAP: | |
| 179 if (is_player) teleport(); | |
| 180 else { | |
| 181 register int rm; | |
| 182 struct room *old_room; /* old room of monster */ | |
| 183 | |
| 184 /* | |
| 185 * Erase the monster from the old position | |
| 186 */ | |
| 187 if (isalpha(mvwinch(cw, th->t_pos.y, th->t_pos.x))) | |
| 188 mvwaddch(cw, th->t_pos.y, th->t_pos.x, th->t_oldch); | |
| 189 mvwaddch(mw, th->t_pos.y, th->t_pos.x, ' '); | |
| 190 /* | |
| 191 * check to see if room should go dark | |
| 192 */ | |
| 193 if (on(*th, HASFIRE)) { | |
| 194 old_room=roomin(&th->t_pos); | |
| 195 if (old_room != NULL) { | |
| 196 register struct linked_list *fire_item; | |
| 197 | |
| 198 for (fire_item = old_room->r_fires; fire_item != NULL; | |
| 199 fire_item = next(fire_item)) { | |
| 200 if (THINGPTR(fire_item) == th) { | |
| 201 detach(old_room->r_fires, fire_item); | |
| 202 destroy_item(fire_item); | |
| 203 | |
| 204 if (old_room->r_fires == NULL) { | |
| 205 old_room->r_flags &= ~HASFIRE; | |
| 206 if (can_see) light(&hero); | |
| 207 } | |
| 208 } | |
| 209 } | |
| 210 } | |
| 211 } | |
| 212 | |
| 213 /* Get a new position */ | |
| 214 do { | |
| 215 rm = rnd_room(); | |
| 216 rnd_pos(&rooms[rm], &th->t_pos); | |
| 217 } until(winat(th->t_pos.y, th->t_pos.x) == FLOOR); | |
| 218 | |
| 219 /* Put it there */ | |
| 220 mvwaddch(mw, th->t_pos.y, th->t_pos.x, th->t_type); | |
| 221 th->t_oldch = CCHAR( mvwinch(cw, th->t_pos.y, th->t_pos.x) ); | |
| 222 /* | |
| 223 * check to see if room that creature appears in should | |
| 224 * light up | |
| 225 */ | |
| 226 if (on(*th, HASFIRE)) { | |
| 227 register struct linked_list *fire_item; | |
| 228 | |
| 229 fire_item = creat_item(); | |
| 230 ldata(fire_item) = (char *) th; | |
| 231 attach(rooms[rm].r_fires, fire_item); | |
| 232 | |
| 233 rooms[rm].r_flags |= HASFIRE; | |
| 234 if(cansee(th->t_pos.y, th->t_pos.x) && | |
| 235 next(rooms[rm].r_fires) == NULL) | |
| 236 light(&hero); | |
| 237 } | |
| 238 if (can_see) msg("The %s seems to have disappeared!", mname); | |
| 239 } | |
| 240 when DARTTRAP: | |
| 241 if (swing(th->t_ctype, th->t_stats.s_lvl+1, th->t_stats.s_arm, 1)) { | |
| 242 if (is_player) { | |
| 243 msg("A small dart just hit you in the shoulder."); | |
| 244 if ((pstats.s_hpt -= roll(1, 4)) <= 0) { | |
| 245 msg("The dart killed you."); | |
| 246 death(D_DART); | |
| 247 } | |
| 248 | |
| 249 /* Now the poison */ | |
| 250 if (!save(VS_POISON, &player, 0)) { | |
| 251 /* 75% chance it will do point damage - else strength */ | |
| 252 if (rnd(100) < 75) { | |
| 253 pstats.s_hpt /= 2; | |
| 254 if (pstats.s_hpt == 0) death(D_POISON); | |
| 255 } | |
| 256 else if (!ISWEARING(R_SUSABILITY)) | |
| 257 chg_str(-1); | |
| 258 } | |
| 259 } | |
| 260 else { | |
| 261 if (can_see) | |
| 262 msg("A small dart just hit the %s in the shoulder.", | |
| 263 mname); | |
| 264 if ((th->t_stats.s_hpt -= roll(1,4)) <= 0) { | |
| 265 if (can_see) msg("The dart killed the %s.", mname); | |
| 266 killed(mitem, FALSE, FALSE); | |
| 267 } | |
| 268 if (!save(VS_POISON, th, 0)) { | |
| 269 th->t_stats.s_hpt /= 2; | |
| 270 if (th->t_stats.s_hpt <= 0) { | |
| 271 if (can_see) msg("The dart killed the %s.", mname); | |
| 272 killed(mitem, FALSE, FALSE); | |
| 273 } | |
| 274 } | |
| 275 } | |
| 276 } | |
| 277 else { | |
| 278 if (is_player) | |
| 279 msg("A small dart whizzes by your ear and vanishes."); | |
| 280 else if (can_see) | |
| 281 msg("A small dart whizzes by the %s's ear and vanishes.", | |
| 282 mname); | |
| 283 } | |
| 284 when POOL: { | |
| 285 register int i; | |
| 286 | |
| 287 i = rnd(100); | |
| 288 if (is_player) { | |
| 289 if ((tp->tr_flags & ISGONE)) { | |
| 290 if (i < 30) { | |
| 291 teleport(); /* teleport away */ | |
| 292 pool_teleport = TRUE; | |
| 293 } | |
| 294 else if((i < 45) && level > 2) { | |
| 295 level -= rnd(2) + 1; | |
| 296 cur_max = level; | |
| 297 new_level(NORMLEV); | |
| 298 pool_teleport = TRUE; | |
| 299 msg("You here a faint groan from below."); | |
| 300 } | |
| 301 else if(i < 70) { | |
| 302 level += rnd(4) + 1; | |
| 303 new_level(NORMLEV); | |
| 304 pool_teleport = TRUE; | |
| 305 msg("You find yourself in strange surroundings."); | |
| 306 } | |
| 307 else if(i > 95) { | |
| 308 msg("Oh no!!! You drown in the pool!!! --More--"); | |
| 309 wait_for(cw,' '); | |
| 310 death(D_DROWN); | |
| 311 } | |
| 312 } | |
| 313 } | |
| 314 else { | |
| 315 if (i < 60) { | |
| 316 if (can_see) { | |
| 317 /* Drowns */ | |
| 318 if (i < 30) msg("The %s drowned in the pool!", mname); | |
| 319 | |
| 320 /* Teleported to another level */ | |
| 321 else msg("The %s disappeared!", mname); | |
| 322 } | |
| 323 killed(mitem, FALSE, FALSE); | |
| 324 } | |
| 325 } | |
| 326 } | |
| 327 when MAZETRAP: | |
| 328 if (is_player) { | |
| 329 pstats.s_hpt -= roll(1, 10); | |
| 330 level++; | |
| 331 msg("You fell through a trap door!"); | |
| 332 if (pstats.s_hpt <= 0) death(D_FALL); | |
| 333 new_level(MAZELEV); | |
| 334 msg("You are surrounded by twisty passages!"); | |
| 335 } | |
| 336 else { | |
| 337 if (can_see) msg("The %s fell into a trap!", mname); | |
| 338 killed(mitem, FALSE, FALSE); | |
| 339 } | |
| 340 } | |
| 341 | |
| 342 /* Move the cursor back onto the hero */ | |
| 343 wmove(cw, hero.y, hero.x); | |
| 344 | |
| 345 md_flushinp(); /* flush typeahead */ | |
| 346 | |
| 347 return(ch); | |
| 348 } | |
| 349 | |
| 350 /* | |
| 351 * blue_light: | |
| 352 * magically light up a room (or level or make it dark) | |
| 353 */ | |
| 354 | |
| 355 bool | |
| 356 blue_light(blessed, cursed) | |
| 357 bool blessed, cursed; | |
| 358 { | |
| 359 register struct room *rp; | |
| 360 bool ret_val=FALSE; /* Whether or not affect is known */ | |
| 361 | |
| 362 rp = roomin(&hero); /* What room is hero in? */ | |
| 363 | |
| 364 /* Darken the room if the magic is cursed */ | |
| 365 if (cursed) { | |
| 366 if ((rp == NULL) || !lit_room(rp)) msg(nothing); | |
| 367 else { | |
| 368 rp->r_flags |= ISDARK; | |
| 369 if (!lit_room(rp) && (levtype != OUTSIDE || !daytime)) | |
| 370 msg("The %s suddenly goes dark.", | |
| 371 levtype == OUTSIDE ? "area" : "room"); | |
| 372 else msg(nothing); | |
| 373 ret_val = TRUE; | |
