Add some sanity checking to newdungeon.py.
[open-adventure.git] / adventure.yaml
index 60177932c5514b59a0795ff6ec2730d922c344d7..a1c10fd173c4dae9114e539211d0e65138642419 100644 (file)
@@ -6,19 +6,22 @@
 #
 # We define a bunch of YAML structures:
 #
-# hints: Each item contains a hint number (add 10 to get cond bit),
-#    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 (section 6) of the question, and the message
-#    number of the hint.  These values are stashed in the "hints"
-#    array.
+# 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.
 #
-# locations: They have attributes as follows...
+# 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.
 #
-#    long:         Long description, always shown on first encounter.
-#    short:        Short description. If none, use long description.
-#    conditions:   A dictionary of attributes
+# 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
 #        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.
-#
+#      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.
 #
 #
 # 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, deaykting to false.
+#    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
 #    significant, they're used in succession as the player racks up
 #    deaths.
 #
-# These correspond to sections 1, 2, 5, 6, 9, 10, 11, 13, and 14 in the old
-# adventure.text format.  Sections 3, 4, 7, and 8 haven't moved yet.
-# Section 12 was obsolete.
+# 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:
@@ -1484,37 +1833,47 @@ object_descriptions: !!omap
     longs: !!null
 - OBJ_1:
     inventory: 'Set of keys'
+    locations: LOC_BUILDING
     longs:
     - 'There are some keys on the ground here.'
 - OBJ_2:
     inventory: 'Brass lantern'
+    locations: LOC_BUILDING
     longs:
     - [LAMP_DARK, 'There is a shiny brass lamp nearby.']
     - [LAMP_BRIGHT, 'There is a lamp shining nearby.']
 - OBJ_3:
     inventory: '*grate'
+    locations: [LOC_GRATE, LOC_BELOWGRATE]
+    immovable: true
     longs:
     - [GRATE_CLOSED, 'The grate is locked.']
     - [GRATE_OPEN, 'The grate is open.']
 - OBJ_4:
     inventory: 'Wicker cage'
+    locations: LOC_COBBLE
     longs:
     - 'There is a small wicker cage discarded nearby.'
 - OBJ_5:
     inventory: 'Black rod'
+    locations: LOC_DEBRIS
     longs:
     - 'A three foot black rod with a rusty star on an end lies nearby.'
 - OBJ_6:
     inventory: 'Black rod'
+    locations: LOC_NOWHERE
     longs:
     - 'A three foot black rod with a rusty mark on an end lies nearby.'
 - OBJ_7:
     inventory: '*steps'
+    locations: [LOC_PITTOP, LOC_MISTHALL]
+    immovable: true
     longs:
     - 'Rough stone steps lead down the pit.'
     - 'Rough stone steps lead up the dome.'
 - OBJ_8:
     inventory: 'Little bird in cage'
+    locations: LOC_BIRD
     longs:
     - [BIRD_UNCAGED, 'A cheerful little bird is sitting here singing.']
     - [BIRD_CAGED, 'There is a little bird in the cage.']
@@ -1528,15 +1887,20 @@ object_descriptions: !!omap
     - 'The bird is singing to you in gratitude for your having returned it to\nits home.  In return, it informs you of a magic word which it thinks\nyou may find useful somewhere near the Hall of Mists.  The magic word\nchanges frequently, but for now the bird believes it is "%s".  You\nthank the bird for this information, and it flies off into the forest.'
 - OBJ_9:
     inventory: '*rusty door'
+    locations: LOC_IMMENSE
+    immovable: true
     longs:
     - 'The way north is barred by a massive, rusty, iron door.'
     - 'The way north leads through a massive, rusty, iron door.'
 - OBJ_10:
     inventory: 'Velvet pillow'
+    locations: LOC_SOFTROOM
     longs:
     - 'A small velvet pillow lies on the floor.'
 - OBJ_11:
     inventory: '*snake'
+    locations: LOC_KINGHALL
+    immovable: true
     longs:
     - 'A huge green fierce snake bars the way!'
     - '' # chased away
@@ -1544,24 +1908,30 @@ object_descriptions: !!omap
     - 'The snake is hissing venomously.'
 - OBJ_12:
     inventory: '*fissure'
+    locations: [LOC_EASTBANK, LOC_WESTBANK]
+    immovable: true
     longs:
     - ''
     - 'A crystal bridge now spans the fissure.'
     - 'The crystal bridge has vanished!'
 - OBJ_13:
     inventory: '*stone tablet'
+    locations: LOC_DARKROOM
+    immovable: true
     longs:
     - 'A massive stone tablet imbedded in the wall reads:\n"Congratulations on bringing light into the dark-room!"'
     texts:
     - '"Congratulations on bringing light into the dark-room!"'
 - OBJ_14:
     inventory: 'Giant clam  >GRUNT!<'
