/* FIRST THINGS FIRST - init.t - Release Version 1.1
/* Copyright (c) 1996, 1997, 1999, 2000, 2001 by J. Robinson Wheeler. All Rights Reserved. */
/*
* ***** BASIC OBJECT DEFINITIONS *****
*/
/* The "version" object defines, via its "sdesc" property, the name and
* version number of the game.
*/
replace version: object
sdesc = "\(First Things First\)\
-\ A Text Adventure Game by J.\ Robinson Wheeler
\nDeveloped with TADS: The Text Adventure Development System.
\bRelease Version 3.0 20061221
\nCopyright 2001, 2006 by J.\ Robinson Wheeler. All Rights Reserved.
\nPublished by JRW Digital Media.
\nType ABOUT, CREDITS, and HELP for general information. "
;
/* The "global" object is the dumping ground for any data items that
* don't fit very well into any other objects.
*/
replace global: object
turnsofar = 0 // no turns have transpired so far
score = 0 // no points have been accumulated yet
maxscore = 151 // maximum possible score
lastScore = 0 // last registered score value
verbose = true // we start in VERBOSE mode
firstTime = 0 // time of entering the clearing
machineTime = 0 // interval after appearance
lamplist = [] // list of all known light providers in the game
timeLoc = 3 // start time in the PRESENT
newRoof = nil // is the roof good or bad? --Bad
money = 0 // no money to speak of
moneyLostDuringJump = nil // flag for losing cash during a time jump
notifie = true // score notification is ON
scoreCard = [ 0 0 0 0 0
0 0 0 0 0
0 0 0 0 0 //
0 0 0 0 0 // List of point scoring turns
0 0 0 0 0 0 0 ] //
NPC_list = [ Fred FFred Laura PLaura FLaura FFLaura Architect squirrel
youngMan securityGuard teller workers Blackie antiqueMerchant ]
;
/*
* ***** INIT AND META FUNCTION DEFINITIONS *****
*/
/* Initialization Routines
*
* Pre-declare some functions, so the compiler knows they are functions.
* (This is only really necessary when a function will be referenced
* as a daemon or fuse before it is defined; however, it doesn't hurt
* anything to pre-declare all of them.)
*/
die: function;
scoreRank: function;
init: function;
terminate: function;
pardon: function;
darkTravel: function;
timemachineDaemon: function; // used for first appearance of machine
newTime: function; // computes the destination time for a jump
moveTimeMachine: function; // handles movement of the machine
printTimeMessage: function; // determines time jump descriptions, prints
timeJump: function; // checks for valid jump, executes if true
garageState: function; // handles the garageDoor opens & closes
coolOffDaemon: function; // cools off items over a number of turns
cartMove: function; // moves the cart and the actor to next loc
interest: function; // recursion to compute interest dividends
updateAccount: function; // updates the account balances for all 4 periods
setupAccount: function; // sets up the player's bank account
timeOfDay: function; // returns a string with the time of day
consultWords: function; // returns true if NPC says something
doSquirrelAction: function; // animates the squirrel
doFredAction: function; // animates Fred
doLauraAction: function; // animates Laura
newListenDesc: function; // replaces current room listenDesc
swapListenDesc: function; // basic swap function
restoreListenDesc: function; // restores current room listenDesc
chooseTopic: function; // automagic NPC conversation hint system
provideHint: function; // gives the player a hint about what to do next
listIssues: function; // provides a full list of problems facing the player
handleMoneyTrade: function; // handles messy business of acquiring cash
sayMessage: function; // provides busy construction site
sayMessage2: function; // movement and descriptions
housekeeping: function; // performs end-of-turn duties
CYOA_quit: function; // return from CYOA module
parseAskobjActor: function; // special ask-for-dobj message
deepGrab: function; // moves hidden items to top inventory
recursiveOpen: function; // helper function for deepGrab
/*
* preinit() is called after compiling the game, before it is written
* to the binary game file. It performs all the initialization that can
* be done statically before storing the game in the file, which speeds
* loading the game, since all this work has been done ahead of time.
*
* This routine puts all lamp objects (those objects with islamp = true) into
* the list global.lamplist. This list is consulted when determining whether
* a dark room contains any light sources.
*/
preinit: function
{
local o;
global.lamplist := [];
o := firstobj();
while(o <> nil)
{
if (o.islamp)
global.lamplist := global.lamplist + o;
o := nextobj(o);
}
initSearch();
}
/* The init() function is run at the very beginning of the game.
* We display some introductory text, then move the player (Me) to the
* initial location and set up some background activity.
*/
replace init: function
{
clearscreen();
"\bYou've just arrived at home from your nightly visit to the science and
invention section of the local public library, where you spend each night
dreaming your dreamy dreams of one day inventing a time travel machine.
Tonight, for some reason, you're especially fatigued, and can't wait to
get inside and go right to bed. Seems like a good plan, but somehow you
have a premonition it's not going to be that easy...\b";
"\n"; version.sdesc; // display the game's name and version number
"\b";
setdaemon( turncount, nil ); // start the turn counter daemon
setdaemon( housekeeping, nil ); // start the housekeeping daemon
Me.location := frontOfHouse; // move player to initial location
moveTimeMachine( nil ); // just to make sure it starts nil
frontOfHouse.lookAround( true ); // show player where he is
frontOfHouse.isseen := true; // set this flag manually
iVerb.useInventoryTall := true; // use 'TALL' inventory style
}
/*
* initRestore() - the system calls this function automatically at game
* startup if the player specifies a saved game to restore on the
* run-time command line (or through another appropriate
* system-dependent mechanism). We'll simply restore the game in the
* normal way.
*/
initRestore: function(fname)
{
/* perform common initializations */
// commonInit();
/* tell the player we're restoring a game */
"\b[Restoring saved position...]\b";
/* go restore the game in the normal way */
mainRestore(fname);
if ( parserGetMe() = CYOA_Me )
{
"\H+"; CYOA_global.html_mode := true;
}
else
{
"\H-"; CYOA_global.html_mode := nil;
}
}
/*
commonInit: function( parm )
{
}
*/
/* provide a preparse function, but don't bother doing anything */
preparse: function( cmd )
{
if ( parserGetMe() = CYOA_Me )
{
local foo;
if ( cmd = '' ) {
"Pardon me? ";
return nil;
}
foo := cvtnum( cmd );
switch( foo ) {
case 1: return 'one';
case 2: return 'two';
case 3: return 'three';
case 4: return 'four';
case 5: return 'five';
case 6: return 'six';
case 7: return 'seven';
case 8: return 'eight';
case 9: return 'nine';
default:
if ( foo < 0 || foo > 9 || cmd = '0' ) {
"Enter a choice from the menu, please. ";
return nil;
}
return true;
}
}
return(true);
}
/* provide a parseError function */
parseError: function( num, str )
{
if ( parserGetMe() = CYOA_Me )
{
if ( num = 2 )
return 'I don\'t understand that command. For a list of ' +
'valid commands, please type \'help\'.';
else
return nil;
}
if ( num = 2 )
{
return( 'I don\'t know the word "%s".' );
}
if ( global.allMessage ) // You can't use ALL with that verb.
{
local r;
r := global.allMessage;
global.allMessage := nil;
return( r );
}
return( nil );
}
preparseCmd: function( list )
{
if ( parserGetMe() = CYOA_Me )
{
local foo := [];
if ( length( list ) = 1 )
return true;
else {
foo += list[ 1 ];
return foo;
}
}
return( true );
}
commandPrompt: function( type )
{
if ( parserGetMe() = CYOA_Me )
{
if ( type = 0 || type = 1 ) {
"\b";
CYOA_Me.location.choices;
"\b";
say( CYOA_global.prompt );
}
}
else if ( CYOA_global.html_mode )
{
"\b>";
"";
}
else "\b>";
}
commandAfterRead: function(code)
{
if ( CYOA_global.html_mode )
"";
}
helpSystem: object
sdesc = "help system"
ldesc = "\(First Things First\) is a large-scale text adventure game in
the classic style. There are no treasures to collect or monsters to
outwit, but you will have to overcome a lot of obstacles as you make
your way through the story. You will come across a number of objects,
some of which will be obviously helpful, others which may or not
be, and still others which are no help at all. Figuring out what
you need will be a matter of exploration and trial and error. \b
There are no included hints to help you along, although the game
is populated by various characters who might be able to nudge you
along if you ask them about various items in your possession or
obstacles you are butting against. There will be times when you
definitely know more about a topic than the person you're talking
to, and you can impart this information by telling them about it.
Like the character you will portray in the story, however, you
will mostly be on your own. \b
Remember to examine everything, and make liberal use of your
ability to search. When in doubt, revisit places; sometimes,
you will find something new in a place you thought you had
already scoured. \b
It is possible to lose or destroy items that you will need later
on, so before you do anything irrevocable, remember to save your
game. Don't be reckless, and the game will try to play fair. \b
Use the FULLSCORE (FULL) command to keep track of how far along you
are in the story. The EXITS (XITS) command will remind you of which
directions are open to you. \b
Good luck, and thank you for playing \(First Things First\). ";
;
hintSystem: object
sdesc = "help system"
ldesc = "This release of \(First Things First\) does not have a
hint system. You might try asking someone else in the
game some questions if you're really stuck. "
;
credits: object
sdesc = "This game has been a long haul, with many people deserving of thanks
along the way. First, I must thank my brother Diek Wheeler, for
getting me started with TADS five years ago. He's been waiting that
long to see the game I said would take me a couple of weeks to
finish. \b
For betatesting, I extend many hearty thanks to Admiral Jota for
getting me moving again after a long hiatus. His diligence and
stubbornness (especially about NPC interaction) have made the final
product more complete (and more interesting) than it would have been.
Special thanks to Doug Jones and Vincent Lynch, for their betatesting
dedication and their sharp eyes for missing details. \b
Other people who provided testing and feedback at various points:
Jonathan Blask, Tyson Boucher, Tony Delgado, Iain Merrick,
and Lenny Pitts. Last but not least, thanks to Geoff Bailey,
Vincent Laviano, Peter Nepstad, and the rest of the \"Iron-Men\"
Betatest gang. For Version 2.0: Jason Dyer, Paul Godfrey,
Dr.\ D.J.\ Picton, Christopher Tate, and Andrew Walters.
Version 3.0: D.J.\ Picton, Steven Tucker.\b
Honorable mention for general help and problem-solving goes
to Neil K.\ Guy, Gunther Schmidl, Dan Schmidt, Dan Shiovitz,
John McCall, and Michael J.\ Roberts. "
;
aboutTheGame: object
sdesc =
{
"\(First Things First\) was the first game I started writing in TADS,
way back in 1996. My brother had just purchased TADS, then available
only as shareware. We both sat down to write a quick game to test it
out. A couple of days later, he had finished his one-room demo. I had
already built about twenty rooms and had invented the basic plot and
one or two puzzles. Five years later, Version 1.0 was finally released.
Now it's a further five years later, and the release of Version 3.0
can almost be seen as a 10th anniversary edition. Given the central
premise of the game, fixing bugs today that I put into the code fully
ten years ago was an interesting experience. Life imitating art, and
so on. \b";
"Interactive Fiction has evolved since I first started, and so have
I. This adventure presents both my naive 1996-era and my matured
2006-era imaginings, as well as the progessive steps in between. \b
This game is free, but if you would like to make a shareware
donation in support of it, please visit http://jrwdigitalmedia.com/ftf/
and use one of the PayPal links to do so. Feel free to send me
email at ftf@jrwdigitalmedia.com. \b
Thank you for playing \(First Things First\). I hope you enjoy it. ";
}
;
/* strObj works like numObj, but for strings. So, a player command of
* type "hello" on the keyboard
* will result in a direct object of strObj, with its "value" property
* set to the string 'hello'.
*
* Note that, because a string direct object is used in the save, restore,
* and script commands, this object must handle those commands.
*/
strObj: basicStrObj
verDoSay( actor ) =
{
if ( self.value = 'lothario' )
"You hear a rumble in the distance. Something about it makes you shudder. ";
}
doSay( actor ) =
{
"Okay, \""; say( self.value ); "\". ";
}
verDoDrawOn( actor, io ) = {}
verDoNote( actor ) = {}
doNote( actor ) =
{
"Noted. ";
}
;
numObj: basicNumObj // use default definition from adv.t
verDoPush( actor ) = {}
doPush( actor ) =
{
if ( Me.location = inTheElevator )
{
numberedButtons.value := self.value;
numberedButtons.doPush( actor );
}
else if ( Me.location = stripMall )
{
ATMkeypad.ioTypeOn( actor, self );
}
else
"I don't know how to push <>. ";
}
verDoXyzzy( actor ) =
{
if ( not actor.islit )
"Nothing happens. ";
}
doXyzzy( actor ) =
{
local old_count;
old_count := acornMound.groCount;
acornMound.groCount := self.value;
acornMound.checkGrowth( acornMound.groCount, old_count );
"\nDone. ";
}
verDoSay( actor ) =
{
if ( not global.wizard )
"You say, \"<>.\" ";
}
doSay( actor ) =
{
future.state := self.value;
"\nDone. ";
}
verDoTime( actor ) =
{
if ( not global.wizard )
"I don't know how to time <>. ";
}
doTime( actor ) =
{
global.timeLoc := self.value;
"\nDone. ";
}
;
replace incscore: function( amount )
{
global.score := global.score + amount;
global.lastScore += amount;
scoreStatus( global.score, global.turnsofar );
}
/* The pardon function is run when a player enters a blank line. */
pardon: function
{
"I beg your pardon? ";
}
/* "Me" is the player's actor. Pick up the default definition, basicMe,
* from "adv.t".
*/
replace Me: basicMe
noun = 'self' 'me' 'myself'
adjective = 'my' 'ear' 'ears' 'nose' 'face' 'head' 'clothes' 'arm' 'arms'
'vein' 'veins' 'neck' 'muscle' 'muscles' 'hand' 'hands' 'leg' 'legs'
'foot' 'feet' 'ankle' 'ankles' 'body'
ldesc= "You have never been one to care about your appearance. You're
wearing comfortable clothes, the same as always. "
money = 0 // absolutely broke
verDoClean( actor ) =
{
"You make yourself look a little bit more presentable. ";
}
verDoCleanWith( actor, iobj ) =
{
"You clean yourself with <>. A somewhat odd way to
to do it, I suppose, and you don't look much cleaner afterward. ";
}
verDoEmpty( actor ) = {}
doEmpty( actor ) =
{
local errorCode, i;
"(dropping all)\b";
if ( length( Me.contents ) = 0 )
{
"You aren't carrying anything at the moment. ";
}
else
{
while( length( Me.contents ) > 0 )
{
"<>: ";
errorCode := execCommand( Me, dropVerb, car( Me.contents ) );
"\n";
}
}
}
ioGiveTo( actor, dobj ) =
{
"You accept <> from <>.";
dobj.moveInto( Me );
}
verDoHello( actor ) =
{
"Greetings. ";
}
verDoStabWith( actor, io ) = {}
verDoKillWith( actor, io ) =
{
"Suicide is never the answer. ";
}
verDoRelax( actor ) = {}
doRelax( actor ) =
{
relaxVerb.action( actor );
}
verDoRub( actor ) =
{
"You don't really need to rub yourself. ";
}
verDoScratch( actor ) =
{
"You aren't itching at the moment. ";
}
verDoTickle( actor ) =
{
"You have never been able to successfully tickle yourself. ";
}
verDoTickleWith( actor, io ) =
{
"Tickling yourself with <> isn't going to be a fruitful
enterprise. ";
}
verDoThrow( actor ) =
{
"You can't throw yourself. ";
}
verIoThrowAt( actor ) =
{
"You can't throw things at yourself. ";
}
verIoThrowTo( actor ) =
{
"You can't throw things to yourself. ";
}
verIoThrowIn( actor ) =
{
"You can't throw things in yourself, whatever that means. ";
}
verIoThrowOut( actor ) =
{
"You can't throw things out yourself, whatever that means. ";
}
verDoUnwear( actor ) =
{
"There is no need to take off your clothes. ";
}
;
CYOA_quit: function
{
if ( CYOA_global.html_mode )
{
"";
"\H-"; CYOA_global.html_mode := nil;
CYOA_global.html_mode := nil;
}
"\bYour adventure over, you find yourself back in the
sitting room. ";
parserSetMe( Me );
}
/* parseAskobjActor - Special ask-for-dobj message function */
parseAskobjActor: function( a, v, ... )
{
if ( argcount = 3 )
{
"What do you want ";
if ( a <> parserGetMe() )
a.thedesc;
" to <> it <>?";
}
else
{
if ( v = waitForVerb && Fred.lockingUpTheShop = true )
"Whom ";
else
"What ";
"do you want ";
if ( a <> parserGetMe() )
a.thedesc;
"to <>?";
}
}
/*********** END OF INIT AND META FUNCTIONS ***********/
/* eof */