Mercurial > hg > early-roguelike
comparison arogue7/command.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 | b786053d2f37 |
comparison
equal
deleted
inserted
replaced
| 124:d10fc4a065ac | 125:adfa37e67084 |
|---|---|
| 1 /* | |
| 2 * command.c - Read and execute the user 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 * Read and execute the user commands | |
| 17 * | |
| 18 */ | |
| 19 | |
| 20 #include "curses.h" | |
| 21 #include <ctype.h> | |
| 22 #include <signal.h> | |
| 23 #include "mach_dep.h" | |
| 24 #include "rogue.h" | |
| 25 #ifdef PC7300 | |
| 26 #include "sys/window.h" | |
| 27 extern struct uwdata wdata; | |
| 28 #endif | |
| 29 | |
| 30 /* | |
| 31 * command: | |
| 32 * Process the user commands | |
| 33 */ | |
| 34 | |
| 35 command() | |
| 36 { | |
| 37 unsigned char ch; | |
| 38 struct linked_list *item; | |
| 39 unsigned char countch, direction, newcount = FALSE; | |
| 40 int segment = 1; | |
| 41 int monst_limit, monst_current; | |
| 42 | |
| 43 monst_limit = monst_current = 1; | |
| 44 while (playing) { | |
| 45 /* | |
| 46 * Let the daemons start up, but only do them once a round | |
| 47 * (round = 10 segments). | |
| 48 */ | |
| 49 if (segment >= 10) { | |
| 50 do_daemons(BEFORE); | |
| 51 do_fuses(BEFORE); | |
| 52 } | |
| 53 | |
| 54 after = TRUE; | |
| 55 do { | |
| 56 /* One more tick of the clock. */ | |
| 57 if (segment >= 10 && after && (++turns % DAYLENGTH) == 0) { | |
| 58 daytime ^= TRUE; | |
| 59 if (levtype == OUTSIDE) { | |
| 60 if (daytime) msg("The sun rises above the horizon"); | |
| 61 else msg("The sun sinks below the horizon"); | |
| 62 } | |
| 63 light(&hero); | |
| 64 } | |
| 65 | |
| 66 /* | |
| 67 * Don't bother with these updates unless the player's going | |
| 68 * to do something. | |
| 69 */ | |
| 70 if (player.t_action == A_NIL && player.t_no_move <= 1) { | |
| 71 look(after, FALSE); | |
| 72 lastscore = purse; | |
| 73 wmove(cw, hero.y, hero.x); | |
| 74 if (!((running || count) && jump)) { | |
| 75 status(FALSE); | |
| 76 } | |
| 77 } | |
| 78 | |
| 79 /* Draw the screen */ | |
| 80 if (!((running || count) && jump)) { | |
| 81 wmove(cw, hero.y, hero.x); | |
| 82 draw(cw); | |
| 83 } | |
| 84 | |
| 85 after = TRUE; | |
| 86 | |
| 87 /* | |
| 88 * Read command or continue run | |
| 89 */ | |
| 90 if (--player.t_no_move <= 0) { | |
| 91 take = 0; /* Nothing here to start with */ | |
| 92 player.t_no_move = 0; /* Be sure we don't go too negative */ | |
| 93 if (!running) door_stop = FALSE; | |
| 94 | |
| 95 /* Was the player being held? */ | |
| 96 if (player.t_action == A_FREEZE) { | |
| 97 player.t_action = A_NIL; | |
| 98 msg("You can move again."); | |
| 99 } | |
| 100 | |
| 101 if (player.t_action != A_NIL) ch = (char) player.t_action; | |
| 102 else if (running) { | |
| 103 char scratch; | |
| 104 | |
| 105 /* If in a corridor or maze, if we are at a turn with | |
| 106 * only one way to go, turn that way. | |
| 107 */ | |
| 108 scratch = CCHAR( winat(hero.y, hero.x) ); | |
| 109 if ((scratch==PASSAGE||scratch==DOOR||levtype==MAZELEV) && | |
| 110 off(player, ISHUH) && | |
| 111 off(player, ISBLIND)) { | |
| 112 int y, x; | |
| 113 if (getdelta(runch, &y, &x) == TRUE) { | |
| 114 corr_move(y, x); | |
| 115 } | |
| 116 } | |
| 117 ch = runch; | |
| 118 } | |
| 119 else if (count) ch = countch; | |
| 120 else { | |
| 121 ch = readchar(); | |
| 122 if (mpos != 0 && !running) /* Erase message if its there */ | |
| 123 msg(""); | |
| 124 } | |
| 125 | |
| 126 /* | |
| 127 * check for prefixes | |
| 128 */ | |
| 129 if (isdigit(ch)) | |
| 130 { | |
| 131 count = 0; | |
| 132 newcount = TRUE; | |
| 133 while (isdigit(ch)) | |
| 134 { | |
| 135 count = count * 10 + (ch - '0'); | |
| 136 if (count > 255) | |
| 137 count = 255; | |
| 138 ch = readchar(); | |
| 139 } | |
| 140 countch = ch; | |
| 141 /* | |
| 142 * turn off count for commands which don't make sense | |
| 143 * to repeat | |
| 144 */ | |
| 145 switch (ch) { | |
| 146 case 'h': case 'j': case 'k': case 'l': | |
| 147 case 'y': case 'u': case 'b': case 'n': | |
| 148 case 'H': case 'J': case 'K': case 'L': | |
| 149 case 'Y': case 'U': case 'B': case 'N': | |
| 150 case C_SEARCH: case '.': | |
| 151 break; | |
| 152 default: | |
| 153 count = 0; | |
| 154 } | |
| 155 } | |
| 156 | |
| 157 /* Save current direction */ | |
| 158 if (!running) { /* If running, it is already saved */ | |
| 159 switch (ch) { | |
| 160 case 'h': case 'j': case 'k': case 'l': | |
| 161 case 'y': case 'u': case 'b': case 'n': | |
| 162 case 'H': case 'J': case 'K': case 'L': | |
| 163 case 'Y': case 'U': case 'B': case 'N': | |
| 164 runch = tolower(ch); | |
| 165 } | |
| 166 } | |
| 167 | |
| 168 /* Perform the action */ | |
| 169 switch (ch) { | |
| 170 case 'f': | |
| 171 if (!on(player, ISBLIND)) | |
| 172 { | |
| 173 door_stop = TRUE; | |
| 174 firstmove = TRUE; | |
| 175 } | |
| 176 if (count && !newcount) | |
| 177 ch = direction; | |
| 178 else | |
| 179 ch = readchar(); | |
| 180 switch (ch) | |
| 181 { | |
| 182 case 'h': case 'j': case 'k': case 'l': | |
| 183 case 'y': case 'u': case 'b': case 'n': | |
| 184 ch = toupper(ch); | |
| 185 } | |
| 186 direction = ch; | |
| 187 } | |
| 188 newcount = FALSE; | |
| 189 | |
| 190 /* | |
| 191 * execute a command | |
| 192 */ | |
| 193 if (count && !running) | |
| 194 count--; | |
| 195 switch (ch) { | |
| 196 case '!' : shell(); | |
| 197 when 'h' : do_move(0, -1); | |
| 198 when 'j' : do_move(1, 0); | |
| 199 when 'k' : do_move(-1, 0); | |
| 200 when 'l' : do_move(0, 1); | |
| 201 when 'y' : do_move(-1, -1); | |
| 202 when 'u' : do_move(-1, 1); | |
| 203 when 'b' : do_move(1, -1); | |
| 204 when 'n' : do_move(1, 1); | |
| 205 when 'H' : do_run('h'); | |
| 206 when 'J' : do_run('j'); | |
| 207 when 'K' : do_run('k'); | |
| 208 when 'L' : do_run('l'); | |
| 209 when 'Y' : do_run('y'); | |
| 210 when 'U' : do_run('u'); | |
| 211 when 'B' : do_run('b'); | |
| 212 when 'N' : do_run('n'); | |
| 213 when A_PICKUP: | |
| 214 player.t_action = A_NIL; | |
| 215 if (add_pack(NULL, FALSE, NULL)) { | |
| 216 char tch; | |
| 217 | |
| 218 tch = CCHAR( mvwinch(stdscr, hero.y, hero.x) ); | |
| 219 if (tch != FLOOR && tch != PASSAGE) { | |
| 220 player.t_action = A_PICKUP; /*get more */ | |
| 221 player.t_no_move += 2 * movement(&player); | |
| 222 } | |
| 223 } | |
| 224 when A_ATTACK: | |
| 225 /* Is our attackee still there? */ | |
| 226 if (isalpha(winat(player.t_newpos.y, | |
| 227 player.t_newpos.x))) { | |
| 228 /* Our friend is still here */ | |
| 229 player.t_action = A_NIL; | |
| 230 fight(&player.t_newpos, cur_weapon, FALSE); | |
| 231 } | |
| 232 else { /* Our monster has moved */ | |
| 233 player.t_action = A_NIL; | |
| 234 } | |
| 235 when A_THROW: | |
| 236 if (player.t_action == A_NIL) { | |
| 237 item = get_item(pack, "throw", ALL, FALSE, FALSE); | |
| 238 if (item != NULL && get_dir(&player.t_newpos)) { | |
| 239 player.t_action = A_THROW; | |
| 240 player.t_using = item; | |
| 241 player.t_no_move = 2 * movement(&player); | |
| 242 } | |
| 243 else | |
| 244 after = FALSE; | |
| 245 } | |
| 246 else { | |
| 247 missile(player.t_newpos.y, player.t_newpos.x, | |
| 248 player.t_using, &player); | |
| 249 player.t_action = A_NIL; | |
| 250 player.t_using = 0; | |
| 251 } | |
| 252 when 'Q' : after = FALSE; quit(0); | |
| 253 when 'i' : after = FALSE; inventory(pack, ALL); | |
| 254 when 'I' : after = FALSE; picky_inven(); | |
| 255 when C_DROP : player.t_action = C_DROP; drop(NULL); | |
| 256 when 'P' : | |
| 257 if (levtype != POSTLEV) { | |
| 258 /* We charge 2 movement units per item */ | |
| 259 player.t_no_move = | |
| 260 2 * grab(hero.y, hero.x) * movement(&player); | |
| 261 } | |
| 262 else { | |
| 263 /* Let's quote the wise guy a price */ | |
| 264 buy_it(); | |
| 265 after = FALSE; | |
| 266 } | |
| 267 when C_COUNT : count_gold(); | |
| 268 when C_QUAFF : quaff(-1, NULL, NULL, TRUE); | |
| 269 when C_READ : read_scroll(-1, NULL, TRUE); | |
| 270 when C_EAT : eat(); | |
| 271 when C_WIELD : wield(); | |
| 272 when C_WEAR : wear(); | |
| 273 when C_TAKEOFF : take_off(); | |
| 274 when 'o' : option(); | |
| 275 when CTRL('N') : nameit(); | |
| 276 when '=' : after = FALSE; display(); | |
| 277 when 'm' : nameitem(NULL, TRUE); | |
| 278 when '>' : after = FALSE; d_level(); | |
| 279 when '<' : after = FALSE; u_level(); | |
| 280 when '?' : after = FALSE; help(); | |
| 281 when '/' : after = FALSE; identify(NULL); | |
| 282 when C_USE : use_mm(-1); | |
| 283 when CTRL('T') : | |
| 284 if (player.t_action == A_NIL) { | |
| 285 if (get_dir(&player.t_newpos)) { | |
| 286 player.t_action = CTRL('T'); | |
| 287 player.t_no_move = 2 * movement(&player); | |
| 288 } | |
| 289 else | |
| 290 after = FALSE; | |
| 291 } | |
| 292 else { | |
| 293 steal(); | |
| 294 player.t_action = A_NIL; | |
| 295 } | |
| 296 when C_DIP : dip_it(); | |
| 297 when 'G' : | |
| 298 if (player.t_action == A_NIL) { | |
| 299 player.t_action = 'G'; | |
| 300 player.t_no_move = movement(&player); | |
| 301 } | |
| 302 else { | |
| 303 gsense(); | |
| 304 player.t_action = A_NIL; | |
| 305 } | |
| 306 when C_SETTRAP : set_trap(&player, hero.y, hero.x); | |
| 307 when C_SEARCH : | |
| 308 if (player.t_action == A_NIL) { | |
| 309 player.t_action = C_SEARCH; | |
| 310 player.t_no_move = 5 * movement(&player); | |
| 311 } | |
| 312 else { | |
| 313 search(FALSE, FALSE); | |
| 314 player.t_action = A_NIL; | |
| 315 } | |
| 316 when C_ZAP : if (!player_zap(NULL, FALSE)) | |
| 317 after=FALSE; | |
| 318 when C_PRAY : pray(); | |
| 319 when C_CHANT : chant(); | |
| 320 when C_CAST : cast(); | |
| 321 when 'a' : | |
| 322 if (player.t_action == A_NIL) { | |
| 323 if (get_dir(&player.t_newpos)) { | |
| 324 player.t_action = 'a'; | |
| 325 player.t_no_move = 2 * movement(&player); | |
| 326 } | |
| 327 else | |
| 328 after = FALSE; | |
| 329 } | |
| 330 else { | |
| 331 affect(); | |
| 332 player.t_action = A_NIL; | |
| 333 } | |
| 334 when 'v' : after = FALSE; | |
| 335 msg("Advanced Rogue Version %s.", | |
| 336 release); | |
| 337 when CTRL('L') : after = FALSE; clearok(curscr, TRUE); | |
| 338 touchwin(cw); /* MMMMMMMMMM */ | |
| 339 when CTRL('R') : after = FALSE; msg(huh); | |
| 340 when 'S' : | |
| 341 after = FALSE; | |
| 342 if (save_game()) | |
| 343 { | |
| 344 wclear(cw); | |
| 345 draw(cw); | |
| 346 endwin(); | |
| 347 #ifdef PC7300 | |
| 348 endhardwin(); | |
| 349 #endif | |
| 350 exit(0); | |
| 351 } | |
| 352 when '.' : | |
| 353 player.t_no_move = movement(&player); /* Rest */ | |
| 354 player.t_action = A_NIL; | |
| 355 when ' ' : after = FALSE; /* Do Nothing */ | |
| 356 #ifdef WIZARD | |
| 357 when CTRL('P') : | |
| 358 after = FALSE; | |
| 359 if (wizard) | |
| 360 { | |
| 361 wizard = FALSE; | |
| 362 trader = 0; | |
| 363 msg("Not wizard any more"); | |
| 364 } | |
| 365 else | |
| 366 { | |
| 367 if (waswizard || passwd()) | |
| 368 { | |
| 369 msg("Welcome, oh mighty wizard."); | |
| 370 wizard = waswizard = TRUE; | |
| 371 } | |
| 372 else | |
| 373 msg("Sorry"); | |
| 374 } | |
| 375 #endif | |
| 376 when ESCAPE : /* Escape */ | |
| 377 door_stop = FALSE; | |
