+# This YAML file gets processed into a collection of data structures and
+# variable initializers describing Colossal Cave. It replaces an ad-hoc
+# text database shipped with Adventure versions up to 2.5. The format
+# change enabled a lot of use of symbolic names where there were previously
+# inscrutable numeric literals.
+#
+# We define a bunch of YAML structures:
+#
+# vocabulary: Almost all the words the game knows - one of them gets
+# replaced with a randomly-generated cookie. For each word there
+# is a type (motion, action, object, or special) and a numeric value.
+# Multiple synonyms may have the same value.
+#
+# hints: Each item contains a hint number, a hint label (used to
+# generate the value macro for the hint) the number of turns he
+# must be at the right loc(s) before triggering the hint, the
+# points deducted for taking the hint, the message number (in
+# arbitrary_messages) of the question, and the message number of
+# the hint.
+#
+# locations: They have attributes as follows...
+# long: Long description, always shown on first encounter.
+# short: Short description. If none, use long description.
+# conditions: A dictionary of attributes
+# LIT Light
+# OILY If FLUID flag is on: true for oil, false for water
+# FLUID Liquid asset
+# NOARRR Pirate doesn't go here unless following player
+# NOBACK Cannot use "back" to move away
+# HCAVE Trying to get into cave
+# HBIRD Trying to catch bird
+# HSNAKE Trying to deal with snake
+# HMAZE Lost in maze
+# HDARK Pondering dark room
+# HWITT At Witt's End
+# HCLIFF Cliff with urn
+# HWOODS Lost in forest
+# HOGRE Trying to deal with ogre
+# HJADE Found all treasures except jade
+# hints: A list of YAML references to hints that may be available at
+# this location. (This is why locations has to follow hints.)
+# sound: Label for a location sound.
+# loud: If true, object sounds are drowned out at this location.
+# All attributes are optional except the long description. Order of
+# locations is not significant.
+#
+# arbitrary_messages: These are arguments to rspeak(). Some spans of
+# these messages need to be kept adjacent and ordered (for now).
+# To see which, grep for rspeak() calls containing expressions with
+# arithmetic. Eventually, these will be pulled out into more appropriate
+# data structures. Then ordering can be dropped, and gaps removed.
+#
+# classes: Each item contains a point threshold and a message
+# describing a classification of player. Point thresholds must be
+# in ascending order. The scoring code selects the appropriate
+# message, where each message is considered to apply to players
+# whose scores are higher than the previous N but not higher than
+# this N. Note that these scores probably change with every
+# modification (and particularly expansion) of the program.
+#
+# turn_thresholds: Each item contains a number and a message
+# berating the player for taking so many turns. When the turn count
+# matches one of the thresholds, the corresponding message is shown.
+# Order doesn't matter; the logic simply tests every threshold on
+# the assumption that turn counts never decrease nor skip values.
+#
+# objects: Each item contains a description for use in the inventory command
+# and one or more messages describing the object in different states.
+# There is also a boolean "treasure" attribute, defaulting to false.
+# An pbject may have one or two start locations (the gate is an example
+# of a two-location object; it can be accessed from above or below).
+# An object may also be flagged immovable, meaning it cannot be carried.
+# If a state message is a tuple then the first element is made the name
+# of a #define viible to the code for the associayed state, numbered
+# from zero upwards. If the inventory desription begins with "*" the
+# object is dungeon furniture that cannot be taken or carried.
+#
+# obituaries: Death messages and reincarnation queries. Order is
+# significant, they're used in succession as the player racks up
+# deaths.
+#
+# These correspond to sections 1, 2, 4, 5, 6, 7, 9, 10, 11, 13, and 14 in
+# the old adventure.text format. Sections 3 and 8 haven't moved
+# yet. Section 12 was obsolete.
+#
+# Message strings may include certain special character sequences to
+# denote that the program must provide parameters to insert into a
+# message when the message is printed. These sequences are:
+# %S = The letter 'S' or nothing (if a given value is exactly 1)
+# %W = A word (up to 10 characters)
+# %L = A word mapped to lower-case letters
+# %U = A word mapped to upper-case letters
+# %C = A word mapped to lower-case, first letter capitalised
+# %T = Several words of text, ending with a word of -1
+# %1 = A 1-digit number
+# %2 = A 2-digit number
+# ...
+# %9 = A 9-digit number
+# %B = Variable number of blanks
+# %! = The entire message should be suppressed
+
+vocabulary: {
+ "ROAD": {type: motion, value: 2},
+ "HILL": {type: motion, value: 2},
+ "ENTER": {type: motion, value: 3},
+ "UPSTR": {type: motion, value: 4},
+ "DOWNS": {type: motion, value: 5},
+ "FORES": {type: motion, value: 6},
+ "FORWA": {type: motion, value: 7},
+ "CONTI": {type: motion, value: 7},
+ "ONWAR": {type: motion, value: 7},
+ "BACK": {type: motion, value: 8},
+ "RETUR": {type: motion, value: 8},
+ "RETRE": {type: motion, value: 8},
+ "VALLE": {type: motion, value: 9},
+ "STAIR": {type: motion, value: 10},
+ "OUT": {type: motion, value: 11},
+ "OUTSI": {type: motion, value: 11},
+ "EXIT": {type: motion, value: 11},
+ "LEAVE": {type: motion, value: 11},
+ "BUILD": {type: motion, value: 12},
+ "HOUSE": {type: motion, value: 12},
+ "GULLY": {type: motion, value: 13},
+ "STREA": {type: motion, value: 14},
+ "FORK": {type: motion, value: 15},
+ "BED": {type: motion, value: 16},
+ "CRAWL": {type: motion, value: 17},
+ "COBBL": {type: motion, value: 18},
+ "INWAR": {type: motion, value: 19},
+ "INSID": {type: motion, value: 19},
+ "IN": {type: motion, value: 19},
+ "SURFA": {type: motion, value: 20},
+ "NULL": {type: motion, value: 21},
+ "NOWHE": {type: motion, value: 21},
+ "DARK": {type: motion, value: 22},
+ "PASSA": {type: motion, value: 23},
+ "TUNNE": {type: motion, value: 23},
+ "LOW": {type: motion, value: 24},
+ "CANYO": {type: motion, value: 25},
+ "AWKWA": {type: motion, value: 26},
+ "GIANT": {type: motion, value: 27},
+ "VIEW": {type: motion, value: 28},
+ "UPWAR": {type: motion, value: 29},
+ "UP": {type: motion, value: 29},
+ "U": {type: motion, value: 29},
+ "ABOVE": {type: motion, value: 29},
+ "ASCEN": {type: motion, value: 29},
+ "D": {type: motion, value: 30},
+ "DOWNW": {type: motion, value: 30},
+ "DOWN": {type: motion, value: 30},
+ "DESCE": {type: motion, value: 30},
+ "PIT": {type: motion, value: 31},
+ "OUTDO": {type: motion, value: 32},
+ "CRACK": {type: motion, value: 33},
+ "STEPS": {type: motion, value: 34},
+ "DOME": {type: motion, value: 35},
+ "LEFT": {type: motion, value: 36},
+ "RIGHT": {type: motion, value: 37},
+ "HALL": {type: motion, value: 38},
+ "JUMP": {type: motion, value: 39},
+ "BARRE": {type: motion, value: 40},
+ "OVER": {type: motion, value: 41},
+ "ACROS": {type: motion, value: 42},
+ "EAST": {type: motion, value: 43},
+ "E": {type: motion, value: 43},
+ "WEST": {type: motion, value: 44},
+ "W": {type: motion, value: 44},
+ "NORTH": {type: motion, value: 45},
+ "N": {type: motion, value: 45},
+ "SOUTH": {type: motion, value: 46},
+ "S": {type: motion, value: 46},
+ "NE": {type: motion, value: 47},
+ "SE": {type: motion, value: 48},
+ "SW": {type: motion, value: 49},
+ "NW": {type: motion, value: 50},
+ "DEBRI": {type: motion, value: 51},
+ "HOLE": {type: motion, value: 52},
+ "WALL": {type: motion, value: 53},
+ "BROKE": {type: motion, value: 54},
+ "Y2": {type: motion, value: 55},
+ "CLIMB": {type: motion, value: 56},
+ "LOOK": {type: motion, value: 57},
+ "EXAMI": {type: motion, value: 57},
+ "TOUCH": {type: motion, value: 57},
+ "DESCR": {type: motion, value: 57},
+ "FLOOR": {type: motion, value: 58},
+ "ROOM": {type: motion, value: 59},
+ "SLIT": {type: motion, value: 60},
+ "SLAB": {type: motion, value: 61},
+ "SLABR": {type: motion, value: 61},
+ "XYZZY": {type: motion, value: 62},
+ "DEPRE": {type: motion, value: 63},
+ "ENTRA": {type: motion, value: 64},
+ "PLUGH": {type: motion, value: 65},
+ "SECRE": {type: motion, value: 66},
+ "CAVE": {type: motion, value: 67},
+ "CROSS": {type: motion, value: 69},
+ "BEDQU": {type: motion, value: 70},
+ "PLOVE": {type: motion, value: 71},
+ "ORIEN": {type: motion, value: 72},
+ "CAVER": {type: motion, value: 73},
+ "SHELL": {type: motion, value: 74},
+ "RESER": {type: motion, value: 75},
+ "MAIN": {type: motion, value: 76},
+ "OFFIC": {type: motion, value: 76},
+ "KEYS": {type: object, value: 1},
+ "KEY": {type: object, value: 1},
+ "LAMP": {type: object, value: 2},
+ "LANTE": {type: object, value: 2},
+ "GRATE": {type: object, value: 3},
+ "CAGE": {type: object, value: 4},
+ "ROD": {type: object, value: 5},
+ "ROD": {type: object, value: 6}, # Must be next object after "real" rod
+ "STEPS": {type: object, value: 7},
+ "BIRD": {type: object, value: 8},
+ "DOOR": {type: object, value: 9},
+ "PILLO": {type: object, value: 10},
+ "VELVE": {type: object, value: 10},
+ "SNAKE": {type: object, value: 11},
+ "FISSU": {type: object, value: 12},
+ "TABLE": {type: object, value: 13},
+ "CLAM": {type: object, value: 14},
+ "OYSTE": {type: object, value: 15},
+ "MAGAZ": {type: object, value: 16},
+ "ISSUE": {type: object, value: 16},
+ "SPELU": {type: object, value: 16},
+ '"SPEL': {type: object, value: 16},
+ "DWARF": {type: object, value: 17},
+ "DWARV": {type: object, value: 17},
+ "KNIFE": {type: object, value: 18},
+ "KNIVE": {type: object, value: 18},
+ "FOOD": {type: object, value: 19},
+ "RATIO": {type: object, value: 19},
+ "BOTTL": {type: object, value: 20},
+ "JAR": {type: object, value: 20},
+ "WATER": {type: object, value: 21},
+ "H2O": {type: object, value: 21},
+ "OIL": {type: object, value: 22},
+ "MIRRO": {type: object, value: 23},
+ "PLANT": {type: object, value: 24},
+ "BEANS": {type: object, value: 24},
+ "PLANT": {type: object, value: 25}, # Must be next object after "real" plant
+ "STALA": {type: object, value: 26},
+ "SHADO": {type: object, value: 27},
+ "FIGUR": {type: object, value: 27},
+ "WINDO": {type: object, value: 27}, # Same as figure
+ "AXE": {type: object, value: 28},
+ "DRAWI": {type: object, value: 29},
+ "PIRAT": {type: object, value: 30},
+ "GENIE": {type: object, value: 30},
+ "DJINN": {type: object, value: 30},
+ "DRAGO": {type: object, value: 31},
+ "CHASM": {type: object, value: 32},
+ "TROLL": {type: object, value: 33},
+ "TROLL": {type: object, value: 34}, # Must be next object after "real" troll
+ "BEAR": {type: object, value: 35},
+ "MESSA": {type: object, value: 36},
+ "VOLCA": {type: object, value: 37},
+ "GEYSE": {type: object, value: 37}, # Same as volcano
+ "MACHI": {type: object, value: 38},
+ "VENDI": {type: object, value: 38},
+ "BATTE": {type: object, value: 39},
+ "CARPE": {type: object, value: 40},
+ "MOSS": {type: object, value: 40},
+ "CURTA": {type: object, value: 40}, # Same as carpet
+ "OGRE": {type: object, value: 41},
+ "URN": {type: object, value: 42},
+ "CAVIT": {type: object, value: 43},
+ "BLOOD": {type: object, value: 44},
+ "RESER": {type: object, value: 45}, # Verb overrides
+ "APPEN": {type: object, value: 46},
+ "LEPOR": {type: object, value: 46},
+ "MUD": {type: object, value: 47},
+ "NOTE": {type: object, value: 48},
+ "SIGN": {type: object, value: 49},
+ "GOLD": {type: object, value: 50},
+ "NUGGE": {type: object, value: 50},
+ "DIAMO": {type: object, value: 51},
+ "SILVE": {type: object, value: 52},
+ "BARS": {type: object, value: 52},
+ "JEWEL": {type: object, value: 53},
+ "COINS": {type: object, value: 54},
+ "CHEST": {type: object, value: 55},
+ "BOX": {type: object, value: 55},
+ "TREAS": {type: object, value: 55},
+ "EGGS": {type: object, value: 56},
+ "EGG": {type: object, value: 56},
+ "NEST": {type: object, value: 56},
+ "TRIDE": {type: object, value: 57},
+ "VASE": {type: object, value: 58},
+ "MING": {type: object, value: 58},
+ "SHARD": {type: object, value: 58},
+ "POTTE": {type: object, value: 58},
+ "EMERA": {type: object, value: 59},
+ "PLATI": {type: object, value: 60},
+ "PYRAM": {type: object, value: 60},
+ "PEARL": {type: object, value: 61},
+ "RUG": {type: object, value: 62},
+ "PERSI": {type: object, value: 62},
+ "SPICE": {type: object, value: 63},
+ "CHAIN": {type: object, value: 64},
+ "RUBY": {type: object, value: 65},
+ "JADE": {type: object, value: 66},
+ "NECKL": {type: object, value: 66},
+ "AMBER": {type: object, value: 67},
+ "GEMST": {type: object, value: 67},
+ "SAPPH": {type: object, value: 68},
+ "EBONY": {type: object, value: 69},
+ "STATU": {type: object, value: 69},
+ "CARRY": {type: action, value: 1},
+ "TAKE": {type: action, value: 1},
+ "KEEP": {type: action, value: 1},
+ "CATCH": {type: action, value: 1},
+ "STEAL": {type: action, value: 1},
+ "CAPTU": {type: action, value: 1},
+ "GET": {type: action, value: 1},
+ "TOTE": {type: action, value: 1},
+ "SNARF": {type: action, value: 1},
+ "DROP": {type: action, value: 2},
+ "RELEA": {type: action, value: 2},
+ "FREE": {type: action, value: 2},
+ "DISCA": {type: action, value: 2},
+ "DUMP": {type: action, value: 2},
+ "SAY": {type: action, value: 3},
+ "CHANT": {type: action, value: 3},
+ "SING": {type: action, value: 3},
+ "UTTER": {type: action, value: 3},
+ "MUMBL": {type: action, value: 3},
+ "UNLOC": {type: action, value: 4},
+ "OPEN": {type: action, value: 4},
+ "NOTHI": {type: action, value: 5},
+ "LOCK": {type: action, value: 6},
+ "CLOSE": {type: action, value: 6},
+ "LIGHT": {type: action, value: 7},
+ "ON": {type: action, value: 7},
+ "EXTIN": {type: action, value: 8},
+ "OFF": {type: action, value: 8},
+ "WAVE": {type: action, value: 9},
+ "SHAKE": {type: action, value: 9},
+ "SWING": {type: action, value: 9},
+ "CALM": {type: action, value: 10},
+ "PLACA": {type: action, value: 10},
+ "TAME": {type: action, value: 10},
+ "WALK": {type: action, value: 11},
+ "RUN": {type: action, value: 11},
+ "TRAVE": {type: action, value: 11},
+ "GO": {type: action, value: 11},
+ "PROCE": {type: action, value: 11},
+ "CONTI": {type: action, value: 11},
+ "EXPLO": {type: action, value: 11},
+ "FOLLO": {type: action, value: 11},
+ "TURN": {type: action, value: 11},
+ "ATTAC": {type: action, value: 12},
+ "KILL": {type: action, value: 12},
+ "FIGHT": {type: action, value: 12},
+ "HIT": {type: action, value: 12},
+ "STRIK": {type: action, value: 12},
+ "SLAY": {type: action, value: 12},
+ "POUR": {type: action, value: 13},
+ "EAT": {type: action, value: 14},
+ "DEVOU": {type: action, value: 14},
+ "DRINK": {type: action, value: 15},
+ "RUB": {type: action, value: 16},
+ "THROW": {type: action, value: 17},
+ "TOSS": {type: action, value: 17},
+ "QUIT": {type: action, value: 18},
+ "FIND": {type: action, value: 19},
+ "WHERE": {type: action, value: 19},
+ "INVEN": {type: action, value: 20},
+ "FEED": {type: action, value: 21},
+ "FILL": {type: action, value: 22},
+ "BLAST": {type: action, value: 23},
+ "DETON": {type: action, value: 23},
+ "IGNIT": {type: action, value: 23},
+ "BLOWU": {type: action, value: 23},
+ "SCORE": {type: action, value: 24},
+ "FEE": {type: action, value: 25},
+ "FIE": {type: action, value: 25},
+ "FOE": {type: action, value: 25},
+ "FOO": {type: action, value: 25},
+ "FUM": {type: action, value: 25},
+ "BRIEF": {type: action, value: 26},
+ "READ": {type: action, value: 27},
+ "PERUS": {type: action, value: 27},
+ "BREAK": {type: action, value: 28},
+ "SHATT": {type: action, value: 28},
+ "SMASH": {type: action, value: 28},
+ "WAKE": {type: action, value: 29},
+ "DISTU": {type: action, value: 29},
+ "SUSPE": {type: action, value: 30},
+ "PAUSE": {type: action, value: 30},
+ "SAVE": {type: action, value: 30},
+ "RESUM": {type: action, value: 31},
+ "RESTA": {type: action, value: 31},
+ "FLY": {type: action, value: 32},
+ "LISTE": {type: action, value: 33},
+ "Z'ZZZ": {type: action, value: 34}, # Gets replaced
+ "FEE": {type: special, value: 1},
+ "FIE": {type: special, value: 2},
+ "FOE": {type: special, value: 3},
+ "FOO": {type: special, value: 4},
+ "FUM": {type: special, value: 5},
+ "THANK": {type: special, value: 13},
+ "SESAM": {type: special, value: 50},
+ "OPENS": {type: special, value: 50},
+ "ABRA": {type: special, value: 50},
+ "ABRAC": {type: special, value: 50},
+ "SHAZA": {type: special, value: 50},
+ "HOCUS": {type: special, value: 50},
+ "POCUS": {type: special, value: 50},
+ "HELP": {type: special, value: 51},
+ "?": {type: special, value: 51},
+ "NO": {type: special, value: 54},
+ "TREE": {type: special, value: 64},
+ "TREES": {type: special, value: 64},
+ "DIG": {type: special, value: 66},
+ "EXCAV": {type: special, value: 66},
+ "LOST": {type: special, value: 68},
+ "MIST": {type: special, value: 69},
+ "FUCK": {type: special, value: 79},
+ "STOP": {type: special, value: 139},
+ "INFO": {type: special, value: 142},
+ "INFOR": {type: special, value: 142},
+ "SWIM": {type: special, value: 147},
+ "WIZAR": {type: special, value: 246},
+ "YES": {type: special, value: 271},
+ "NEWS": {type: special, value: 275},
+}
+
+# FIXME: Hint texts shouldn't be in arbitrary_messages, but inlined here
+hints:
+ - hint: &grate
+ name: CAVE
+ number: 1
+ turns: 4
+ penalty: 2
+ question: ENTRY_QUERY
+ hint: HARD_GRATE
+ - hint: &bird
+ name: BIRD
+ number: 2
+ turns: 5
+ penalty: 2
+ question: BIRD_QUERY
+ hint: SKITTISH_BIRD
+ - hint: &snake
+ name: SNAKE
+ number: 3
+ turns: 8
+ penalty: 2
+ question: SNAKE_QUERY
+ hint: SNAKE_HINT
+ - hint: &maze
+ name: MAZE
+ number: 4
+ turns: 75
+ penalty: 4
+ question: MAZE_HELP
+ hint: DROP_THINGS
+ - hint: &dark
+ name: DARK
+ number: 5
+ turns: 25
+ penalty: 5
+ question: PLOVER_QUERY
+ hint: EXPLORE_HINT
+ - hint: &witt
+ name: WITT
+ number: 6
+ turns: 20
+ penalty: 3
+ question: HELP_LEAVING
+ hint: NOGO_WEST
+ - hint: &urn
+ name: CLIFF
+ number: 7
+ turns: 8
+ penalty: 2
+ question: WONDERING_QUERY
+ hint: ADVANCED_SECTION
+ - hint: &forest
+ name: WOODS
+ number: 8
+ turns: 25
+ penalty: 2
+ question: FOREST_QUERY
+ hint: GO_EAST
+ - hint: &ogre
+ name: OGRE
+ number: 9
+ turns: 10
+ penalty: 4
+ question: OGRE_QUERY
+ hint: OGRE_CLUE
+ - hint: &jade
+ name: JADE
+ number: 10
+ turns: 1
+ penalty: 4
+ question: MISSING_ONE
+ hint: NO_LOCATE
+