+    locations: LOC_SHELLROOM
     longs:
     - 'There is an enormous clam here with its shell tightly closed.'
     sounds:
     - 'The clam is as tight-mouthed as a, er, clam.'
 - OBJ_15:
     inventory: 'Giant oyster  >GROAN!<'
+    locations: LOC_NOWHERE
     longs:
     - 'There is an enormous oyster here with its shell tightly closed.'
     - 'Interesting.  There seems to be something written on the underside of\nthe oyster.'
@@ -1570,37 +1940,49 @@ object_descriptions: !!omap
     - 'It says the same thing it did before.  Hm, maybe it''s a pun?'
 - OBJ_16:
     inventory: '"Spelunker Today"'
+    locations: LOC_ANTEROOM
     longs:
     - 'There are a few recent issues of "Spelunker Today" magazine here.'
     texts:
     - 'I''m afraid the magazine is written in dwarvish.  But pencilled on one\ncover you see, "Please leave the magazines at the construction site."'
 - OBJ_17:
     inventory: !!null
+    locations: LOC_NOWHERE
+    immovable: true
     longs: !!null
 - OBJ_18:
     inventory: !!null
+    locations: LOC_NOWHERE
     longs: !!null
 - OBJ_19:
     inventory: 'Tasty food'
+    locations: LOC_BUILDING
     longs:
     - 'There is food here.'
 - OBJ_20:
     inventory: 'Small bottle'
+    locations: LOC_BUILDING
     longs:
     - [WATER_BOTTLE, 'There is a bottle of water here.']
     - [EMPTY_BOTTLE, 'There is an empty bottle here.']
     - [OIL_BOTTLE, 'There is a bottle of oil here.']
 - OBJ_21:
     inventory: 'Water in the bottle'
+    locations: LOC_NOWHERE
     longs: !!null
 - OBJ_22:
     inventory: 'Oil in the bottle'
+    locations: LOC_NOWHERE
     longs: !!null
 - OBJ_23:
     inventory: '*mirror'
+    locations: LOC_MIRRORCANYON
+    immovable: true
     longs: !!null
 - OBJ_24:
     inventory: '*plant'
+    locations: LOC_WESTPIT
+    immovable: true
     longs:
     - 'There is a tiny little plant in the pit, murmuring "water, water, ..."'
     - 'There is a 12-foot-tall beanstalk stretching up out of the pit,\nbellowing "WATER!! WATER!!"'
@@ -1614,31 +1996,44 @@ object_descriptions: !!omap
     - 'The plant now maintains a contented silence.'
 - OBJ_25:
     inventory: '*phony plant' # seen in Twopit Room only when tall enough
+    locations: [LOC_WESTEND, LOC_EASTEND]
+    immovable: true
     longs:
     - ''
     - 'The top of a 12-foot-tall beanstalk is poking out of the west pit.'
     - 'There is a huge beanstalk growing out of the west pit up to the hole.'
 - OBJ_26:
     inventory: '*stalactite'
+    locations: LOC_TOPSTALACTITE
+    immovable: true
     longs:
     - ''
 - OBJ_27:
     inventory: '*shadowy figure and/or window'
+    locations: [LOC_WINDOW1, LOC_WINDOW2]
+    immovable: true
     longs:
     - 'The shadowy figure seems to be trying to attract your attention.'
 - OBJ_28:
     inventory: 'Dwarf''s axe'
+    locations: LOC_NOWHERE
     longs:
     - 'There is a little axe here.'
     - 'There is a little axe lying beside the bear.'
 - OBJ_29:
     inventory: '*cave drawings'
+    locations: LOC_ORIENTAL
+    immovable: true
     longs: !!null
 - OBJ_30:
     inventory: '*pirate/genie'
+    locations: LOC_NOWHERE
+    immovable: true
     longs: !!null # never present
 - OBJ_31:
     inventory: '*dragon'
+    locations: [LOC_SECRET4, LOC_SECRET6]
+    immovable: true
     longs:
     - 'A huge green fierce dragon bars the way!'
     - 'The blood-specked body of a huge green dead dragon lies to one side.'
@@ -1650,11 +2045,15 @@ object_descriptions: !!omap
     - 'The dragon is, not surprisingly, silent.'
 - OBJ_32:
     inventory: '*chasm'
+    locations: [LOC_SWCHASM, LOC_NECHASM]
+    immovable: true
     longs:
     - 'A rickety wooden bridge extends across the chasm, vanishing into the\nmist.  A notice posted on the bridge reads, "Stop! Pay troll!"'
     - 'The wreckage of a bridge (and a dead bear) can be seen at the bottom\nof the chasm.'
 - OBJ_33:
     inventory: '*troll'
