Even less magic

This commit is contained in:
NHOrus 2017-06-19 20:13:50 +03:00
parent 18a9be501f
commit e9aff2568f
7 changed files with 89 additions and 88 deletions

View file

@ -134,7 +134,7 @@ static int bigwords(long foo)
} else { } else {
/* Bring back troll if we steal the eggs back from him before /* Bring back troll if we steal the eggs back from him before
* crossing. */ * crossing. */
if (game.place[EGGS] == 0 && game.place[TROLL] == 0 && game.prop[TROLL] == 0) if (game.place[EGGS] == LOC_NOWHERE && game.place[TROLL] == LOC_NOWHERE && game.prop[TROLL] == 0)
game.prop[TROLL] = 1; game.prop[TROLL] = 1;
k = 2; k = 2;
if (HERE(EGGS))k = 1; if (HERE(EGGS))k = 1;
@ -389,7 +389,7 @@ static int discard(token_t verb, token_t obj, bool just_do_it)
int k = LIQUID(); int k = LIQUID();
if (k == obj)obj = BOTTLE; if (k == obj)obj = BOTTLE;
if (obj == BOTTLE && k != 0) if (obj == BOTTLE && k != 0)
game.place[k] = NOWHERE; game.place[k] = LOC_NOWHERE;
if (obj == CAGE && game.prop[BIRD] == 1)DROP(BIRD, game.loc); if (obj == CAGE && game.prop[BIRD] == 1)DROP(BIRD, game.loc);
DROP(obj, game.loc); DROP(obj, game.loc);
if (obj != BIRD) return GO_CLEAROBJ; if (obj != BIRD) return GO_CLEAROBJ;
@ -409,7 +409,7 @@ static int drink(token_t verb, token_t obj)
if (obj != 0 && obj != WATER)spk = RIDICULOUS_ATTEMPT; if (obj != 0 && obj != WATER)spk = RIDICULOUS_ATTEMPT;
if (spk != RIDICULOUS_ATTEMPT && LIQUID() == WATER && HERE(BOTTLE)) { if (spk != RIDICULOUS_ATTEMPT && LIQUID() == WATER && HERE(BOTTLE)) {
game.prop[BOTTLE] = 1; game.prop[BOTTLE] = 1;
game.place[WATER] = NOWHERE; game.place[WATER] = LOC_NOWHERE;
spk = BOTTLE_EMPTY; spk = BOTTLE_EMPTY;
} }
} else { } else {
@ -539,7 +539,7 @@ int fill(token_t verb, token_t obj)
RSPEAK(spk); RSPEAK(spk);
return GO_CLEAROBJ; return GO_CLEAROBJ;
} }
game.place[k] = NOWHERE; game.place[k] = LOC_NOWHERE;
game.prop[BOTTLE] = 1; game.prop[BOTTLE] = 1;
if (k == OIL)game.prop[URN] = 1; if (k == OIL)game.prop[URN] = 1;
spk = WATER_URN + game.prop[URN]; spk = WATER_URN + game.prop[URN];
@ -764,7 +764,7 @@ static int pour(token_t verb, token_t obj)
if (HERE(URN) && game.prop[URN] == 0) if (HERE(URN) && game.prop[URN] == 0)
return fill(verb, URN); return fill(verb, URN);
game.prop[BOTTLE] = 1; game.prop[BOTTLE] = 1;
game.place[obj] = NOWHERE; game.place[obj] = LOC_NOWHERE;
spk = GROUND_WET; spk = GROUND_WET;
if (!(AT(PLANT) || AT(DOOR))) { if (!(AT(PLANT) || AT(DOOR))) {
RSPEAK(spk); RSPEAK(spk);
@ -800,7 +800,6 @@ static int quit(void)
static int read(token_t verb, token_t obj) static int read(token_t verb, token_t obj)
/* Read. Print stuff based on objtxt. Oyster (?) is special case. */ /* Read. Print stuff based on objtxt. Oyster (?) is special case. */
{ {
int spk = ACTSPK[verb];
if (obj == INTRANSITIVE) { if (obj == INTRANSITIVE) {
obj = 0; obj = 0;
for (int i = 1; i <= NOBJECTS; i++) { for (int i = 1; i <= NOBJECTS; i++) {
@ -816,7 +815,7 @@ static int read(token_t verb, token_t obj)
return GO_CLEAROBJ; return GO_CLEAROBJ;
} }
if (OBJTXT[obj] == 0 || game.prop[obj] < 0) { if (OBJTXT[obj] == 0 || game.prop[obj] < 0) {
RSPEAK(spk); RSPEAK(ACTSPK[verb]);
return GO_CLEAROBJ; return GO_CLEAROBJ;
} }
if (obj == OYSTER && !game.clshnt) { if (obj == OYSTER && !game.clshnt) {
@ -891,7 +890,7 @@ static int throw_support(long spk)
return GO_MOVE; return GO_MOVE;
} }
static int throw(FILE *cmdin, long verb, token_t obj) static int throw (FILE *cmdin, long verb, token_t obj)
/* Throw. Same as discard unless axe. Then same as attack except /* Throw. Same as discard unless axe. Then same as attack except
* ignore bird, and if dwarf is present then one might be killed. * ignore bird, and if dwarf is present then one might be killed.
* (Only way to do so!) Axe also special for dragon, bear, and * (Only way to do so!) Axe also special for dragon, bear, and
@ -923,34 +922,34 @@ static int throw(FILE *cmdin, long verb, token_t obj)
if (obj != AXE) if (obj != AXE)
return (discard(verb, obj, false)); return (discard(verb, obj, false));
else { else {
int i = ATDWRF(game.loc); int i = ATDWRF(game.loc);
if (i <= 0) { if (i <= 0) {
if (AT(DRAGON) && game.prop[DRAGON] == 0) if (AT(DRAGON) && game.prop[DRAGON] == 0)
return throw_support(DRAGON_SCALES); return throw_support(DRAGON_SCALES);
if (AT(TROLL)) if (AT(TROLL))
return throw_support(TROLL_RETURNS); return throw_support(TROLL_RETURNS);
else if (AT(OGRE)) else if (AT(OGRE))
return throw_support(OGRE_DODGE); return throw_support(OGRE_DODGE);
else if (HERE(BEAR) && game.prop[BEAR] == 0) { else if (HERE(BEAR) && game.prop[BEAR] == 0) {
/* This'll teach him to throw the axe at the bear! */ /* This'll teach him to throw the axe at the bear! */
DROP(AXE, game.loc); DROP(AXE, game.loc);
game.fixed[AXE] = -1; game.fixed[AXE] = -1;
game.prop[AXE] = 1; game.prop[AXE] = 1;
JUGGLE(BEAR); JUGGLE(BEAR);
RSPEAK(AXE_LOST); RSPEAK(AXE_LOST);
return GO_CLEAROBJ; return GO_CLEAROBJ;
} }
return (attack(cmdin, verb, 0)); return (attack(cmdin, verb, 0));
} }
if (randrange(NDWARVES + 1) < game.dflag) { if (randrange(NDWARVES + 1) < game.dflag) {
return throw_support(DWARF_DODGES); return throw_support(DWARF_DODGES);
} else { } else {
game.dseen[i] = false; game.dseen[i] = false;
game.dloc[i] = 0; game.dloc[i] = 0;
return throw_support((++game.dkill == 1) return throw_support((++game.dkill == 1)
? DWARF_SMOKE : KILLED_DWARF); ? DWARF_SMOKE : KILLED_DWARF);
} }
} }
} }

