X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=make_dungeon.py;h=7a16970df83ea3b369c920f880d1661172fa03ef;hb=551838cea217e3d9df11dcaea52c42b02449de91;hp=6f4715238a5465c7fe51e2cb32563f3063625a67;hpb=db281a96d70a43c6a6d5b516eceb6e4f67637c57;p=open-adventure.git diff --git a/make_dungeon.py b/make_dungeon.py index 6f47152..7a16970 100755 --- a/make_dungeon.py +++ b/make_dungeon.py @@ -141,12 +141,19 @@ typedef struct {{ typedef struct {{ const string_group_t words; - const long message; + const char* message; }} action_t; +typedef struct {{ + const string_group_t words; + const char* message; +}} special_t; + typedef struct {{ const long motion; + const long cond; const long dest; + const bool nodwarves; const bool stop; }} travelop_t; @@ -155,10 +162,6 @@ typedef struct {{ * inherited from FORTRAN, someday. To understand these, read the * encoding description for travel. */ -#define T_DESTINATION(entry) MOD((entry).dest, 1000) -#define T_CONDITION(entry) ((entry).dest / 1000) -#define T_NODWARVES(entry) (T_CONDITION(entry) == 100) -#define T_HIGH(entry) ((entry).dest) #define T_TERMINATE(entry) ((entry).motion == 1) #define L_SPEAK(loc) ((loc) - 500) @@ -172,9 +175,10 @@ extern const hint_t hints[]; extern long conditions[]; extern const motion_t motions[]; extern const action_t actions[]; -extern const action_t specials[]; +extern const special_t specials[]; extern const travelop_t travel[]; extern const long tkey[]; +extern const char *ignore; #define NLOCATIONS {} #define NOBJECTS {} @@ -188,6 +192,8 @@ extern const long tkey[]; #define NTRAVEL {} #define NKEYS {} +#define BIRD_ENDSTATE {} + enum arbitrary_messages_refs {{ {} }}; @@ -262,16 +268,18 @@ const action_t actions[] = {{ {} }}; -const action_t specials[] = {{ +const special_t specials[] = {{ {} }}; -{} +const long tkey[] = {{{}}}; const travelop_t travel[] = {{ {} }}; +const char *ignore = \"{}\"; + /* end */ """ @@ -347,7 +355,7 @@ def get_turn_thresholds(trn): return trn_str def get_locations(loc): - template = """ {{ // {} + template = """ {{ // {}: {} .description = {{ .small = {}, .big = {}, @@ -362,12 +370,12 @@ def get_locations(loc): long_d = make_c_string(item[1]["description"]["long"]) sound = item[1].get("sound", "SILENT") loud = "true" if item[1].get("loud") else "false" - loc_str += template.format(i, short_d, long_d, sound, loud) + loc_str += template.format(i, item[0], short_d, long_d, sound, loud) loc_str = loc_str[:-1] # trim trailing newline return loc_str def get_objects(obj): - template = """ {{ // {} + template = """ {{ // {}: {} .words = {}, .inventory = {}, .plac = {}, @@ -401,18 +409,15 @@ def get_objects(obj): else: labels = [] for l_msg in attr["descriptions"]: - if not isinstance(l_msg, str): - labels.append(l_msg) - l_msg = l_msg[1] descriptions_str += " " * 12 + make_c_string(l_msg) + ",\n" + for label in attr.get("states", []): + labels.append(label) descriptions_str = descriptions_str[:-1] # trim trailing newline if labels: global statedefines statedefines += "/* States for %s */\n" % item[0] - for (i, (label, message)) in enumerate(labels): - if len(message) >= 45: - message = message[:45] + "..." - statedefines += "#define %s\t%d /* %s */\n" % (label, i, message) + for (i, label) in enumerate(labels): + statedefines += "#define %s\t%d\n" % (label, i) statedefines += "\n" sounds_str = "" if attr.get("sounds") == None: @@ -439,14 +444,12 @@ def get_objects(obj): immovable = attr.get("immovable", False) try: if type(locs) == str: - locs = [locnames.index(locs), -1 if immovable else 0] - else: - locs = [locnames.index(x) for x in locs] + locs = [locs, -1 if immovable else 0] except IndexError: sys.stderr.write("dungeon: unknown object location in %s\n" % locs) sys.exit(1) treasure = "true" if attr.get("treasure") else "false" - obj_str += template.format(i, words_str, i_msg, locs[0], locs[1], treasure, descriptions_str, sounds_str, texts_str, changes_str) + obj_str += template.format(i, item[0], words_str, i_msg, locs[0], locs[1], treasure, descriptions_str, sounds_str, texts_str, changes_str) obj_str = obj_str[:-1] # trim trailing newline return obj_str @@ -506,18 +509,6 @@ def get_condbits(locations): cnd_str += " " + line + ",\t// " + name + "\n" return cnd_str -def recompose(type_word, value): - "Compose the internal code for a vocabulary word from its YAML entry" - parts = ("motion", "action", "object", "special") - try: - return value + 1000 * parts.index(type_word) - except KeyError: - sys.stderr.write("dungeon: %s is not a known word\n" % word) - sys.exit(1) - except IndexError: - sys.stderr.write("%s is not a known word classifier\n" % attrs["type"]) - sys.exit(1) - def get_motions(motions): template = """ {{ .words = {}, @@ -531,6 +522,11 @@ def get_motions(motions): else: words_str = get_string_group(contents["words"]) mot_str += template.format(words_str) + global ignore + if contents.get("oldstyle", True) == False: + for word in contents["words"]: + if len(word) == 1: + ignore += word.upper() return mot_str def get_actions(actions): @@ -554,9 +550,43 @@ def get_actions(actions): message = contents["message"] act_str += template.format(words_str, message) + global ignore + if contents.get("oldstyle", True) == False: + for word in contents["words"]: + if len(word) == 1: + ignore += word.upper() act_str = act_str[:-1] # trim trailing newline return act_str +def get_specials(specials): + template = """ {{ + .words = {}, + .message = {}, + }}, +""" + spc_str = "" + for special in specials: + contents = special[1] + + if contents["words"] == None: + words_str = get_string_group([]) + else: + words_str = get_string_group(contents["words"]) + + if contents["message"] == None: + message = "NULL" + else: + message = make_c_string(contents["message"]) + + spc_str += template.format(words_str, message) + global ignore + if contents.get("oldstyle", True) == False: + for word in contents["words"]: + if len(word) == 1: + ignore += word.upper() + spc_str = spc_str[:-1] # trim trailing newline + return spc_str + def bigdump(arr): out = "" for (i, entry) in enumerate(arr): @@ -564,16 +594,19 @@ def bigdump(arr): if out and out[-1] == ' ': out = out[:-1] out += "\n " - out += str(arr[i]) + ", " + out += str(arr[i]).lower() + ", " out = out[:-2] + "\n" return out -def buildtravel(locs, objs, voc): +def buildtravel(locs, objs): ltravel = [] verbmap = {} - for entry in db["vocabulary"]: - if entry["type"] == "motion" and entry["value"] not in verbmap: - verbmap[entry["word"]] = entry["value"] + for i, motion in enumerate(db["motions"]): + try: + for word in motion[1]["words"]: + verbmap[word.upper()] = i + except TypeError: + pass def dencode(action, name): "Decode a destination number" if action[0] == "goto": @@ -593,7 +626,9 @@ def buildtravel(locs, objs, voc): raise ValueError def cencode(cond, name): if cond is None: - return 0; + return 0 + elif cond == ["nodwarves"]: + return 100 elif cond[0] == "pct": return cond[1] elif cond[0] == "carry": @@ -609,11 +644,12 @@ def buildtravel(locs, objs, voc): sys.stderr.write("dungeon: unknown object name %s in with clause of \n" % (cond[1], name)) sys.exit(1) elif cond[0] == "not": - # FIXME: Allow named as well as numbered states try: obj = objnames.index(cond[1]) if type(cond[2]) == int: state = cond[2] + elif cond[2] in objs[obj][1].get("states", []): + state = objs[obj][1].get("states").index(cond[2]) else: for (i, stateclause) in enumerate(objs[obj][1]["descriptions"]): if type(stateclause) == list: @@ -637,7 +673,7 @@ def buildtravel(locs, objs, voc): tt = [i] dest = dencode(rule["action"], name) + 1000 * cencode(rule.get("cond"), name) tt.append(dest) - tt += [verbmap[e] for e in rule["verbs"]] + tt += [motionnames[verbmap[e]].upper() for e in rule["verbs"]] if not rule["verbs"]: tt.append(1) ltravel.append(tuple(tt)) @@ -666,7 +702,7 @@ def buildtravel(locs, objs, voc): # # In order to de-crypticize the runtime code, we're going to break these # magic numbers up into a struct. - travel = [[0, 0, False]] + travel = [[0, "LOC_NOWHERE", 0, 0, 0, "false", "false"]] tkey = [0] oldloc = 0 while ltravel: @@ -677,22 +713,32 @@ def buildtravel(locs, objs, voc): tkey.append(len(travel)) oldloc = loc elif travel: - travel[-1][2] = not travel[-1][2] + travel[-1][-1] = "false" if travel[-1][-1] == "true" else "true" while rule: - travel.append([rule.pop(0), newloc, False]) - travel[-1][2] = True + cond = newloc // 1000 + dest = newloc % 1000 + travel.append([len(tkey)-1, + locnames[len(tkey)-1], + rule.pop(0), + cond, + locnames[dest] if dest <= 300 else dest, + "true" if cond==100 else "false", + "false"]) + travel[-1][-1] = "true" return (travel, tkey) def get_travel(travel): - template = """ {{ + template = """ {{ // from {}: {} .motion = {}, + .cond = {}, .dest = {}, + .nodwarves = {}, .stop = {}, }}, """ out = "" for entry in travel: - out += template.format(entry[0], entry[1], entry[2]).lower() + out += template.format(*entry) out = out[:-1] # trim trailing newline return out @@ -703,11 +749,11 @@ if __name__ == "__main__": locnames = [x[0] for x in db["locations"]] msgnames = [el[0] for el in db["arbitrary_messages"]] objnames = [el[0] for el in db["objects"]] + motionnames = [el[0] for el in db["motions"]] (travel, tkey) = buildtravel(db["locations"], - db["objects"], - db["vocabulary"]) - + db["objects"]) + ignore = "" c = c_template.format( h_name, get_arbitrary_messages(db["arbitrary_messages"]), @@ -719,12 +765,17 @@ if __name__ == "__main__": get_hints(db["hints"], db["arbitrary_messages"]), get_condbits(db["locations"]), get_motions(db["motions"]), - get_actions(db["actions"]), - get_actions(db["specials"]), - "const long tkey[] = {%s};" % bigdump(tkey), + get_specials(db["actions"]), + get_specials(db["specials"]), + bigdump(tkey), get_travel(travel), + ignore, ) + # 0-origin index of birds's last song. Bird should + # die after player hears this. + deathbird = len(dict(db["objects"])["BIRD"]["sounds"]) - 1 + h = h_template.format( len(db["locations"])-1, len(db["objects"])-1, @@ -737,6 +788,7 @@ if __name__ == "__main__": len(db["specials"]), len(travel), len(tkey), + deathbird, get_refs(db["arbitrary_messages"]), get_refs(db["locations"]), get_refs(db["objects"]),