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