Mercurial > hg > early-roguelike
comparison xrogue/command.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 | ce0cf824c192 |
comparison
equal
deleted
inserted
replaced
| 124:d10fc4a065ac | 133:e6179860cb76 |
|---|---|
| 1 /* | |
| 2 command.c - Read and execute the user 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 <signal.h> | |
| 22 #include "mach_dep.h" | |
| 23 #include "rogue.h" | |
| 24 | |
| 25 /* | |
| 26 * command: | |
| 27 * Process the user commands | |
| 28 */ | |
| 29 | |
| 30 command() | |
| 31 { | |
| 32 unsigned int ch; | |
| 33 struct linked_list *item; | |
| 34 unsigned int countch = 0, direction = 0, newcount = FALSE; | |
| 35 int segment = 1; | |
| 36 int monst_limit, monst_current; | |
| 37 | |
| 38 monst_limit = monst_current = 1; | |
| 39 while (playing) { | |
| 40 /* | |
| 41 * Let the daemons start up, but only do them once a round | |
| 42 * (round = 10 segments). | |
| 43 */ | |
| 44 if (segment >= 10) { | |
| 45 do_daemons(BEFORE); | |
| 46 do_fuses(BEFORE); | |
| 47 } | |
| 48 | |
| 49 after = TRUE; | |
| 50 do { | |
| 51 /* One more tick of the clock. */ | |
| 52 if (segment >= 10 && after && (++turns % DAYLENGTH) == 0) { | |
| 53 daytime ^= TRUE; | |
| 54 if (levtype == OUTSIDE) { | |
| 55 if (daytime) msg("A bright star flares above the horizon."); | |
| 56 else msg("The bright star travels beyond the horizon."); | |
| 57 } | |
| 58 light(&hero); | |
| 59 } | |
| 60 | |
| 61 /* | |
| 62 * Don't bother with these updates unless the player's going | |
| 63 * to do something. | |
| 64 */ | |
| 65 if (player.t_action == A_NIL && player.t_no_move <= 1) { | |
| 66 look(after, FALSE); | |
| 67 lastscore = purse; | |
| 68 wmove(cw, hero.y, hero.x); | |
| 69 if (!((running || count) && jump)) { | |
| 70 status(FALSE); | |
| 71 } | |
| 72 } | |
| 73 | |
| 74 /* Draw the screen */ | |
| 75 if (!((running || count) && jump)) { | |
| 76 wmove(cw, hero.y, hero.x); | |
| 77 draw(cw); | |
| 78 } | |
| 79 | |
| 80 after = TRUE; | |
| 81 | |
| 82 /* | |
| 83 * Read command or continue run | |
| 84 */ | |
| 85 if (--player.t_no_move <= 0) { | |
| 86 take = 0; /* Nothing here to start with */ | |
| 87 player.t_no_move = 0; /* Be sure we don't go too negative */ | |
| 88 if (!running) door_stop = FALSE; | |
| 89 | |
| 90 /* Was the player being held? */ | |
| 91 if (player.t_action == A_FREEZE) { | |
| 92 player.t_action = A_NIL; | |
| 93 msg("You can move again."); | |
| 94 } | |
| 95 | |
| 96 if (player.t_action != A_NIL) ch = player.t_action; | |
| 97 else if (running) { | |
| 98 char scratch; | |
| 99 | |
| 100 /* If in a corridor or maze, if we are at a turn with | |
| 101 * only one way to go, turn that way. | |
| 102 */ | |
| 103 scratch = winat(hero.y, hero.x); | |
| 104 if ((scratch==PASSAGE||scratch==DOOR||levtype==MAZELEV) && | |
| 105 off(player, ISHUH) && | |
| 106 off(player, ISBLIND)) { | |
| 107 int y, x; | |
| 108 if (getdelta(runch, &y, &x) == TRUE) { | |
| 109 corr_move(y, x); | |
| 110 } | |
| 111 } | |
| 112 ch = runch; | |
| 113 } | |
| 114 else if (count) ch = countch; | |
| 115 else { | |
| 116 ch = wgetch(cw); | |
| 117 if (mpos != 0 && !running) /* Erase message if its there */ | |
| 118 msg(""); | |
| 119 } | |
| 120 | |
| 121 /* | |
| 122 * check for prefixes | |
| 123 */ | |
| 124 if (isascii(ch) && isdigit(ch)) | |
| 125 { | |
| 126 count = 0; | |
| 127 newcount = TRUE; | |
| 128 while (isascii(ch) && isdigit(ch)) | |
| 129 { | |
| 130 count = count * 10 + (ch - '0'); | |
| 131 ch = wgetch(cw); | |
| 132 } | |
| 133 countch = ch; | |
| 134 /* | |
| 135 * turn off count for commands which don't make sense | |
| 136 * to repeat | |
| 137 */ | |
| 138 switch (ch) { | |
| 139 case 'h': case 'j': case 'k': case 'l': | |
| 140 case 'y': case 'u': case 'b': case 'n': | |
| 141 case 'H': case 'J': case 'K': case 'L': | |
| 142 case 'Y': case 'U': case 'B': case 'N': | |
| 143 case C_SEARCH: case '.': | |
| 144 break; | |
| 145 default: | |
| 146 count = 0; | |
| 147 } | |
| 148 } | |
| 149 | |
| 150 /* Save current direction */ | |
| 151 if (!running) { /* If running, it is already saved */ | |
| 152 switch (ch) { | |
| 153 case 'h': case 'j': case 'k': case 'l': | |
| 154 case 'y': case 'u': case 'b': case 'n': | |
| 155 case 'H': case 'J': case 'K': case 'L': | |
| 156 case 'Y': case 'U': case 'B': case 'N': | |
| 157 runch = tolower(ch); | |
| 158 } | |
| 159 } | |
| 160 | |
| 161 /* Perform the action */ | |
| 162 switch (ch) { | |
| 163 case 'f': | |
| 164 if (!on(player, ISBLIND)) | |
| 165 { | |
| 166 door_stop = TRUE; | |
| 167 firstmove = TRUE; | |
| 168 } | |
| 169 if (count && !newcount) | |
| 170 ch = direction; | |
| 171 else | |
| 172 ch = wgetch(cw); | |
| 173 switch (ch) | |
| 174 { | |
| 175 case 'h': case 'j': case 'k': case 'l': | |
| 176 case 'y': case 'u': case 'b': case 'n': | |
| 177 ch = toupper(ch); | |
| 178 } | |
| 179 direction = ch; | |
| 180 } | |
| 181 newcount = FALSE; | |
| 182 | |
| 183 /* | |
| 184 * execute a command | |
| 185 */ | |
| 186 if (count && !running) | |
| 187 count--; | |
| 188 | |
| 189 switch (ch) { | |
| 190 case '!' : shell(); | |
| 191 case KEY_LEFT : do_move(0, -1); | |
| 192 when KEY_DOWN : do_move(1, 0); | |
| 193 when KEY_UP : do_move(-1, 0); | |
| 194 when KEY_RIGHT : do_move(0, 1); | |
| 195 when KEY_HOME : do_move(-1, -1); | |
| 196 when KEY_A1 : do_move(-1, -1); | |
| 197 when KEY_PPAGE : do_move(-1, 1); | |
| 198 when KEY_A3 : do_move(-1, 1); | |
| 199 when KEY_END : do_move(1, -1); | |
| 200 when KEY_C1 : do_move(1, -1); | |
| 201 when KEY_NPAGE : do_move(1, 1); | |
| 202 when KEY_C3 : do_move(1, 1); | |
| 203 #ifdef CTL_RIGHT | |
| 204 when CTL_RIGHT : do_run('l'); | |
| 205 when CTL_LEFT : do_run('h'); | |
| 206 when CTL_UP : do_run('k'); | |
| 207 when CTL_DOWN : do_run('j'); | |
| 208 when CTL_HOME : do_run('y'); | |
| 209 when CTL_PGUP : do_run('u'); | |
| 210 when CTL_END : do_run('b'); | |
| 211 when CTL_PGDN : do_run('n'); | |
| 212 #endif | |
| 213 when 'h' : do_move(0, -1); | |
| 214 when 'j' : do_move(1, 0); | |
| 215 when 'k' : do_move(-1, 0); | |
| 216 when 'l' : do_move(0, 1); | |
| 217 when 'y' : do_move(-1, -1); | |
| 218 when 'u' : do_move(-1, 1); | |
| 219 when 'b' : do_move(1, -1); | |
| 220 when 'n' : do_move(1, 1); | |
| 221 when 'H' : do_run('h'); | |
| 222 when 'J' : do_run('j'); | |
| 223 when 'K' : do_run('k'); | |
| 224 when 'L' : do_run('l'); | |
| 225 when 'Y' : do_run('y'); | |
| 226 when 'U' : do_run('u'); | |
| 227 when 'B' : do_run('b'); | |
| 228 when 'N' : do_run('n'); | |
| 229 when A_ATTACK: | |
| 230 /* Is our attackee still there? */ | |
| 231 if (isalpha(winat(player.t_newpos.y, | |
| 232 player.t_newpos.x))) { | |
| 233 /* Our friend is still here */ | |
| 234 player.t_action = A_NIL; | |
| 235 fight(&player.t_newpos, cur_weapon, FALSE); | |
| 236 } | |
| 237 else { /* Our monster has moved */ | |
| 238 player.t_action = A_NIL; | |
| 239 } | |
| 240 when A_PICKUP: | |
| 241 player.t_action = A_NIL; | |
| 242 if (add_pack((struct linked_list *)NULL, FALSE)) { | |
| 243 char tch; | |
| 244 tch = mvwinch(stdscr, hero.y, hero.x); | |
| 245 if (tch != FLOOR && tch != PASSAGE) { | |
| 246 player.t_action = A_PICKUP; /*get more */ | |
| 247 player.t_no_move += 2 * movement(&player); | |
| 248 } | |
| 249 } | |
| 250 when A_THROW: | |
| 251 if (player.t_action == A_NIL) { | |
| 252 item = get_item(pack, "throw", ALL, FALSE, FALSE); | |
| 253 if (item != NULL && get_dir(&player.t_newpos)) { | |
| 254 player.t_action = A_THROW; | |
| 255 player.t_using = item; | |
| 256 player.t_no_move = 2 * movement(&player); | |
| 257 } | |
| 258 else | |
| 259 after = FALSE; | |
| 260 } | |
| 261 else { | |
| 262 missile(player.t_newpos.y, player.t_newpos.x, | |
| 263 player.t_using, &player); | |
| 264 player.t_action = A_NIL; | |
| 265 player.t_using = 0; | |
| 266 } | |
| 267 when 'a' : | |
| 268 if (player.t_action == A_NIL) { | |
| 269 if (get_dir(&player.t_newpos)) { | |
| 270 player.t_action = 'a'; | |
| 271 player.t_no_move = 1 + movement(&player); | |
| 272 } | |
| 273 else | |
| 274 after = FALSE; | |
| 275 } | |
| 276 else { | |
| 277 affect(); | |
| 278 player.t_action = A_NIL; | |
| 279 } | |
| 280 when 'A' : choose_qst(); | |
| 281 when 'F' : /* frighten a monster */ | |
| 282 if (player.t_action == A_NIL) { | |
| 283 player.t_action = 'F'; | |
| 284 player.t_no_move = 2*movement(&player); | |
| 285 } | |
| 286 else { | |
| 287 after = FALSE; | |
| 288 player.t_action = A_NIL; | |
| 289 fright(); | |
| 290 } | |
| 291 when 'g' : /* Give command: give slime-molds to monsters */ | |
| 292 if (player.t_action == A_NIL) { | |
| 293 player.t_action = 'g'; | |
| 294 player.t_no_move = 2*movement(&player); | |
| 295 } | |
| 296 else { | |
| 297 after = FALSE; | |
| 298 player.t_action = A_NIL; | |
| 299 give(); | |
| 300 } | |
| 301 when 'G' : | |
| 302 if (player.t_action == A_NIL) { | |
| 303 player.t_action = 'G'; | |
| 304 player.t_no_move = movement(&player); | |
| 305 } | |
| 306 else { | |
| 307 player.t_action = A_NIL; | |
| 308 gsense(); | |
| 309 } | |
| 310 when 'i' : after = FALSE; inventory(pack, ALL); | |
| 311 when 'I' : after = FALSE; picky_inven(); | |
| 312 when 'm' : nameitem((struct linked_list *)NULL, TRUE); | |
| 313 when 'o' : option(); | |
| 314 when 'O' : msg("Charactor type: %s Quest item: %s", char_class[char_type].name, rel_magic[quest_item].mi_name); | |
| 315 when ',' : | |
| 316 case 'P' : | |
| 317 if (levtype != POSTLEV) { | |
| 318 /* We charge 2 movement units per item */ | |
| 319 player.t_no_move = | |
| 320 2 * grab(hero.y, hero.x) * movement(&player); | |
| 321 } | |
| 322 else { | |
| 323 /* Let's quote the wise guy a price */ | |
| 324 buy_it(); | |
| 325 after = FALSE; | |
| 326 } | |
| 327 when 'Q' : after = FALSE; quit(0); | |
| 328 when 'S' : | |
| 329 after = FALSE; | |
| 330 if (save_game()) | |
| 331 exit_game(EXIT_CLS | EXIT_ENDWIN); | |
| 332 when 'v' : after = FALSE; | |
| 333 msg("Advanced xrogue, Version %s ", release); | |
| 334 when 'X' : /* trap sense */ | |
| 335 after = FALSE; | |
| 336 if (player.t_action == A_NIL) { | |
| 337 player.t_action = 'X'; | |
| 338 player.t_no_move = movement(&player); | |
| 339 } | |
| 340 else { | |
| 341 xsense(); | |
| 342 player.t_action = A_NIL; | |
| 343 } | |
| 344 when '.' : | |