+    locations: [LOC_SWCHASM, LOC_NECHASM]
+    immovable: true
     longs:
     - 'A burly troll stands by the bridge and insists you throw him a\ntreasure before you may cross.'
     - 'The troll steps out from beneath the bridge and blocks your way.'
@@ -1663,10 +2062,14 @@ object_descriptions: !!omap
     - 'The troll sounds quite adamant in his demand for a treasure.'
 - OBJ_34:
     inventory: '*phony troll'
+    locations: [LOC_NOWHERE, LOC_NOWHERE]
+    immovable: true
     longs:
     - 'The troll is nowhere to be seen.'
 - OBJ_35:
     inventory: !!null # bear uses rtext 141
+    locations: LOC_BARRENROOM
+    immovable: true
     longs:
     - 'There is a ferocious cave bear eying you from the far end of the room!'
     - 'There is a gentle cave bear sitting placidly in one corner.'
@@ -1674,15 +2077,21 @@ object_descriptions: !!omap
     - '' # dead
 - OBJ_36:
     inventory: '*message in second maze'
+    locations: LOC_NOWHERE
+    immovable: true
     longs:
     - 'There is a message scrawled in the dust in a flowery script, reading:\n"This is not the maze where the pirate leaves his treasure chest."'
     texts:
     - '"This is not the maze where the pirate leaves his treasure chest."'
 - OBJ_37:
     inventory: '*volcano and/or geyser'
+    locations: LOC_BREATHTAKING
+    immovable: true
     longs: !!null
 - OBJ_38:
     inventory: '*vending machine'
+    locations: LOC_DEADEND13
+    immovable: true
     longs:
     - [VEND_BLOCKS, 'There is a massive and somewhat battered vending machine here.  The\ninstructions on it read: "Drop coins here to receive fresh batteries."']
     - [VEND_UNBLOCKS, 'There is a massive vending machine here, swung back to reveal a\nsouthward passage.']
@@ -1691,57 +2100,77 @@ object_descriptions: !!omap
     - '"Drop coins here to receive fresh batteries."'
 - OBJ_39:
     inventory: 'Batteries'
+    locations: LOC_NOWHERE
     longs:
     - [FRESH_BATTERIES, 'There are fresh batteries here.']
     - [DEAD_BATTERIES, 'Some worn-out batteries have been discarded nearby.']
 - OBJ_40:
     inventory: '*carpet and/or moss and/or curtains'
+    locations: LOC_SOFTROOM
+    immovable: true
     longs: !!null
 - OBJ_41:
     inventory: '*ogre'
+    locations: LOC_LARGE
+    immovable: true
     longs:
     - 'A formidable ogre bars the northern exit.'
     sounds:
     - 'The ogre is apparently the strong, silent type.'
 - OBJ_42:
     inventory: '*urn'
+    locations: LOC_CLIFF
+    immovable: true
     longs:
     - 'A small urn is embedded in the rock.'
     - 'A small urn full of oil is embedded in the rock.'
     - 'A small oil flame extrudes from an urn embedded in the rock.'
 - OBJ_43:
     inventory: '*cavity'
+    locations: LOC_NOWHERE
+    immovable: true
     longs:
     - '' # something in it
     - 'There is a small urn-shaped cavity in the rock.'
 - OBJ_44:
     inventory: '*blood'
+    locations: LOC_NOWHERE
+    immovable: true
     longs:
     - '' # described with dragon
 - OBJ_45:
     inventory: '*reservoir'
+    locations: [LOC_RESERVOIR, LOC_RESNORTH]
+    immovable: true
     longs:
     - ''
     - 'The waters have parted to form a narrow path across the reservoir.'
     - 'The waters crash together again.'
 - OBJ_46:
     inventory: 'Leporine appendage'
+    locations: LOC_FOREST22
     longs:
     - 'Your keen eye spots a severed leporine appendage lying on the ground.'
 - OBJ_47:
     inventory: '*mud'
+    locations: LOC_DEBRIS
+    immovable: true
     longs:
     - ''
     texts:
     - '"MAGIC WORD XYZZY"'
 - OBJ_48:
     inventory: '*note'
+    locations: LOC_NUGGET
+    immovable: true
     longs:
     - ''
     texts:
     - '"You won''t get it up the steps"'
 - OBJ_49:
     inventory: '*sign'
+    locations: LOC_ANTEROOM
+    immovable: true
     longs:
     - [INGAME_SIGN, '']
     - [ENDGAME_SIGN, '']