View file

@ -14,6 +14,8 @@
#define INVLIMIT 7 /* inverntory limit (# of objects) */ #define INVLIMIT 7 /* inverntory limit (# of objects) */
#define INTRANSITIVE -1 /* illegal object number */ #define INTRANSITIVE -1 /* illegal object number */
#define SPECIALBASE 300 /* base number of special rooms */ #define SPECIALBASE 300 /* base number of special rooms */
#define GAMELIMIT 330 /* base limit of turns */
#define NOVICELIMIT 1000 /* limit of turns for novice */
#define WARNTIME 30 /* late game starts at game.limit-this */ #define WARNTIME 30 /* late game starts at game.limit-this */
#define PANICTIME 15 /* time left after closing */ #define PANICTIME 15 /* time left after closing */
#define BATTERYLIFE 2500 /* turn limit increment from batteries */ #define BATTERYLIFE 2500 /* turn limit increment from batteries */
@ -60,23 +62,23 @@ struct game_t {
long turns; long turns;
long wzdark; long wzdark;
long zzword; long zzword;
long abbrev[LOCSIZ+1]; long abbrev[LOCSIZ + 1];
long atloc[LOCSIZ+1]; long atloc[LOCSIZ + 1];
long dseen[NDWARVES+1]; long dseen[NDWARVES + 1];
long dloc[NDWARVES+1]; long dloc[NDWARVES + 1];
long odloc[NDWARVES+1]; long odloc[NDWARVES + 1];
long fixed[NOBJECTS+1]; long fixed[NOBJECTS + 1];
long link[NOBJECTS*2 + 1]; long link[NOBJECTS * 2 + 1];
long place[NOBJECTS+1]; long place[NOBJECTS + 1];
long hinted[HNTSIZ+1]; long hinted[HNTSIZ + 1];
long hintlc[HNTSIZ+1]; long hintlc[HNTSIZ + 1];
long prop[NOBJECTS+1]; long prop[NOBJECTS + 1];
}; };
extern struct game_t game; extern struct game_t game;
extern long LNLENG, LNPOSN, PARMS[]; extern long LNLENG, LNPOSN, PARMS[];
extern char rawbuf[LINESIZE], INLINE[LINESIZE+1]; extern char rawbuf[LINESIZE], INLINE[LINESIZE + 1];
extern const char ascii_to_advent[]; extern const char ascii_to_advent[];
extern const char advent_to_ascii[]; extern const char advent_to_ascii[];
extern FILE *logfp; extern FILE *logfp;
@ -89,25 +91,25 @@ extern void* xmalloc(size_t size);
extern char* xstrdup(const char*); extern char* xstrdup(const char*);
extern void packed_to_token(long, char token[]); extern void packed_to_token(long, char token[]);
extern void speak(const char*); extern void speak(const char*);
extern void PSPEAK(vocab_t,int); extern void PSPEAK(vocab_t, int);
extern void RSPEAK(vocab_t); extern void RSPEAK(vocab_t);
extern void SETPRM(long,long,long); extern void SETPRM(long, long, long);
extern bool GETIN(FILE *,token_t*,token_t*,token_t*,token_t*); extern bool GETIN(FILE *, token_t*, token_t*, token_t*, token_t*);
extern void echo_input(FILE*, char*, char*); extern void echo_input(FILE*, char*, char*);
extern char* get_input(void); extern char* get_input(void);
extern bool YES(const char*, const char*, const char*); extern bool YES(const char*, const char*, const char*);
extern long GETTXT(bool,bool,bool); extern long GETTXT(bool, bool, bool);
extern token_t MAKEWD(long); extern token_t MAKEWD(long);
extern long VOCAB(long,long); extern long VOCAB(long, long);
extern void JUGGLE(long); extern void JUGGLE(long);
extern void MOVE(long,long); extern void MOVE(long, long);
extern long PUT(long,long,long); extern long PUT(long, long, long);
extern void CARRY(long,long); extern void CARRY(long, long);
extern void DROP(long,long); extern void DROP(long, long);
extern long ATDWRF(long); extern long ATDWRF(long);
extern long SETBIT(long); extern long SETBIT(long);
extern bool TSTBIT(long,int); extern bool TSTBIT(long, int);
extern long RNDVOC(long,long); extern long RNDVOC(long, long);
extern bool MAPLIN(FILE *); extern bool MAPLIN(FILE *);
extern void DATIME(long*, long*); extern void DATIME(long*, long*);
@ -136,7 +138,7 @@ extern int restore(FILE *);
* PCT(N) = true N% of the time (N integer from 0 to 100) * PCT(N) = true N% of the time (N integer from 0 to 100)
* TOTING(OBJ) = true if the OBJ is being carried */ * TOTING(OBJ) = true if the OBJ is being carried */
#define DESTROY(N) MOVE(N, NOWHERE) #define DESTROY(N) MOVE(N, LOC_NOWHERE)
#define MOD(N,M) ((N) % (M)) #define MOD(N,M) ((N) % (M))
#define TOTING(OBJ) (game.place[OBJ] == CARRIED) #define TOTING(OBJ) (game.place[OBJ] == CARRIED)
#define AT(OBJ) (game.place[OBJ] == game.loc || game.fixed[OBJ] == game.loc) #define AT(OBJ) (game.place[OBJ] == game.loc || game.fixed[OBJ] == game.loc)
@ -162,23 +164,23 @@ extern int restore(FILE *);
#define OUTSID(LOC) ((LOC) <= LOC_GRATE || FOREST(LOC) || (LOC) == PLAC[SAPPH] || (LOC) == LOC_FOOF2 || (LOC) == LOC_FOOF4) #define OUTSID(LOC) ((LOC) <= LOC_GRATE || FOREST(LOC) || (LOC) == PLAC[SAPPH] || (LOC) == LOC_FOOF2 || (LOC) == LOC_FOOF4)
#define INDEEP(LOC) ((LOC) >= LOC_MISTHALL && !OUTSID(LOC) && (LOC) != LOC_FOOF1) #define INDEEP(LOC) ((LOC) >= LOC_MISTHALL && !OUTSID(LOC) && (LOC) != LOC_FOOF1)
/* vocabulary items */ /* vocabulary items */
extern long AMBER, ATTACK, AXE, BACK, BATTERY, BEAR, extern long AMBER, ATTACK, AXE, BACK, BATTERY, BEAR,
BIRD, BLOOD, BOTTLE, CAGE, CAVE, CAVITY, CHAIN, CHASM, CHEST, BIRD, BLOOD, BOTTLE, CAGE, CAVE, CAVITY, CHAIN, CHASM, CHEST,
CLAM, COINS, DOOR, DPRSSN, DRAGON, DWARF, EGGS, CLAM, COINS, DOOR, DPRSSN, DRAGON, DWARF, EGGS,
EMERALD, ENTER, ENTRNC, FIND, FISSURE, FOOD, GRATE, HINT, INVENT, EMERALD, ENTER, ENTRNC, FIND, FISSURE, FOOD, GRATE, HINT, INVENT,
JADE, KEYS, KNIFE, LAMP, LOCK, LOOK, MAGAZINE, MESSAG, MIRROR, NUGGET, NUL, JADE, KEYS, KNIFE, LAMP, LOCK, LOOK, MAGAZINE, MESSAG, MIRROR, NUGGET, NUL,
OGRE, OIL, OYSTER, PANIC, PEARL, PILLOW, PLANT, PLANT2, PYRAMID, OGRE, OIL, OYSTER, PANIC, PEARL, PILLOW, PLANT, PLANT2, PYRAMID,
RESER, ROD, ROD2, RUBY, RUG, SAPPH, SAY, SIGN, SNAKE, RESER, ROD, ROD2, RUBY, RUG, SAPPH, SAY, SIGN, SNAKE,
STEPS, STICK, STREAM, THROW, TRIDENT, TROLL, TROLL2, STEPS, STICK, STREAM, THROW, TRIDENT, TROLL, TROLL2,
URN, VASE, VEND, VOLCANO, WATER; URN, VASE, VEND, VOLCANO, WATER;
enum speechpart {unknown, intransitive, transitive}; enum speechpart {unknown, intransitive, transitive};
void initialise(void); void initialise(void);
int action(FILE *input, enum speechpart part, long verb, token_t obj); int action(FILE *input, enum speechpart part, long verb, token_t obj);
/* Phase codes for action returns. /* Phase codes for action returns.
* These were at one time FORTRAN line numbers. * These were at one time FORTRAN line numbers.
* The values don't matter, but perturb their order at your peril. * The values don't matter, but perturb their order at your peril.
*/ */
@ -203,7 +205,7 @@ int action(FILE *input, enum speechpart part, long verb, token_t obj);
#define NOARRR 3 /* Pirate doesn't go here unless following player */ #define NOARRR 3 /* Pirate doesn't go here unless following player */
#define NOBACK 4 /* Cannot use "back" to move away */ #define NOBACK 4 /* Cannot use "back" to move away */
/* Bits past 10 indicate areas of interest to "hint" routines */ /* Bits past 10 indicate areas of interest to "hint" routines */
#define HBASE 10 /* Base for location hint bitss */ #define HBASE 10 /* Base for location hint bits */
#define HCAVE 11 /* Trying to get into cave */ #define HCAVE 11 /* Trying to get into cave */
#define HBIRD 12 /* Trying to catch bird */ #define HBIRD 12 /* Trying to catch bird */
#define HSNAKE 13 /* Trying to deal with snake */ #define HSNAKE 13 /* Trying to deal with snake */
@ -217,7 +219,6 @@ int action(FILE *input, enum speechpart part, long verb, token_t obj);
/* Special object statuses in game.place - can also be a location number (> 0) */ /* Special object statuses in game.place - can also be a location number (> 0) */
#define CARRIED -1 /* Player is toting it */ #define CARRIED -1 /* Player is toting it */
#define NOWHERE 0 /* It's destroyed */
/* hack to ignore GCC Unused Result */ /* hack to ignore GCC Unused Result */
#define IGNORE(r) do{if (r){}}while(0) #define IGNORE(r) do{if (r){}}while(0)

