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