Mercurial > hg > early-roguelike
comparison urogue/command.c @ 256:c495a4f288c6
Import UltraRogue from the Roguelike Restoration Project (r1490)
| author | John "Elwin" Edwards |
|---|---|
| date | Tue, 31 Jan 2017 19:56:04 -0500 |
| parents | |
| children | 911f0aa6e758 |
comparison
equal
deleted
inserted
replaced
| 253:d9badb9c0179 | 256:c495a4f288c6 |
|---|---|
| 1 /* | |
| 2 command.c - Read and execute the user commands | |
| 3 | |
| 4 UltraRogue: The Ultimate Adventure in the Dungeons of Doom | |
| 5 Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong | |
| 6 All rights reserved. | |
| 7 | |
| 8 Based on "Advanced Rogue" | |
| 9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka | |
| 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 <string.h> | |
| 20 #include <stdlib.h> | |
| 21 #include <ctype.h> | |
| 22 #include "rogue.h" | |
| 23 | |
| 24 /* | |
| 25 command() | |
| 26 Process the user commands | |
| 27 */ | |
| 28 | |
| 29 void | |
| 30 command(void) | |
| 31 { | |
| 32 static char repcommand; /* Command to repeat if we are repeating */ | |
| 33 static int fight_to_death; /* Flags if we are fighting to death */ | |
| 34 static coord dir; /* Last direction specified */ | |
| 35 | |
| 36 object *obj; | |
| 37 char ch; | |
| 38 int ntimes = 1; /* Number of player moves */ | |
| 39 coord nullcoord; | |
| 40 | |
| 41 nullcoord.x = nullcoord.y = 0; | |
| 42 | |
| 43 if (on(player, CANFLY) && rnd(2)) | |
| 44 ntimes++; | |
| 45 | |
| 46 if (on(player, ISHASTE)) | |
| 47 ntimes++; | |
| 48 | |
| 49 if (fighting && att_bonus()) | |
| 50 ntimes *= 2; | |
| 51 | |
| 52 if (on(player, ISSLOW)) | |
| 53 { | |
| 54 if (player.t_turn != TRUE) | |
| 55 ntimes--; | |
| 56 | |
| 57 player.t_turn ^= TRUE; | |
| 58 } | |
| 59 | |
| 60 if (ntimes == 0) | |
| 61 return; | |
| 62 | |
| 63 while (ntimes--) | |
| 64 { | |
| 65 moving = FALSE; | |
| 66 | |
| 67 /* If player is infested, take off a hit point */ | |
| 68 | |
| 69 if (on(player, HASINFEST) && !is_wearing(R_HEALTH)) | |
| 70 { | |
| 71 if ((pstats.s_hpt -= infest_dam) <= 0) | |
| 72 { | |
| 73 death(D_INFESTATION); | |
| 74 return; | |
| 75 } | |
| 76 } | |
| 77 | |
| 78 look(after); | |
| 79 | |
| 80 if (!running) | |
| 81 door_stop = FALSE; | |
| 82 | |
| 83 status(FALSE); | |
| 84 wmove(cw, hero.y, hero.x); | |
| 85 | |
| 86 if (!((running || count) && jump)) | |
| 87 wrefresh(cw); /* Draw screen */ | |
| 88 | |
| 89 take = 0; | |
| 90 after = TRUE; | |
| 91 | |
| 92 /* | |
| 93 * Read command or continue run | |
| 94 */ | |
| 95 | |
| 96 if (!no_command) | |
| 97 { | |
| 98 if (fighting) | |
| 99 { | |
| 100 ch = (fight_to_death) ? 'F' : 'f'; | |
| 101 } | |
| 102 else if (running) | |
| 103 { | |
| 104 /* | |
| 105 * If in a corridor, if we are at a turn with | |
| 106 * only one way to go, turn that way. | |
| 107 */ | |
| 108 | |
| 109 if ((winat(hero.y, hero.x) == PASSAGE) && off(player, ISHUH) && | |
| 110 (off(player, ISBLIND))) | |
| 111 switch (runch) | |
| 112 { | |
| 113 case 'h': corr_move(0, -1); break; | |
| 114 case 'j': corr_move(1, 0); break; | |
| 115 case 'k': corr_move(-1, 0); break; | |
| 116 case 'l': corr_move(0, 1); break; | |
| 117 } | |
| 118 | |
| 119 ch = runch; | |
| 120 } | |
| 121 else if (count) | |
| 122 ch = repcommand; | |
| 123 else | |
| 124 { | |
| 125 ch = readchar(); | |
| 126 | |
| 127 if (mpos != 0 && !running) | |
| 128 msg(""); /* Erase message if its there */ | |
| 129 } | |
| 130 } | |
| 131 else | |
| 132 { | |
| 133 ch = '.'; | |
| 134 fighting = moving = FALSE; | |
| 135 } | |
| 136 | |
| 137 if (no_command) | |
| 138 { | |
| 139 if (--no_command == 0) | |
| 140 msg("You can move again."); | |
| 141 } | |
| 142 else | |
| 143 { | |
| 144 | |
| 145 /* | |
| 146 * check for prefixes | |
| 147 */ | |
| 148 | |
| 149 if (isdigit(ch)) | |
| 150 { | |
| 151 count = 0; | |
| 152 while (isdigit(ch)) | |
| 153 { | |
| 154 count = count * 10 + (ch - '0'); | |
| 155 ch = readcharw(cw); | |
| 156 } | |
| 157 repcommand = ch; | |
| 158 | |
| 159 /* | |
| 160 * Preserve count for commands which can be | |
| 161 * repeated. | |
| 162 */ | |
| 163 | |
| 164 switch(ch) | |
| 165 { | |
| 166 case 'h': | |
| 167 case 'j': | |
| 168 case 'k': | |
| 169 case 'l': | |
| 170 case 'y': | |
| 171 case 'u': | |
| 172 case 'b': | |
| 173 case 'n': | |
| 174 case 'H': | |
| 175 case 'J': | |
| 176 case 'K': | |
| 177 case 'L': | |
| 178 case 'Y': | |
| 179 case 'U': | |
| 180 case 'B': | |
| 181 case 'N': | |
| 182 case 'q': | |
| 183 case 'r': | |
| 184 case 's': | |
| 185 case 'm': | |
| 186 case 't': | |
| 187 case 'C': | |
| 188 case 'I': | |
| 189 case '.': | |
| 190 case 'z': | |
| 191 case 'p': | |
| 192 break; | |
| 193 default: | |
| 194 count = 0; | |
| 195 } | |
| 196 } | |
| 197 | |
| 198 /* Save current direction */ | |
| 199 | |
| 200 if (!running) /* If running, it is already saved */ | |
| 201 switch (ch) | |
| 202 { | |
| 203 case 'h': | |
| 204 case 'j': | |
| 205 case 'k': | |
| 206 case 'l': | |
| 207 case 'y': | |
| 208 case 'u': | |
| 209 case 'b': | |
| 210 case 'n': | |
| 211 runch = ch; | |
| 212 break; | |
| 213 case 'H': | |
| 214 case 'J': | |
| 215 case 'K': | |
| 216 case 'L': | |
| 217 case 'Y': | |
| 218 case 'U': | |
| 219 case 'B': | |
| 220 case 'N': | |
| 221 runch = (char) tolower(ch); | |
| 222 break; | |
| 223 } | |
| 224 | |
| 225 /* | |
| 226 * execute a command | |
| 227 */ | |
| 228 | |
| 229 if (count && !running) | |
| 230 count--; | |
| 231 | |
| 232 switch(ch) | |
| 233 { | |
| 234 /* | |
| 235 * Movement and combat commands | |
| 236 */ | |
| 237 | |
| 238 case 'h': do_move(0,-1); break; | |
| 239 case 'j': do_move(1, 0); break; | |
| 240 case 'k': do_move(-1, 0); break; | |
| 241 case 'l': do_move(0, 1); break; | |
| 242 case 'y': do_move(-1, -1); break; | |
| 243 case 'u': do_move(-1, 1); break; | |
| 244 case 'b': do_move(1, -1); break; | |
| 245 case 'n': do_move(1, 1); break; | |
| 246 case 'H': do_run('h'); break; | |
| 247 case 'J': do_run('j'); break; | |
| 248 case 'K': do_run('k'); break; | |
| 249 case 'L': do_run('l'); break; | |
| 250 case 'Y': do_run('y'); break; | |
| 251 case 'U': do_run('u'); break; | |
| 252 case 'B': do_run('b'); break; | |
| 253 case 'N': do_run('n'); break; | |
| 254 case 'm': | |
| 255 moving = TRUE; | |
| 256 if (!get_dir()) | |
| 257 { | |
| 258 after = FALSE; | |
| 259 break; | |
| 260 } | |
| 261 do_move(delta.y, delta.x); | |
| 262 break; | |
| 263 case 'F': | |
| 264 case 'f': | |
| 265 fight_to_death = (ch == 'F'); | |
| 266 if (!fighting) | |
| 267 { | |
| 268 if (get_dir()) | |
| 269 { | |
| 270 dir = delta; | |
| 271 beast = NULL; | |
| 272 } | |
| 273 else | |
| 274 { | |
| 275 after = FALSE; | |
| 276 break; | |
| 277 } | |
| 278 } | |
| 279 do_fight(dir, (ch == 'F') ? TRUE : FALSE); | |
| 280 break; | |
| 281 case 't': | |
| 282 if (get_dir()) | |
| 283 missile(delta.y, delta.x, get_item("throw", 0), | |
| 284 &player); | |
| 285 else | |
| 286 after = FALSE; | |
| 287 | |
| 288 /* | |
| 289 * Informational commands - Do not do | |
| 290 * after daemons | |
| 291 */ | |
| 292 break; | |
| 293 | |
| 294 case 0x7f: /* sometime generated by */ | |
| 295 /* suspend/foreground */ | |
| 296 case ESCAPE: | |
| 297 case ' ': | |
| 298 after = FALSE; /* do nothing */ | |
| 299 break; | |
| 300 case 'Q': | |
| 301 after = FALSE; | |
| 302 quit(); | |
| 303 break; | |
| 304 case 'i': | |
| 305 after = FALSE; | |
| 306 inventory(pack, '*'); | |
| 307 break; | |
| 308 case 'I': | |
| 309 after = FALSE; | |
| 310 inventory(pack, 0); | |
| 311 break; | |
| 312 case '~': | |
| 313 after = FALSE; | |
| 314 next_exp_level(MESSAGE); | |
| 315 break; | |
| 316 case '>': | |
| 317 after = FALSE; | |
| 318 d_level(); | |
| 319 break; | |
| 320 case '<': | |
| 321 after = FALSE; | |
| 322 u_level(); | |
| 323 break; | |
| 324 case '?': | |
| 325 after = FALSE; | |
| 326 help(); | |
| 327 break; | |
| 328 case '/': | |
| 329 after = FALSE; | |
| 330 identify(); | |
| 331 break; | |
| 332 case 'v': | |
| 333 after = FALSE; | |
| 334 msg("UltraRogue Version %s.", release); | |
| 335 break; | |
| 336 case 'o': | |
| 337 after = FALSE; | |
| 338 option(); | |
| 339 strcpy(fd_data[1].mi_name, fruit); | |
| 340 break; | |
| 341 case 12: /* ctrl-l */ | |
| 342 case 18: /* ctrl-r */ | |
| 343 after = FALSE; | |
| 344 clearok(cw, TRUE); | |
| 345 wrefresh(cw); | |
| 346 break; | |
| 347 case 16: /* ctrl-p */ | |
| 348 { | |
| 349 int decrement = FALSE; | |
| 350 after = FALSE; | |
| 351 | |
| 352 if (mpos == 0) | |
| 353 decrement = TRUE; | |
| 354 | |
| 355 msg_index = (msg_index + 9) % 10; | |
| 356 msg(msgbuf[msg_index]); | |
| 357 if (decrement) | |
| 358 msg_index = (msg_index + 9) % 10; | |
| 359 } | |
| 360 break; | |
| 361 | |
| 362 case 'S': | |
| 363 after = FALSE; | |
| 364 if (save_game()) | |
| 365 { | |
| 366 wclear(cw); | |
| 367 wrefresh(cw); | |
| 368 endwin(); | |
| 369 exit(0); | |
| 370 } | |
