Rationalize names of structure array sizes.
[open-adventure.git] / newdungeon.py
index d16dc5608511c5b08df43f988e18d162c8a4573c..7f70741d331f62aebe962f47a8e09434db3dbf6b 100755 (executable)
@@ -8,11 +8,22 @@ yaml_name = "adventure.yaml"
 h_name = "newdb.h"
 c_name = "newdb.c"
 
-h_template = """#include <stdio.h>
+statedefines = ""
+
+h_template = """/* Generated from adventure.yaml - do not hand-hack! */
+#ifndef NEWDB_H
+#define NEWDB_H
+
+#include <stdio.h>
+#include <stdbool.h>
+
+#define SILENT -1      /* no sound */
 
 typedef struct {{
   const char* inventory;
   const char** longs;
+  const char** sounds;
+  const char** texts;
 }} object_description_t;
 
 typedef struct {{
@@ -22,6 +33,8 @@ typedef struct {{
 
 typedef struct {{
   descriptions_t description;
+  const long sound;
+  const bool loud;
 }} location_t;
 
 typedef struct {{
@@ -35,25 +48,37 @@ typedef struct {{
   const char* message;
 }} turn_threshold_t;
 
+typedef struct {{
+  const int threshold;
+  const char* message;
+}} class_t;
+
+typedef struct {{
+  const int number;
+  const int turns;
+  const int penalty;
+  const char* question;
+  const char* hint;
+}} hint_t;
+
 extern location_t locations[];
 extern object_description_t object_descriptions[];
 extern const char* arbitrary_messages[];
-extern const char* class_messages[];
+extern const class_t classes[];
 extern turn_threshold_t turn_thresholds[];
 extern obituary_t obituaries[];
+extern hint_t hints[];
+extern long conditions[];
 
-extern size_t CLSSES;
-extern int maximum_deaths;
-extern int turn_threshold_count;
+#define NHINTS         {}
+#define NCLASSES       {}
+#define NDEATHS                {}
+#define NTHRESHOLDS    {}
 
 enum arbitrary_messages_refs {{
 {}
 }};
 
-enum class_messages_refs {{
-{}
-}};
-
 enum locations_refs {{
 {}
 }};
@@ -61,15 +86,23 @@ enum locations_refs {{
 enum object_descriptions_refs {{
 {}
 }};
+
+/* State definitions */
+
+{}
+#endif /* end NEWDB_H */
 """
 
-c_template = """#include "{}"
+c_template = """/* Generated from adventure.yaml - do not hand-hack! */
+
+#include "common.h"
+#include "{}"
 
 const char* arbitrary_messages[] = {{
 {}
 }};
 
-const char* class_messages[] = {{
+const class_t classes[] = {{
 {}
 }};
 
@@ -89,9 +122,15 @@ obituary_t obituaries[] = {{
 {}
 }};
 
-size_t CLSSES = {};
-int maximum_deaths = {};
-int turn_threshold_count = {};
+hint_t hints[] = {{
+{}
+}};
+
+long conditions[] = {{
+{}
+}};
+
+/* end */
 """
 
 def make_c_string(string):
@@ -123,20 +162,25 @@ def get_arbitrary_messages(arb):
     return arb_str
 
 def get_class_messages(cls):
-    template = """    {},
+    template = """    {{
+        .threshold = {},
+        .message = {},
+    }},
 """
     cls_str = ""
     for item in cls:
-        cls_str += template.format(make_c_string(item[1]))
+        threshold = item["threshold"]
+        message = make_c_string(item["message"])
+        cls_str += template.format(threshold, message)
     cls_str = cls_str[:-1] # trim trailing newline
-    return cls_str    
+    return cls_str
 
 def get_turn_thresholds(trn):
     template = """    {{
         .threshold = {},
         .point_loss = {},
         .message = {},
-}},
+    }},
 """
     trn_str = ""
     for item in trn:
@@ -153,13 +197,17 @@ def get_locations(loc):
             .small = {},
             .big = {},
         }},
+        .sound = {},
+        .loud = {},
     }},
 """
     loc_str = ""
     for item in loc:
         short_d = make_c_string(item[1]["description"]["short"])
         long_d = make_c_string(item[1]["description"]["long"])
-        loc_str += template.format(short_d, long_d)
+        sound = item[1].get("sound", "SILENT")
+        loud = "true" if item[1].get("loud") else "false"
+        loc_str += template.format(short_d, long_d, sound, loud)
     loc_str = loc_str[:-1] # trim trailing newline
     return loc_str
 
@@ -167,6 +215,12 @@ def get_object_descriptions(obj):
     template = """    {{
         .inventory = {},
         .longs = (const char* []) {{
+{}
+        }},
+        .sounds = (const char* []) {{
+{}
+        }},
+        .texts = (const char* []) {{
 {}
         }},
     }},
@@ -178,10 +232,36 @@ def get_object_descriptions(obj):
         if item[1]["longs"] == None:
             longs_str = " " * 12 + "NULL,"
         else:
+            labels = []
             for l_msg in item[1]["longs"]:
+                if not isinstance(l_msg, str):
+                    labels.append(l_msg)
+                    l_msg = l_msg[1]
                 longs_str += " " * 12 + make_c_string(l_msg) + ",\n"
             longs_str = longs_str[:-1] # trim trailing newline
-        obj_str += template.format(i_msg, longs_str)
+            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)
+                statedefines += "\n"
+        sounds_str = ""
+        if item[1].get("sounds") == None:
+            sounds_str = " " * 12 + "NULL,"
+        else:
+             for l_msg in item[1]["sounds"]:
+                 sounds_str += " " * 12 + make_c_string(l_msg) + ",\n"
+             sounds_str = sounds_str[:-1] # trim trailing newline
+        texts_str = ""
+        if item[1].get("texts") == None:
+            texts_str = " " * 12 + "NULL,"
+        else:
+             for l_msg in item[1]["texts"]:
+                 texts_str += " " * 12 + make_c_string(l_msg) + ",\n"
+             texts_str = texts_str[:-1] # trim trailing newline
+        obj_str += template.format(i_msg, longs_str, sounds_str, texts_str)
     obj_str = obj_str[:-1] # trim trailing newline
     return obj_str
 
@@ -199,31 +279,79 @@ def get_obituaries(obit):
     obit_str = obit_str[:-1] # trim trailing newline
     return obit_str
 
-with open(yaml_name, "r") as f:
-    db = yaml.load(f)
-
-h = h_template.format(
-    get_refs(db["arbitrary_messages"]),
-    get_refs(db["class_messages"]),
-    get_refs(db["locations"]),
-    get_refs(db["object_descriptions"]),
-)
-
-c = c_template.format(
-    h_name,
-    get_arbitrary_messages(db["arbitrary_messages"]),
-    get_class_messages(db["class_messages"]),
-    get_turn_thresholds(db["turn_thresholds"]),
-    get_locations(db["locations"]),
-    get_object_descriptions(db["object_descriptions"]),
-    get_obituaries(db["obituaries"]),
-    len(db["class_messages"]),
-    len(db["obituaries"]),
-    len(db["turn_thresholds"]),
-)
-
-with open(h_name, "w") as hf:
-    hf.write(h)
-
-with open(c_name, "w") as cf:
-    cf.write(c)
+def get_hints(hnt, arb):
+    template = """    {{
+        .number = {},
+        .penalty = {},
+        .turns = {},
+        .question = {},
+        .hint = {},
+    }},
+"""
+    hnt_str = ""
+    md = dict(arb)
+    for member in hnt:
+        item = member["hint"]
+        number = item["number"]
+        penalty = item["penalty"]
+        turns = item["turns"]
+        question = make_c_string(md[item["question"]])
+        hint = make_c_string(md[item["hint"]])
+        hnt_str += template.format(number, penalty, turns, question, hint)
+    hnt_str = hnt_str[:-1] # trim trailing newline
+    return hnt_str
+
+def get_condbits(locations):
+    cnd_str = ""
+    for (name, loc) in locations:
+        conditions = loc["conditions"]
+        hints = loc.get("hints") or []
+        flaglist = []
+        for flag in conditions:
+            if conditions[flag]:
+                flaglist.append(flag)
+        line = "|".join([("(1<<COND_%s)" % f) for f in flaglist])
+        trail = "|".join([("(1<<COND_H%s)" % f['name']) for f in hints])
+        if trail:
+            line += "|" + trail
+        if line.startswith("|"):
+            line = line[1:]
+        if not line:
+            line = "0"
+        cnd_str += "    " + line + ",\t// " + name + "\n"
+    return cnd_str
+
+if __name__ == "__main__":
+    with open(yaml_name, "r") as f:
+        db = yaml.load(f)
+
+    c = c_template.format(
+        h_name,
+        get_arbitrary_messages(db["arbitrary_messages"]),
+        get_class_messages(db["classes"]),
+        get_turn_thresholds(db["turn_thresholds"]),
+        get_locations(db["locations"]),
+        get_object_descriptions(db["object_descriptions"]),
+        get_obituaries(db["obituaries"]),
+        get_hints(db["hints"], db["arbitrary_messages"]),
+        get_condbits(db["locations"]),
+    )
+
+    h = h_template.format(
+        len(db["hints"]),
+        len(db["classes"]),
+        len(db["obituaries"]),
+        len(db["turn_thresholds"]),
+        get_refs(db["arbitrary_messages"]),
+        get_refs(db["locations"]),
+        get_refs(db["object_descriptions"]),
+        statedefines,
+    )
+
+    with open(h_name, "w") as hf:
+        hf.write(h)
+
+    with open(c_name, "w") as cf:
+        cf.write(c)
+
+# end