X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=actions.c;h=8f852aa2a1b0bcd4e2229e1884d22e08ef2e78d6;hb=3ed8b91eb7f636e49fd8e5f4cdea495ba410b6cb;hp=356b2b9c7d1f524a2e57eee8fb81ac71e1466fc4;hpb=9bac28878d14fc8eebc1cc654586f689dfa3a06d;p=open-adventure.git diff --git a/actions.c b/actions.c index 356b2b9..8f852aa 100644 --- a/actions.c +++ b/actions.c @@ -3,8 +3,6 @@ #include "advent.h" #include "database.h" -#define VRSION 25 /* bump on save format change */ - /* * Action handlers. Eventually we'll do lookup through a method table * that calls these. Absolutely nothing like the original FORTRAN. @@ -754,7 +752,7 @@ static int rub(token_t obj) DSTROY(URN); DROP(AMBER,game.loc); game.prop[AMBER]=1; - game.tally=game.tally-1; + --game.tally; DROP(CAVITY,game.loc); SPK=216; return(2011); @@ -776,88 +774,6 @@ static int say(void) } -static int suspendresume(FILE *input, bool resume) -/* Suspend and resume */ -{ - int kk; - long i; - if (!resume) { - /* Suspend. Offer to save things in a file, but charging - * some points (so can't win by using saved games to retry - * battles or to start over after learning zzword). */ - SPK=201; - RSPEAK(260); - if (!YES(input,200,54,54)) return(2012); - game.saved=game.saved+5; - kk= -1; - } - else - { - /* Resume. Read a suspended game back from a file. */ - kk=1; - if (game.loc != 1 || game.abbrev[1] != 1) { - RSPEAK(268); - if (!YES(input,200,54,54)) return(2012); - } - } - - /* Suspend vs resume cases are distinguished by the value of kk - * (-1 for suspend, +1 for resume). */ - - /* - * FIXME: This is way more complicated than it needs to be in C. - * What we ought to do is define a save-block structure that - * includes a game state block and then use a single fread/fwrite - * for I/O. All the SAV* functions can be scrapped. - */ - - DATIME(&i,&K); - K=i+650*K; - SAVWRD(kk,K); - K=VRSION; - SAVWRD(0,K); - if (K != VRSION) { - SETPRM(1,K/10,MOD(K,10)); - SETPRM(3,VRSION/10,MOD(VRSION,10)); - RSPEAK(269); - return(2000); - } - /* Herewith are all the variables whose values can change during a game, - * omitting a few (such as I, J) whose values between turns are - * irrelevant and some whose values when a game is - * suspended or resumed are guaranteed to match. If unsure whether a value - * needs to be saved, include it. Overkill can't hurt. Pad the last savwds - * with junk variables to bring it up to 7 values. */ - SAVWDS(game.abbnum,game.blklin,game.bonus,game.clock1,game.clock2,game.closed,game.closng); - SAVWDS(game.detail,game.dflag,game.dkill,game.dtotal,game.foobar,game.holdng,game.iwest); - SAVWDS(game.knfloc,game.limit,K,game.lmwarn,game.loc,game.newloc,game.numdie); - SAVWDS(K,game.oldlc2,game.oldloc,game.oldobj,game.panic,game.saved,game.setup); - SAVWDS(SPK,game.tally,game.thresh,game.trndex,game.trnluz,game.turns,OBJTXT[OYSTER]); - SAVWDS(K,WD1,WD1X,WD2,game.wzdark,game.zzword,OBJSND[BIRD]); - SAVWDS(OBJTXT[SIGN],game.clshnt,game.novice,K,K,K,K); - SAVARR(game.abbrev,LOCSIZ); - SAVARR(game.atloc,LOCSIZ); - SAVARR(game.dloc,NDWARVES); - SAVARR(game.dseen,NDWARVES); - SAVARR(game.fixed,NOBJECTS); - SAVARR(game.hinted,HNTSIZ); - SAVARR(game.hintlc,HNTSIZ); - SAVARR(game.link,NOBJECTS*2); - SAVARR(game.odloc,NDWARVES); - SAVARR(game.place,NOBJECTS); - SAVARR(game.prop,NOBJECTS); - SAVWRD(kk,K); - if (K != 0) { - RSPEAK(270); - exit(0); - } - K=NUL; - game.zzword=RNDVOC(3,game.zzword); - if (kk > 0) return(8); - RSPEAK(266); - exit(0); -} - static int throw_support(long spk) { RSPEAK(spk); @@ -926,7 +842,7 @@ static int throw(FILE *cmdin, long verb, long obj) game.dseen[i]=false; game.dloc[i]=0; SPK=47; - game.dkill=game.dkill+1; + ++game.dkill; if (game.dkill == 1)SPK=149; return throw_support(SPK); @@ -959,7 +875,7 @@ static int wave(token_t obj) if (SPK == 206 && game.loc == game.place[STEPS] && game.prop[JADE] < 0) { DROP(JADE,game.loc); game.prop[JADE]=0; - game.tally=game.tally-1; + --game.tally; SPK=208; return(2011); } else { @@ -972,17 +888,67 @@ static int wave(token_t obj) } } -/* We're called with a number that says what label the caller wanted - * to "goto", and we return a similar label number for the caller to - * "goto". - */ - int action(FILE *input, enum speechpart part, long verb, long obj) /* Analyse a verb. Remember what it was, go back for object if second word * unless verb is "say", which snarfs arbitrary second word. */ { int kk; + + if (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 + * unless verb is "find" or "invent(ory)" (and no new verb + * yet to be analysed). Water and oil are also funny, since + * they are never actually dropped at any location, but might + * be here inside the bottle or urn or as a feature of the + * location. */ + if (HERE(obj)) + /* FALL THROUGH */; + else if (obj == GRATE) { + if (game.loc == 1 || game.loc == 4 || game.loc == 7) + obj=DPRSSN; + if (game.loc > 9 && game.loc < 15) + obj=ENTRNC; + if (obj != GRATE) + return(8); + } + else if (obj == DWARF && ATDWRF(game.loc) > 0) + /* FALL THROUGH */; + else if ((LIQ(0) == obj && HERE(BOTTLE)) || obj == LIQLOC(game.loc)) + /* FALL THROUGH */; + else if (obj == OIL && HERE(URN) && game.prop[URN] != 0) { + obj=URN; + /* FALL THROUGH */; + } + else if (obj == PLANT && AT(PLANT2) && game.prop[PLANT2] != 0) { + obj=PLANT2; + /* FALL THROUGH */; + } + else if (obj == KNIFE && game.knfloc == game.loc) { + game.knfloc= -1; + SPK=116; + return(2011); + } + else if (obj == ROD && HERE(ROD2)) { + obj=ROD2; + /* FALL THROUGH */; + } + else if ((verb == FIND || verb == INVENT) && WD2 <= 0) + /* FALL THROUGH */; + else { + SETPRM(1,WD1,WD1X); + RSPEAK(256); + return(2012); + } + + if (WD2 > 0) + return(2800); + if (verb != 0) + part = transitive; + } + switch(part) { case intransitive: @@ -1021,8 +987,8 @@ int action(FILE *input, enum speechpart part, long verb, long obj) case 26: /* READ */ return read(input, INTRANSITIVE); case 27: /* BREAK */ return(8000); case 28: /* WAKE */ return(8000); - case 29: /* SUSP */ return suspendresume(input, false); - case 30: /* RESU */ return suspendresume(input, true); + case 29: /* SUSP */ return saveresume(input, false); + case 30: /* RESU */ return saveresume(input, true); case 31: /* FLY */ return fly(INTRANSITIVE); case 32: /* LISTE */ return listen(); case 33: /* ZZZZ */ return reservoir(); @@ -1031,7 +997,6 @@ int action(FILE *input, enum speechpart part, long verb, long obj) } /* FALLTHRU */ case transitive: - L4090: /* Analyse a transitive verb. */ switch (verb-1) { case 0: /* CARRY */ return carry(obj); @@ -1071,62 +1036,11 @@ int action(FILE *input, enum speechpart part, long verb, long obj) } BUG(24); case 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 - * unless verb is "find" or "invent(ory)" (and no new verb - * yet to be analysed). Water and oil are also funny, since - * they are never actually dropped at any location, but might - * be here inside the bottle or urn or as a feature of the - * location. */ - if (!HERE(obj)) - goto L5100; - L5010: - if (WD2 > 0) - return(2800); - if (verb != 0) - goto L4090; + /* Unknown verb, couldn't deduce object - might need hint */ SETPRM(1,WD1,WD1X); RSPEAK(255); return(2600); - - L5100: - if (obj == GRATE) { - if (game.loc == 1 || game.loc == 4 || game.loc == 7) - obj=DPRSSN; - if (game.loc > 9 && game.loc < 15) - obj=ENTRNC; - if (obj != GRATE) - return(8); - } - - if (obj == DWARF && ATDWRF(game.loc) > 0) - goto L5010; - if ((LIQ(0) == obj && HERE(BOTTLE)) || obj == LIQLOC(game.loc)) - goto L5010; - if (obj == OIL && HERE(URN) && game.prop[URN] != 0) { - obj=URN; - goto L5010; - } - if (obj == PLANT && AT(PLANT2) && game.prop[PLANT2] != 0) { - obj=PLANT2; - goto L5010; - } - if (obj == KNIFE && game.knfloc == game.loc) { - game.knfloc= -1; - SPK=116; - return(2011); - } - if (obj == ROD && HERE(ROD2)) { - obj=ROD2; - goto L5010; - } - if ((verb == FIND || verb == INVENT) && WD2 <= 0) - goto L5010; - - SETPRM(1,WD1,WD1X); - RSPEAK(256); - return(2012); - default: + default: BUG(99); } }