X-Git-Url: https://jxself.org/git/?p=open-adventure.git;a=blobdiff_plain;f=make_dungeon.py;h=f8b3147e46c4fc65ad64ad40cc3e2c620bf342cb;hp=7e18d76c41da7851a2c0b9deaa5989dc5a18ad88;hb=100152c21df9a5508936e31a3971aea71a280165;hpb=3f580acc0565587e4fab1f2181f4ff859e9c3aef diff --git a/make_dungeon.py b/make_dungeon.py index 7e18d76..f8b3147 100755 --- a/make_dungeon.py +++ b/make_dungeon.py @@ -6,43 +6,7 @@ # # The nontrivial part of this is the compilation of the YAML for # movement rules to the travel array that's actually used by -# playermove(). This program first compiles the YAML to a form -# identical to the data in section 3 of the old adventure.text file, -# then a second stage unpacks that data into the travel array. -# -# Here are the rules of the intermediate form: -# -# Each row of data contains a location number (X), a second -# location number (Y), and a list of motion numbers (see section 4). -# each motion represents a verb which will go to Y if currently at X. -# Y, in turn, is interpreted as follows. Let M=Y/1000, N=Y mod 1000. -# If N<=300 it is the location to go to. -# If 300500 message N-500 from section 6 is printed, -# and he stays wherever he is. -# Meanwhile, M specifies the conditions on the motion. -# If M=0 it's unconditional. -# If 0= 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 +413,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 @@ -519,6 +491,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): @@ -542,9 +519,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): @@ -552,11 +563,56 @@ 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): + assert len(locs) <= 300 + assert len(objs) <= 100 + # THIS CODE IS WAAAY MORE COMPLEX THAN IT NEEDS TO BE. It's the + # result of a massive refactoring exercise that concentrated all + # the old nastiness in one spot. It hasn't been finally simplified + # because there's no need to do it until one of the asserions + # fails. Hint: if you try cleaning this up, the acceptance test is + # simple - the output dungeon.c must not change. + # + # This function first compiles the YAML to a form identical to the + # data in section 3 of the old adventure.text file, then a second + # stage unpacks that data into the travel array. Here are the + # rules of that intermediate form: + # + # Each row of data contains a location number (X), a second + # location number (Y), and a list of motion numbers (see section 4). + # each motion represents a verb which will go to Y if currently at X. + # Y, in turn, is interpreted as follows. Let M=Y/1000, N=Y mod 1000. + # If N<=300 it is the location to go to. + # If 300500 message N-500 from section 6 is printed, + # and he stays wherever he is. + # Meanwhile, M specifies the conditions on the motion. + # If M=0 it's unconditional. + # If 0 500: + desttype = "dest_speak"; + destval = msgnames[dest - 500] + else: + desttype = "dest_special"; + destval = locnames[dest - 300] + travel.append([len(tkey)-1, + locnames[len(tkey)-1], + rule.pop(0), + condtype, + condarg1, + condarg2, + desttype, + destval, + "true" if nodwarves else "false", + "false"]) + travel[-1][-1] = "true" return (travel, tkey) def get_travel(travel): - template = """ {{ + template = """ {{ // from {}: {} .motion = {}, - .dest = {}, + .condtype = {}, + .condarg1 = {}, + .condarg2 = {}, + .desttype = {}, + .destval = {}, + .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 @@ -694,10 +782,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"]) - + ignore = "" c = c_template.format( h_name, get_arbitrary_messages(db["arbitrary_messages"]), @@ -709,12 +798,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, @@ -727,6 +821,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"]),