[open-adventure] 01/04: New upstream version 1.4+git20170917.0.d512384
Dr. Tobias Quathamer
toddy at debian.org
Sat Sep 30 07:16:09 UTC 2017
This is an automated email from the git hooks/post-receive script.
toddy pushed a commit to branch master
in repository open-adventure.
commit 62a223679c3c661a056bf103df5961ebe7bf357c
Author: Dr. Tobias Quathamer <toddy at debian.org>
Date: Sat Sep 30 09:08:04 2017 +0200
New upstream version 1.4+git20170917.0.d512384
---
NEWS | 2 +-
actions.c | 47 +++++++++---------
advent.h | 43 ++++++++++-------
init.c | 6 ---
main.c | 80 +++++++++++++++---------------
misc.c | 32 ++++++------
saveresume.c | 131 +++++++++++++++++++++++++++++++++++++++++++++++---
tests/Makefile | 1 -
tests/illformed.chk | 2 +-
tests/resumefail2.chk | 2 +-
10 files changed, 233 insertions(+), 113 deletions(-)
diff --git a/NEWS b/NEWS
index 487dd2d..28ba0f8 100644
--- a/NEWS
+++ b/NEWS
@@ -2,7 +2,7 @@
1.4: 2017-08-07::
Repair packaging error (omitted templates.)
- Minor improvents in odd grammar cases.
+ Minor improvements in odd grammar cases.
1.3: 2017-08-01::
Split commands with objectless transitive verbs are handled correctly.
diff --git a/actions.c b/actions.c
index ec25552..059d92b 100644
--- a/actions.c
+++ b/actions.c
@@ -3,6 +3,7 @@
#include <string.h>
#include "advent.h"
#include "dungeon.h"
+#include <inttypes.h>
static int fill(verb_t, obj_t);
@@ -265,7 +266,7 @@ static int vbreak(verb_t verb, obj_t obj)
game.fixed[VASE] = IS_FIXED;
break;
}
- /* FALLTHRU */
+ /* FALLTHRU */
default:
speak(actions[verb].message);
}
@@ -592,7 +593,7 @@ static int eat(verb_t verb, obj_t obj)
case INTRANSITIVE:
if (!HERE(FOOD))
return GO_UNKNOWN;
- /* FALLTHRU */
+ /* FALLTHRU */
case FOOD:
DESTROY(FOOD);
rspeak(THANKS_DELICIOUS);
@@ -1145,21 +1146,21 @@ static int say(command_t command)
/* Say. Echo WD2. Magic words override. */
{
if (command.word[1].type == MOTION &&
- (command.word[1].id == XYZZY ||
- command.word[1].id == PLUGH ||
- command.word[1].id == PLOVER)) {
- return GO_WORD2;
+ (command.word[1].id == XYZZY ||
+ command.word[1].id == PLUGH ||
+ command.word[1].id == PLOVER)) {
+ return GO_WORD2;
}
if (command.word[1].type == ACTION && command.word[1].id == PART)
return reservoir();
-
+
if (command.word[1].type == ACTION &&
(command.word[1].id == FEE ||
- command.word[1].id == FIE ||
- command.word[1].id == FOE ||
- command.word[1].id == FOO ||
- command.word[1].id == FUM ||
- command.word[1].id == PART)) {
+ command.word[1].id == FIE ||
+ command.word[1].id == FOE ||
+ command.word[1].id == FOO ||
+ command.word[1].id == FUM ||
+ command.word[1].id == PART)) {
return bigwords(command.word[1].id);
}
sspeak(OKEY_DOKEY, command.word[1].raw);
@@ -1250,7 +1251,7 @@ static int wake(verb_t verb, obj_t obj)
static int seed(verb_t verb, const char *arg)
/* Set seed */
{
- int seed = atoi(arg);
+ int32_t seed = strtol(arg, NULL, 10);
speak(actions[verb].message, seed);
set_seed(seed);
--game.turns;
@@ -1316,14 +1317,14 @@ int action(command_t command)
* unless verb is "say", which snarfs arbitrary second word.
*/
{
- /* Previously, actions that result in a message, but don't do anything
- * further were called "specials". Now they're handled here as normal
+ /* Previously, actions that result in a message, but don't do anything
+ * further were called "specials". Now they're handled here as normal
* actions. If noaction is true, then we spit out the message and return */
if (actions[command.verb].noaction) {
speak(actions[command.verb].message);
return GO_CLEAROBJ;
}
-
+
if (command.part == unknown) {
/* Analyse an object word. See if the thing is here, whether
* we've got a verb yet, and so on. Object must be here
@@ -1369,9 +1370,9 @@ int action(command_t command)
if (command.word[1].raw[0] != '\0' && command.verb != SAY)
return GO_WORD2;
if (command.verb == SAY)
- /* KEYS is not special, anything not NO_OBJECT or INTRANSITIVE
- * will do here. We're preventing interpretation as an intransitive
- * verb when the word is unknown. */
+ /* KEYS is not special, anything not NO_OBJECT or INTRANSITIVE
+ * will do here. We're preventing interpretation as an intransitive
+ * verb when the word is unknown. */
command.obj = command.word[1].raw[0] != '\0' ? KEYS : NO_OBJECT;
if (command.obj == NO_OBJECT ||
command.obj == INTRANSITIVE) {
@@ -1508,7 +1509,7 @@ int action(command_t command)
case RUB:
return rub(command.verb, command.obj);
case THROW:
- return throw(command);
+ return throw (command);
case QUIT: {
speak(actions[command.verb].message);
return GO_CLEAROBJ;
@@ -1560,11 +1561,11 @@ int action(command_t command)
speak(actions[command.verb].message);
return GO_CLEAROBJ;
}
- // LCOV_EXCL_START
- // This case should never happen - here only as placeholder
+ // LCOV_EXCL_START
+ // This case should never happen - here only as placeholder
case PART:
return reservoir();
- // LCOV_EXCL_STOP
+ // LCOV_EXCL_STOP
case SEED:
return seed(command.verb, command.word[1].raw);
case WASTE:
diff --git a/advent.h b/advent.h
index 4491b42..e43459b 100644
--- a/advent.h
+++ b/advent.h
@@ -2,9 +2,16 @@
#include <stdlib.h>
#include <stdbool.h>
#include <stdarg.h>
+#include <inttypes.h>
#include "dungeon.h"
+/* LCG PRNG parameters tested against
+ * Knuth vol. 2. by the original authors */
+#define LCG_A 1093L
+#define LCG_C 221587L
+#define LCG_M 1048576L
+
#define LINESIZE 1024
#define TOKLEN 5 // № sigificant characters in a token */
#define NDWARVES 6 // number of dwarves
@@ -112,7 +119,7 @@ typedef long loc_t; // index into the locations array */
typedef long turn_t; // turn counter or threshold */
struct game_t {
- unsigned long lcg_a, lcg_c, lcg_m, lcg_x;
+ int32_t lcg_x;
long abbnum; // How often to print long descriptions
score_t bonus; // What kind of finishing bonus we are getting
loc_t chloc; // pirate chest location
@@ -122,6 +129,11 @@ struct game_t {
bool clshnt; // has player read the clue in the endgame?
bool closed; // whether we're all the way closed
bool closng; // whether it's closing time yet
+ bool lmwarn; // has player been warned about lamp going dim?
+ bool novice; // asked for instructions at start-up?
+ bool panic; // has player found out he's trapped?
+ bool wzdark; // whether the loc he's leaving was dark
+ bool blooded; // has player drunk of dragon's blood?
long conds; // min value for cond[loc] if loc has any hints
long detail; // level of detail in descriptions
@@ -134,38 +146,33 @@ struct game_t {
long dflag;
long dkill; // dwarves killed
- long dtotal; // total dwarves (including pirate)
+ long dtotal; // total dwarves (including pirate) in loc
long foobar; // progress in saying "FEE FIE FOE FOO".
long holdng; // number of objects being carried
long igo; // # uses of "go" instead of a direction
long iwest; // # times he's said "west" instead of "w"
long knfloc; // knife location; 0 if none, -1 after caveat
turn_t limit; // lifetime of lamp
- bool lmwarn; // has player been warned about lamp going dim?
loc_t loc; // where player is now
loc_t newloc; // where player is going
- bool novice; // asked for instructions at start-up?
turn_t numdie; // number of times killed so far
loc_t oldloc; // where player was
- loc_t oldlc2; // where player was two moves ago
+ loc_t oldlc2; // where player was two moves ago
obj_t oldobj; // last object player handled
- bool panic; // has player found out he's trapped?
long saved; // point penalty for saves
long tally; // count of treasures gained
long thresh; // current threshold for endgame scoring tier
turn_t trndex; // FIXME: not used, remove on next format bump
turn_t trnluz; // # points lost so far due to turns used
turn_t turns; // counts commands given (ignores yes/no)
- bool wzdark; // whether the loc he's leaving was dark
char zzword[TOKLEN + 1]; // randomly generated magic word from bird
- bool blooded; // has player drunk of dragon's blood?
long abbrev[NLOCATIONS + 1]; // has location been seen?
long atloc[NLOCATIONS + 1]; // head of object linked list per location
long dseen[NDWARVES + 1]; // true if dwarf has seen him
loc_t dloc[NDWARVES + 1]; // location of dwarves, initially hard-wired in
loc_t odloc[NDWARVES + 1]; // prior loc of each dwarf, initially garbage
loc_t fixed[NOBJECTS + 1]; // fixed location of object (if not IS_FREE)
- long link[NOBJECTS * 2 + 1]; // object-list links
+ obj_t link[NOBJECTS * 2 + 1]; // object-list links
loc_t place[NOBJECTS + 1]; // location of object
long hinted[NHINTS]; // hinted[i] = true iff hint i has been used.
long hintlc[NHINTS]; // hintlc[i] = how long at LOC with cond bit i
@@ -183,9 +190,9 @@ struct settings_t {
};
typedef struct {
- char raw[LINESIZE];
- vocab_t id;
- word_type_t type;
+ char raw[LINESIZE];
+ vocab_t id;
+ word_type_t type;
} command_word_t;
typedef struct {
@@ -214,11 +221,11 @@ extern void drop(obj_t, loc_t);
extern int atdwrf(loc_t);
extern long setbit(int);
extern bool tstbit(long, int);
-extern void set_seed(long);
-extern long randrange(long);
+extern void set_seed(int32_t);
+extern int32_t randrange(int32_t);
extern long score(enum termination);
extern void terminate(enum termination) __attribute__((noreturn));
-extern int savefile(FILE *, long);
+extern int savefile(FILE *, int32_t);
extern int suspend(void);
extern int resume(void);
extern int restore(FILE *);
@@ -231,9 +238,9 @@ void bug(enum bugtype, const char *) __attribute__((__noreturn__));
/* represent an empty command word */
static const command_word_t empty_command_word = {
- .raw = "",
- .id = WORD_EMPTY,
- .type = NO_WORD_TYPE,
+ .raw = "",
+ .id = WORD_EMPTY,
+ .type = NO_WORD_TYPE,
};
/* end */
diff --git a/init.c b/init.c
index be5c3fb..fbe4410 100644
--- a/init.c
+++ b/init.c
@@ -37,12 +37,6 @@ struct game_t game = {
.loc = LOC_START,
.limit = GAMELIMIT,
.foobar = WORD_EMPTY,
-
- /* Initialize our LCG PRNG with parameters tested against
- * Knuth vol. 2. by the original authors */
- .lcg_a = 1093,
- .lcg_c = 221587,
- .lcg_m = 1048576,
};
long initialise(void)
diff --git a/main.c b/main.c
index 41bbe95..1b725c9 100644
--- a/main.c
+++ b/main.c
@@ -85,7 +85,6 @@ int main(int argc, char *argv[])
fprintf(stderr,
"advent: can't open save file %s for read\n",
optarg);
- signal(SIGINT, sig_handler);
break;
#endif
default:
@@ -461,6 +460,8 @@ static bool dwarfmove(void)
static void croak(void)
/* Okay, he's dead. Let's get on with it. */
{
+ if (game.numdie < 0)
+ game.numdie = 0;
const char* query = obituaries[game.numdie].query;
const char* yes_response = obituaries[game.numdie].yes_response;
++game.numdie;
@@ -1050,43 +1051,43 @@ Lclearobj:
if (game.knfloc > 0 && game.knfloc != game.loc)
game.knfloc = 0;
- /* Preserve state from last command for reuse when required */
- command_t preserve = command;
+ /* Preserve state from last command for reuse when required */
+ command_t preserve = command;
- // Get command input from user
+ // Get command input from user
if (!get_command_input(&command))
return false;
#ifdef GDEBUG
- /* Needs to stay synced with enum word_type_t */
- const char *types[] = {"NO_WORD_TYPE", "MOTION", "OBJECT", "ACTION", "NUMERIC"};
- /* needs to stay synced with enum speechpart */
- const char *roles[] = {"unknown", "intransitive", "transitive"};
- printf("Preserve: role = %s type1 = %s, id1 = %ld, type2 = %s, id2 = %ld\n",
- roles[preserve.part],
- types[preserve.word[0].type],
- preserve.word[0].id,
- types[preserve.word[1].type],
- preserve.word[1].id);
- printf("Command: role = %s type1 = %s, id1 = %ld, type2 = %s, id2 = %ld\n",
- roles[command.part],
- types[command.word[0].type],
- command.word[0].id,
- types[command.word[1].type],
- command.word[1].id);
+ /* Needs to stay synced with enum word_type_t */
+ const char *types[] = {"NO_WORD_TYPE", "MOTION", "OBJECT", "ACTION", "NUMERIC"};
+ /* needs to stay synced with enum speechpart */
+ const char *roles[] = {"unknown", "intransitive", "transitive"};
+ printf("Preserve: role = %s type1 = %s, id1 = %ld, type2 = %s, id2 = %ld\n",
+ roles[preserve.part],
+ types[preserve.word[0].type],
+ preserve.word[0].id,
+ types[preserve.word[1].type],
+ preserve.word[1].id);
+ printf("Command: role = %s type1 = %s, id1 = %ld, type2 = %s, id2 = %ld\n",
+ roles[command.part],
+ types[command.word[0].type],
+ command.word[0].id,
+ types[command.word[1].type],
+ command.word[1].id);
#endif
- /* Handle of objectless action followed by actionless object */
- if (preserve.word[0].type == ACTION && preserve.word[1].type == NO_WORD_TYPE && command.word[1].id == 0)
- command.verb = preserve.verb;
+ /* Handle of objectless action followed by actionless object */
+ if (preserve.word[0].type == ACTION && preserve.word[1].type == NO_WORD_TYPE && command.word[1].id == 0)
+ command.verb = preserve.verb;
#ifdef BROKEN
- /* Handling of actionless object followed by objectless action */
- if (preserve.type1 == OBJECT && preserve.type2 == NO_WORD_TYPE && command.id2 == 0)
- command.obj = preserve.obj;
+ /* Handling of actionless object followed by objectless action */
+ if (preserve.type1 == OBJECT && preserve.type2 == NO_WORD_TYPE && command.id2 == 0)
+ command.obj = preserve.obj;
#endif
- ++game.turns;
+ ++game.turns;
if (closecheck()) {
if (game.closed)
@@ -1122,8 +1123,8 @@ Lclearobj:
}
if ((command.word[0].id == WATER || command.word[0].id == OIL) && (command.word[1].id == PLANT || command.word[1].id == DOOR)) {
if (AT(command.word[1].id)) {
- command.word[1] = command.word[0];
- command.word[0].id = POUR;
+ command.word[1] = command.word[0];
+ command.word[0].id = POUR;
command.word[0].type = ACTION;
strncpy(command.word[0].raw, "pour", LINESIZE - 1);
}
@@ -1133,12 +1134,12 @@ Lclearobj:
command.word[0].type = ACTION;
}
- /* From OV to VO form */
- if (command.word[0].type==OBJECT && command.word[1].type==ACTION) {
- command_word_t stage = command.word[0];
- command.word[0] = command.word[1];
- command.word[1] = stage;
- }
+ /* From OV to VO form */
+ if (command.word[0].type == OBJECT && command.word[1].type == ACTION) {
+ command_word_t stage = command.word[0];
+ command.word[0] = command.word[1];
+ command.word[1] = stage;
+ }
}
Lookup:
@@ -1165,7 +1166,7 @@ Lookup:
command.obj = command.word[0].id;
break;
case ACTION:
- if(command.word[1].type == NUMERIC)
+ if (command.word[1].type == NUMERIC)
command.part = transitive;
else
command.part = intransitive;
@@ -1175,7 +1176,6 @@ Lookup:
default: // LCOV_EXCL_LINE
BUG(VOCABULARY_TYPE_N_OVER_1000_NOT_BETWEEN_0_AND_3); // LCOV_EXCL_LINE
}
-
switch (action(command)) {
case GO_TERMINATE:
return true;
@@ -1186,11 +1186,11 @@ Lookup:
continue; /* back to top of main interpreter loop */
case GO_WORD2:
#ifdef GDEBUG
- printf("Word shift\n");
+ printf("Word shift\n");
#endif /* GDEBUG */
/* Get second word for analysis. */
- command.word[0] = command.word[1];
- command.word[1] = empty_command_word;
+ command.word[0] = command.word[1];
+ command.word[1] = empty_command_word;
goto Lookup;
case GO_UNKNOWN:
/* Random intransitive verbs come here. Clear obj just in case
diff --git a/misc.c b/misc.c
index 5386ff7..80e4352 100644
--- a/misc.c
+++ b/misc.c
@@ -6,6 +6,7 @@
#include <sys/time.h>
#include <ctype.h>
#include <editline/readline.h>
+#include <inttypes.h>
#include "advent.h"
#include "dungeon.h"
@@ -66,8 +67,8 @@ static void vspeak(const char* msg, bool blank, va_list ap)
i++;
// Integer specifier.
if (msg[i] == 'd') {
- long arg = va_arg(ap, long);
- int ret = snprintf(renderp, size, "%ld", arg);
+ int32_t arg = va_arg(ap, int32_t);
+ int ret = snprintf(renderp, size, "%" PRId32, arg);
if (ret < size) {
renderp += ret;
size -= ret;
@@ -388,22 +389,21 @@ static int get_action_vocab_id(const char* word)
return (WORD_NOT_FOUND);
}
-static bool is_valid_int(const char *str)
-/* Returns true if the string passed in is represents a valid integer,
+static bool is_valid_int(const char *str)
+/* Returns true if the string passed in is represents a valid integer,
* that could then be parsed by atoi() */
{
// Handle negative number
if (*str == '-')
++str;
- // Handle empty string or just "-". Should never reach this
+ // Handle empty string or just "-". Should never reach this
// point, because this is only used with transitive verbs.
if (!*str)
return false; // LCOV_EXCL_LINE
// Check for non-digit chars in the rest of the stirng.
- while (*str)
- {
+ while (*str) {
if (!isdigit(*str))
return false;
else
@@ -643,11 +643,13 @@ bool tstbit(long mask, int bit)
return (mask & (1 << bit)) != 0;
}
-void set_seed(long seedval)
+void set_seed(int32_t seedval)
/* Set the LCG seed */
{
- game.lcg_x = (unsigned long) seedval % game.lcg_m;
-
+ game.lcg_x = seedval % LCG_M;
+ if (game.lcg_x < 0) {
+ game.lcg_x = LCG_M + game.lcg_x;
+ }
// once seed is set, we need to generate the Z`ZZZ word
for (int i = 0; i < 5; ++i) {
game.zzword[i] = 'A' + randrange(26);
@@ -656,18 +658,18 @@ void set_seed(long seedval)
game.zzword[5] = '\0';
}
-static unsigned long get_next_lcg_value(void)
+static int32_t get_next_lcg_value(void)
/* Return the LCG's current value, and then iterate it. */
{
- unsigned long old_x = game.lcg_x;
- game.lcg_x = (game.lcg_a * game.lcg_x + game.lcg_c) % game.lcg_m;
+ int32_t old_x = game.lcg_x;
+ game.lcg_x = (LCG_A * game.lcg_x + LCG_C) % LCG_M;
return old_x;
}
-long randrange(long range)
+int32_t randrange(int32_t range)
/* Return a random integer from [0, range). */
{
- return range * get_next_lcg_value() / game.lcg_m;
+ return range * get_next_lcg_value() / LCG_M;
}
// LCOV_EXCL_START
diff --git a/saveresume.c b/saveresume.c
index d854174..d494015 100644
--- a/saveresume.c
+++ b/saveresume.c
@@ -2,6 +2,7 @@
#include <string.h>
#include <editline/readline.h>
#include <time.h>
+#include <inttypes.h>
#include "advent.h"
#include "dungeon.h"
@@ -11,7 +12,7 @@
* see the history.adoc file in the source distribution for discussion.
*/
-#define VRSION 27 /* bump on save format change */
+#define VRSION 28 /* bump on save format change */
/*
* If you change the first three members, the resume function may not properly
@@ -20,16 +21,16 @@
* when you do that.
*/
struct save_t {
- long savetime;
- long mode; /* not used, must be present for version detection */
- long version;
+ int64_t savetime;
+ int32_t mode; /* not used, must be present for version detection */
+ int32_t version;
struct game_t game;
};
struct save_t save;
#define IGNORE(r) do{if (r){}}while(0)
-int savefile(FILE *fp, long version)
+int savefile(FILE *fp, int32_t version)
/* Save game to file. No input or output from user. */
{
save.savetime = time(NULL);
@@ -105,6 +106,8 @@ int resume(void)
return restore(fp);
}
+bool is_valid(struct game_t*);
+
int restore(FILE* fp)
{
/* Read and restore game state from file, assuming
@@ -118,10 +121,124 @@ int restore(FILE* fp)
fclose(fp);
if (save.version != VRSION) {
rspeak(VERSION_SKEW, save.version / 10, MOD(save.version, 10), VRSION / 10, MOD(VRSION, 10));
- } else {
- game = save.game;
+ } else if (is_valid(&save.game)) {
+ game = save.game;
}
return GO_TOP;
}
+bool is_valid(struct game_t* valgame)
+{
+ /* Save files can be roughly grouped into three groups:
+ * With valid, reaceable state, with valid, but unreachable
+ * state and with invaild state. We check that state is
+ * valid: no states are outside minimal or maximal value
+ */
+
+ /* Prevent division by zero */
+ if (valgame->abbnum == 0) {
+ return false;
+ }
+
+ /* Check for RNG overflow. Truncate */
+ if (valgame->lcg_x >= LCG_M) {
+ valgame->lcg_x %= LCG_M;
+ }
+
+ /* Check for RNG underflow. Transpose */
+ if (valgame->lcg_x < LCG_M) {
+ valgame->lcg_x = LCG_M + (valgame->lcg_x % LCG_M);
+ }
+
+ /* Bounds check for locations */
+ if ( valgame->chloc < -1 || valgame->chloc > NLOCATIONS ||
+ valgame->chloc2 < -1 || valgame->chloc2 > NLOCATIONS ||
+ valgame->loc < 0 || valgame->loc > NLOCATIONS ||
+ valgame->newloc < 0 || valgame->newloc > NLOCATIONS ||
+ valgame->oldloc < 0 || valgame->oldloc > NLOCATIONS ||
+ valgame->oldlc2 < 0 || valgame->oldlc2 > NLOCATIONS) {
+ return false;
+ }
+ /* Bounds check for location arrays */
+ for (int i = 0; i <= NDWARVES; i++) {
+ if (valgame->dloc[i] < -1 || valgame->dloc[i] > NLOCATIONS ||
+ valgame->odloc[i] < -1 || valgame->odloc[i] > NLOCATIONS) {
+ return false;
+ }
+ }
+
+ for (int i = 0; i <= NOBJECTS; i++) {
+ if (valgame->place[i] < -1 || valgame->place[i] > NLOCATIONS ||
+ valgame->fixed[i] < -1 || valgame->fixed[i] > NLOCATIONS) {
+ return false;
+ }
+ }
+
+ /* Bounds check for dwarves */
+ if (valgame->dtotal < 0 || valgame->dtotal > NDWARVES ||
+ valgame->dkill < 0 || valgame->dkill > NDWARVES) {
+ return false;
+ }
+
+ /* Validate that we didn't die too many times in save */
+ if (valgame->numdie >= NDEATHS) {
+ return false;
+ }
+
+ /* Recalculate tally, throw the towel if in disagreement */
+ long temp_tally = 0;
+ for (int treasure = 1; treasure <= NOBJECTS; treasure++) {
+ if (objects[treasure].is_treasure) {
+ if (valgame->prop[treasure] == STATE_NOTFOUND) {
+ ++temp_tally;
+ }
+ }
+ }
+ if (temp_tally != valgame->tally) {
+ return false;
+ }
+
+ /* Check that properties of objects aren't beyond expected */
+ for (obj_t obj = 0; obj <= NOBJECTS; obj++) {
+ if (valgame->prop[obj] < STATE_NOTFOUND || valgame->prop[obj] > 1) {
+ switch (obj) {
+ case RUG:
+ case DRAGON:
+ case BIRD:
+ case BOTTLE:
+ case PLANT:
+ case PLANT2:
+ case TROLL:
+ case URN:
+ case EGGS:
+ case VASE:
+ case CHAIN:
+ if (valgame->prop[obj] == 2) // There are multiple different states, but it's convenient to clump them together
+ continue;
+ /* FALLTHRU */
+ case BEAR:
+ if (valgame->prop[BEAR] == CONTENTED_BEAR || valgame->prop[BEAR] == BEAR_DEAD)
+ continue;
+ /* FALLTHRU */
+ default:
+ return false;
+ }
+ }
+ }
+
+ /* Check that values in linked lists for objects in locations are inside bounds */
+ for (loc_t loc = LOC_NOWHERE; loc <= NLOCATIONS; loc++) {
+ if (valgame->atloc[loc] < NO_OBJECT || valgame->atloc[loc] > NOBJECTS * 2) {
+ return false;
+ }
+ }
+ for (obj_t obj = 0; obj <= NOBJECTS * 2; obj++ ) {
+ if (valgame->link[obj] < NO_OBJECT || valgame->link[obj] > NOBJECTS * 2) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
/* end */
diff --git a/tests/Makefile b/tests/Makefile
index 4d7f215..fc4801f 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -25,7 +25,6 @@ check: savecheck regress
@-advent -l /dev/null <pitfall.log >/dev/null
coverage: check
- ls -lR $(PARDIR)
lcov -t "advent" -o $(PARDIR)/advent.info -c -d $(PARDIR) --gcov-tool=$(GCOV)
genhtml -o $(PARDIR)/coverage/ $(PARDIR)/advent.info
./coverage_dungeon.py
diff --git a/tests/illformed.chk b/tests/illformed.chk
index 20f18c9..3c763af 100644
--- a/tests/illformed.chk
+++ b/tests/illformed.chk
@@ -669,7 +669,7 @@ The grate is locked.
> seed -123
-Seed set to 4294967173
+Seed set to -123
You're outside grate.
diff --git a/tests/resumefail2.chk b/tests/resumefail2.chk
index cdda771..a34e001 100644
--- a/tests/resumefail2.chk
+++ b/tests/resumefail2.chk
@@ -11,7 +11,7 @@ down a gully.
Can't open file y, try again.
I'm sorry, but that Adventure was begun using Version -133.-7 of the
-save file format, and this program uses Version 2.7. You must find an instance
+save file format, and this program uses Version 2.8. You must find an instance
using that other version in order to resume that Adventure.
You're in front of building.
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/open-adventure.git
More information about the Pkg-games-commits
mailing list