1 /* 2 * Hero movement commands 3 * 4 * move.c 1.4 (A.I. Design) 12/22/84 5 */ 6 7 #include "rogue.h" 8 #include "curses.h" 9 10 /* 11 * Used to hold the new hero position 12 */ 13 14 coord nh; 15 16 /* 17 * do_run: 18 * Start the hero running 19 */ 20 do_run(ch) 21 byte ch; 22 { 23 running = TRUE; 24 after = FALSE; 25 runch = ch; 26 } 27 28 /* 29 * do_move: 30 * Check to see that a move is legal. If it is handle the 31 * consequences (fighting, picking up, etc.) 32 */ 33 do_move(dy, dx) 34 int dy, dx; 35 { 36 register byte ch; 37 register int fl; 38 39 firstmove = FALSE; 40 if (bailout) { 41 bailout = 0; 42 msg("the crack widens ... "); 43 descend(""); 44 return ; 45 } 46 if (no_move) { 47 no_move--; 48 msg("you are still stuck in the bear trap"); 49 return; 50 } 51 /* 52 * Do a confused move (maybe) 53 */ 54 if (on(player, ISHUH) && rnd(5) != 0) 55 rndmove(&player,&nh); 56 else { 57 over: 58 nh.y = hero.y + dy; 59 nh.x = hero.x + dx; 60 } 61 62 /* 63 * Check if he tried to move off the screen or make an illegal 64 * diagonal move, and stop him if he did. 65 * fudge it for 40/80 jll -- 2/7/84 66 */ 67 if (offmap(nh.y, nh.x)) 68 goto hit_bound; 69 if (!diag_ok(&hero, &nh)) { 70 after = FALSE; 71 running = FALSE; 72 return; 73 } 74 /* 75 * If you are running and the move does 76 * not get you anywhere stop running 77 */ 78 if (running && ce(hero, nh)) 79 after = running = FALSE; 80 fl = flat(nh.y, nh.x); 81 ch = winat(nh.y, nh.x); 82 /* 83 * When the hero is on the door do not allow him 84 * to run until he enters the room all the way 85 */ 86 if ((chat(hero.y,hero.x) == DOOR) && (ch == FLOOR)) 87 running = FALSE; 88 if (!(fl & F_REAL) && ch == FLOOR) { 89 chat(nh.y, nh.x) = ch = TRAP; 90 flat(nh.y, nh.x) |= F_REAL; 91 } 92 else if (on(player, ISHELD) && ch != 'F') { 93 msg("you are being held"); 94 return; 95 } 96 switch (ch) { 97 case ' ': 98 case VWALL: 99 case HWALL: 100 case ULWALL: 101 case URWALL: 102 case LLWALL: 103 case LRWALL: 104 hit_bound: 105 if (running && isgone(proom) && !on(player, ISBLIND)) { 106 register bool b1, b2; 107 108 switch (runch) 109 { 110 case 'h': 111 case 'l': 112 b1 = (hero.y > 1 && 113 ((flat(hero.y - 1, hero.x) & F_PASS) || 114 chat(hero.y - 1, hero.x) == DOOR)); 115 b2 = (hero.y < maxrow - 1 && 116 ((flat(hero.y + 1, hero.x) & F_PASS) || 117 chat(hero.y + 1, hero.x) == DOOR)); 118 if (!(b1 ^ b2)) 119 break; 120 if (b1) { 121 runch = 'k'; 122 dy = -1; 123 } else { 124 runch = 'j'; 125 dy = 1; 126 } 127 dx = 0; 128 goto over; 129 case 'j': 130 case 'k': 131 b1 = (hero.x > 1 && 132 ((flat(hero.y, hero.x - 1) & F_PASS) 133 || chat(hero.y, hero.x - 1) == DOOR)); 134 b2 = (hero.x < COLS-2 && 135 ((flat(hero.y, hero.x + 1) & F_PASS) 136 || chat(hero.y, hero.x + 1) == DOOR)); 137 if (!(b1 ^ b2)) 138 break; 139 if (b1) { 140 runch = 'h'; 141 dx = -1; 142 } else { 143 runch = 'l'; 144 dx = 1; 145 } 146 dy = 0; 147 goto over; 148 } 149 } 150 after = running = FALSE; 151 break; 152 case DOOR: 153 running = FALSE; 154 if (flat(hero.y, hero.x) & F_PASS) 155 enter_room(&nh); 156 goto move_stuff; 157 case TRAP: 158 ch = be_trapped(&nh); 159 if (ch == T_DOOR || ch == T_TELEP) 160 return; 161 case PASSAGE: 162 goto move_stuff; 163 case FLOOR: 164 if (!(fl & F_REAL)) 165 be_trapped(&hero); 166 goto move_stuff; 167 default: 168 running = FALSE; 169 if (isupper(ch) || moat(nh.y, nh.x)) 170 fight(&nh, ch, cur_weapon, FALSE); 171 else { 172 running = FALSE; 173 if (ch != STAIRS) 174 take = ch; 175 move_stuff: 176 mvaddch(hero.y, hero.x, chat(hero.y, hero.x)); 177 if ((fl & F_PASS) && (chat(oldpos.y, oldpos.x) == DOOR 178 || (flat(oldpos.y, oldpos.x) & F_MAZE))) 179 leave_room(&nh); 180 if ((fl & F_MAZE) && (flat(oldpos.y, oldpos.x) & F_MAZE) == 0) 181 enter_room(&nh); 182 bcopy(hero,nh); 183 } 184 } 185 } 186 187 /* 188 * door_open: 189 * Called to illuminate a room. If it is dark, remove anything 190 * that might move. 191 */ 192 door_open(rp) 193 struct room *rp; 194 { 195 register int j, k; 196 register byte ch; 197 register THING *item; 198 199 if (!(rp->r_flags & ISGONE) && !on(player, ISBLIND)) 200 for (j = rp->r_pos.y; j < rp->r_pos.y + rp->r_max.y; j++) 201 for (k = rp->r_pos.x; k < rp->r_pos.x + rp->r_max.x; k++) { 202 ch = winat(j, k); 203 /* move(j, k); Why do this,?????? */ 204 if (isupper(ch)) { 205 item = wake_monster(j, k); 206 if (item->t_oldch == ' ' && !(rp->r_flags & ISDARK) 207 && !on(player, ISBLIND)) 208 item->t_oldch = chat(j, k); 209 } 210 } 211 } 212 213 /* 214 * be_trapped: 215 * The guy stepped on a trap.... Make him pay. 216 */ 217 be_trapped(tc) 218 register coord *tc; 219 { 220 register byte tr; 221 register int index; 222 223 count = running = FALSE; 224 index = INDEX(tc->y, tc->x); 225 _level[index] = TRAP; 226 tr = _flags[index] & F_TMASK; 227 was_trapped = TRUE; 228 switch (tr) { 229 when T_DOOR: 230 descend("you fell into a trap!"); 231 when T_BEAR: 232 no_move += BEARTIME; 233 msg("you are caught in a bear trap"); 234 when T_SLEEP: 235 no_command += SLEEPTIME; 236 player.t_flags &= ~ISRUN; 237 msg("a %smist envelops you and you fall asleep", 238 noterse("strange white ")); 239 when T_ARROW: 240 if (swing(pstats.s_lvl-1, pstats.s_arm, 1)) { 241 pstats.s_hpt -= roll(1, 6); 242 if (pstats.s_hpt <= 0) { 243 msg("an arrow killed you"); 244 death('a'); 245 } else 246 msg("oh no! An arrow shot you"); 247 } 248 else { 249 THING *arrow; 250 251 if ((arrow = new_item()) != NULL) { 252 arrow->o_type = WEAPON; 253 arrow->o_which = ARROW; 254 init_weapon(arrow, ARROW); 255 arrow->o_count = 1; 256 bcopy(arrow->o_pos,hero); 257 fall(arrow, FALSE); 258 } 259 msg("an arrow shoots past you"); 260 } 261 when T_TELEP: 262 teleport(); 263 mvaddch(tc->y, tc->x, TRAP); /* since the hero's leaving, look() 264 won't put it on for us */ 265 was_trapped++; 266 when T_DART: 267 if (swing(pstats.s_lvl+1, pstats.s_arm, 1)) { 268 pstats.s_hpt -= roll(1, 4); 269 if (pstats.s_hpt <= 0) { 270 msg("a poisoned dart killed you"); 271 death('d'); 272 } 273 if (!ISWEARING(R_SUSTSTR) && !save(VS_POISON)) 274 chg_str(-1); 275 msg("a dart just hit you in the shoulder"); 276 } else 277 msg("a dart whizzes by your ear and vanishes"); 278 } 279 flush_type(); 280 return tr; 281 } 282 283 descend(mesg) 284 char *mesg; 285 { 286 level++; 287 if (*mesg == 0) 288 msg(" "); 289 new_level(); 290 msg(""); 291 msg(mesg); 292 if (!save(VS_LUCK)) { 293 msg("you are damaged by the fall"); 294 if ((pstats.s_hpt -= roll(1,8)) <= 0) 295 death('f'); 296 } 297 } 298 299 /* 300 * rndmove: 301 * Move in a random direction if the monster/person is confused 302 */ 303 rndmove(who,newmv) 304 THING *who; 305 coord *newmv; 306 { 307 register int x, y; 308 register byte ch; 309 register THING *obj; 310 311 y = newmv->y = who->t_pos.y + rnd(3) - 1; 312 x = newmv->x = who->t_pos.x + rnd(3) - 1; 313 /* 314 * Now check to see if that's a legal move. If not, don't move. 315 * (I.e., bump into the wall or whatever) 316 */ 317 if (y == who->t_pos.y && x == who->t_pos.x) 318 return ; 319 if ((y < 1 || y >= maxrow) || (x < 0 || x >= COLS)) 320 goto bad; 321 else if (!diag_ok(&who->t_pos, newmv)) 322 goto bad; 323 else { 324 ch = winat(y, x); 325 if (!step_ok(ch)) 326 goto bad; 327 if (ch == SCROLL) { 328 for (obj = lvl_obj; obj != NULL; obj = next(obj)) 329 if (y == obj->o_pos.y && x == obj->o_pos.x) 330 break; 331 if (obj != NULL && obj->o_which == S_SCARE) 332 goto bad; 333 } 334 } 335 return ; 336 337 bad: 338 bcopy((*newmv),who->t_pos); 339 return ; 340 } 341 ÿ