//
// += 3: A Logical Adventure
//
// Concept by Carl de Marcken and Dave Baggett.
// Coding by Dave Baggett.
//
// Created 15-Nov-94.
// Made easier 19-Nov-94 (v1.1)
// Fixed bug (things given to troll don't disappear) (v1.2)
//
// This source requires WorldClass, a free TADS class library available
// from ftp.gmd.de: if-archive/programming/tads/worldclass/
//
#include <world.t>
l := actor.itemcontents(actor, nil);
r := [];
for (i := 1; i <= length(l); i++)
if (not l[i].isworn)
r += l[i];
return r;
}
;
replace intro: function
{
I(); "Wow! This sure has been one tough game so far. But
you're almost there -- 99 points out of 100 and what looks to
be a run-of-the-mill troll on the bridge puzzle. Should be
trivial for an adventure game god like you. And besides,
any puzzle with a logical solution can't be *too* hard to
solve. It's about time you got busy and finished the last
puzzle and wrote up a walkthrough for...";
"\b"; version.sdesc; "\b";
}
replace version: object
name = {
"\(+=\ 3: A Controversial but Nevertheless Logical Adventure\)\n
Version 1.2";
}
sdesc = {
self.name; "\n";
"Copyright (C) 1994 David M.\ Baggett\n
All rights reserved.\n
Developed with TADS, the Text Adventure Development System.\n";
classlibrary.info; "\n";
"Difficulty Rating: Probably Requires Random Search
(10 out of 10)\b";
"***"; P();
I(); "For instructions, type \"instructions\"."; P();
I(); "Read footnotes "; note(self); " with the note command;
e.g., type \"note 1.\""; P();
I(); "Type \"credits\" for more information about the
game."; P();
"***"; P();
}
footnote = {
"Footnote markers are numbers enclosed in square brackets.";
}
;
replace userpreinit: function
{
local v;
for (v := firstobj(Verb); v <> nil; v := nextobj(v, Verb))
v.allok := nil;
}
replace userinit: function
{
if (global.restarting = nil) {
"\b\b\b\b\b\b\b\b";
intro();
}
global.lastactor := Me;
Me.location.enter(Me);
score_statusline();
}
creditsVerb: Soloverb
verb = 'credits' 'acknowledgements'
sdesc = "list credits for"
soloaction(actor) = {
I(); "Carl de Marcken and Dave Baggett designed this game.
Dave Baggett coded."; P();
I(); "Russ Bryan asked for it."; P();
I(); "\"You know, it looks to me like the real message
of the game is that common-sense puzzles are a bad idea.\""; P();
"\t\t\t -- Felix Lee\n";
}
;
instructVerb: Soloverb
verb = 'instructions' 'help' 'hint'
sdesc = "HELP!"
soloaction(help) = {
I(); "This game is not impossible, but it is very
difficult. In fact, the authors suspect that few (if
any) will be able to solve it the direct way; i.e., by
using the clues in the game and common sense to figure
out how to solve the puzzles."; P();
}
;
Me: Player
location = bridge
noun = 'me' 'self' 'myself'
ldesc = {
"You're the adventurer in \(Zork\) who was too polite
to open someone else's mailbox.";
}
isnoticeable(actor) = { return nil; }
smelldesc = "You smell inextinguishable."
listendesc = "You sound like a colorless green idea."
starvationcheck = nil
dehydrationcheck = nil
sleepcheck = nil
;
bridge: Room
tdesc = "On the Three Troll Bridge"
ldesc = {
I(); "You are standing on a rickety wooden bridge. ";
if (troll.givencount < 3) {
"A burly Three Troll blocks your passage
north, across the bridge.";
}
}
sdesc = "<<self.tdesc>>"
verGoSouth(actor) = {
"Sorry, you've already explored that area and
gotten all the points.";
}
verGoNorth(actor) = {
if (troll.givencount < 3)
"The troll won't let you pass.";
}
goNorth(actor) = {
"You stride confidently past the troll and
onto a glorious but drafty victory.";
incscore(1);
end();
}
verGoDown(actor) = {
"There's no way to get down there short of jumping,
which seems like a bad idea indeed.";
}
verJump(actor) = { return self.verGoDown(actor); }
;
bridgedecoration: Qover
location = bridge
noun = 'bridge'
adjective = 'troll' 'three' 'rickety' 'wooden'
sdesc = "rickety wooden bridge"
ldesc = "It's just a typical rickety adventure game bridge."
acceptsput(actor, loctype) = { "You can't reach."; }
;
water: Qcontainer
sdesc = "the water"
isdetermined = true
ldesc = "There's nothing special about the water."
location = bridgedecoration
locationtype = 'under'
noun = 'water'
verIoPutin(actor) = {}
ioPutin(actor, dobj) = {
local r;
"Splash. ";
r := rand(4);
if (r = 1)
"The fish jumps.";
else if (r = 2)
"The fish jumps high in the air, executes a
flawless double twist, and then splashes back
into the water.";
else if (r = 3)
"The fish jumps high in the air -- almost
as high as the bridge.";
else if (r = 4)
"The fish jumps over the bridge and back
into the water, startling the troll!";
dobj.movein(nil);
}
passgen(actor, obj, loctype, passmethod) = {
// If not "in" containment or nil, call our parent's method.
if (loctype <> nil and loctype <> 'in')
return inherited.(passmethod)(actor, obj, loctype);
"You can't reach the water from here.";
return nil;
}
passcantouchin(actor, obj, loctype) = {
return self.passgen(actor, obj, loctype, &passcantouch);
}
passcantakein(actor, obj, loctype) = {
return self.passgen(actor, obj, loctype, &passcantake);
}
passcansmellin(actor, obj, loctype) = {
return self.passgen(actor, obj, loctype, &passcansmell);
}
;
redthing: Decoration
location = water
locationtype = 'in'
sdesc = "red thing"
ldesc = "It seems to be swimming around."
noun = 'thing' 'fish' 'herring'
adjective = 'red'
verDoTake(actor) = { "There is no \(obvious\) way to get at it."; }
;
troll: Male, Actor, Listablesound
givencount = 0
sdesc = "burly Three Troll"
ldesc = {
if (self.givencount < 3)
"He holds his hand out expectantly.";
else
"He seems to be ignoring you.";
}
noun = 'troll'
adjective = 'burly'
location = bridge
actordesc = {}
islistable(actor) = { return nil; }
verIoGiveto(actor) = {}
ioGiveto(actor, dobj) = {
if (self.givencount = 3) {
"The troll ignores you.";
}
else {
dobj.movein(nil);
self.givencount++;
"\^\"<<saynum(self.givencount)>>!\" he grunts.";
if (self.givencount = 3)
" The troll now seems less overbearing.";
}
}
listlistendesc = "is ticking."
listendesc = "The troll, oddly enough, seems to be ticking."
smelldesc = "The troll smells lemony fresh."
;
trollhand: Part
partof = troll
sdesc = "troll's hand"
ldesc = {
if (troll.givencount < 3)
"It's being held out by its owner, the troll,
expectantly.";
else
"It looks like an ordinary troll hand.";
}
noun = 'hand'
adjective = 'troll\'s' 'troll'
acceptsput(actor, loctype) = { return loctype = 'in' ? true : nil; }
verIoPutin(actor) = { troll.verIoPutin(actor); }
ioPutin(actor, dobj) = { troll.ioPutin(actor, dobj); }
;
class myclothes: Clothing
ldesc = "There's nothing special about <<self.objthedesc(nil)>>."
isdetermined = true
adjective = 'my'
location = Me
isnoticeable(actor) = {
if (self.isin(Me) and self.isworn)
return nil;
else
return true;
}
isworn = true
;
shirt: myclothes
sdesc = "your shirt"
noun = 'shirt'
;
pants: myclothes
isplural = true
sdesc = "your pants"
noun = 'pants'
;
shoes: myclothes
isplural = true
sdesc = "your shoes"
noun = 'shoes'
;
socks: myclothes
isplural = true
sdesc = "your socks"
noun = 'socks'
;
glasses: myclothes
isplural = true
sdesc = "your glasses"
noun = 'glasses' 'spectacles' 'specs'
;
underwear: myclothes
sdesc = "your underwear (yuck)"
noun = 'underwear'
;
clothes: Decoration
noun = 'clothes' 'clothing'
adjective = 'my'
location = bridge
sdesc = "your clothes"
isplural = true
isdetermined = true
ldesc = {
if (troll.givencount = 0)
"There's nothing unusual about your clothes.";
else
"There's nothing unusual about the clothing that
you still have.";
}
verDoTake(actor) = { "You'll need to be more specific."; }
;
qual_calculator: Item
sdesc = "qualitative calculator"
ldesc = {
I(); "Your parents gave you this for your birthday
last year. It's just the sort of thing they'd be
absolutely wrong about thinking you'd need. And
indeed, you've found no use for it to
date. <<note(self)>>"; P();
I(); "It has has 9 buttons: ZERO, POSITIVE, NEGATIVE,
ADD, SUBTRACT, MULTIPLY, DIVIDE, Clear and deClear.
The readout currently shows <<self.sayreadout>>.";
}
noun = 'calculator' 'calc'
adjective = 'qualitative'
location = Me
footnote = { "Respects to Walter Hamscher and Carl de Marcken."; }
stack = []
secondstack = []
saynewreadout = { "\nThe readout now shows <<self.sayreadout>>.\n"; }
sayreadout = {
local v;
if (length(stack) < 1)
v := 0;
else
v := stack[1];
if (v = -1)
"[[\ -\ ]]";
else if (v = 0)
"[[\ 0\ ]]";
else if (v = 1)
"[[\ +\ ]]";
else
"[[\ ?\ ]]";
}
pop = {
local v;
if (length(stack) < 1)
v := 0;
else {
v := car(stack);
stack := cdr(stack);
}
addbutton: qualbutton
sdesc = "ADD button"
noun = 'button'
adjective = 'add'
doPush(actor) = {
local v, v1, v2;
v1 := qual_calculator.pop;
v2 := qual_calculator.pop;
if (v1=2 or v2=2) v := 2;
else if ((v1=1 and v2=-1) or (v1=-1 and v2=1)) v := 2;
else if (v1=1 or v2=1) v := 1;
else if (v1=-1 or v2=-1) v := -1;
else v := 0;
qual_calculator.stack := [ v ] + qual_calculator.stack;
qual_calculator.saynewreadout;
}
;
subtractbutton: qualbutton
sdesc = "SUBTRACT button"
noun = 'button'
adjective = 'subtract'
doPush(actor) = {
local v, v1, v2;
v1 := qual_calculator.pop;
v2 := qual_calculator.pop;
if (v1=2 or v2=2) v := 2;
else if ((v1=1 and v2=1) or (v1=-1 and v2=-1)) v := 2;
else if (v2<>0) v := v2;
else v := -v1;
qual_calculator.stack := [ v ] + qual_calculator.stack;
qual_calculator.saynewreadout;
}
;
multiplybutton: qualbutton
sdesc = "MULTIPLY button"
noun = 'button'
adjective = 'multiply'
doPush(actor) = {
local v, v1, v2;
v1 := qual_calculator.pop;
v2 := qual_calculator.pop;
if (v1=2 or v2=2) v := 2;
else if (v1=0 or v2=0) v:= 0;
else if (v1=v2) v := 1;
else v := -1;
qual_calculator.stack := [ v ] + qual_calculator.stack;
qual_calculator.saynewreadout;
}
;
dividebutton: qualbutton
sdesc = "DIVIDE button"
noun = 'button'
adjective = 'divide'
doPush(actor) = {
local v, v1, v2;
v1 := qual_calculator.pop;
v2 := qual_calculator.pop;
if (v1=2 or v2=2 or v1=0) v := 2;
else if (v2=0) v := 0;
else if (v1=v2) v := 1;
else v := -1;
qual_calculator.stack := [ v ] + qual_calculator.stack;
qual_calculator.saynewreadout;
}
;