Completely wire vocab words in YAML to the code.

This massive patch:
* Finishes working all the vocab words into YAML structures.
* Adds vocab ID generator functions.
* Redoes the input-getting system, removing the need for GETIN(),
  GETTXT(), etc.
* Changes advent<->ascii mapping to avoid the special 'shift'
  character.
* Works around some bad behavior in the dragon attack logic.
* Handles the reservoir magic word without changing the database
  contents.
This commit is contained in:
Jason S. Ninneman 2017-06-28 09:35:55 -07:00
parent 9d918edeaa
commit 50435465a6
11 changed files with 460 additions and 52 deletions

58
main.c
View file

@ -20,6 +20,7 @@
#include <getopt.h>
#include <signal.h>
#include <time.h>
#include <string.h>
#include "advent.h"
#include "database.h"
#include "linenoise/linenoise.h"
@ -61,7 +62,7 @@ static void sig_handler(int signo)
* Revived 2017 as Open Adventure.
*/
static bool do_command(FILE *);
static bool do_command(void);
int main(int argc, char *argv[])
{
@ -136,7 +137,7 @@ int main(int argc, char *argv[])
initialise();
/* Start-up, dwarf stuff */
game.zzword = rndvoc(3, 0);
make_zzword(game.zzword);
game.newloc = LOC_START;
game.loc = LOC_START;
game.limit = GAMELIMIT;
@ -153,7 +154,7 @@ int main(int argc, char *argv[])
/* interpret commands until EOF or interrupt */
for (;;) {
if (!do_command(stdin))
if (!do_command())
break;
}
/* show score and exit */
@ -170,7 +171,7 @@ static bool fallback_handler(char *buf)
// autogenerated, so don't charge user time for it.
--game.turns;
// here we reconfigure any global game state that uses random numbers
game.zzword = rndvoc(3, 0);
make_zzword(game.zzword);
return true;
}
return false;
@ -931,7 +932,7 @@ static void listobjects(void)
}
}
static bool do_command(FILE *cmdin)
static bool do_command()
/* Get and execute a command */
{
long V1, V2;
@ -1024,8 +1025,25 @@ L2600:
game.knfloc = 0;
/* This is where we get a new command from the user */
if (!GETIN(cmdin, &command.wd1, &command.wd1x, &command.wd2, &command.wd2x))
return false;
char* input;
for (;;) {
input = get_input();
if (input == NULL)
return(false);
if (word_count(input) > 2)
{
rspeak(TWO_WORDS);
continue;
}
if (strcmp(input, "") != 0)
break;
}
long tokens[4];
tokenize(input, tokens);
command.wd1 = tokens[0];
command.wd1x = tokens[1];
command.wd2 = tokens[2];
command.wd2x = tokens[3];
/* Every input, check "game.foobar" flag. If zero, nothing's
* going on. If pos, make neg. If neg, he skipped a word,
@ -1057,8 +1075,12 @@ L2607:
} else
lampcheck();
V1 = vocab(command.wd1, -1);
V2 = vocab(command.wd2, -1);
char word1[6];
char word2[6];
packed_to_token(command.wd1, word1);
packed_to_token(command.wd2, word2);
V1 = get_vocab_id(word1);
V2 = get_vocab_id(word2);
if (V1 == ENTER && (V2 == STREAM || V2 == 1000 + WATER)) {
if (LIQLOC(game.loc) == WATER) {
rspeak(FEET_WET);
@ -1076,26 +1098,27 @@ L2607:
if (!((V1 != 1000 + WATER && V1 != 1000 + OIL) ||
(V2 != 1000 + PLANT && V2 != 1000 + DOOR))) {
if (AT(V2 - 1000))
command.wd2 = MAKEWD(WORD_POUR);
command.wd2 = token_to_packed("POUR");
}
if (V1 == 1000 + CAGE && V2 == 1000 + BIRD && HERE(CAGE) && HERE(BIRD))
command.wd1 = MAKEWD(WORD_CATCH);
command.wd1 = token_to_packed("CATCH");
}
L2620:
if (wordeq(command.wd1, MAKEWD(WORD_WEST))) {
if (wordeq(command.wd1, token_to_packed("WEST"))) {
++game.iwest;
if (game.iwest == 10)
rspeak(W_IS_WEST);
}
if (wordeq(command.wd1, MAKEWD(WORD_GO)) && !wordempty(command.wd2)) {
if (wordeq(command.wd1, token_to_packed("GO")) && !wordempty(command.wd2)) {
if (++igo == 10)
rspeak(GO_UNNEEDED);
}
Lookup:
defn = vocab(command.wd1, -1);
packed_to_token(command.wd1, word1);
defn = get_vocab_id(word1);
if (defn == -1) {
/* Gee, I don't understand. */
if (fallback_handler(rawbuf))
if (fallback_handler(input))
continue;
rspeak(DONT_KNOW, command.wd1, command.wd1x);
goto L2600;
@ -1116,14 +1139,14 @@ Lookup:
command.verb = kmod;
break;
case 3:
rspeak(kmod);
rspeak(specials[kmod].message);
goto L2012;
default:
BUG(VOCABULARY_TYPE_N_OVER_1000_NOT_BETWEEN_0_AND_3); // LCOV_EXCL_LINE
}
Laction:
switch (action(cmdin, &command)) {
switch (action(&command)) {
case GO_TERMINATE:
return true;
case GO_MOVE:
@ -1158,6 +1181,7 @@ Laction:
default:
BUG(ACTION_RETURNED_PHASE_CODE_BEYOND_END_OF_SWITCH); // LCOV_EXCL_LINE
}
linenoiseFree(input);
}
}