home *** CD-ROM | disk | FTP | other *** search
/ Fatal Distractions! / fataldistractions.bin / chap01 / ccr / ccr-item.t < prev    next >
Text File  |  1993-07-10  |  27KB  |  1,146 lines

  1. /*
  2.  * Colossal Cave Revisited
  3.  *
  4.  * A remake of Willie Crowther and Don Woods' classic Adventure.
  5.  * Converted from Donald Ekman's PC port of the original FORTRAN source.
  6.  * TADS version by David M. Baggett for ADVENTIONS.
  7.  *
  8.  * Please document all changes in the history so we know who did what.
  9.  *
  10.  * This source code is copylefted under the terms of the GNU Public
  11.  * License.  Essentially, this means that you are free to do whatever
  12.  * you wish with this source code, provided you do not charge any
  13.  * money for it or for any derivative works.
  14.  *
  15.  * ADVENTIONS distributes this game, but you are free to do what you will
  16.  * with it, provided you adhere to the terms in the GNU Public License.
  17.  * Send correspondence regarding this game or original works distributed
  18.  * by ADVENTIONS to 
  19.  *
  20.  *    ADVENTIONS
  21.  *    PO Box 851
  22.  *    Columbia, MD 21044 USA
  23.  *
  24.  * If you would like a catalog of releases, please enclose a SASE.  Thanks!
  25.  *
  26.  * Contributors
  27.  *
  28.  *    dmb    In real life:    David M. Baggett
  29.  *        Internet:    <dmb@ai.mit.edu>
  30.  *        Compu$erve:    76440,2671 (ADVENTIONS account)
  31.  *        GEnie:        ADVENTIONS
  32.  *
  33.  * Modification History
  34.  *
  35.  *  1-Jan-93    dmb    rec.arts.int-fiction BETA release (source only)
  36.  *                      For beta testing only -- not for general
  37.  *            distribution.
  38.  * 20-Apr-93    dmb    Fixed a bug with the treasures: you could
  39.  *            get points for a treasure without being able
  40.  *            to carry it.
  41.  */
  42.  
  43. /*
  44.  * This file defines all carryable items in the game.
  45.  */
  46. class CCR_item: item;
  47.  
  48. /*
  49.  * Important notes about treasures:
  50.  *
  51.  * If you want to add treasures, use the CCR_treasure_item class.  Take
  52.  * care to call the original doDrop and pass doTake if you override the
  53.  * doDrop or doTake methods, because it is in these methods that we
  54.  * handle the scoring.
  55.  *
  56.  * Each treasure is worth self.takepoints points when taken for the
  57.  * first time, and an additional self.depositpoints when deposited
  58.  * in the bulding.  Be sure to update global.maxscore and scoreRank
  59.  * if you add treasures (or anything else that gives the player points,
  60.  * for that matter).
  61.  *
  62.  * The proper way to check if an object is a treasure is:
  63.  *
  64.  *     if (isclass(obj, CCR_treasure_item))
  65.  *        ...
  66.  *
  67.  */
  68. class CCR_treasure_item: CCR_item
  69.     plural = 'treasures' 'goodies' 'loot'
  70.  
  71.     takepoints = 2        // points for taking this treasure
  72.     depositpoints = 12    // points for putting in building
  73.  
  74.     awardedpointsfortaking = nil
  75.     awardedpointsfordepositing = nil
  76.     
  77.     doTake(actor) = {
  78.         inherited.doTake(actor);
  79.  
  80.         //
  81.         // If we didn't get the object (e.g., if the actor's carrying
  82.         // too much), don't give points.
  83.         //
  84.         if (not self.isIn(actor))
  85.             return;
  86.  
  87.         //
  88.         // Give the player some points for taking the treasure
  89.         // the first time.
  90.         //
  91.         // If the player removes a treasure from the bulding
  92.         // floor, reduce his score by the value of that
  93.         // treasure.  (This is to prevent him from dropping
  94.         // a treasure off, getting the points, and then giving
  95.         // it to the troll or otherwise losing it.) 
  96.         //
  97.         if (not self.awardedpointsfortaking) {
  98.             incscore(self.takepoints);
  99.             self.awardedpointsfortaking := true;
  100.         }
  101.         if (self.awardedpointsfordepositing) {
  102.             if (self.isIn(Inside_Building)) {
  103.                 incscore(-1 * self.depositpoints);
  104.                 self.awardedpointsfordepositing := nil;
  105.  
  106.                 // That's one more treasure to deposit.
  107.                 global.treasures := global.treasures + 1;
  108.             }
  109.         }
  110.     }
  111.     doDrop(actor) = {
  112.         self.checkpoints;
  113.         pass doDrop;
  114.     }
  115.  
  116.     checkpoints = {
  117.         //
  118.         // Award points for putting treasure in building (unless
  119.         // we've already awarded the points for depositing this
  120.         // treasure).
  121.         //
  122.         if (Me.isIn(Inside_Building)) {
  123.             if (not self.awardedpointsfortaking) {
  124.                 //
  125.                 // This shouldn't happen, but just in case...
  126.                 //
  127.                 incscore(self.takepoints);
  128.                 self.awardedpointsfortaking := true;
  129.             }
  130.             else if (not self.awardedpointsfordepositing) {
  131.                 incscore(self.depositpoints);
  132.                 self.awardedpointsfordepositing := true;
  133.  
  134.                 // That's one less treasure to deposit.
  135.                 global.treasures := global.treasures - 1;
  136.             } 
  137.         }
  138.     }
  139. ;
  140.  
  141. set_of_keys: CCR_item, keyItem
  142.     sdesc = "set of keys"
  143.     ldesc = "It's just a normal-looking set of keys."
  144.     location = Inside_Building
  145.     noun = 'keys' 'key' 'keyring' 'set'
  146.     adjective = 'key'
  147. ;
  148.  
  149. brass_lantern: CCR_item, lightsource
  150.     turnsleft = 330        // expert mode (default)
  151.     sdesc = "brass lantern"
  152.     ldesc = {
  153.         "It is a shiny brass lamp";
  154.  
  155.         if (self.islit) {
  156.             if (self.turnsleft <= 30)
  157.                 ", glowing dimly.";
  158.             else
  159.                 ", glowing brightly.";
  160.         }
  161.         else
  162.             ".  It is not currently lit.";
  163.     }
  164.     location = Inside_Building
  165.     noun = 'lamp' 'headlamp' 'headlight' 'lantern' 'light'
  166.  
  167.     ison = nil
  168.     islit = {
  169.         if (self.ison and self.turnsleft > 0)
  170.             return true;
  171.         else
  172.             return nil;
  173.     }    
  174.     
  175.     verDoRub(actor) = {}
  176.     doRub(actor) = {
  177.         "Rubbing the electric lamp is not particularly 
  178.         rewarding.  Anyway, nothing exciting happens.";
  179.     }
  180.  
  181.     verDoTurnon(actor) = {
  182.         if (self.ison)
  183.             "It's already on.";
  184.     }
  185.     doTurnon(actor) = {
  186.         "The lamp is now on.";
  187.         self.ison := true;
  188.  
  189.         if (self.turnsleft > 0)
  190.             notify(self, &wearbatteries, 0);
  191.         else
  192.             "  Unfortunately, the batteries seem to
  193.             be dead.";
  194.     }
  195.     verDoTurnoff(actor) = {
  196.         if (not self.ison)
  197.             "It's already off.";
  198.     }
  199.     doTurnoff(actor) = {
  200.         "The lamp is now off.";
  201.         self.turnoff;
  202.     }
  203.     verDoLight(actor) = { self.verDoTurnon(actor); }
  204.     doLight(actor) = { self.doTurnon(actor); }
  205.  
  206.     verIoPutIn(actor) = {}
  207.     ioPutIn(actor, dobj) = {
  208.         if (dobj = old_batteries)
  209.             "Those batteries are dead; they won't
  210.             do any good at all.";
  211.         else if (dobj = fresh_batteries)
  212.             self.do_replace;
  213.         else
  214.             "The only thing you might successfully put in 
  215.             the lamp is a fresh pair of batteries.";
  216.     }
  217.  
  218.     // The following method is called when the player gets resurrected.
  219.     turnoff = {
  220.         if (self.ison) {
  221.             self.ison := nil;
  222.             unnotify(self, &wearbatteries);
  223.         }
  224.     }
  225.  
  226.     wearbatteries = {
  227.         self.turnsleft := self.turnsleft - 1;
  228.  
  229.         if (self.turnsleft < 1) {
  230.             P(); I();
  231.             "Your lamp has run out of power. ";
  232.  
  233.             if (self.replace_batteries) {
  234.                 // do nothing
  235.             }
  236.             else if (Me.location.isoutside) {
  237.                 "There's not much point in wandering 
  238.                 around out here, and you can't 
  239.                 explore the cave without a lamp. So 
  240.                 let's just call it a day.";
  241.  
  242.                 call_it_a_day();
  243.             }
  244.         }
  245.         else if (self.turnsleft = 30) {
  246.             P(); I();
  247.             "Your lamp is getting dim. ";
  248.  
  249.             if (self.replace_batteries) {
  250.                 // do nothing.
  251.             }
  252.             else if (fresh_batteries.used) {
  253.                 // DMB: changed the wording of this
  254.                 // slightly for convenience.
  255.                 "You're also out of spare batteries.  
  256.                 You'd best start wrapping this up.";
  257.             }
  258.             else if (fresh_batteries.location <> nil) {
  259.                 "You'd best go back for those 
  260.                 batteries.";
  261.             }
  262.             else {
  263.                 "You'd best start wrapping this up, 
  264.                 unless you can find some fresh 
  265.                 batteries. I seem to recall there's a 
  266.                 vending machine in the maze.  Bring 
  267.                 some coins with you.";
  268.             }
  269.         }
  270.     }
  271.  
  272.     replace_batteries = {
  273.         if (fresh_batteries.isIn(Me.location)) {
  274.             " I'm taking the liberty of replacing the
  275.             batteries.";
  276.  
  277.             self.do_replace;
  278.  
  279.             return true;
  280.         }
  281.         else
  282.             return nil;
  283.     }
  284.  
  285.     do_replace = {
  286.         fresh_batteries.used := true;
  287.         fresh_batteries.moveInto(nil);
  288.         old_batteries.moveInto(Me.location);
  289.         self.turnsleft := 2500;
  290.     }
  291. ;
  292.  
  293. black_rod: CCR_item
  294.     sdesc = "black rod"
  295.     ldesc = "It's a three foot black rod with a rusty star on an end."
  296.     location = In_Debris_Room
  297.     noun = 'rod' 'star'
  298.     adjective = 'black' 'rusty' 'star'
  299.  
  300.     verDoWave(actor) = {}
  301.     doWave(actor) = {
  302.         if (self.isIn(West_Side_Of_Fissure) or
  303.             self.isIn(On_East_Bank_Of_Fissure)) {
  304.  
  305.             if (global.closed) {
  306.                 "Peculiar.  Nothing happens.";
  307.             }
  308.             else {
  309.                 if (CrystalBridge.exists) {
  310.                     "The crystal bridge has 
  311.                     vanished!";
  312.                     CrystalBridge.exists := nil;
  313.                 }
  314.                 else {
  315.                     "A crystal bridge now spans 
  316.                     the fissure.";
  317.                     CrystalBridge.exists := true;
  318.                 }
  319.             }
  320.         }
  321.         else
  322.             "Nothing happens.";
  323.     }
  324. ;
  325.  
  326. wicker_cage: CCR_item, container
  327.     sdesc = "wicker cage"
  328.     ldesc = {
  329.         "It's a small wicker cage.";
  330.     }
  331.     location = In_Cobble_Crawl
  332.     noun = 'cage'
  333.     adjective = 'small' 'wicker' 'bird'
  334.  
  335.     verDoPutIn(actor) = {}
  336.     doPutIn(actor, io) = {
  337.         if (io <> little_bird) {
  338.             caps(); self.thedesc; " isn't big enough
  339.             to hold "; io.thedesc; ".";
  340.         }
  341.         else
  342.             pass doPutIn;
  343.     }
  344. ;
  345.  
  346. /*
  347.  * The following rod is actually an explosive.  Don't ask ME how anyone
  348.  * is supposed to figure this out from the description.  I've left it
  349.  * the way it was even though I think it's pretty bogus.
  350.  *
  351.  * I've added the words 'explosive' and 'dynamite' as nouns and adjectives,
  352.  * and 'blast' as an adjective.  Perhaps this will give some lucky soul
  353.  * a clue.
  354.  */
  355. black_mark_rod: CCR_item
  356.     sdesc = "marked rod"
  357.     ldesc = {
  358.         "It's a three foot black rod with a rusty mark on an end.";
  359.     }
  360.     location = At_Sw_End
  361.     noun = 'rod' 'mark' 'explosive' 'dynamite'
  362.     adjective = 'black' 'rusty' 'mark' 'blast' 'explosive' 'dynamite'
  363.  
  364.     verDoWave(actor) = {}
  365.     doWave(actor) = { "Nothing happens."; }
  366.  
  367.     verDoBlastWith(actor) = {}
  368.     doBlastWith(actor) = { endpuzzle(); }
  369. ;
  370.  
  371. little_bird: CCR_item
  372.     sdesc = {
  373.         if (not self.isIn(wicker_cage))
  374.             "cheerful ";
  375.         
  376.         "little bird";
  377.     }
  378.     ldesc = {
  379.         if (self.isIn(wicker_cage))
  380.             "The little bird looks unhappy in the cage.";
  381.         else
  382.             "The cheerful little bird is sitting here singing.";
  383.     }
  384.     location = In_Bird_Chamber
  385.     noun = 'bird'
  386.  
  387.     verDoFeed(actor) = {}
  388.     doFeed(actor) = {
  389.         "It's not hungry. (It's merely pinin' for the fjords). 
  390.          Besides, you have no bird seed.";
  391.     }
  392.     verIoGiveTo(actor) = {
  393.         "I suspect it would prefer bird seed.";
  394.     }
  395.  
  396.     /*
  397.      * Catch any attempt to remove the bird.  It won't cooperate
  398.      * When the player has the rod with the star on the end.
  399.      */
  400.     verifyRemove(actor) = {
  401.         if (self.isIn(Me)) {
  402.             "You already have the little bird.  If
  403.             you take it out of the cage it will likely
  404.             fly away from you.";
  405.         }
  406.         else if (black_rod.isIn(Me)) {
  407.             "The bird was unafraid when you entered, but 
  408.             as you approach it becomes disturbed and you 
  409.             cannot catch it.";
  410.         }
  411.         else
  412.             pass verifyRemove;
  413.     }
  414.  
  415.     verDoTake(actor) = {
  416.         if (not wicker_cage.isIn(Me))
  417.             "You can catch the bird, but you cannot carry it.";
  418.         else
  419.             pass verDoTake;
  420.     }
  421.     doTake(actor) = {
  422.         self.doPutIn(Me, wicker_cage);
  423.     }
  424.  
  425.     verDoPutIn(actor) = {}
  426.     doPutIn(actor, io) = {
  427.         if (io <> wicker_cage) {
  428.             "Don't put the poor bird in "; io.thedesc; "!";
  429.         }
  430.         else
  431.             pass doPutIn;
  432.     }
  433.  
  434.     verDoAttack(actor) = {
  435.         if (self.isIn(wicker_cage)) 
  436.             "Oh, leave the poor unhappy bird alone.";
  437.         else {
  438.             "The little bird is now dead.  Its body disappears.";
  439.             self.moveInto(nil);
  440.         }
  441.     }
  442.  
  443.     verDoDrop(actor) = {}
  444.     doDrop(actor) = {
  445.         if (self.isIn(Snake.location)) {
  446.             "The little bird attacks the green snake, and 
  447.             in an astounding flurry drives the snake 
  448.             away.";
  449.  
  450.             Snake.moveInto(nil);
  451.             self.moveInto(Me.location);
  452.         }
  453.         else if (self.isIn(Dragon.location)) {
  454.             "The little bird attacks the green dragon, 
  455.             and in an astounding flurry gets burnt to a 
  456.             cinder.  The ashes blow away.";
  457.  
  458.             self.moveInto(nil);
  459.         }
  460.         else
  461.             pass doDrop;
  462.     }
  463.  
  464.     doTakeOut(actor, io) = {
  465.         // Drop ourselves automatically.  (The bird flies away
  466.         // when taken out of a container.)
  467.         self.doDrop(actor);
  468.     }
  469. ;
  470.  
  471. velvet_pillow: CCR_item
  472.     sdesc = "velvet pillow"
  473.     ldesc = "It's just a small velvet pillow."
  474.     location = In_Soft_Room
  475.     noun = 'pillow'
  476.     adjective = 'velvet' 'small'
  477. ;
  478.  
  479. giant_bivalve: CCR_item
  480.     opened = nil
  481.  
  482.     sdesc = {
  483.         if (self.opened)
  484.             "giant oyster";
  485.         else
  486.             "giant clam";
  487.  
  488.         if (self.isIn(Me))
  489.             " >grunt!<";
  490.     }
  491.     thedesc = {
  492.         if (self.opened)
  493.             "the giant oyster";
  494.         else
  495.             "the giant clam";
  496.     }
  497.     
  498.     ldesc = {
  499.         "It's an enormous clam with its shell tightly closed.";
  500.  
  501.         // During the endgame, the oyster has something
  502.         // written on it.
  503.         if (self.isIn(At_Ne_End) or self.isIn(At_Sw_End)) {
  504.             "Interesting.  There seems to be something 
  505.             written on the underside of the oyster.";
  506.         }
  507.     }
  508.     location = In_Shell_Room
  509.     noun = 'clam' 'oyster' 'bivalve' 'shell'
  510.     adjective = 'giant' 'enormous' 'massive' 'big' 'huge' 'tightly'
  511.         'closed' 'five' 'foot' 'five-foot' '5-foot'
  512.  
  513.     verDoOpen(actor) = { self.verDoOpenWith(actor, nil); }
  514.     doOpen(actor) = {
  515.         if (trident.isIn(Me)) {
  516.             //
  517.             // In the original, "open clam" would work
  518.             // ask long as you were carrying the trident,
  519.             // but this seems very prone to accidental
  520.             // solving, and since we aren't limited to
  521.             // two word parsing, I've just taken the
  522.             // liberty of forcing the player to type
  523.             // "open clam with trident."
  524.             //
  525.             "You'll need to be a bit more specific that 
  526.             that, I'm afraid.";
  527.         }
  528.         else {
  529.             "You don't have anything strong enough to 
  530.             open "; self.thedesc; ".";
  531.         }
  532.     }
  533.     verDoOpenWith(actor, io) = {
  534.         if (self.isIn(Me)) {
  535.             "I advise you to put down "; self.thedesc;
  536.             " before opening it.  >Strain!<";
  537.         }
  538.     }
  539.     doOpenWith(actor, io) = {
  540.         if (io = trident) {
  541.             if (self.opened) {
  542.                 "The oyster creaks open, revealing nothing 
  543.                 but oyster inside.  It promptly snaps shut 
  544.                 again.";  
  545.             }
  546.             else {
  547.                 "A glistening pearl falls out of the clam and 
  548.                 rolls away.  Goodness, this must really be an 
  549.                 oyster.  (I never was very good at 
  550.                 identifying bivalves.)  Whatever it is, it 
  551.                 has now snapped shut again.";
  552.  
  553.                 self.opened := true;
  554.                 pearl.moveInto(In_A_Cul_De_Sac);
  555.             }
  556.         }
  557.         else {
  558.             caps(); io.thedesc; " isn't strong enough to 
  559.             open "; self.thedesc; ".";
  560.         }
  561.     }
  562.     verDoBreak(actor) = {
  563.         "The shell is very strong and is impervious to 
  564.         attack.";
  565.     }
  566.     verDoAttack(actor) = { self.verDoBreak(actor); }
  567.     verDoAttackWith(actor, io) = { self.verDoBreak(actor); }
  568.  
  569.     //
  570.     // The oyster has a hint written on its underside once
  571.     // the cave's closed.  (Look, don't ask me, I'm just
  572.     // porting this game!)
  573.     //
  574.     verDoRead(actor) = {
  575.         if (not self.isIn(At_Ne_End) and not self.isIn(At_Sw_End))
  576.             "You're babbling -- snap out of it!";
  577.     }
  578.     doRead(actor) = {
  579.         //
  580.         // This is supposed to be a hint (i.e., it's supposed
  581.         // to cost points), but I've put it in as a freebie
  582.         // because I think the final puzzle is absurdly
  583.         // difficult even with the free hint.
  584.         //
  585.         "It says, \"There is something strange about this 
  586.         place, such that one of the words I've always known 
  587.         now has a new effect.\"";
  588.     }
  589. ;
  590.  
  591. spelunker_today: CCR_item, readable
  592.     sdesc = "recent issues of \"Spelunker Today\""
  593.     adesc = { self.sdesc; }
  594.     ldesc = { self.readdesc; }
  595.     readdesc = {
  596.         // This said "magazine is written" in the original,
  597.         // which is obviously wrong given the sdesc.
  598.  
  599.         "I'm afraid the magazines are written in Dwarvish.";
  600.     }
  601.  
  602.     location = In_Anteroom
  603.     plural = 'magazines'
  604.     noun = 'magazine' 'issue' 'issue' 'spelunker'
  605.         'today' 'dwarvish'
  606.     adjective = 'spelunker' 'today' 'dwarvish'
  607.  
  608.     doDrop(actor) = {
  609.         if (Me.isIn(At_Witts_End))
  610.             silent_incscore(global.wittpoints);
  611.  
  612.         pass doDrop;
  613.     }
  614.     doTake(actor) = {
  615.         if (Me.isIn(At_Witts_End))
  616.             silent_incscore(-1 * global.wittpoints);
  617.  
  618.         pass doTake;
  619.     }
  620. ;
  621.  
  622. tasty_food: CCR_item, fooditem
  623.     sdesc = "some tasty food"
  624.     adesc = { self.sdesc; }
  625.     thedesc = "the tasty food"
  626.     ldesc = "Sure looks yummy!"
  627.     location = Inside_Building
  628.     noun = 'food' 'ration' 'rations' 'tripe'
  629.     adjective = 'yummy' 'tasty' 'delicious' 'scrumptious'
  630. ;
  631.  
  632. bottle: CCR_item
  633.     haswater = true
  634.     hasoil = nil
  635.  
  636.     sdesc = {
  637.         if (self.haswater)
  638.             "small bottle of water";
  639.         else if (self.hasoil)
  640.             "small bottle of oil";
  641.         else
  642.             "small empty bottle";
  643.     }
  644.     location = Inside_Building
  645.     noun = 'bottle' 'jar' 'flask'
  646.  
  647.     verIoPutIn(actor) = {}
  648.     ioPutIn(actor, dobj) = {
  649.         if (self.haswater)
  650.             "The bottle is already full of water.";
  651.         else if (self.hasoil)
  652.             "The bottle is already full of oil.";
  653.         else if (dobj = Stream) {
  654.             "The bottle is now full of water.";
  655.             self.haswater := true;
  656.         }
  657.         else if (dobj = Oil) {
  658.             "The bottle is now full of oil.";
  659.             self.hasoil := true;
  660.         }
  661.         else {
  662.             "I'm not sure how to do that.";
  663.         }
  664.     }
  665.  
  666.     verDoFill(actor) = {}
  667.     doFill(actor) = {
  668.         if (self.isIn(Stream.location))
  669.             self.ioPutIn(actor, Stream);
  670.         else if (self.isIn(Oil.location))
  671.             self.ioPutIn(actor, Oil);
  672.         else
  673.             "There is nothing here with which to fill the 
  674.             bottle.";
  675.     }
  676.  
  677.     verDoEmpty(actor) = {}
  678.     doEmpty(actor) = {
  679.         if (self.haswater or self.hasoil)
  680.             "Your bottle is now empty and the ground is 
  681.             now wet.";
  682.         else
  683.             "The bottle is already empty!";
  684.  
  685.         self.empty;
  686.     }
  687.  
  688.     verDoPourOn(actor, io) = {}
  689.     doPourOn(actor, io) = {
  690.         if (io = RustyDoor) {
  691.             if (self.hasoil) {
  692.                 "The oil has freed up the hinges so that the 
  693.                 door will now move, although it requires some 
  694.                 effort.";
  695.  
  696.                 RustyDoor.isoiled := true;
  697.             }
  698.             else if (self.haswater) {
  699.                 "The hinges are quite thoroughly 
  700.                 rusted now and won't budge.";
  701.             }
  702.             else {
  703.                 "The bottle is empty.";
  704.             }
  705.  
  706.             self.empty;
  707.         }
  708.         else if (io = Plant) {
  709.             if (self.haswater) {
  710.                 Plant.water;
  711.             }
  712.             else if (self.hasoil) {
  713.                 "The plant indignantly shakes the oil 
  714.                 off its leaves and asks, \"Water?\"";
  715.             }
  716.             else {
  717.                 "The bottle is empty.";
  718.             }
  719.  
  720.             self.empty;
  721.         }
  722.         else if (io = theFloor)
  723.             self.doEmpty(actor);
  724.         else
  725.             "That doesn't seem productive.";
  726.     }
  727.  
  728.     verDoDrink(actor) = {
  729.         if (not self.hasoil and not self.haswater)
  730.             "The bottle is empty.";
  731.  
  732.         if (self.hasoil)
  733.             "Don't drink the oil, you fool!";
  734.     }
  735.     doDrink(actor) = {
  736.         "The bottle is now empty.";
  737.         self.empty;
  738.     }
  739.  
  740.     empty = {
  741.         self.haswater := nil;
  742.         self.hasoil := nil;
  743.     }
  744. ;
  745. water_in_the_bottle: CCR_decoration
  746.     sdesc = "water in the bottle"
  747.     adesc = "water"
  748.     ldesc = "It looks like ordinary water to me."
  749.     locationOK = true    // tell compiler OK for location to be method
  750.     location = {
  751.         if (bottle.haswater)
  752.             return bottle.location;
  753.         else
  754.             return nil;
  755.     }
  756.     noun = 'water' 'h2o'
  757.  
  758.     verDoPourOn(actor, io) = {}
  759.     doPourOn(actor, io) = { bottle.doPourOn(actor, io); }
  760.     verDoDrink(actor) = { bottle.verDoDrink(actor); }
  761.     doDrink(actor) = { bottle.doDrink(actor); }
  762. ;
  763. oil_in_the_bottle: CCR_decoration
  764.     sdesc = "oil in the bottle"
  765.     adesc = "oil"
  766.     ldesc = "It looks like ordinary oil to me."
  767.     locationOK = true    // tell compiler OK for location to be method
  768.     location = {
  769.         if (bottle.hasoil)
  770.             return bottle.location;
  771.         else
  772.             return nil;
  773.     }
  774.     noun = 'oil' 'lubricant' 'grease'
  775.  
  776.     verDoPourOn(actor, io) = {}
  777.     doPourOn(actor, io) = { bottle.doPourOn(actor, io); }
  778.     verDoDrink(actor) = { bottle.verDoDrink(actor); }
  779.     doDrink(actor) = { bottle.doDrink(actor); }
  780. ;
  781.  
  782. axe: CCR_item
  783.     nograb = nil    // hack for when you attack the bear with it
  784.  
  785.     sdesc = "dwarf's axe"
  786.     ldesc = {
  787.         if (self.nograb)
  788.             "It's lying beside the bear.";
  789.         else
  790.             "It's just a little axe.";
  791.     }
  792.     location = nil        // created when first dwarf attacks
  793.     noun = 'axe'
  794.     adjective = 'little' 'dwarf' 'dwarvish' 'dwarven' 'dwarf\'s'
  795.  
  796.     verifyRemove(actor) = {
  797.         if (self.nograb)
  798.             "No chance.  It's lying beside the ferocious 
  799.             bear, quite within harm's way.";
  800.     }
  801. ;
  802.  
  803. fresh_batteries: CCR_item
  804.     used = nil    // used in lamp yet?
  805.  
  806.     sdesc = "fresh batteries"
  807.     ldesc = {
  808.         "They look like ordinary batteries.  (A sepulchral 
  809.         voice says, \"Still going!\")";
  810.     }
  811.     noun = 'batteries' 'battery' 'duracel' 'duracell' 'duracels'
  812.         'duracells' 'energizer' 'energizers' 'everready'
  813.         'everreadies' 'eveready' 'evereadies'
  814.     adjective = 'fresh'
  815.  
  816.     location = nil
  817. ;
  818.  
  819. old_batteries: CCR_item
  820.     sdesc = "worn-out batteries"
  821.     ldesc = {
  822.         "They look like ordinary batteries.";
  823.     }
  824.     noun = 'batteries' 'battery' 'duracel' 'duracell' 'duracels'
  825.         'duracells' 'energizer' 'energizers' 'everready'
  826.         'everreadies' 'eveready' 'evereadies'
  827.     adjective = 'worn' 'out' 'worn-out' 'dead' 'empty' 'dry' 'old'
  828.  
  829.     location = nil
  830. ;
  831.  
  832. /*
  833.  * Treasures
  834.  */
  835. large_gold_nugget: CCR_treasure_item
  836.     depositpoints = 10
  837.     sdesc = "large gold nugget"
  838.     ldesc = "It's a large sparkling nugget of gold!"
  839.     location = In_Nugget_Of_Gold_Room
  840.     noun = 'gold' 'nugget'
  841.     adjective = 'gold' 'large'
  842. ;
  843. several_diamonds: CCR_treasure_item
  844.     depositpoints = 10
  845.     sdesc = "several diamonds"
  846.     adesc = { self.sdesc; }
  847.     thedesc = "the diamonds"
  848.     ldesc = "They look to be of the highest quality!"
  849.     location = West_Side_Of_Fissure
  850.     noun = 'diamond' 'diamonds'
  851.     adjective = 'several' 'high' 'quality' 'high-quality'
  852. ;
  853. bars_of_silver: CCR_treasure_item
  854.     depositpoints = 10
  855.     sdesc = "bars of silver"
  856.     adesc = { self.sdesc; }
  857.     ldesc = "They're probably worth a fortune!"
  858.     location = Low_N_S_Passage
  859.     noun = 'silver' 'bars'
  860.     adjective = 'silver'
  861. ;
  862. precious_jewelry: CCR_treasure_item
  863.     depositpoints = 10
  864.     sdesc = "precious jewelry"
  865.     adesc = { self.sdesc; }
  866.     ldesc = "It's all quite exquisite!"
  867.     location = In_South_Side_Chamber
  868.     noun = 'jewel' 'jewels' 'jewelry'
  869.     adjective = 'precious' 'exquisite'
  870. ;
  871. rare_coins: CCR_treasure_item
  872.     depositpoints = 10
  873.     sdesc = "rare coins"
  874.     adesc = { self.sdesc; }
  875.     ldesc = "They're a numismatist's dream!"
  876.     location = In_West_Side_Chamber
  877.     noun = 'coins'
  878.     adjective = 'rare'
  879. ;
  880. treasure_chest: CCR_treasure_item
  881.     spotted = nil    // found yet?  See also Dead_End_13 in ccr-room.t
  882.  
  883.     depositpoints = 12
  884.     sdesc = "treasure chest"
  885.     ldesc = {
  886.         "It's the pirate's treasure chest, filled with
  887.         riches of all kinds!";
  888.     }
  889.     location = nil
  890.     noun = 'chest' 'box' 'treasure' 'riches'
  891.     adjective = 'pirate' 'pirate\'s' 'treasure'     
  892. ;
  893. golden_eggs: CCR_treasure_item
  894.     depositpoints = 14
  895.     sdesc = "nest of golden eggs"
  896.     ldesc = "The nest is filled with beautiful golden eggs!"
  897.     location = In_Giant_Room
  898.     noun = 'eggs' 'egg' 'nest'
  899.     adjective = 'golden' 'beautiful'
  900. ;
  901. trident: CCR_treasure_item
  902.     depositpoints = 14
  903.     sdesc = "jeweled trident"
  904.     ldesc = "The trident is covered with fabulous jewels!"
  905.     location = In_Cavern_With_Waterfall
  906.     noun = 'trident'
  907.     adjective = 'jeweled' 'jewel-encrusted' 'encrusted' 'fabulous'
  908.  
  909.     verIoOpenWith(actor) = {}
  910.     ioOpenWith(actor, dobj) = {
  911.         dobj.doOpenWith(actor, self);
  912.     }
  913. ;
  914. ming_vase: CCR_treasure_item
  915.     depositpoints = 14
  916.     sdesc = "ming vase"
  917.     ldesc = {
  918.         "It's a delicate, previous, ming vase!";
  919.     }
  920.     location = In_Oriental_Room
  921.     noun = 'vase' 'ming' 'shards' 'pottery'
  922.  
  923.     doDrop(actor) = {
  924.         if (velvet_pillow.isIn(Me.location)) {
  925.             "The vase is now resting, delicately, on a 
  926.             velvet pillow.";
  927.  
  928.             self.moveInto(Me.location);
  929.             
  930.             self.checkpoints;    // make sure we count points
  931.                         // for putting this in building
  932.         }
  933.         else {
  934.             "The ming vase drops with a delicate crash.";
  935.             self.shatter;
  936.         }
  937.     }
  938.  
  939.     verIoPutIn(actor) = {}
  940.     ioPutIn(actor, dobj) = {
  941.         if (dobj = Stream or dobj = Oil) {
  942.             "The sudden change in temperature has 
  943.             delicately shattered the vase.";
  944.  
  945.             self.shatter;
  946.         }
  947.         else {
  948.             "I'm not sure how to do that.";
  949.         }
  950.     }
  951.  
  952.     verDoFill(actor) = {}
  953.     doFill(actor) = {
  954.         if (self.isIn(Stream.location))
  955.             self.ioPutIn(actor, Stream);
  956.         else if (self.isIn(Oil.location))
  957.             self.ioPutIn(actor, Oil);
  958.         else
  959.             "There is nothing here with which to fill the 
  960.             vase.";
  961.     }
  962.  
  963.     verDoBreak(actor) = {}
  964.     doBreak(actor) = {
  965.         "You have taken the vase and hurled it delicately to 
  966.         the ground.";
  967.  
  968.         self.shatter;
  969.     }
  970.  
  971.     shatter = {
  972.         self.moveInto(nil);
  973.         shards.moveInto(Me.location);
  974.     }
  975. ;
  976. shards: CCR_item
  977.     sdesc = "some worthless shards of pottery"
  978.     adesc = { self.sdesc; }
  979.     ldesc = {
  980.         "They're just worthless shards of pottery"; 
  981.  
  982.         if (self.location = Me.location)    // not in a container
  983.             ", littered everywhere.";
  984.         else
  985.             ".";
  986.  
  987.         " They look to be the remains of what was once a
  988.         beautiful vase.  I guess some oaf must have dropped it.";
  989.     }
  990.  
  991.     noun = 'pottery' 'shards'
  992.     adjective = 'worthless'
  993. ;
  994.  
  995. egg_sized_emerald: CCR_treasure_item
  996.     depositpoints = 14
  997.     sdesc = "emerald the size of a plover's egg"
  998.     adesc = { "an "; self.sdesc; }
  999.     ldesc = "Plover's eggs, by the way, are quite large."
  1000.     location = In_Plover_Room
  1001.     noun = 'emerald'
  1002.     adjective = 'egg-sized'
  1003. ;
  1004. platinum_pyramid: CCR_treasure_item
  1005.     depositpoints = 14
  1006.     sdesc = "platinum pyramid"
  1007.     ldesc = "The platinum pyramid is 8 inches on a side!"
  1008.     location = In_Dark_Room
  1009.     noun = 'platinum' 'pyramid'
  1010.     adjective = 'platinum' 'pyramidal'
  1011. ;
  1012. pearl: CCR_treasure_item
  1013.     depositpoints = 14
  1014.     sdesc = "glistening pearl"
  1015.     ldesc = "It's incredibly large!"
  1016.     location = nil
  1017.     noun = 'pearl'
  1018.     adjective = 'glistening' 'incredible' 'incredibly' 'large'
  1019. ;
  1020. persian_rug: CCR_treasure_item
  1021.     depositpoints = 14
  1022.     sdesc = {
  1023.         "Persian rug";
  1024.  
  1025.         if (self.isIn(Dragon.location))
  1026.             " (upon which the dragon is sprawled out)";
  1027.     }
  1028.     adesc = {
  1029.         "a "; self.sdesc; 
  1030.     }
  1031.     ldesc = {
  1032.         if (self.isIn(Dragon.location))
  1033.             "The dragon is sprawled out on the Persian rug!!";
  1034.         else if (not self.isIn(Me))
  1035.             "The Persian rug is spread out on the floor here.";
  1036.         else
  1037.             "The Persian rug is the finest you've ever seen!";
  1038.     }
  1039.     location = In_Secret_Canyon
  1040.     noun = 'rug' 'persian'
  1041.     adjective = 'persian' 'fine' 'finest' 'dragon\'s'
  1042.  
  1043.     verifyRemove(actor) = {
  1044.         if (self.isIn(Dragon.location))
  1045.             "You'll need to get the dragon to move first!";
  1046.     }
  1047. ;
  1048. rare_spices: CCR_treasure_item
  1049.     depositpoints = 14
  1050.     sdesc = "rare spices"
  1051.     adesc = { self.sdesc; }
  1052.     ldesc = "They smell wonderfully exotic!"
  1053.     location = In_Chamber_Of_Boulders
  1054.     noun = 'spices' 'spice'
  1055.     adjective = 'rare' 'exotic'
  1056.  
  1057.     verDoSmell(actor) = {}
  1058.     doSmell(actor) = { self.ldesc; }
  1059. ;
  1060. golden_chain: CCR_treasure_item, keyedLockable
  1061.     depositpoints = 14
  1062.     isfixed = {
  1063.         if (self.islocked)
  1064.             return true;
  1065.         else
  1066.             return nil;
  1067.     }
  1068.     isListed = { return not self.isfixed; }
  1069.  
  1070.     mykey = set_of_keys    // pretty handy, those!
  1071.     islocked = true        // locked meaning "locked to the wall."
  1072.     isopen = nil        // need this since we're keyedLockable
  1073.  
  1074.     sdesc = "golden chain"
  1075.     ldesc = {
  1076.         "The chain has thick links of solid gold!";
  1077.  
  1078.         if (self.islocked) {
  1079.             if (Bear.wasreleased)
  1080.                 "It's locked to the wall!";
  1081.             else
  1082.                 " The bear is chained to the wall with it!";
  1083.         }
  1084.     }
  1085.     heredesc = {
  1086.         if (self.isfixed) {
  1087.             P(); I();
  1088.             if (Bear.wasreleased)
  1089.                 "There is a golden chain here, locked 
  1090.                 to the wall.";
  1091.             else
  1092.                 "There is a golden chain here, and a 
  1093.                 large cave bear is locked to the wall 
  1094.                 with it!";
  1095.         }
  1096.     }
  1097.     
  1098.     location = In_Barren_Room
  1099.     noun = 'chain' 'links' 'shackles'
  1100.     adjective = 'solid' 'gold' 'golden' 'thick'
  1101.  
  1102.     verDoLock(actor) = {
  1103.         if (not self.isIn(In_Barren_Room)) {
  1104.             "There is nothing here to which the chain can 
  1105.             be locked.";
  1106.         }
  1107.         else
  1108.             pass verDoLock;
  1109.     }
  1110.     verDoLockWith(actor, io) = {
  1111.         self.verDoLock(actor);    // -> pass verDoLock (OK?)
  1112.         pass verDoLockWith;
  1113.     }
  1114.  
  1115.     verDoUnlock(actor) = {
  1116.         if (not Bear.wasreleased and not Bear.istame) {
  1117.             "There is no way to get past the bear to 
  1118.             unlock the chain, which is probably just as 
  1119.             well.";
  1120.         }
  1121.         else
  1122.             pass verDoUnlock;
  1123.     }
  1124.     verDoUnlockWith(actor, io) = {
  1125.         self.verDoUnlock(actor);
  1126.         pass verDoUnlockWith;
  1127.     }
  1128.  
  1129.     // inherit proper doUnlock from keyedLockable
  1130.     doUnlockWith(actor, io) = {
  1131.         Bear.wasreleased := true;
  1132.         pass doUnlockWith;
  1133.     }
  1134.     
  1135.     verifyRemove(actor) = {
  1136.         if (not Bear.wasreleased) {
  1137.             if (Bear.istame)
  1138.                 "It's locked to the friendly bear.";
  1139.             else
  1140.                 "It's locked to the ferocious bear!";
  1141.         }
  1142.         else if (self.islocked)
  1143.             "The chain is still locked to the wall.";
  1144.     }
  1145. ;
  1146.