@@ -1750,36 +2179,43 @@ object_descriptions: !!omap
     - '"Treasure Vault.  Keys in main office."'
 - OBJ_50:
     inventory: 'Large gold nugget'
+    locations: LOC_NUGGET
     treasure: true
     longs:
     - 'There is a large sparkling nugget of gold here!'
 - OBJ_51:
     inventory: 'Several diamonds'
+    locations: LOC_WESTBANK
     treasure: true
     longs:
     - 'There are diamonds here!'
 - OBJ_52:
     inventory: 'Bars of silver'
+    locations: LOC_FLOORHOLE
     treasure: true
     longs:
     - 'There are bars of silver here!'
 - OBJ_53:
     inventory: 'Precious jewelry'
+    locations: LOC_SOUTHSIDE
     treasure: true
     longs:
     - 'There is precious jewelry here!'
 - OBJ_54:
     inventory: 'Rare coins'
+    locations: LOC_WESTSIDE
     treasure: true
     longs:
     - 'There are many coins here!'
 - OBJ_55:
     inventory: 'Treasure chest'
+    locations: LOC_NOWHERE
     treasure: true
     longs:
     - 'The pirate''s treasure chest is here!'
 - OBJ_56:
     inventory: 'Golden eggs'
+    locations: LOC_GIANTROOM
     treasure: true
     longs:
     - 'There is a large nest here, full of golden eggs!'
@@ -1787,11 +2223,13 @@ object_descriptions: !!omap
     - 'Done!'
 - OBJ_57:
     inventory: 'Jeweled trident'
+    locations: LOC_WATERFALL
     treasure: true
     longs:
     - 'There is a jewel-encrusted trident here!'
 - OBJ_58:
     inventory: 'Ming vase'
+    locations: LOC_ORIENTAL
     treasure: true
     longs:
     - [VASE_WHOLE, 'There is a delicate, precious, ming vase here!']
@@ -1800,22 +2238,27 @@ object_descriptions: !!omap
     - [VASE_DROPS, 'The ming vase drops with a delicate crash.']
 - OBJ_59:
     inventory: 'Egg-sized emerald'
+    locations: LOC_PLOVER
     treasure: true
     longs:
     - 'There is an emerald here the size of a plover''s egg!'
     - 'There is an emerald resting in a small cavity in the rock!'
 - OBJ_60:
     inventory: 'Platinum pyramid'
+    locations: LOC_DARKROOM
     treasure: true
     longs:
     - 'There is a platinum pyramid here, 8 inches on a side!'
 - OBJ_61:
     inventory: 'Glistening pearl'
+    locations: LOC_NOWHERE
     treasure: true
     longs:
     - 'Off to one side lies a glistening pearl!'
 - OBJ_62:
     inventory: 'Persian rug'
+    locations: [LOC_SECRET4, LOC_SECRET6]
+    immovable: true
     treasure: true
     longs:
     - 'There is a persian rug spread out on the floor!'
@@ -1823,11 +2266,14 @@ object_descriptions: !!omap
     - 'There is a persian rug here, hovering in mid-air!'
 - OBJ_63:
     inventory: 'Rare spices'
+    locations: LOC_BOULDERS2
     treasure: true
     longs:
     - 'There are rare spices here!'
 - OBJ_64:
     inventory: 'Golden chain'
+    locations: LOC_BARRENROOM
+    immovable: true
     treasure: true
     longs:
     - 'There is a golden chain lying in a heap on the floor!'
@@ -1835,29 +2281,34 @@ object_descriptions: !!omap
     - 'There is a golden chain locked to the wall!'
 - OBJ_65:
     inventory: 'Giant ruby'
+    locations: LOC_STOREROOM
     treasure: true
     longs:
     - 'There is an enormous ruby here!'
     - 'There is a ruby resting in a small cavity in the rock!'
 - OBJ_66:
     inventory: 'Jade necklace'
+    locations: LOC_NOWHERE
     treasure: true
     longs:
     - 'A precious jade necklace has been dropped here!'
 - OBJ_67:
     inventory: 'Amber gemstone'
+    locations: LOC_NOWHERE
     treasure: true
     longs:
     - 'There is a rare amber gemstone here!'
     - 'There is an amber gemstone resting in a small cavity in the rock!'
 - OBJ_68:
     inventory: 'Star sapphire'
+    locations: LOC_LEDGE
     treasure: true
     longs:
     - 'A brilliant blue star sapphire is here!'
     - 'There is a star sapphire resting in a small cavity in the rock!'
 - OBJ_69:
     inventory: 'Ebony statuette'
+    locations: LOC_REACHDEAD
     treasure: true
     longs:
     - 'There is a richly-carved ebony statuette here!'