*/
static bool do_command(void);
+static bool do_move(void);
int main(int argc, char *argv[])
{
}
/* Initialize game variables */
- long seedval = initialise();
+ int seedval = initialise();
#ifndef ADVENT_NOSAVE
if (!rfp) {
#endif
if (settings.logfp)
- fprintf(settings.logfp, "seed %ld\n", seedval);
+ fprintf(settings.logfp, "seed %d\n", seedval);
/* interpret commands until EOF or interrupt */
for (;;) {
+ // if we're supposed to move, move
+ if (!do_move())
+ continue;
+
+ // get command
if (!do_command())
break;
}
terminate(quitgame);
}
-/* Check if this loc is eligible for any hints. If been here long
+/* Check if this loc is eligible for any hints. If been here int
* enough, display. Ignore "HINTS" < 4 (special stuff, see database
* notes). */
static void checkhints(void)
if (!CNDBIT(game.loc, hint + 1 + COND_HBASE))
game.hintlc[hint] = -1;
++game.hintlc[hint];
- /* Come here if he's been long enough at required loc(s) for some
+ /* Come here if he's been int enough at required loc(s) for some
* unused hint. */
if (game.hintlc[hint] >= hints[hint].turns) {
int i;
}
}
}
-
-
}
static bool spotted_by_pirate(int i)
static void croak(void)
/* Okay, he's dead. Let's get on with it. */
{
- if (game.numdie < 0)
- game.numdie = 0; // LCOV_EXCL_LINE
const char* query = obituaries[game.numdie].query;
const char* yes_response = obituaries[game.numdie].yes_response;
+
++game.numdie;
+
if (game.closng) {
/* He died during closing time. No resurrection. Tally up a
* death and exit. */
rspeak(DEATH_CLOSING);
terminate(endgame);
- } else if ( !yes(query, yes_response, arbitrary_messages[OK_MAN])
- || game.numdie == NDEATHS)
+ } else if (!yes(query, yes_response, arbitrary_messages[OK_MAN])
+ || game.numdie == NDEATHS) {
+ /* Player is asked if he wants to try again. If not, or if
+ * he's already used all of his lives, we end the game */
terminate(endgame);
- else {
+ } else {
+ /* If player wishes to continue, we empty the liquids in the
+ * user's inventory, turn off the lamp, and drop all items
+ * where he died. */
game.place[WATER] = game.place[OIL] = LOC_NOWHERE;
if (TOTING(LAMP))
game.prop[LAMP] = LAMP_DARK;
}
}
-static void describe_location(void) {
+static void describe_location(void)
+/* Describe the location to the user */
+{
const char* msg = locations[game.loc].description.small;
+
if (MOD(game.abbrev[game.loc], game.abbnum) == 0 ||
msg == NO_MESSAGE)
msg = locations[game.loc].description.big;
speak(msg);
- if (game.loc == LOC_Y2 && PCT(25) && !game.closng) // FIXME: magic number
+ if (game.loc == LOC_Y2 && PCT(25) && !game.closng)
rspeak(SAYS_PLUGH);
}
for (;;) { /* L12 loop */
for (;;) {
enum condtype_t condtype = travel[travel_entry].condtype;
- long condarg1 = travel[travel_entry].condarg1;
- long condarg2 = travel[travel_entry].condarg2;
+ int condarg1 = travel[travel_entry].condarg1;
+ int condarg2 = travel[travel_entry].condarg2;
if (condtype < cond_not) {
/* YAML N and [pct N] conditionals */
if (condtype == cond_goto || condtype == cond_pct) {
if (game.prop[TROLL] == TROLL_PAIDONCE) {
pspeak(TROLL, look, true, TROLL_PAIDONCE);
game.prop[TROLL] = TROLL_UNPAID;
- move(TROLL2, LOC_NOWHERE);
+ DESTROY(TROLL2);
move(TROLL2 + NOBJECTS, IS_FREE);
move(TROLL, objects[TROLL].plac);
move(TROLL + NOBJECTS, objects[TROLL].fixd);
game.dseen[i] = false;
game.dloc[i] = LOC_NOWHERE;
}
- move(TROLL, LOC_NOWHERE);
+ DESTROY(TROLL);
move(TROLL + NOBJECTS, IS_FREE);
move(TROLL2, objects[TROLL].plac);
move(TROLL2 + NOBJECTS, objects[TROLL].fixd);
}
}
-void clear_command(command_t *cmd)
-{
- cmd->verb = ACT_NULL;
- cmd->part = unknown;
- game.oldobj = cmd->obj;
- cmd->obj = NO_OBJECT;
- cmd->state = EMPTY;
-}
-
bool preprocess_command(command_t *command)
/* Pre-processes a command input to see if we need to tease out a few specific cases:
* - "enter water" or "enter stream":
command->word[0].type = ACTION;
}
}
+
+ /* If no word type is given for the first word, we assume it's a motion. */
+ if(command->word[0].type == NO_WORD_TYPE)
+ command->word[0].type = MOTION;
+
command->state = PREPROCESSED;
return true;
}
return false;
}
-static bool do_command()
-/* Get and execute a command */
+static bool do_move(void)
+/* Actually execute the move to the new location and dwarf movement */
{
- static command_t command;
- command.state = EMPTY;
-
/* Can't leave cave once it's closing (except by main office). */
if (OUTSID(game.newloc) && game.newloc != 0 && game.closng) {
rspeak(EXIT_CLOSED);
if (!dwarfmove())
croak();
- if (game.loc == LOC_NOWHERE) {
+ if (game.loc == LOC_NOWHERE)
croak();
- }
/* The easiest way to get killed is to fall into a pit in
* pitch darkness. */
rspeak(PIT_FALL);
game.oldlc2 = game.loc;
croak();
- return true;
+ return false;
}
+ return true;
+}
+
+static bool do_command()
+/* Get and execute a command */
+{
+ static command_t command;
+ clear_command(&command);
+
/* Describe the current location and (maybe) get next command. */
while (command.state != EXECUTED) {
describe_location();
}
switch (command.word[0].type) {
- case NO_WORD_TYPE: // FIXME: treating NO_WORD_TYPE as a motion word is confusing
case MOTION:
playermove(command.word[0].id);
command.state = EXECUTED;
clear_command(&command);
continue;
}
- break;
+ break;// LCOV_EXCL_LINE
default: // LCOV_EXCL_LINE
BUG(VOCABULARY_TYPE_N_OVER_1000_NOT_BETWEEN_0_AND_3); // LCOV_EXCL_LINE
}
/* object cleared; we need to go back to the preprocessing step */
command.state = GIVEN;
break;
+ case GO_CHECKHINT: // FIXME: re-name to be more contextual; this was previously a label
+ command.state = GIVEN;
+ break;
case GO_DWARFWAKE:
/* Oh dear, he's disturbed the dwarves. */
rspeak(DWARVES_AWAKEN);
break;
case GO_TOP: // FIXME: re-name to be more contextual; this was previously a label
break;
- case GO_CHECKHINT: // FIXME: re-name to be more contextual; this was previously a label
- command.state = GIVEN;
- break;
default: // LCOV_EXCL_LINE
BUG(ACTION_RETURNED_PHASE_CODE_BEYOND_END_OF_SWITCH); // LCOV_EXCL_LINE
}