home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!news.tek.com!saab!billr
- From: billr@saab.CNA.TEK.COM (Bill Randle)
- Newsgroups: comp.sources.games
- Subject: v18i024: ccr - colossal cave (adventure) implemented in TADS, Part09/11
- Date: 12 Jul 1993 19:29:11 GMT
- Organization: Tektronix, Inc, Redmond, OR, USA
- Lines: 2427
- Approved: billr@saab.CNA.TEK.COM
- Message-ID: <21se27$1d2@ying.cna.tek.com>
- NNTP-Posting-Host: saab.cna.tek.com
- Xref: uunet comp.sources.games:1824
-
- Submitted-by: David Baggett <dmb@xbar.ai.mit.edu>
- Posting-number: Volume 18, Issue 24
- Archive-name: ccr/part09
- Environment: TADS
-
-
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 9 (of 11)."
- # Contents: src/ccr-item.t src/ccr-npc.t src/ccr.t src/makefile
- # Wrapped by billr@saab on Mon Jul 12 12:02:45 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'src/ccr-item.t' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/ccr-item.t'\"
- else
- echo shar: Extracting \"'src/ccr-item.t'\" \(26875 characters\)
- sed "s/^X//" >'src/ccr-item.t' <<'END_OF_FILE'
- X/*
- X * Colossal Cave Revisited
- X *
- X * A remake of Willie Crowther and Don Woods' classic Adventure.
- X * Converted from Donald Ekman's PC port of the original FORTRAN source.
- X * TADS version by David M. Baggett for ADVENTIONS.
- X *
- X * Please document all changes in the history so we know who did what.
- X *
- X * This source code is copylefted under the terms of the GNU Public
- X * License. Essentially, this means that you are free to do whatever
- X * you wish with this source code, provided you do not charge any
- X * money for it or for any derivative works.
- X *
- X * ADVENTIONS distributes this game, but you are free to do what you will
- X * with it, provided you adhere to the terms in the GNU Public License.
- X * Send correspondence regarding this game or original works distributed
- X * by ADVENTIONS to
- X *
- X * ADVENTIONS
- X * PO Box 851
- X * Columbia, MD 21044 USA
- X *
- X * If you would like a catalog of releases, please enclose a SASE. Thanks!
- X *
- X * Contributors
- X *
- X * dmb In real life: David M. Baggett
- X * Internet: <dmb@ai.mit.edu>
- X * Compu$erve: 76440,2671 (ADVENTIONS account)
- X * GEnie: ADVENTIONS
- X *
- X * Modification History
- X *
- X * 1-Jan-93 dmb rec.arts.int-fiction BETA release (source only)
- X * For beta testing only -- not for general
- X * distribution.
- X * 20-Apr-93 dmb Fixed a bug with the treasures: you could
- X * get points for a treasure without being able
- X * to carry it.
- X */
- X
- X/*
- X * This file defines all carryable items in the game.
- X */
- Xclass CCR_item: item;
- X
- X/*
- X * Important notes about treasures:
- X *
- X * If you want to add treasures, use the CCR_treasure_item class. Take
- X * care to call the original doDrop and pass doTake if you override the
- X * doDrop or doTake methods, because it is in these methods that we
- X * handle the scoring.
- X *
- X * Each treasure is worth self.takepoints points when taken for the
- X * first time, and an additional self.depositpoints when deposited
- X * in the bulding. Be sure to update global.maxscore and scoreRank
- X * if you add treasures (or anything else that gives the player points,
- X * for that matter).
- X *
- X * The proper way to check if an object is a treasure is:
- X *
- X * if (isclass(obj, CCR_treasure_item))
- X * ...
- X *
- X */
- Xclass CCR_treasure_item: CCR_item
- X plural = 'treasures' 'goodies' 'loot'
- X
- X takepoints = 2 // points for taking this treasure
- X depositpoints = 12 // points for putting in building
- X
- X awardedpointsfortaking = nil
- X awardedpointsfordepositing = nil
- X
- X doTake(actor) = {
- X inherited.doTake(actor);
- X
- X //
- X // If we didn't get the object (e.g., if the actor's carrying
- X // too much), don't give points.
- X //
- X if (not self.isIn(actor))
- X return;
- X
- X //
- X // Give the player some points for taking the treasure
- X // the first time.
- X //
- X // If the player removes a treasure from the bulding
- X // floor, reduce his score by the value of that
- X // treasure. (This is to prevent him from dropping
- X // a treasure off, getting the points, and then giving
- X // it to the troll or otherwise losing it.)
- X //
- X if (not self.awardedpointsfortaking) {
- X incscore(self.takepoints);
- X self.awardedpointsfortaking := true;
- X }
- X if (self.awardedpointsfordepositing) {
- X if (self.isIn(Inside_Building)) {
- X incscore(-1 * self.depositpoints);
- X self.awardedpointsfordepositing := nil;
- X
- X // That's one more treasure to deposit.
- X global.treasures := global.treasures + 1;
- X }
- X }
- X }
- X doDrop(actor) = {
- X self.checkpoints;
- X pass doDrop;
- X }
- X
- X checkpoints = {
- X //
- X // Award points for putting treasure in building (unless
- X // we've already awarded the points for depositing this
- X // treasure).
- X //
- X if (Me.isIn(Inside_Building)) {
- X if (not self.awardedpointsfortaking) {
- X //
- X // This shouldn't happen, but just in case...
- X //
- X incscore(self.takepoints);
- X self.awardedpointsfortaking := true;
- X }
- X else if (not self.awardedpointsfordepositing) {
- X incscore(self.depositpoints);
- X self.awardedpointsfordepositing := true;
- X
- X // That's one less treasure to deposit.
- X global.treasures := global.treasures - 1;
- X }
- X }
- X }
- X;
- X
- Xset_of_keys: CCR_item, keyItem
- X sdesc = "set of keys"
- X ldesc = "It's just a normal-looking set of keys."
- X location = Inside_Building
- X noun = 'keys' 'key' 'keyring' 'set'
- X adjective = 'key'
- X;
- X
- Xbrass_lantern: CCR_item, lightsource
- X turnsleft = 330 // expert mode (default)
- X sdesc = "brass lantern"
- X ldesc = {
- X "It is a shiny brass lamp";
- X
- X if (self.islit) {
- X if (self.turnsleft <= 30)
- X ", glowing dimly.";
- X else
- X ", glowing brightly.";
- X }
- X else
- X ". It is not currently lit.";
- X }
- X location = Inside_Building
- X noun = 'lamp' 'headlamp' 'headlight' 'lantern' 'light'
- X
- X ison = nil
- X islit = {
- X if (self.ison and self.turnsleft > 0)
- X return true;
- X else
- X return nil;
- X }
- X
- X verDoRub(actor) = {}
- X doRub(actor) = {
- X "Rubbing the electric lamp is not particularly
- X rewarding. Anyway, nothing exciting happens.";
- X }
- X
- X verDoTurnon(actor) = {
- X if (self.ison)
- X "It's already on.";
- X }
- X doTurnon(actor) = {
- X "The lamp is now on.";
- X self.ison := true;
- X
- X if (self.turnsleft > 0)
- X notify(self, &wearbatteries, 0);
- X else
- X " Unfortunately, the batteries seem to
- X be dead.";
- X }
- X verDoTurnoff(actor) = {
- X if (not self.ison)
- X "It's already off.";
- X }
- X doTurnoff(actor) = {
- X "The lamp is now off.";
- X self.turnoff;
- X }
- X verDoLight(actor) = { self.verDoTurnon(actor); }
- X doLight(actor) = { self.doTurnon(actor); }
- X
- X verIoPutIn(actor) = {}
- X ioPutIn(actor, dobj) = {
- X if (dobj = old_batteries)
- X "Those batteries are dead; they won't
- X do any good at all.";
- X else if (dobj = fresh_batteries)
- X self.do_replace;
- X else
- X "The only thing you might successfully put in
- X the lamp is a fresh pair of batteries.";
- X }
- X
- X // The following method is called when the player gets resurrected.
- X turnoff = {
- X if (self.ison) {
- X self.ison := nil;
- X unnotify(self, &wearbatteries);
- X }
- X }
- X
- X wearbatteries = {
- X self.turnsleft := self.turnsleft - 1;
- X
- X if (self.turnsleft < 1) {
- X P(); I();
- X "Your lamp has run out of power. ";
- X
- X if (self.replace_batteries) {
- X // do nothing
- X }
- X else if (Me.location.isoutside) {
- X "There's not much point in wandering
- X around out here, and you can't
- X explore the cave without a lamp. So
- X let's just call it a day.";
- X
- X call_it_a_day();
- X }
- X }
- X else if (self.turnsleft = 30) {
- X P(); I();
- X "Your lamp is getting dim. ";
- X
- X if (self.replace_batteries) {
- X // do nothing.
- X }
- X else if (fresh_batteries.used) {
- X // DMB: changed the wording of this
- X // slightly for convenience.
- X "You're also out of spare batteries.
- X You'd best start wrapping this up.";
- X }
- X else if (fresh_batteries.location <> nil) {
- X "You'd best go back for those
- X batteries.";
- X }
- X else {
- X "You'd best start wrapping this up,
- X unless you can find some fresh
- X batteries. I seem to recall there's a
- X vending machine in the maze. Bring
- X some coins with you.";
- X }
- X }
- X }
- X
- X replace_batteries = {
- X if (fresh_batteries.isIn(Me.location)) {
- X " I'm taking the liberty of replacing the
- X batteries.";
- X
- X self.do_replace;
- X
- X return true;
- X }
- X else
- X return nil;
- X }
- X
- X do_replace = {
- X fresh_batteries.used := true;
- X fresh_batteries.moveInto(nil);
- X old_batteries.moveInto(Me.location);
- X self.turnsleft := 2500;
- X }
- X;
- X
- Xblack_rod: CCR_item
- X sdesc = "black rod"
- X ldesc = "It's a three foot black rod with a rusty star on an end."
- X location = In_Debris_Room
- X noun = 'rod' 'star'
- X adjective = 'black' 'rusty' 'star'
- X
- X verDoWave(actor) = {}
- X doWave(actor) = {
- X if (self.isIn(West_Side_Of_Fissure) or
- X self.isIn(On_East_Bank_Of_Fissure)) {
- X
- X if (global.closed) {
- X "Peculiar. Nothing happens.";
- X }
- X else {
- X if (CrystalBridge.exists) {
- X "The crystal bridge has
- X vanished!";
- X CrystalBridge.exists := nil;
- X }
- X else {
- X "A crystal bridge now spans
- X the fissure.";
- X CrystalBridge.exists := true;
- X }
- X }
- X }
- X else
- X "Nothing happens.";
- X }
- X;
- X
- Xwicker_cage: CCR_item, container
- X sdesc = "wicker cage"
- X ldesc = {
- X "It's a small wicker cage.";
- X }
- X location = In_Cobble_Crawl
- X noun = 'cage'
- X adjective = 'small' 'wicker' 'bird'
- X
- X verDoPutIn(actor) = {}
- X doPutIn(actor, io) = {
- X if (io <> little_bird) {
- X caps(); self.thedesc; " isn't big enough
- X to hold "; io.thedesc; ".";
- X }
- X else
- X pass doPutIn;
- X }
- X;
- X
- X/*
- X * The following rod is actually an explosive. Don't ask ME how anyone
- X * is supposed to figure this out from the description. I've left it
- X * the way it was even though I think it's pretty bogus.
- X *
- X * I've added the words 'explosive' and 'dynamite' as nouns and adjectives,
- X * and 'blast' as an adjective. Perhaps this will give some lucky soul
- X * a clue.
- X */
- Xblack_mark_rod: CCR_item
- X sdesc = "marked rod"
- X ldesc = {
- X "It's a three foot black rod with a rusty mark on an end.";
- X }
- X location = At_Sw_End
- X noun = 'rod' 'mark' 'explosive' 'dynamite'
- X adjective = 'black' 'rusty' 'mark' 'blast' 'explosive' 'dynamite'
- X
- X verDoWave(actor) = {}
- X doWave(actor) = { "Nothing happens."; }
- X
- X verDoBlastWith(actor) = {}
- X doBlastWith(actor) = { endpuzzle(); }
- X;
- X
- Xlittle_bird: CCR_item
- X sdesc = {
- X if (not self.isIn(wicker_cage))
- X "cheerful ";
- X
- X "little bird";
- X }
- X ldesc = {
- X if (self.isIn(wicker_cage))
- X "The little bird looks unhappy in the cage.";
- X else
- X "The cheerful little bird is sitting here singing.";
- X }
- X location = In_Bird_Chamber
- X noun = 'bird'
- X
- X verDoFeed(actor) = {}
- X doFeed(actor) = {
- X "It's not hungry. (It's merely pinin' for the fjords).
- X Besides, you have no bird seed.";
- X }
- X verIoGiveTo(actor) = {
- X "I suspect it would prefer bird seed.";
- X }
- X
- X /*
- X * Catch any attempt to remove the bird. It won't cooperate
- X * When the player has the rod with the star on the end.
- X */
- X verifyRemove(actor) = {
- X if (self.isIn(Me)) {
- X "You already have the little bird. If
- X you take it out of the cage it will likely
- X fly away from you.";
- X }
- X else if (black_rod.isIn(Me)) {
- X "The bird was unafraid when you entered, but
- X as you approach it becomes disturbed and you
- X cannot catch it.";
- X }
- X else
- X pass verifyRemove;
- X }
- X
- X verDoTake(actor) = {
- X if (not wicker_cage.isIn(Me))
- X "You can catch the bird, but you cannot carry it.";
- X else
- X pass verDoTake;
- X }
- X doTake(actor) = {
- X self.doPutIn(Me, wicker_cage);
- X }
- X
- X verDoPutIn(actor) = {}
- X doPutIn(actor, io) = {
- X if (io <> wicker_cage) {
- X "Don't put the poor bird in "; io.thedesc; "!";
- X }
- X else
- X pass doPutIn;
- X }
- X
- X verDoAttack(actor) = {
- X if (self.isIn(wicker_cage))
- X "Oh, leave the poor unhappy bird alone.";
- X else {
- X "The little bird is now dead. Its body disappears.";
- X self.moveInto(nil);
- X }
- X }
- X
- X verDoDrop(actor) = {}
- X doDrop(actor) = {
- X if (self.isIn(Snake.location)) {
- X "The little bird attacks the green snake, and
- X in an astounding flurry drives the snake
- X away.";
- X
- X Snake.moveInto(nil);
- X self.moveInto(Me.location);
- X }
- X else if (self.isIn(Dragon.location)) {
- X "The little bird attacks the green dragon,
- X and in an astounding flurry gets burnt to a
- X cinder. The ashes blow away.";
- X
- X self.moveInto(nil);
- X }
- X else
- X pass doDrop;
- X }
- X
- X doTakeOut(actor, io) = {
- X // Drop ourselves automatically. (The bird flies away
- X // when taken out of a container.)
- X self.doDrop(actor);
- X }
- X;
- X
- Xvelvet_pillow: CCR_item
- X sdesc = "velvet pillow"
- X ldesc = "It's just a small velvet pillow."
- X location = In_Soft_Room
- X noun = 'pillow'
- X adjective = 'velvet' 'small'
- X;
- X
- Xgiant_bivalve: CCR_item
- X opened = nil
- X
- X sdesc = {
- X if (self.opened)
- X "giant oyster";
- X else
- X "giant clam";
- X
- X if (self.isIn(Me))
- X " >grunt!<";
- X }
- X thedesc = {
- X if (self.opened)
- X "the giant oyster";
- X else
- X "the giant clam";
- X }
- X
- X ldesc = {
- X "It's an enormous clam with its shell tightly closed.";
- X
- X // During the endgame, the oyster has something
- X // written on it.
- X if (self.isIn(At_Ne_End) or self.isIn(At_Sw_End)) {
- X "Interesting. There seems to be something
- X written on the underside of the oyster.";
- X }
- X }
- X location = In_Shell_Room
- X noun = 'clam' 'oyster' 'bivalve' 'shell'
- X adjective = 'giant' 'enormous' 'massive' 'big' 'huge' 'tightly'
- X 'closed' 'five' 'foot' 'five-foot' '5-foot'
- X
- X verDoOpen(actor) = { self.verDoOpenWith(actor, nil); }
- X doOpen(actor) = {
- X if (trident.isIn(Me)) {
- X //
- X // In the original, "open clam" would work
- X // ask long as you were carrying the trident,
- X // but this seems very prone to accidental
- X // solving, and since we aren't limited to
- X // two word parsing, I've just taken the
- X // liberty of forcing the player to type
- X // "open clam with trident."
- X //
- X "You'll need to be a bit more specific that
- X that, I'm afraid.";
- X }
- X else {
- X "You don't have anything strong enough to
- X open "; self.thedesc; ".";
- X }
- X }
- X verDoOpenWith(actor, io) = {
- X if (self.isIn(Me)) {
- X "I advise you to put down "; self.thedesc;
- X " before opening it. >Strain!<";
- X }
- X }
- X doOpenWith(actor, io) = {
- X if (io = trident) {
- X if (self.opened) {
- X "The oyster creaks open, revealing nothing
- X but oyster inside. It promptly snaps shut
- X again.";
- X }
- X else {
- X "A glistening pearl falls out of the clam and
- X rolls away. Goodness, this must really be an
- X oyster. (I never was very good at
- X identifying bivalves.) Whatever it is, it
- X has now snapped shut again.";
- X
- X self.opened := true;
- X pearl.moveInto(In_A_Cul_De_Sac);
- X }
- X }
- X else {
- X caps(); io.thedesc; " isn't strong enough to
- X open "; self.thedesc; ".";
- X }
- X }
- X verDoBreak(actor) = {
- X "The shell is very strong and is impervious to
- X attack.";
- X }
- X verDoAttack(actor) = { self.verDoBreak(actor); }
- X verDoAttackWith(actor, io) = { self.verDoBreak(actor); }
- X
- X //
- X // The oyster has a hint written on its underside once
- X // the cave's closed. (Look, don't ask me, I'm just
- X // porting this game!)
- X //
- X verDoRead(actor) = {
- X if (not self.isIn(At_Ne_End) and not self.isIn(At_Sw_End))
- X "You're babbling -- snap out of it!";
- X }
- X doRead(actor) = {
- X //
- X // This is supposed to be a hint (i.e., it's supposed
- X // to cost points), but I've put it in as a freebie
- X // because I think the final puzzle is absurdly
- X // difficult even with the free hint.
- X //
- X "It says, \"There is something strange about this
- X place, such that one of the words I've always known
- X now has a new effect.\"";
- X }
- X;
- X
- Xspelunker_today: CCR_item, readable
- X sdesc = "recent issues of \"Spelunker Today\""
- X adesc = { self.sdesc; }
- X ldesc = { self.readdesc; }
- X readdesc = {
- X // This said "magazine is written" in the original,
- X // which is obviously wrong given the sdesc.
- X
- X "I'm afraid the magazines are written in Dwarvish.";
- X }
- X
- X location = In_Anteroom
- X plural = 'magazines'
- X noun = 'magazine' 'issue' 'issue' 'spelunker'
- X 'today' 'dwarvish'
- X adjective = 'spelunker' 'today' 'dwarvish'
- X
- X doDrop(actor) = {
- X if (Me.isIn(At_Witts_End))
- X silent_incscore(global.wittpoints);
- X
- X pass doDrop;
- X }
- X doTake(actor) = {
- X if (Me.isIn(At_Witts_End))
- X silent_incscore(-1 * global.wittpoints);
- X
- X pass doTake;
- X }
- X;
- X
- Xtasty_food: CCR_item, fooditem
- X sdesc = "some tasty food"
- X adesc = { self.sdesc; }
- X thedesc = "the tasty food"
- X ldesc = "Sure looks yummy!"
- X location = Inside_Building
- X noun = 'food' 'ration' 'rations' 'tripe'
- X adjective = 'yummy' 'tasty' 'delicious' 'scrumptious'
- X;
- X
- Xbottle: CCR_item
- X haswater = true
- X hasoil = nil
- X
- X sdesc = {
- X if (self.haswater)
- X "small bottle of water";
- X else if (self.hasoil)
- X "small bottle of oil";
- X else
- X "small empty bottle";
- X }
- X location = Inside_Building
- X noun = 'bottle' 'jar' 'flask'
- X
- X verIoPutIn(actor) = {}
- X ioPutIn(actor, dobj) = {
- X if (self.haswater)
- X "The bottle is already full of water.";
- X else if (self.hasoil)
- X "The bottle is already full of oil.";
- X else if (dobj = Stream) {
- X "The bottle is now full of water.";
- X self.haswater := true;
- X }
- X else if (dobj = Oil) {
- X "The bottle is now full of oil.";
- X self.hasoil := true;
- X }
- X else {
- X "I'm not sure how to do that.";
- X }
- X }
- X
- X verDoFill(actor) = {}
- X doFill(actor) = {
- X if (self.isIn(Stream.location))
- X self.ioPutIn(actor, Stream);
- X else if (self.isIn(Oil.location))
- X self.ioPutIn(actor, Oil);
- X else
- X "There is nothing here with which to fill the
- X bottle.";
- X }
- X
- X verDoEmpty(actor) = {}
- X doEmpty(actor) = {
- X if (self.haswater or self.hasoil)
- X "Your bottle is now empty and the ground is
- X now wet.";
- X else
- X "The bottle is already empty!";
- X
- X self.empty;
- X }
- X
- X verDoPourOn(actor, io) = {}
- X doPourOn(actor, io) = {
- X if (io = RustyDoor) {
- X if (self.hasoil) {
- X "The oil has freed up the hinges so that the
- X door will now move, although it requires some
- X effort.";
- X
- X RustyDoor.isoiled := true;
- X }
- X else if (self.haswater) {
- X "The hinges are quite thoroughly
- X rusted now and won't budge.";
- X }
- X else {
- X "The bottle is empty.";
- X }
- X
- X self.empty;
- X }
- X else if (io = Plant) {
- X if (self.haswater) {
- X Plant.water;
- X }
- X else if (self.hasoil) {
- X "The plant indignantly shakes the oil
- X off its leaves and asks, \"Water?\"";
- X }
- X else {
- X "The bottle is empty.";
- X }
- X
- X self.empty;
- X }
- X else if (io = theFloor)
- X self.doEmpty(actor);
- X else
- X "That doesn't seem productive.";
- X }
- X
- X verDoDrink(actor) = {
- X if (not self.hasoil and not self.haswater)
- X "The bottle is empty.";
- X
- X if (self.hasoil)
- X "Don't drink the oil, you fool!";
- X }
- X doDrink(actor) = {
- X "The bottle is now empty.";
- X self.empty;
- X }
- X
- X empty = {
- X self.haswater := nil;
- X self.hasoil := nil;
- X }
- X;
- Xwater_in_the_bottle: CCR_decoration
- X sdesc = "water in the bottle"
- X adesc = "water"
- X ldesc = "It looks like ordinary water to me."
- X locationOK = true // tell compiler OK for location to be method
- X location = {
- X if (bottle.haswater)
- X return bottle.location;
- X else
- X return nil;
- X }
- X noun = 'water' 'h2o'
- X
- X verDoPourOn(actor, io) = {}
- X doPourOn(actor, io) = { bottle.doPourOn(actor, io); }
- X verDoDrink(actor) = { bottle.verDoDrink(actor); }
- X doDrink(actor) = { bottle.doDrink(actor); }
- X;
- Xoil_in_the_bottle: CCR_decoration
- X sdesc = "oil in the bottle"
- X adesc = "oil"
- X ldesc = "It looks like ordinary oil to me."
- X locationOK = true // tell compiler OK for location to be method
- X location = {
- X if (bottle.hasoil)
- X return bottle.location;
- X else
- X return nil;
- X }
- X noun = 'oil' 'lubricant' 'grease'
- X
- X verDoPourOn(actor, io) = {}
- X doPourOn(actor, io) = { bottle.doPourOn(actor, io); }
- X verDoDrink(actor) = { bottle.verDoDrink(actor); }
- X doDrink(actor) = { bottle.doDrink(actor); }
- X;
- X
- Xaxe: CCR_item
- X nograb = nil // hack for when you attack the bear with it
- X
- X sdesc = "dwarf's axe"
- X ldesc = {
- X if (self.nograb)
- X "It's lying beside the bear.";
- X else
- X "It's just a little axe.";
- X }
- X location = nil // created when first dwarf attacks
- X noun = 'axe'
- X adjective = 'little' 'dwarf' 'dwarvish' 'dwarven' 'dwarf\'s'
- X
- X verifyRemove(actor) = {
- X if (self.nograb)
- X "No chance. It's lying beside the ferocious
- X bear, quite within harm's way.";
- X }
- X;
- X
- Xfresh_batteries: CCR_item
- X used = nil // used in lamp yet?
- X
- X sdesc = "fresh batteries"
- X ldesc = {
- X "They look like ordinary batteries. (A sepulchral
- X voice says, \"Still going!\")";
- X }
- X noun = 'batteries' 'battery' 'duracel' 'duracell' 'duracels'
- X 'duracells' 'energizer' 'energizers' 'everready'
- X 'everreadies' 'eveready' 'evereadies'
- X adjective = 'fresh'
- X
- X location = nil
- X;
- X
- Xold_batteries: CCR_item
- X sdesc = "worn-out batteries"
- X ldesc = {
- X "They look like ordinary batteries.";
- X }
- X noun = 'batteries' 'battery' 'duracel' 'duracell' 'duracels'
- X 'duracells' 'energizer' 'energizers' 'everready'
- X 'everreadies' 'eveready' 'evereadies'
- X adjective = 'worn' 'out' 'worn-out' 'dead' 'empty' 'dry' 'old'
- X
- X location = nil
- X;
- X
- X/*
- X * Treasures
- X */
- Xlarge_gold_nugget: CCR_treasure_item
- X depositpoints = 10
- X sdesc = "large gold nugget"
- X ldesc = "It's a large sparkling nugget of gold!"
- X location = In_Nugget_Of_Gold_Room
- X noun = 'gold' 'nugget'
- X adjective = 'gold' 'large'
- X;
- Xseveral_diamonds: CCR_treasure_item
- X depositpoints = 10
- X sdesc = "several diamonds"
- X adesc = { self.sdesc; }
- X thedesc = "the diamonds"
- X ldesc = "They look to be of the highest quality!"
- X location = West_Side_Of_Fissure
- X noun = 'diamond' 'diamonds'
- X adjective = 'several' 'high' 'quality' 'high-quality'
- X;
- Xbars_of_silver: CCR_treasure_item
- X depositpoints = 10
- X sdesc = "bars of silver"
- X adesc = { self.sdesc; }
- X ldesc = "They're probably worth a fortune!"
- X location = Low_N_S_Passage
- X noun = 'silver' 'bars'
- X adjective = 'silver'
- X;
- Xprecious_jewelry: CCR_treasure_item
- X depositpoints = 10
- X sdesc = "precious jewelry"
- X adesc = { self.sdesc; }
- X ldesc = "It's all quite exquisite!"
- X location = In_South_Side_Chamber
- X noun = 'jewel' 'jewels' 'jewelry'
- X adjective = 'precious' 'exquisite'
- X;
- Xrare_coins: CCR_treasure_item
- X depositpoints = 10
- X sdesc = "rare coins"
- X adesc = { self.sdesc; }
- X ldesc = "They're a numismatist's dream!"
- X location = In_West_Side_Chamber
- X noun = 'coins'
- X adjective = 'rare'
- X;
- Xtreasure_chest: CCR_treasure_item
- X spotted = nil // found yet? See also Dead_End_13 in ccr-room.t
- X
- X depositpoints = 12
- X sdesc = "treasure chest"
- X ldesc = {
- X "It's the pirate's treasure chest, filled with
- X riches of all kinds!";
- X }
- X location = nil
- X noun = 'chest' 'box' 'treasure' 'riches'
- X adjective = 'pirate' 'pirate\'s' 'treasure'
- X;
- Xgolden_eggs: CCR_treasure_item
- X depositpoints = 14
- X sdesc = "nest of golden eggs"
- X ldesc = "The nest is filled with beautiful golden eggs!"
- X location = In_Giant_Room
- X noun = 'eggs' 'egg' 'nest'
- X adjective = 'golden' 'beautiful'
- X;
- Xtrident: CCR_treasure_item
- X depositpoints = 14
- X sdesc = "jeweled trident"
- X ldesc = "The trident is covered with fabulous jewels!"
- X location = In_Cavern_With_Waterfall
- X noun = 'trident'
- X adjective = 'jeweled' 'jewel-encrusted' 'encrusted' 'fabulous'
- X
- X verIoOpenWith(actor) = {}
- X ioOpenWith(actor, dobj) = {
- X dobj.doOpenWith(actor, self);
- X }
- X;
- Xming_vase: CCR_treasure_item
- X depositpoints = 14
- X sdesc = "ming vase"
- X ldesc = {
- X "It's a delicate, previous, ming vase!";
- X }
- X location = In_Oriental_Room
- X noun = 'vase' 'ming' 'shards' 'pottery'
- X
- X doDrop(actor) = {
- X if (velvet_pillow.isIn(Me.location)) {
- X "The vase is now resting, delicately, on a
- X velvet pillow.";
- X
- X self.moveInto(Me.location);
- X
- X self.checkpoints; // make sure we count points
- X // for putting this in building
- X }
- X else {
- X "The ming vase drops with a delicate crash.";
- X self.shatter;
- X }
- X }
- X
- X verIoPutIn(actor) = {}
- X ioPutIn(actor, dobj) = {
- X if (dobj = Stream or dobj = Oil) {
- X "The sudden change in temperature has
- X delicately shattered the vase.";
- X
- X self.shatter;
- X }
- X else {
- X "I'm not sure how to do that.";
- X }
- X }
- X
- X verDoFill(actor) = {}
- X doFill(actor) = {
- X if (self.isIn(Stream.location))
- X self.ioPutIn(actor, Stream);
- X else if (self.isIn(Oil.location))
- X self.ioPutIn(actor, Oil);
- X else
- X "There is nothing here with which to fill the
- X vase.";
- X }
- X
- X verDoBreak(actor) = {}
- X doBreak(actor) = {
- X "You have taken the vase and hurled it delicately to
- X the ground.";
- X
- X self.shatter;
- X }
- X
- X shatter = {
- X self.moveInto(nil);
- X shards.moveInto(Me.location);
- X }
- X;
- Xshards: CCR_item
- X sdesc = "some worthless shards of pottery"
- X adesc = { self.sdesc; }
- X ldesc = {
- X "They're just worthless shards of pottery";
- X
- X if (self.location = Me.location) // not in a container
- X ", littered everywhere.";
- X else
- X ".";
- X
- X " They look to be the remains of what was once a
- X beautiful vase. I guess some oaf must have dropped it.";
- X }
- X
- X noun = 'pottery' 'shards'
- X adjective = 'worthless'
- X;
- X
- Xegg_sized_emerald: CCR_treasure_item
- X depositpoints = 14
- X sdesc = "emerald the size of a plover's egg"
- X adesc = { "an "; self.sdesc; }
- X ldesc = "Plover's eggs, by the way, are quite large."
- X location = In_Plover_Room
- X noun = 'emerald'
- X adjective = 'egg-sized'
- X;
- Xplatinum_pyramid: CCR_treasure_item
- X depositpoints = 14
- X sdesc = "platinum pyramid"
- X ldesc = "The platinum pyramid is 8 inches on a side!"
- X location = In_Dark_Room
- X noun = 'platinum' 'pyramid'
- X adjective = 'platinum' 'pyramidal'
- X;
- Xpearl: CCR_treasure_item
- X depositpoints = 14
- X sdesc = "glistening pearl"
- X ldesc = "It's incredibly large!"
- X location = nil
- X noun = 'pearl'
- X adjective = 'glistening' 'incredible' 'incredibly' 'large'
- X;
- Xpersian_rug: CCR_treasure_item
- X depositpoints = 14
- X sdesc = {
- X "Persian rug";
- X
- X if (self.isIn(Dragon.location))
- X " (upon which the dragon is sprawled out)";
- X }
- X adesc = {
- X "a "; self.sdesc;
- X }
- X ldesc = {
- X if (self.isIn(Dragon.location))
- X "The dragon is sprawled out on the Persian rug!!";
- X else if (not self.isIn(Me))
- X "The Persian rug is spread out on the floor here.";
- X else
- X "The Persian rug is the finest you've ever seen!";
- X }
- X location = In_Secret_Canyon
- X noun = 'rug' 'persian'
- X adjective = 'persian' 'fine' 'finest' 'dragon\'s'
- X
- X verifyRemove(actor) = {
- X if (self.isIn(Dragon.location))
- X "You'll need to get the dragon to move first!";
- X }
- X;
- Xrare_spices: CCR_treasure_item
- X depositpoints = 14
- X sdesc = "rare spices"
- X adesc = { self.sdesc; }
- X ldesc = "They smell wonderfully exotic!"
- X location = In_Chamber_Of_Boulders
- X noun = 'spices' 'spice'
- X adjective = 'rare' 'exotic'
- X
- X verDoSmell(actor) = {}
- X doSmell(actor) = { self.ldesc; }
- X;
- Xgolden_chain: CCR_treasure_item, keyedLockable
- X depositpoints = 14
- X isfixed = {
- X if (self.islocked)
- X return true;
- X else
- X return nil;
- X }
- X isListed = { return not self.isfixed; }
- X
- X mykey = set_of_keys // pretty handy, those!
- X islocked = true // locked meaning "locked to the wall."
- X isopen = nil // need this since we're keyedLockable
- X
- X sdesc = "golden chain"
- X ldesc = {
- X "The chain has thick links of solid gold!";
- X
- X if (self.islocked) {
- X if (Bear.wasreleased)
- X "It's locked to the wall!";
- X else
- X " The bear is chained to the wall with it!";
- X }
- X }
- X heredesc = {
- X if (self.isfixed) {
- X P(); I();
- X if (Bear.wasreleased)
- X "There is a golden chain here, locked
- X to the wall.";
- X else
- X "There is a golden chain here, and a
- X large cave bear is locked to the wall
- X with it!";
- X }
- X }
- X
- X location = In_Barren_Room
- X noun = 'chain' 'links' 'shackles'
- X adjective = 'solid' 'gold' 'golden' 'thick'
- X
- X verDoLock(actor) = {
- X if (not self.isIn(In_Barren_Room)) {
- X "There is nothing here to which the chain can
- X be locked.";
- X }
- X else
- X pass verDoLock;
- X }
- X verDoLockWith(actor, io) = {
- X self.verDoLock(actor); // -> pass verDoLock (OK?)
- X pass verDoLockWith;
- X }
- X
- X verDoUnlock(actor) = {
- X if (not Bear.wasreleased and not Bear.istame) {
- X "There is no way to get past the bear to
- X unlock the chain, which is probably just as
- X well.";
- X }
- X else
- X pass verDoUnlock;
- X }
- X verDoUnlockWith(actor, io) = {
- X self.verDoUnlock(actor);
- X pass verDoUnlockWith;
- X }
- X
- X // inherit proper doUnlock from keyedLockable
- X doUnlockWith(actor, io) = {
- X Bear.wasreleased := true;
- X pass doUnlockWith;
- X }
- X
- X verifyRemove(actor) = {
- X if (not Bear.wasreleased) {
- X if (Bear.istame)
- X "It's locked to the friendly bear.";
- X else
- X "It's locked to the ferocious bear!";
- X }
- X else if (self.islocked)
- X "The chain is still locked to the wall.";
- X }
- X;
- END_OF_FILE
- if test 26875 -ne `wc -c <'src/ccr-item.t'`; then
- echo shar: \"'src/ccr-item.t'\" unpacked with wrong size!
- fi
- # end of 'src/ccr-item.t'
- fi
- if test -f 'src/ccr-npc.t' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/ccr-npc.t'\"
- else
- echo shar: Extracting \"'src/ccr-npc.t'\" \(25988 characters\)
- sed "s/^X//" >'src/ccr-npc.t' <<'END_OF_FILE'
- X/*
- X * Colossal Cave Revisited
- X *
- X * A remake of Willie Crowther and Don Woods' classic Adventure.
- X * Converted from Donald Ekman's PC port of the original FORTRAN source.
- X * TADS version by David M. Baggett for ADVENTIONS.
- X *
- X * Please document all changes in the history so we know who did what.
- X *
- X * This source code is copylefted under the terms of the GNU Public
- X * License. Essentially, this means that you are free to do whatever
- X * you wish with this source code, provided you do not charge any
- X * money for it or for any derivative works.
- X *
- X * ADVENTIONS distributes this game, but you are free to do what you will
- X * with it, provided you adhere to the terms in the GNU Public License.
- X * Send correspondence regarding this game or original works distributed
- X * by ADVENTIONS to
- X *
- X * ADVENTIONS
- X * PO Box 851
- X * Columbia, MD 21044
- X *
- X * If you would like a catalog of releases, please enclose a SASE. Thanks!
- X *
- X * Contributors
- X *
- X * dmb In real life: David M. Baggett
- X * Internet: <dmb@ai.mit.edu>
- X * Compu$erve: 76440,2671 (ADVENTIONS account)
- X * GEnie: ADVENTIONS
- X *
- X * Modification History
- X *
- X * 1-Jan-93 dmb rec.arts.int-fiction BETA release (source only)
- X * For beta testing only -- not for general
- X * distribution.
- X * 20-Apr-93 dmb Incorporated Mike Roberts' changes to make
- X * this a lot faster. Uses the new intersect
- X * built-in, so CCR must now be built with TADS
- X * >= 2.0.13.
- X *
- X */
- X
- X/*
- X * This file handles non-player character (dwarves and pirate) movement.
- X *
- X * Be sure to update exitlist and/or npclist if you add any new travel
- X * verbs to CCR_Room.
- X */
- XinitNPC: function
- X{
- X local o;
- X
- X //
- X // Construct list of NPC exits for each room
- X //
- X o := firstobj(CCR_room);
- X while (o <> nil) {
- X if (not o.noNPCs) {
- X //
- X // Add this room to the global list of rooms
- X // the NPC's can be in.
- X //
- X global.NPCrooms := global.NPCrooms + o;
- X
- X do_exitlist(o);
- X do_npclist(o);
- X }
- X else if (global.debug) {
- X //
- X // Debugging info:
- X //
- X "\b\"<< o.sdesc >>\" is off limits to NPC's.";
- X }
- X
- X o := nextobj(o, CCR_room);
- X }
- X}
- X
- X/*
- X * Add standard exits to the list of exits that NPC's should check
- X * when they're wandering about randomly.
- X */
- Xdo_exitlist: function(o)
- X{
- X local exitlist, i, j, gotit;
- X local tot1, tot2;
- X
- X //
- X // List of all exit property names that NPC's will consider.
- X // Note that magic words are left out because NPC's don't
- X // know them.
- X //
- X exitlist := [
- X &north &south &east &west
- X &ne &nw &se &sw
- X &up &down &in &out
- X
- X &jump &upstream &downstream &forwards &outdoors
- X &left &right &cross &over &across &road &forest
- X &valley &stairs &building &gully &stream &rock &bed
- X &crawl &cobble &tosurface &dark &passage &low &canyon
- X &awkward &giant &view &pit &crack &steps &dome &hall
- X &barren &debris &hole &wall &broken &floor &toroom
- X &slit &slab &depression &entrance &secret &cave
- X &bedquilt &oriental &cavern &shell &reservoir &main
- X &office &fork
- X ];
- X tot1 := length(exitlist);
- X
- X for (i := 1; i <= tot1; i++) {
- X //
- X // If this exit property is a simple
- X // object (prop 2), NPC's can use it, so
- X // add it to the room's NPC exit list.
- X //
- X // Make sure we don't add the same
- X // desination room twice. Just because
- X // there are multiple travel verbs from
- X // one place to another doesn't mean the
- X // destination should be more likely.
- X //
- X if (proptype(o, exitlist[i]) = 2
- X and not o.(exitlist[i]).noNPCs) {
- X
- X //
- X // Search current exitlist for
- X // this exit's destination.
- X //
- X gotit := (find(o.NPCexits, o.(exitlist[i])) <> nil);
- X if (not gotit)
- X o.NPCexits := o.NPCexits + exitlist[i];
- X }
- X }
- X}
- X
- X/*
- X * Add NPC special exits to the list of exits that NPC's should check
- X * when they're wandering about randomly.
- X */
- Xdo_npclist: function(o)
- X{
- X local npclist, i, tot;
- X
- X //
- X // NPC exits. These get considered if even if they're methods.
- X // The only way they won't be added to the list of exits to
- X // try is if they're = nil and not methods.
- X //
- X npclist := [
- X &NPCexit1 &NPCexit2 &NPCexit3 &NPCexit4
- X &NPCexit5 &NPCexit6 &NPCexit7 &NPCexit8
- X ];
- X
- X tot := length(npclist);
- X for (i := 1; i <= tot; i++) {
- X //
- X // If this NPC exit property is anything but
- X // nil (i.e., just nil, and not a method
- X // that returns nil). then NPC's can use it.
- X // Methods that return nil are fine because
- X // they might be conditional on some game
- X // events, like the crystal bridge having
- X // been created, etc.
- X //
- X if (proptype(o, npclist[i]) <> 5) // not = nil
- X o.NPCexits := o.NPCexits + npclist[i];
- X }
- X}
- X
- X/*
- X * Make sure NPC room connections are sound.
- X */
- Xcheck_connections: function
- X{
- X local o;
- X
- X o := firstobj(CCR_room);
- X while (o <> nil) {
- X if (not o.noNPCs)
- X do_debug(o);
- X
- X o := nextobj(o, CCR_room);
- X }
- X}
- X
- Xdo_debug: function(o)
- X{
- X local i, tot;
- X
- X if (length(o.NPCexits) = 0) {
- X P(); I();
- X "Oh dear, someone seems to have damaged one of my
- X room connections. The room \"";
- X
- X o.sdesc;
- X
- X "\" has no exits for NPC's to follow, but it's not
- X listed as off limits to NPC's. Please notify the
- X cave management as soon as possible!";
- X }
- X else if (global.debug) {
- X //
- X // Debugging info:
- X //
- X "\b\""; o.sdesc; "\" has "; say(length(o.NPCexits));
- X if (length(o.NPCexits) > 1)
- X " NPC exits:";
- X else
- X " NPC exit:";
- X
- X tot := length(o.NPCexits);
- X for (i := 1; i <= tot; i++) {
- X "\b\t-> ";
- X if (o.(o.NPCexits[i]))
- X o.(o.NPCexits[i]).sdesc;
- X else
- X "(nil)";
- X }
- X }
- X}
- X
- X/*
- X * A class defining some common things for NPC's.
- X */
- Xclass NPC: object
- X //
- X // List of currect pirate locations.
- X //
- X loclist = [] // where they are
- X newloclist = [] // where they're going
- X
- X //
- X // Scatter any NPC's that are currently in
- X // the room to random rooms in the cave. (We
- X // have to make sure the new rooms aren't off
- X // limits to dwarves, though.)
- X //
- X scatter = {
- X local i, dest, len, r, tot;
- X local melocs;
- X
- X for (melocs := [], i := Me.location ; i ; i := i.location)
- X melocs += i;
- X if (length(intersect(melocs, self.loclist))) return;
- X
- X self.newloclist := [];
- X tot := length(self.loclist);
- X len := length(global.NPCrooms);
- X for (i := 1; i <= tot; i++) {
- X if (find(melocs, self.loclist[i])) {
- X //
- X // Make sure we get a real location.
- X //
- X dest := nil;
- X while (dest = nil) {
- X r := rand(len);
- X dest := global.NPCrooms[r];
- X }
- X
- X self.newloclist += dest;
- X }
- X else {
- X self.newloclist += self.loclist[i];
- X }
- X
- X }
- X self.loclist := self.newloclist;
- X }
- X
- X //
- X // Returns true if any NPC's of this type are in locations
- X // adjacent to the player. (I.e., if any NPC's could take
- X // any exit that would bring them to the player's current
- X // location.)
- X //
- X anyadjacent = {
- X local adjacent, i, j, len, dir, dest, melocs;
- X local tot1;
- X local cur;
- X
- X//"\nanyadjacent(enter)\n";
- X for (melocs := [], i := Me.location ; i ; i := i.location)
- X melocs += i;
- X
- X adjacent := nil;
- X tot1 := length(self.loclist);
- X for (i := 1; i <= tot1; i++) {
- X len := length(self.loclist[i].NPCexits);
- X cur := self.loclist[i];
- X for (j := 1; j <= len; j++) {
- X dest := cur.(cur.NPCexits[j]);
- X
- X //
- X // We need to check the destination
- X // to be sure it exists. It may be
- X // nil if we called an NPCexit method.
- X //
- X if (dest) if (find(melocs, dest)) {
- X adjacent := true;
- X break;
- X }
- X }
- X
- X //
- X // If we've found an adjacent pirate we
- X // can stop looking.
- X //
- X if (adjacent)
- X break;
- X }
- X
- X//"\nanyadjacent(exit)\n";
- X return adjacent;
- X }
- X;
- X
- X/*
- X * Move the dwarves. See the global object in ccr-std.t for paramters.
- X */
- XDwarves: NPC, Actor
- X rhetoricalturn = -999 // hack -- see yesVerb in ccr-verbs.t
- X attackers = 0 // number of dwarves that attack this turn
- X
- X sdesc = "threatening little dwarf"
- X ldesc = {
- X "It's probably not a good idea to get too close. Suffice
- X it to say the little guy's pretty aggressive.";
- X }
- X
- X noun = 'dwarf' 'dwarves' 'guy'
- X adjective = 'threatening' 'nasty' 'little' 'mean'
- X
- X //
- X // We don't use actorDesc for the dwarves because it gets printed
- X // too early. (We want to let the player know that a dwarf is
- X // in the room as soon as the dwarf moves into the room, not at
- X // the start of the next turn.)
- X //
- X actorDesc = {}
- X
- X locationOK = true // tell compiler OK for location to be method
- X location = {
- X local i, melocs;
- X
- X for (melocs := [], i := Me.location ; i ; i := i.location)
- X melocs += i;
- X if (length(intersect(melocs, self.loclist)) = 0)
- X return(nil);
- X
- X //
- X // Check each dwarf's location. If at least one dwarf
- X // is in the same location as the player, make our
- X // location the same as the player's.
- X //
- X for (i := 1; i <= length(self.loclist); i++)
- X if (find(melocs, self.loclist[i]))
- X return self.loclist[i];
- X
- X return nil;
- X }
- X
- X verDoKick(actor) = {}
- X doKick(actor) = {
- X "You boot the dwarf across the room. He curses, then
- X gets up and brushes himself off. Now he's madder
- X than ever!";
- X }
- X verDoAttack(actor) = {
- X if (not axe.isIn(Me)) {
- X "With what? Your bare hands?";
- X self.rhetoricalturn := global.turnsofar;
- X }
- X }
- X doAttack(actor) = { self.doAttackWith(actor, axe); }
- X
- X //
- X // The following method is called when the player responds, "yes"
- X // to "With what? Your bare hands?"
- X //
- X nicetry = { "You wish."; }
- X
- X verDoAttackWith(actor, io) = {}
- X doAttackWith(actor, io) = {
- X //
- X // If the player throws the axe at the dwarf, he
- X // might reduce the dwarf to a cloud of greasy
- X // black smoke.
- X //
- X if (io = axe) {
- X if (rand(100) <= global.dwarfhit) {
- X "You killed a little dwarf. The body
- X vanishes in a cloud of greasy black
- X smoke.";
- X
- X //
- X // Remove this location from our list
- X // of locations where dwarves are.
- X //
- X self.loclist -= self.location;
- X }
- X else {
- X "You attack a little dwarf, but he
- X dodges out of the way.";
- X }
- X
- X axe.moveInto(Me.location);
- X }
- X else if (io = Hands)
- X self.nicetry;
- X else
- X "Somehow I doubt that'll be very effective.";
- X }
- X
- X verIoGiveTo(actor) = {}
- X ioGiveTo(actor, dobj) = {
- X if (dobj = tasty_food) {
- X self.doFeed(Me);
- X }
- X else {
- X "The dwarf is not at all interested in your
- X offer. (The reason being, perhaps, that if
- X he kills you he gets everything you have
- X anyway.)";
- X }
- X }
- X
- X verIoThrowAt(actor) = { self.verIoGiveTo(actor); }
- X ioThrowAt(actor, dobj) = {
- X if (dobj = axe)
- X self.doAttackWith(actor, dobj);
- X else
- X self.ioGiveTo(actor, dobj);
- X }
- X verIoThrowTo(actor) = { self.verIoGiveTo(actor); }
- X ioThrowTo(actor, dobj) = {
- X if (dobj = axe)
- X self.doAttackWith(actor, dobj);
- X else
- X self.ioGiveTo(actor, dobj);
- X }
- X
- X verDoFeed(actor) = {}
- X doFeed(actor) = {
- X if (tasty_food.isIn(Me)) {
- X "You fool, dwarves eat only coal! Now you've
- X made him *really* mad!!";
- X }
- X else {
- X "You have no food to give the dwarf.";
- X }
- X }
- X
- X //
- X // Place dwarves in starting locations.
- X //
- X place = {
- X local i, loc, r;
- X
- X self.loclist := [];
- X for (i := 1; i <= global.dwarves; i++) {
- X //
- X // If there are any fixed starting locations
- X // for dwarves left, put this dwarf in the
- X // next one. Otherwise place him randomly.
- X //
- X loc := nil;
- X if (length(global.dwarfloc) >= i)
- X loc := global.dwarfloc[i];
- X
- X //
- X // Invalidate initial location if it's off limits
- X // to NPC's.
- X //
- X if (loc)
- X if (loc.noNPCs)
- X loc := nil;
- X
- X //
- X // Make sure we get a real location.
- X //
- X while (loc = nil) {
- X r := rand(length(global.NPCrooms));
- X loc := global.NPCrooms[r];
- X }
- X
- X //
- X // Add this dwarf's location to the list.
- X //
- X self.loclist := self.loclist + loc;
- X }
- X }
- X
- X //
- X // Move dwarves.
- X //
- X move = {
- X local i, j, len, r, dest, done, dir, loc;
- X local melocs;
- X//"\ndwarves.move(enter)\n";
- X
- X //
- X // Move each remaining dwarf.
- X //
- X // If the dwarf is currently in the player's location,
- X // he stays where he is.
- X //
- X // If a dwarf is in a location adjacent to the player's
- X // current location, he moves into the player's location
- X // if he can. (We check his possible exits to see if
- X // any of them go the player's location.) A consequence
- X // of this is that dwarves will follow the player
- X // relentlessly once they've spotted him. (But the global
- X // value dwarftenacity can be set to prevent dwarves
- X // from *always following*, of course.)
- X //
- X // If a dwarf isn't adjacent to the player, he just moves
- X // around randomly.
- X //
- X
- X for (melocs := [], i := Me.location ; i ; i := i.location)
- X melocs += i;
- X
- X self.newloclist := [];
- X self.attackers := 0; // assume no dwarves attack this turn
- X for (i := length(self.loclist); i > 0; i--) {
- X //
- X // Get a copy of this dwarf's location for speed.
- X //
- X loc := self.loclist[i];
- X
- X //
- X // Haven't found a new location yet.
- X //
- X done := nil;
- X
- X //
- X // In player's current location?
- X //
- X if (find(melocs, loc)) {
- X dest := loc; // stay put
- X done := true;
- X }
- X
- X //
- X // Try each exit and see if we can reach the
- X // player. If we have an exit that leads to
- X // the player, we know it's an OK destination
- X // location, since we pruned off all the noNPCs
- X // rooms when we constructed the exit lists.
- X //
- X len := length(loc.NPCexits);
- X if (not done) for (j := len; j > 0; j--) {
- X dir := loc.NPCexits[j];
- X dest := loc.(dir);
- X
- X //
- X // We need to check the destination
- X // to be sure it exists. It may be
- X // nil if we called an NPCexit method.
- X //
- X if (dest <> nil and find(melocs, dest) <> nil)
- X {
- X //
- X // Is this dwarf tenacious enough
- X // to follow the player?
- X //
- X if (rand(100) <= global.dtenacity)
- X done := true;
- X break;
- X }
- X }
- X
- X //
- X // Have we found a destination yet? If not,
- X // move dwarf to a randomly selected adjacent
- X // location.
- X //
- X // We need to check the destination because
- X // the NPCexit methods in the rooms can sometimes
- X // return nil. (For example, when the crystal
- X // bridge doesn't exist yet, the giant's door
- X // has not been opened, etc.)
- X //
- X while (not done) {
- X dir := loc.NPCexits[rand(len)];
- X dest := loc.(dir);
- X
- X if (dest)
- X done := true;
- X }
- X
- X //
- X // Set new destination.
- X //
- X self.newloclist += dest;
- X
- X //
- X // If the dwarf didn't move, he has an opportunity
- X // to attack.
- X //
- X if (loc = dest) {
- X if (find(melocs, loc))
- X if (rand(100) <= global.dwarfattack)
- X self.attackers++;
- X
- X //
- X // Print some debugging info if in debug mode
- X //
- X if (global.debug) {
- X P();
- X "Dwarf stays \""; dest.sdesc; ".\"\n";
- X }
- X }
- X else {
- X //
- X // Print some debugging info if in debug mode
- X //
- X if (global.debug) {
- X P();
- X "Dwarf moves from \"";
- X self.loclist[i].sdesc; "\" to \"";
- X dest.sdesc; ".\"\n";
- X }
- X }
- X }
- X
- X //
- X // Replace old locations with destinations.
- X //
- X self.loclist := self.newloclist;
- X
- X self.tell;
- X//"\ndwarves.move(exit)\n";
- X }
- X
- X //
- X // Tell the player what's going on with the dwarves.
- X //
- X tell = {
- X local i, j, len, r, dest, done, dir, count, adjacent;
- X local melocs;
- X//"\ntell(enter)\n";
- X //
- X // Count how many dwarves are in the room with the player.
- X //
- X for (melocs := [], i := Me.location ; i ; i := i.location)
- X melocs += i;
- X count := length(intersect(melocs, self.loclist));
- X
- X //
- X // If any dwarves are in the room with the player and
- X // the axe hasn't been thrown yet, throw the axe and
- X // scatter the dwarves.
- X //
- X if (count > 0 and axe.location = nil) {
- X P(); I();
- X
- X "A little dwarf just walked around a corner,
- X saw you, threw a little axe at you which
- X missed, cursed, and ran away.";
- X
- X axe.moveInto(self.location);
- X
- X //
- X // Scatter any dwarves in the room.
- X //
- X self.scatter;
- X
- X //
- X // No dwarves in the room. Be sure we take back
- X // those attacks too...
- X //
- X count := 0;
- X self.attackers := 0;
- X }
- X
- X //
- X // Tell the player if any dwarves are in the room with him,
- X // or if any are nearby.
- X //
- X if (count = 0) {
- X //
- X // If no dwarves are in the room, but at least
- X // one dwarf is in an adjacent location, tell
- X // the player he hears something.
- X //
- X // (Only the pirate makes noise in the original,
- X // which seem a bit strange and not as much fun.)
- X //
- X if (self.anyadjacent) {
- X P(); I(); "You hear the pitter-patter
- X of little feet.";
- X }
- X }
- X else if (count = 1) {
- X P(); I();
- X "There is a threatening little dwarf in the
- X room with you.";
- X }
- X else if (count > 1) {
- X P(); I();
- X "There are "; say(count); " threatening
- X little dwarves in the room with you.";
- X }
- X
- X //
- X // Handle dwarf attacks.
- X //
- X if (self.attackers > 0) {
- X if (self.attackers = 1) {
- X if (count = 1)
- X " He throws a knife at you!";
- X else
- X " One of them throws a knife
- X at you!";
- X }
- X else {
- X if (self.attackers = count) {
- X if (count = 2)
- X " Both of them throw
- X knives at you!";
- X else
- X " All of them throw
- X knives at you!";
- X }
- X else {
- X say(self.attackers); " of them throw
- X knives at you!";
- X }
- X }
- X
- X //
- X // Curtains for our hero?!
- X //
- X count := 0;
- X for (i := 1; i <= self.attackers; i++) {
- X if (rand(100) <= global.dwarfaccuracy)
- X count++;
- X }
- X
- X P(); I();
- X if (count > 0) {
- X if (count = self.attackers) {
- X if (count = 1)
- X "It gets you!";
- X else if (count = 2)
- X "Both of them get you!";
- X else
- X "All of them get you!";
- X }
- X else if (count = 1) {
- X "One of them gets you!";
- X }
- X else {
- X say(count); " of them get
- X you!";
- X }
- X
- X die();
- X }
- X else {
- X if (self.attackers = 1)
- X "It misses you!";
- X else if (self.attackers = 2)
- X "Both of them miss you!";
- X else
- X "They all miss you!";
- X }
- X }
- X//"\ntell(exit)\n";
- X }
- X;
- X/*
- X * The player can never get the dwarves' knives (that would be too easy),
- X * but we'll let him examine them anyway.
- X */
- XDwarfKnives: decoration
- X sdesc = "dwarf's knife"
- X ldesc = { self.verifyRemove(Me); }
- X noun = 'knife' 'knives'
- X adjective = 'sharp' 'nasty' 'dwarf\'s' 'dwarvish' 'dwarven'
- X 'dwarfish'
- X
- X locationOK = true // tell compiler OK for location to be method
- X location = {
- X return Dwarves.location;
- X }
- X
- X verifyRemove(actor) = {
- X "The dwarves' knives vanish as they strike the walls
- X of the cave.";
- X }
- X
- X verIoAttackWith(actor) = {
- X "You don't have the dwarf's knife!";
- X }
- X;
- X
- X/*
- X * Move the pirate(s). See the global object in ccr-std.t for paramters.
- X *
- X * This code is quite similar to the Dwarves code, but is simple because
- X * there's never any interaction between the player and the pirates. (The
- X * pirates just come in, do their stuff, and vanish.)
- X *
- X * Note that even if there's more than one pirate, the text printed in
- X * in this object will treat all the pirates as a single one. So the
- X * only difference having multiple pirates makes is that the more you
- X * have, the more likely the player is to run into "him."
- X */
- XPirates: NPC, Actor
- X location = nil // not a real actor, so pretend we don't exist
- X
- X seen = nil // has the player seen (one of) us?
- X
- X //
- X // Place pirates in starting locations.
- X //
- X place = {
- X local i, loc, r;
- X
- X self.loclist := [];
- X for (i := 1; i <= global.pirates; i++) {
- X //
- X // If there are any fixed starting locations
- X // for pirates left, put this pirate in the
- X // next one. Otherwise place him randomly.
- X //
- X loc := nil;
- X if (length(global.pirateloc) >= i)
- X loc := global.pirateloc[i];
- X
- X //
- X // Invalidate initial location if it's off limits
- X // to NPC's.
- X //
- X if (loc)
- X if (loc.noNPCs)
- X loc := nil;
- X
- X //
- X // Make sure we get a real location.
- X //
- X while (loc = nil) {
- X r := rand(length(global.NPCrooms));
- X loc := global.NPCrooms[r];
- X }
- X
- X //
- X // Add this pirate's location to the list.
- X //
- X self.loclist := self.loclist + loc;
- X }
- X }
- X
- X //
- X // Move pirates.
- X //
- X move = {
- X local i, j, len, r, dest, done, dir, melocs;
- X
- X//"\npirates.move(enter)\n";
- X //
- X // Move each remaining pirate.
- X //
- X // If the pirate is currently in the player's location,
- X // he stays where he is.
- X //
- X // If a pirate is in a location adjacent to the player's
- X // current location, he moves into the player's location
- X // if he can. We limit this with the ptenacity global.
- X //
- X // If a pirate isn't adjacent to the player, he just moves
- X // around randomly.
- X //
- X self.newloclist := [];
- X for (melocs := [], i := Me.location ; i ; i := i.location)
- X melocs += i;
- X
- X for (i := 1; i <= length(self.loclist); i++) {
- X //
- X // Haven't found a new location yet.
- X //
- X done := nil;
- X
- X //
- X // In player's current location?
- X //
- X if (find(melocs, self.loclist[i])) {
- X dest := self.loclist[i]; // stay put
- X done := true;
- X }
- X
- X //
- X // Try each exit and see if we can reach the
- X // player. If we have an exit that leads to
- X // the player, we know it's an OK destination
- X // location, since we pruned off all the noNPCs
- X // rooms when we constructed the exit lists.
- X //
- X len := length(self.loclist[i].NPCexits);
- X if (not done) for (j := 1; j <= len; j++) {
- X dir := self.loclist[i].NPCexits[j];
- X dest := self.loclist[i].(dir);
- X
- X //
- X // We need to check the destination
- X // to be sure it exists. It may be
- X // nil if we called an NPCexit method.
- X //
- X if (dest) if (find(melocs, dest)) {
- X //
- X // Is this pirate tenacious enough
- X // to follow the player?
- X //
- X if (rand(100) <= global.ptenacity)
- X done := true;
- X break;
- X }
- X }
- X
- X //
- X // Have we found a destination yet? If not,
- X // move pirate to a randomly selected adjacent
- X // location.
- X //
- X // We need to check the destination because
- X // the NPCexit methods in the rooms can sometimes
- X // return nil. (For example, when the crystal
- X // bridge doesn't exist yet, the giant's door
- X // has not been opened, etc.)
- X //
- X while (not done) {
- X dir := self.loclist[i].NPCexits[rand(len)];
- X dest := self.loclist[i].(dir);
- X
- X if (dest)
- X done := true;
- X }
- X
- X //
- X // Set new destination.
- X //
- X self.newloclist += dest;
- X
- X //
- X // Print some debugging info if in debug mode
- X //
- X if (self.loclist[i] = dest) {
- X if (global.debug) {
- X P();
- X "Pirate stays \""; dest.sdesc; ".\"\n";
- X }
- X }
- X else {
- X if (global.debug) {
- X P();
- X "Pirate moves from \"";
- X self.loclist[i].sdesc; "\" to \"";
- X dest.sdesc; ".\"\n";
- X }
- X }
- X }
- X
- X //
- X // Replace old locations with destinations.
- X //
- X self.loclist := self.newloclist;
- X
- X self.tell;
- X//"\npirates.move(exit)\n";
- X }
- X
- X //
- X // Tell the player what's going on with the pirates.
- X //
- X tell = {
- X local i, t, count, snagged, melocs;
- X//"\npirates.tell(enter)\n";
- X
- X //
- X // Count how many pirates are in the room with the player.
- X // (We really only need to know if there are any at all,
- X // but this is just as easy.)
- X //
- X for (melocs := [], i := Me.location ; i ; i := i.location)
- X melocs += i;
- X count := length(intersect(melocs, self.loclist));
- X
- X //
- X // Tell the player if any pirates are nearby.
- X //
- X if (count = 0) {
- X //
- X // If no pirates are in the room, but at least
- X // one pirate is in an adjacent location, tell
- X // the player he hears something.
- X //
- X if (self.anyadjacent) {
- X P(); I();
- X "There are faint rustling noises from
- X the darkness behind you.";
- X }
- X }
- X else if (count > 0) {
- X //
- X // A pirate has snagged the player.
- X // Move any treasures the player is carring
- X // to the pirate's repository, currently
- X // hard-coded as Dead_End_13 because there's
- X // code in that room that can't easily be
- X // made general.
- X //
- X // Since the player may be keeping his treasures
- X // in containers, it's actually easier just
- X // to search through the global list of
- X // treasures and check each one's location to
- X // see if it's in the player, rather than
- X // recursively checking all the player's belongings
- X // and seeing if they're treasures. (Also, we want
- X // to get treasures that are just lying around in
- X // the room too.)
- X //
- X snagged := 0;
- X for (i := 1; i <= length(global.treasurelist); i++) {
- X t := global.treasurelist[i] ;
- X if (t.isIn(Me.location)) {
- X t.moveInto(Dead_End_13);
- X snagged++;
- X }
- X }
- X
- X //
- X // Print a message telling the player what happened.
- X //
- X if (snagged > 0) {
- X P();
- X I(); "Out from the shadows behind you
- X pounces a bearded pirate! \"Har,
- X har,\" he chortles. \"I'll just take
- X all this booty and hide it away with
- X me chest deep in the maze!\" He
- X snatches your treasure and vanishes
- X into the gloom.";
- X }
- X else {
- X //
- X // In the original code, if you weren't
- X // holding the lamp, you just wouldn't
- X // see the pirate when you weren't
- X // carrying any treasures. This seems
- X // bogus, so I've added a conditional here.
- X //
- X P();
- X I(); "There are faint rustling noises
- X from the darkness behind you. As you
- X turn toward them, ";
- X
- X if (brass_lantern.isIn(Me))
- X "the beam of your lamp falls
- X across";
- X else
- X "you spot";
- X
- X " a bearded pirate. He is carrying a
- X large chest. \"Shiver me timbers!\"
- X He cries, \"I've been spotted! I'd
- X best hie meself off to the maze to
- X hide me chest!\" With that, he
- X vanishes into the gloom.";
- X }
- X
- X //
- X // Install the treasure chest if it hasn't
- X // already been installed. No worries about
- X // the chest appearing out of nowhere when
- X // the player's at Dead_End_13, because the
- X // pirate can't go there. (It's off limits
- X // to NPC's.)
- X //
- X if (not self.seen) {
- X treasure_chest.moveInto(Dead_End_13);
- X self.seen := true;
- X }
- X
- X //
- X // Scatter any pirates in the room.
- X //
- X self.scatter;
- X }
- X//"\npirates.tell(enter)\n";
- X }
- X;
- END_OF_FILE
- if test 25988 -ne `wc -c <'src/ccr-npc.t'`; then
- echo shar: \"'src/ccr-npc.t'\" unpacked with wrong size!
- fi
- # end of 'src/ccr-npc.t'
- fi
- if test -f 'src/ccr.t' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/ccr.t'\"
- else
- echo shar: Extracting \"'src/ccr.t'\" \(2419 characters\)
- sed "s/^X//" >'src/ccr.t' <<'END_OF_FILE'
- X/*
- X * Colossal Cave Revisited
- X *
- X * A remake of Willie Crowther and Don Woods' classic Adventure.
- X * Converted from Donald Ekman's PC port of the original FORTRAN source.
- X * TADS version by David M. Baggett for ADVENTIONS.
- X *
- X * Colossal Cave Revisited and its accompanying source code are
- X * Copyright (C) 1993 David M. Baggett.
- X *
- X *---------------------------------------------------------------------------
- X * This program is free software; you can redistribute it and/or modify
- X * it under the terms of version 2 of the GNU General Public License as
- X * published by the Free Software Foundation.
- X *
- X * This program is distributed in the hope that it will be useful,
- X * but WITHOUT ANY WARRANTY; without even the implied warranty of
- X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X * GNU General Public License for more details.
- X *
- X * You should have received a copy of the GNU General Public License
- X * along with this program; if not, write to the Free Software
- X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- X *
- X *---------------------------------------------------------------------------
- X *
- X * Please document all changes in the history (here as well as in the
- X * appropriate source files) so we know who did what.
- X *
- X *---------------------------------------------------------------------------
- X *
- X * ADVENTIONS distributes this game, but you are free to do what you will
- X * with it, provided you adhere to the terms in the GNU Public License.
- X * Send correspondence regarding this game or original works distributed
- X * by ADVENTIONS to
- X *
- X * ADVENTIONS
- X * PO Box 851
- X * Columbia, MD 21044
- X *
- X * If you would like a catalog of releases, please enclose a SASE. Thanks!
- X *
- X * Contributors
- X *
- X * dmb In real life: David M. Baggett
- X * Internet: <dmb@ai.mit.edu>
- X * Compu$erve: 76440,2671 (ADVENTIONS account)
- X * GEnie: ADVENTIONS
- X *
- X * Modification History
- X *
- X * 1-Jan-93 dmb rec.arts.int-fiction BETA release (source only)
- X * For beta testing only -- not for general
- X * distribution.
- X *
- X * 20-Apr-93 dmb Version 1.0 release.
- X *
- X * 9-Jul-93 dmb Widespread version 1.0 release for all supported
- X * machines.
- X *
- X */
- X#include "history.t"
- X
- X#include "ccr-adv.t"
- X#include "format.t"
- X#include "preparse.t"
- X#include "ccr-std.t"
- X#include "ccr-room.t"
- X#include "ccr-item.t"
- X#include "ccr-verb.t"
- X#include "ccr-npc.t"
- X#include "help.t"
- X#include "close.t"
- END_OF_FILE
- if test 2419 -ne `wc -c <'src/ccr.t'`; then
- echo shar: \"'src/ccr.t'\" unpacked with wrong size!
- fi
- # end of 'src/ccr.t'
- fi
- if test -f 'src/makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/makefile'\"
- else
- echo shar: Extracting \"'src/makefile'\" \(884 characters\)
- sed "s/^X//" >'src/makefile' <<'END_OF_FILE'
- X#
- X# Makefile for Colossal Cave Revisited
- X# Requires TADS compiler 2.1.0 or greater.
- X#
- X# Note that some of the Unix versions of the compilers return error
- X# codes when everything's actually fine.
- X#
- X
- X#
- X# Set TC and TR to point to your TADS compiler and run-time.
- X#
- XTC= tadsc
- XTR= tadsr
- X
- XPROGNAME= ccr
- XDEBUG= -ds
- XSWAPTIONS=
- XOOPTIONS= -s -mp32000
- XOPTIONS= $(OOPTIONS) $(SWAPTIONS) $(DEBUG)
- X
- X# Production version options
- XPOPTIONS= $(OOPTIONS) $(SWAPTIONS)
- X
- X.PRECIOUS= $(PROGNAME).gam # do not delete game file on errors
- X
- XHEADERS= ccr-adv.t ccr-std.t
- XROOMS= ccr-room.t
- XOBJECTS= ccr-item.t
- XMISC= close.t ccr-verb.t format.t help.t ccr-npc.t preparse.t thingext.t
- X
- X$(PROGNAME).gam: makefile $(PROGNAME).t $(HEADERS) $(ROOMS) $(OBJECTS) $(MISC)
- X $(TC) $(OPTIONS) $(PROGNAME).t
- X
- Xproduction: makefile $(PROGNAME).t $(HEADERS) $(ROOMS) $(OBJECTS) $(MISC)
- X $(TC) $(POPTIONS) $(PROGNAME).t
- END_OF_FILE
- if test 884 -ne `wc -c <'src/makefile'`; then
- echo shar: \"'src/makefile'\" unpacked with wrong size!
- fi
- # end of 'src/makefile'
- fi
- echo shar: End of archive 9 \(of 11\).
- cp /dev/null ark9isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 11 archives.
- echo "Now run buildit.sh to make gam file"
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-