View file

@ -1,5 +1,5 @@
locations: !!omap locations: !!omap
- LOC_0: - LOC_NOWHERE:
description: description:
long: !!null long: !!null
short: !!null short: !!null

View file

@ -547,8 +547,8 @@ static void write_file(FILE* header_file)
void bug(enum bugtype num, const char *error_string) void bug(enum bugtype num, const char *error_string)
{ {
fprintf(stderr, "Fatal error %d, %s.\n", num, error_string); fprintf(stderr, "Fatal error %d, %s.\n", num, error_string);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
int main(void) int main(void)

2
init.c
View file

@ -176,7 +176,7 @@ void initialise(void)
printf("Initialising...\n"); printf("Initialising...\n");
for (int i = 1; i <= NOBJECTS; i++) { for (int i = 1; i <= NOBJECTS; i++) {
game.place[i] = NOWHERE; game.place[i] = LOC_NOWHERE;
game.prop[i] = 0; game.prop[i] = 0;
game.link[i + NOBJECTS] = game.link[i] = 0; game.link[i + NOBJECTS] = game.link[i] = 0;
} }

21
main.c
View file

@ -78,11 +78,11 @@ int main(int argc, char *argv[])
/* Options. */ /* Options. */
#ifndef ADVENT_NOSAVE #ifndef ADVENT_NOSAVE
char* opts = "l:or:s"; const char* opts = "l:or:s";
char* usage = "Usage: %s [-l logfilename] [-o] [-r restorefilename] [-s] \n"; const char* usage = "Usage: %s [-l logfilename] [-o] [-r restorefilename] [-s] \n";
#else #else
char* opts = "l:os"; const char* opts = "l:os";
char* usage = "Usage: %s [-l logfilename] [-o] [-s] \n"; const char* usage = "Usage: %s [-l logfilename] [-o] [-s] \n";
#endif #endif
while ((ch = getopt(argc, argv, opts)) != EOF) { while ((ch = getopt(argc, argv, opts)) != EOF) {
switch (ch) { switch (ch) {
@ -157,10 +157,11 @@ int main(int argc, char *argv[])
game.zzword = RNDVOC(3, 0); game.zzword = RNDVOC(3, 0);
game.newloc = LOC_START; game.newloc = LOC_START;
game.loc = LOC_START; game.loc = LOC_START;
game.limit = 330; game.limit = GAMELIMIT;
if (!rfp) { if (!rfp) {
game.novice = YES(arbitrary_messages[WELCOME_YOU], arbitrary_messages[CAVE_NEARBY], arbitrary_messages[NO_MESSAGE]); game.novice = YES(arbitrary_messages[WELCOME_YOU], arbitrary_messages[CAVE_NEARBY], arbitrary_messages[NO_MESSAGE]);
if (game.novice)game.limit = 1000; if (game.novice)
game.limit = NOVICELIMIT;
} else { } else {
restore(rfp); restore(rfp);
} }
@ -295,7 +296,7 @@ static bool spotted_by_pirate(int i)
/* The pirate's spotted him. He leaves him alone once we've /* The pirate's spotted him. He leaves him alone once we've
* found chest. K counts if a treasure is here. If not, and * found chest. K counts if a treasure is here. If not, and
* tally=1 for an unseen chest, let the pirate be spotted. Note * tally=1 for an unseen chest, let the pirate be spotted. Note
* that game.place[CHEST] = NOWHERE might mean that he's thrown * that game.place[CHEST] = LOC_NOWHERE might mean that he's thrown
* it to the troll, but in that case he's seen the chest * it to the troll, but in that case he's seen the chest
* (game.prop=0). */ * (game.prop=0). */
if (game.loc == game.chloc || game.prop[CHEST] >= 0) if (game.loc == game.chloc || game.prop[CHEST] >= 0)
@ -316,7 +317,7 @@ static bool spotted_by_pirate(int i)
} }
} }
/* Force chest placement before player finds last treasure */ /* Force chest placement before player finds last treasure */
if (game.tally == 1 && snarfed == 0 && game.place[CHEST] == NOWHERE && HERE(LAMP) && game.prop[LAMP] == 1) { if (game.tally == 1 && snarfed == 0 && game.place[CHEST] == LOC_NOWHERE && HERE(LAMP) && game.prop[LAMP] == 1) {
RSPEAK(PIRATE_SPOTTED); RSPEAK(PIRATE_SPOTTED);
movechest = true; movechest = true;
} }
@ -512,7 +513,7 @@ static void croak(void)
} else if (game.numdie == maximum_deaths || !YES(query, yes_response, arbitrary_messages[OK_MAN])) } else if (game.numdie == maximum_deaths || !YES(query, yes_response, arbitrary_messages[OK_MAN]))
terminate(endgame); terminate(endgame);
else { else {
game.place[WATER] = game.place[OIL] = NOWHERE; game.place[WATER] = game.place[OIL] = LOC_NOWHERE;
if (TOTING(LAMP)) if (TOTING(LAMP))
game.prop[LAMP] = 0; game.prop[LAMP] = 0;
for (int j = 1; j <= NOBJECTS; j++) { for (int j = 1; j <= NOBJECTS; j++) {
@ -878,7 +879,7 @@ static void lampcheck(void)
if (!game.lmwarn && HERE(LAMP)) { if (!game.lmwarn && HERE(LAMP)) {
game.lmwarn = true; game.lmwarn = true;
int spk = GET_BATTERIES; int spk = GET_BATTERIES;
if (game.place[BATTERY] == NOWHERE)spk = LAMP_DIM; if (game.place[BATTERY] == LOC_NOWHERE)spk = LAMP_DIM;
if (game.prop[BATTERY] == 1)spk = MISSING_BATTERYIES; if (game.prop[BATTERY] == 1)spk = MISSING_BATTERYIES;
RSPEAK(spk); RSPEAK(spk);
} }

6
misc.c
View file

@ -417,7 +417,7 @@ void MOVE(long object, long where)
from = game.fixed[object - NOBJECTS]; from = game.fixed[object - NOBJECTS];
else else
from = game.place[object]; from = game.place[object];
if (from != NOWHERE && from != CARRIED && !SPECIAL(from)) if (from != LOC_NOWHERE && from != CARRIED && !SPECIAL(from))
CARRY(object, from); CARRY(object, from);
DROP(object, where); DROP(object, where);
} }
@ -660,8 +660,8 @@ void DATIME(long* d, long* t)
void bug(enum bugtype num, const char *error_string) void bug(enum bugtype num, const char *error_string)
{ {
fprintf(stderr, "Fatal error %d, %s.\n", num, error_string); fprintf(stderr, "Fatal error %d, %s.\n", num, error_string);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
/* end */ /* end */