/*
*
* Portcullis
*
* Things
*
* code and data dealing with 'things' in the game,
* which I'm making a point of NOT calling objects.
*
*/
var Thing = new Object;
NUM_THNG = 0;
function th(name,fullname,wearable,firstplace,description,uses,daemon)
{
Thing[++NUM_THNG] = new Object;
Thing[NUM_THNG].id = NUM_THNG;
Thing[NUM_THNG].name = name; // short version of name
Thing[NUM_THNG].shortname = name; // short version of name
Thing[NUM_THNG].fullname = fullname; // full name
Thing[NUM_THNG].wearable = wearable; // true for clothing
Thing[NUM_THNG].firstplace = firstplace; // starting place
Thing[NUM_THNG].description = description;
Thing[NUM_THNG].uses = uses; // general uses
Thing[NUM_THNG].daemon = daemon; // daemon (run every turn)
var varname = name;
while(varname.indexOf(' ')!=-1) {
varname = varname.replace(' ', '_');
}
eval(varname + ' = Thing[' + NUM_THNG + '];');
}
function pldo(th)
{
return('does');
}
// called when you attempt to foo something that can't be fooed
function default_use(verb,th)
{
if(verb=='eat')
say('I don\'t think the ' + th.name + ' would be very tasty.');
else if(verb=='talk')
say('The ' + th.name + ' doesn\'t seem to be very talkative.');
else if(verb=='smell')
say('The ' + th.name + ' doesn\'t smell very interesting.');
else if(verb=='kiss')
say('I don\'t think you and the ' + th.name + ' are close enough for that.');
else if(verb=='fight')
say('You have no animosity towards the ' + th.name + '.');
else if(verb=='wave')
say('Waving the ' + th.name + ' about has no useful effect.');
else if(verb=='wear')
say('You can\'t wear the ' + th.name + '!');
else
say('You can\'t do that with the ' + th.name + '.');
}
th('nothing',
'nothing',
false,
nowhere,
'It is nothing at all. You shouldn\'t be looking at it!',
'',
''
);
/*** begin BANANASKIN ***/
th('bananaskin',
'a banana skin',
false,
nowhere,
"Yellow and floppy. It feels rather slippery.",
{
eat: "You've already eaten the actual banana. What's left is just the peel."
},
function() {
if(gs(JUST_MOVED)) {
// hero only slips if they just entered the room,
// so that you can drop the bananaskin & stay to watch fun without potentially dying!
check_bananaskin_slip();
}
// characters only slip (or sidestep) the bananaskin once per drop.
if(Token[1]=='drop' && Token[2]=='bananaskin') {
sgs(WHO_KNOWS_ABOUT_BANANASKIN, 0);
}
// make characters slip on the banana peel
// (only Fraf and the mummy are actually vulnerable, but everyone else should acknowledge it.)
if(thingloc(bananaskin)!=nowhere) {
//var bananaloc = thingloc(bananaskin);
var cansee = (heroloc()==thingloc(bananaskin))
for(var i=1; i<=NUM_CHRS; ++i) if(!gs(GAME_OVER)) {
var bananaloc = thingloc(bananaskin); // set here, as it might move during this loop!
if(personloc(Person[i])==bananaloc && !(knows_about_bananaskin(Person[i]))) {
teach_about_bananaskin(Person[i]);
var whoItIs = Person[i];
if(gs(MUMMY_DEAD) || (whoItIs!=fraf && whoItIs!=mummy)) {
// For simplicity, Fraf won't slip on the banana skin after the mummy is dead.
if(cansee) {
if(whoItIs==staunton) { // one way to hear the swearword
say('\nStaunton nearly steps on the banana skin, then picks it up and shoves it into your hands. \
"Stop leaving your [[ gs(MAGIC_WORD) ]] litter around," he swears.');
give_hero(bananaskin);
get_point_for(HEARD_MAGIC_WORD);
return;
}
say('\n' + capitalise(the_person(whoItIs)) + ' sidesteps the banana skin.');
}
// todo: make this only happen once per person per drop of the bananaskin?
} else {
var canhear = (heroloc().isCastle);
var itsFraf = (whoItIs == fraf) // otherwise it's the mummy
if(cansee) { say('\n' + capitalise(the_person(whoItIs)) + ' steps on the banana skin'); }
if(personloc(whoItIs) != castle_stairs_g) {
if(cansee) {
say(' and falls over! ' + (itsFraf ? 'He curses' : 'It grunts') + ', ' +
'gets up, and goes on ' + (itsFraf ? "running" : "shambling") + '.');
} else if(canhear) {
say('\nYou hear a thud and a ' + (itsFraf ? "curse" : "grunt") + '.');
}
} else {
// they fall down the stairs...
if(cansee) {
say(' and goes tumbling down the stairs!');
} else if (heroloc()==kitchen) {
say('\n' + capitalise(the_person(whoItIs)) + ' comes tumbling down the stairs. ');
} else if(canhear) {
say('\nYou hear a series of thuds');
}
if(gs(OVEN_OPEN)) {
// ...into the oven!
if(cansee) {
say('\nYou hear the clang of metal doors swinging shut, and a few ' + (itsFraf ? 'screams' : 'distressed grunts') + '. There is a smell of roast meat.');
} else if(heroloc()==kitchen) {
say('\n' + ( itsFraf ? "He" : "It" ) + ' skids straight into the open oven, and the doors \
clang shut behind ' + (itsFraf ? "him" : "it") + '. There is a smell of roast meat.');
} else {
if(canhear) { say(' followed by the clang of metal doors swinging shut. '); } else { say('\n'); }
say('There is a smell of roast meat.');
}
sgs(FRAF_BEING_CHASED, 0);
set_personloc(whoItIs, nowhere);
if(whoItIs == fraf) {
get_point_for(FRAF_DEAD, 1)
minion_cackle();
} else if(cansee) {
get_point_for(MUMMY_DEAD);
if(personloc(fraf)==heroloc()) { say('\nFraf gives you a curt nod.'); }
sgs(FRAF_FREE, 1);
}
sgs(OVEN_OPEN, 0);
sgs(OVEN_PERMASHUT, 1);
} else {
// they hit the oven doors
if(heroloc()==kitchen) {
say(' ' + (itsFraf ? 'He' : 'It') + ' skids into the closed oven doors with a soft thump, gets up, \
and runs back up the stairs.');
} else {
if(cansee) {
say(' You hear a soft thump, and a moment later ' + (itsFraf ? 'he' : 'it') + ' comes ' + (itsFraf ? 'running' : 'shambling') +
' back up the stairs.');
} else {
say(' followed by a soft thump, then the clattering of some' + (itsFraf? 'one' : 'thing') + ' ascending a staircase at speed.');
}
}
}
}
}
}
}
}
});
bananaskin.shortname = 'banana skin';
function knows_about_bananaskin(person) {
return (('' + gs(WHO_KNOWS_ABOUT_BANANASKIN)).indexOf(''+person.id + ',') != -1);
}
function teach_about_bananaskin(person) {
var knowsStr = '' + gs(WHO_KNOWS_ABOUT_BANANASKIN);
if(knowsStr=='0') { knowsStr = ',' };
knowsStr += person.id + ',';
sgs(WHO_KNOWS_ABOUT_BANANASKIN, knowsStr);
}
function check_bananaskin_slip() { //onEnter for all rooms
// hero might slip on the bananaskin (50% chance, to avoid unwinnable state)
if(pick(2) && heroloc()==thingloc(bananaskin)) {
say('\nYou slip on the banana skin and fall ');
if(heroloc().exits['down']) {
say('downstairs. Oof - whumpf - ow!');
if(heroloc()==castle_stairs_g) {
if(!gs(OVEN_OPEN)) {
say(' You skid right into the closed oven doors. Clang!');
} else {
say('\nYou skid right into the open oven, and the doors clang shut behind you.\n')
die("It's rather hot in here...", "You're toast");
return true;
}
}
say('\n\n');
Token[1] = 'down';
move();
return true;
} else {
say('over. Ow! You pick yourself up.');
}
}
}
/*** end BANANASKIN ***/
/*** begin bow ***/
th('bow',
'a bow and arrows',
false,
nowhere,
'A longbow made of smooth, cream-coloured yew, and a quiver containing a large number of arrows.',
{
shoot: "*shoot_bow()"
},
null);
bow.shortname = 'bow and arrows';
function shoot_bow() {
if(!in_inv(bow)) {
if(Token[2]=='bow' && thingloc(bow)==heroloc()) {
say("You're not carrying the bow.");
} else {
say("You don't have anything to shoot with.");
}
return;
}
var shootAt = Token[2];
if(shootAt=='bow') {
shootAt = Token[3];
}
if(!shootAt) {
say('You fire an arrow. [[ heroloc().isOutdoors ? "It flies out of sight." : "It shatters against a wall." ]]');
return;
} else if(heroloc()==elf_trap_room && gs(ARIANE_IN_TRAP) && shootAt=='rope') {
say('You aim an arrow at the rope, fire, and by some miracle, actually hit it. The cage crashes to the floor and splinters \
into shards. Ariane steps out, trying to look unflustered, grabs her bow back from you without saying a word, \
[[ thingloc(waybread)==elf_trap_room ? \
(set_thingloc(waybread, nowhere), " picks up the waybread and starts idly munching it,") : "" ]] \
and walks south.\n\
A moment later, you hear a "twang" and a soft thump coming from the next room.');
take_away(bow);
sgs(ARIANE_IN_TRAP, 0);
sgs(ARIANE_FREE, 1);
get_point_for(TRAP_DISARMED);
sgs(DWARF_DEAD, 1);
set_personloc(dwarf, nowhere);
set_personloc(ariane, dwarf_room);
return;
} else if (is_thingname(shootAt) || is_sighthere(shootAt)) {
say('That would be pointless.');
return;
} else if(!is_personname(shootAt)) {
say("I don't understand what you want to shoot at.");
return;
}
// shooting a person
var person = eval(shootAt);
if(personloc(person)!=heroloc()) {
say("You can't see " + capitalise(the_person(person)) + ' here.');
return;
}
if(person == ariane) { // only possible when she's trapped
say('"You wouldn\'t dare," says Ariane as you point the bow at her.\n\
You dare. The arrow buries itself in the elf\'s chest. Her mouth is an \'O\' of surprise \
as her body vanishes in a shower of pink sparkles.');
ariane_killed_in_trap();
} else if(person==chef) {
say('"Looks like today\'s special is... kebab!" you say, and let an arrow fly. \
It pierces the chef\'s chest, and he disappears in a splash of Hollandaise sauce.');
inc_score();
set_personloc(chef,nowhere);
} else if(person==dwarf) {
die('You aim the bow at the dwarf. Before you can get the shot off, she pulls a disproportionately large \
axe from her tunic and hurls it at your head. It\'s a well-aimed throw.');
} else if(person==fraf) {
say('You fire an arrow at Fraf. He deftly catches it out of the air and snaps it in half.');
} else if(person==staunton) {
say('You fire an arrow at Staunton. It flies past his pointy hat. "What the [[ gs(MAGIC_WORD) ]] was that?" he cries.');
get_point_for(HEARD_MAGIC_WORD);
} else if(person==miranda) {
say('You fire an arrow at Miranda. It shatters against her armour. She gives you an austere look, and shakes her head.');
} else if(person==minion) {
say('You fire an arrow at the skeletal minion. It passes harmlessly between two of its ribs, then \
[[ heroloc().isOutdoors ? "flies off into the distance" : "shatters against a wall" ]].');
} else {
say('You fire an arrow at ' + the_person(person) + '. It misses wildly.');
}
}
/*** end bow ***/
/*** begin drink (file under BEER) ***/
th('drink',
'a drink',
false,
nowhere,
"A pewter tankard holding a pint of dark foaming ale. It's [[ gs(BEER_LEFT) == 10 ? '' : 'about ' + gs(BEER_LEFT) + '0% ' ]]full.",
{ 'talk' : 'It disagrees with you.',
'drink' : '*drink_beer()',
spill : spill_beer },
function() {
handle_drunkness();
}
);
drunk_levels = [ 'pleasant', 'a bit woozy', 'slightly drunk', 'very drunk', 'blotto' ]
function spill_beer() {
say("A small drop of beer falls to the [[ (heroloc().isCastle || !heroloc().isOutdoors) ? 'floor' : 'ground' ]]. Careful!");
return true;
}
function drink_beer() {
if(in_inv(drink)) {
sgs(BEER_LEFT, gs(BEER_LEFT) - 1);
say("You take a sip of ale. It's delicious, and makes you ");
var drunkness = gs(DRUNK);
if(drunkness==0) {
sgs(DRUNK, 5);
say("feel a bit woozy.");
} else {
sgs(DRUNK, drunkness += 5);
if(drunkness > 25) {
die("die of liver failure.");
} else if(drunkness > 20) {
say("feel rather ill.");
} else if (drunkness > 15) {
say("very drunk.");
} else if (drunkness > 10) {
say("drunk.");
} else say ("feel a bit woozier.");
}
if(!gs(BEER_LEFT) && !gs(GAME_OVER)) {
say(" You discard the empty tankard.");
take_away(drink);
}
} else {
say("I don't understand what you want to drink.");
}
}
function handle_drunkness() {
var drunkness = gs(DRUNK);
if(drunkness) {
// the more you've had to drink, the more often you get the messages
if(drunkness > 1 && pick(10) <= drunkness ) {
say('\n' + pickOne(["You sway on your feet.",
"The world spins.",
"You feel disconsolate.",
"You feel wonderful!",
"You feel like everyone is your best friend.",
"You feel like beating everyone up.",
"You sing a little song."
]));
if(personloc(minion)==heroloc()) {
say('\nThe skeletal minion jabs you with the butt of its spear. "Drunk and disorderly! ');
sayOne(['Get moving, ', 'Sober up, ', 'Move it, ', 'Get a move on, ']);
sayOne(['sot!"', 'lush!"', 'drunkard!"', 'layabout!"', 'wino!', 'souse!']);
say('"');
}
}
sgs(DRUNK, drunkness - 1);
if(!gs(DRUNK)) {
say('\nYour head feels a bit clearer.');
}
}
}
drink.shortname = 'beer';
/*** end drink (file under BEER) ***/
/*** begin BOOK ***/
th("book",
"a leatherbound book",
false,
nowhere,
"[[ get_point_for(READ_BOOK), '' ]]A thick tome bound in brown calfskin leather. You flip it open and read:\
And now we turn to the curious Tale of the towne of Muddy Cove, an \
unremark'd hamlet in the eaftern Marfhlands. It fo happen'd, that in order to booft \
their ftagnant Economie, a confortium of their Merchant-folk did concoct the tale \
that an Evil Sorcerer had ufurped the citie, attracting Queftors, Heroes and Adventurers \
from all o'er the lands, as well as fundry Tourifts, who would purchase tacky gewgaws and fouvenirs, \
e'en unto little glafs globes of Snow which made amufing Blizzards when fhook. The refult was a great \
Fattening of the Wallets of the mercantile peoples, but a fore Burden for the ordinary working townfolk, \
who were threaten'd, beaten and put out of Employment by numerous Undead Minions, \
fummoned by the Merchantmen in order to maintain their lucrative Charade.
",
{},
null);
/*** end BOOK ***/
/*** begin water (file under HOLY WATER) ***/
th('water',
"a phial of holy water",
false,
temple,
'A small glass tube containing a few millilitres of ordinary-looking water, with a small label certifying \
that the contents have been sanctified, beatified, consecrated and lightly carbonated \
by ministers of three popular religions.',
{
eat : "Try drinking it instead.",
drink : drink_holy_water,
spill : spill_holy_water,
drop : drop_holy_water
},
null);
water.shortname = "holy water";
function drink_holy_water() {
say("You chug down the holy water. ");
if(gs(FRAF_DEAD) || gs(ARIANE_DEAD) || gs(MIRANDA_DEAD) || gs(STAUNTON_DEAD)) {
// murderer!
die(" Aaaargh, it burns, it burns!");
} else {
say("It tastes like ordinary water.");
}
return true;
}
function spill_holy_water() {
if(is_personname(Token[3]) || (Token[3])=='on' && is_personname(Token[4])) {
var person = eval(Token[is_personname(Token[3])?3:4]);
if(personloc(person)!=heroloc()) {
say("You can't see " + the_person(person) + " here.");
return true;
} else if(person==hellhound && asleep(hellhound)) {
say("Best let sleeping dogs lie.");
return true;
} else {
take_away(water);
say("You hold the phial aloft and empty it over " + the_person(person) + "'s head.\n");
if(person==robot) {
die("There is a CRACK, an electric blue flash, and an unpleasant tingling sensation \
as an arc of electricity zooms up your arm. ZOT!", "Well done, you've electrocuted yourself");
} else if(person==mummy) {
say("There is a hissing sound, but the mummy shakes it off and carries on. \
(Maybe you were thinking of vampires?)");
/* say("The mummy stops in its tracks, spins around twice, and slowly melts away \
to nothing.");
get_point_for(MUMMY_DEAD); // too easy
set_personloc(mummy, nowhere);
if(!gs(FRAF_DEAD)) {
sgs(FRAF_FREE, 1);
} */
} else if(person==hellhound) {
say("There is a sizzling noise, and the hellhound emits a bewildered whine as it implodes \
in a splash of ectoplasm.");
set_personloc(hellhound, nowhere);
sgs(DOG_HAS_STAUNTON, 0);
get_point_for(HELLHOUND_DEAD);
if(personloc(staunton)==heroloc()) {
get_point_for(STAUNTON_FREE);
}
say('\n"Thank you," says Staunton.');
if(in_inv(staff)) {
take_away(staff);
give_person(staunton, staff);
say(" He grabs his staff back from you.");
} else if(!belongs_to(staunton, staff)) {
say(" He mutters a spell, and his staff flies into his hand.");
give_person(staunton, staff);
}
} else if(person==miranda) {
say('"Thank you, I suppose," says Miranda. "I\'ve been thoroughly baptised already, of course, \
but a top-up can\'t hurt."');
} else if(person==fraf) {
say("Fraf gives you a confused glare, and shakes the water off his head.");
} else if(person==staunton) {
say('Staunton says "' + capitalise(gs(MAGIC_WORD)) + '", and he\'s dry again.');
get_point_for(HEARD_MAGIC_WORD);
} else if(person==ariane) {
say('Ariane laughs as the water runs down her face, and flicks it out of her hair.');
} else if(person==minion) { // nice try
say('The minion looks alarmed, but steps out of the way of the splash before it hits. The water falls to the '
+ ((heroloc().isCastle || !heroloc().isOutdoors) ? 'floor' : 'ground') + '.' );
} else {
say( capitalise(the_person(person)) + ' gives you a glare, and wipes the water off ' + their(person) + ' face.');
}
return true;
}
}
say("You let a drop of holy water fall to the [[ (!heroloc().isOutdoors || heroloc().isCastle) ? 'floor' : 'ground' ]].");
if(heroloc().isCastle) {
say(" It sizzles slightly when it lands.");
}
return true;
}
function drop_holy_water() {
// doesn't make the game unwinnable (but does close off the evil ending)
take_away(water);
say("You drop the holy water. The phial shatters into a thousand pieces, and the water evaporates.");
return true;
}
/*** end HOLY WATER ***/
/*** begin KITE ***/
th('kite',
'a kite',
false,
laboratory,
"A diamond-shaped kite about two feet across, made of a thin shiny foil. It is attached to one end of an almost invisibly thin wire[[\
describe_wire() ]]",
{
fly: fly_kite,
throw: fly_kite,
/* drop: drop_kite */
},
null
);
/* function drop_kite() {
if(!in_inv(kite)) {
return false;
}
if(heroloc()==laboratory) {
return false;
}
say("As you let go of the kite, the wire attached to it spools backwards, pulling it back " + heroloc().kiteTrail +
((traildir=='up' || traildir=='down') ? ' the stairs' : '') + '.');
take_away(kite);
set_thingloc(kite, laboratory);
return true;
} */
function describe_wire() {
if(heroloc()==laboratory) {
say(". The other end of the wire is fixed to one side of the marble slab.");
} else if(typeof heroloc().kiteTrail !== 'undefined') {
var traildir = heroloc().kiteTrail;
say(", which trails " + traildir + ((traildir=='up' || traildir=='down') ? ' the stairs' : '') + '.');
} else {
// shouldn't be able to get here with the kite.
say(", which trails away. There are bugs crawling on it.");
}
}
function fly_kite() {
if(!heroloc().isOutdoors) {
say("You can't fly a kite indoors!");
return true;
} else {
get_point_for(FLOWN_KITE)
say("You throw the kite in the air. It flutters a little in the breeze.");
take_away(kite);
set_thingloc(kite,heroloc()); // should only be possible on battlements, but wherever
}
}
/*** end KITE ***/
/*** begin PAPER ***/
th('paper',
'a scrap of paper',
false,
nowhere,
'[[ get_point_for(READ_NOTE), "" ]]A small scrap of grubby paper, on which is written in a careless hand: "Meet at the Rampart."',
{},
function() {
if(!gs(GOT_NOTE) && gs(TOLD_ABOUT_JOB) && !pick(3) && heroloc().isOutdoors && heroloc().isTown) {
say('\nA scrap of paper flutters along in a breeze, and lands at your feet.');
set_thingloc(paper, heroloc());
sgs(GOT_NOTE, 1);
}
}
);
/*** end PAPER ***/
/*** begin PAINTING ***/
th('painting',
'a painting',
false,
nowhere,
"The painting is a scene by a master surrealist. It depicts the bearded face of a man in a bowler hat, \
surrounded by walls meeting at impossible multidimensional corners, waterfalls that flow upwards, \
fish melting into seagulls that tesselate into lizards, and robed figures standing at odd angles. \
Your eyes hurt a bit just from looking at it.",
{},
null);
/*** end PAINTING ***/
/*** begin SCROLL ***/
th("scroll",
"a scroll",
false,
alchemists_shack,
'The scroll is a page from a recent edition of "Occultists\' Moonly". It reads: \
"Finally, we have been sent a handy tip from Mistress Trellis of North Frobozz, who writes, \'To \
summon a skeletal minion, simply say the magic word CALCANEUS. It may not be friendly, \
but it can be asked about all sorts of things.\' Thanks, Mistress Trellis! \
You win three pounds of frog innards."',
{},
null);
/*** end SCROLL ***/
/*** begin SNOWGLOBE ***/
th('snowglobe',
'a snowglobe',
false,
market,
"A little sphere of glass containing a miniature replica of Zapdorf's castle, and a lot of little flecks of snow.",
{
wave: shake_snowglobe
},
null
);
function shake_snowglobe() {
say("You shake the snowglobe, and nothing happens to the castle inside. What a dud.");
if(heroloc().isOutdoors) {
if(!heroloc().isCastle) {
say("\nTo the [[ heroloc()==beach ? 'east' : 'north' ]], a cloud appears briefly above Zapdorf's castle.");
} else if (heroloc()==battlements) {
say("\nAround you, the wind picks up and it starts to sleet heavily. Thunder roars. ");
if(in_inv(kite)) {
die("A fork of lightning crashes down and connects with the kite you are holding. ZOT!",
"Well done, you've electrocuted yourself");
}
else if(thingloc(kite)==battlements) {
say("The kite takes off into the sky. A fork of lightning crashes down and connects with it. ZOT! \
The kite and its wire crumble into ash and blow away. From far below you, you hear a strange buzzing noise.\n\
As suddenly as it started, the storm stops.");
set_thingloc(kite, nowhere);
get_point_for(ROBOT_ACTIVATED);
unsleep(robot);
}
else {
say("There is a flash of lightning. ")
say("Then, as suddenly as it started, the storm stops.");
}
}
} else if(heroloc().isCastle) {
say(" For a few seconds, you hear the wuther of heavy wind outside.");
}
}
/*** end SNOWGLOBE ***/
/*** begin STAFF ***/
th('staff',
'a magic staff',
false,
nowhere,
'A smooth, two-yard-long stick of some heavy dark material. It has a knob on the end.',
{
point: point_staff,
wave: "You wave the staff about, and immediately nothing happens."
},
function() {
if(gs(STAFF_POINTED_AT)) {
if(personloc(Person[gs(STAFF_POINTED_AT)])!=heroloc()) {
sgs(STAFF_POINTED_AT, 0);
}
}
});
function point_staff() {
if(!Token[3]) {
say("I don't understand who you want to point the staff at.");
} else if(is_thingname(Token[3]) || is_sighthere(Token[3])) {
say("That would be pointless.");
// todo: allow pointing at objects/scenery
} else if(!is_personname(Token[3])) {
say("That would be pointless.");
} else {
var zapee = eval(Token[3]);
if(personloc(zapee)!=heroloc()) {
say("You can't see " + the_person(zapee) + " here.");
return;
}
say("You point the staff at " + the_person(zapee) + ".");
sgs(STAFF_POINTED_AT, zapee.id);
if(zapee==staunton) {
say('\n"Watch what you\'re doing with that," says Staunton. "It\'s very dangerous in the wrong hands."');
} else if(zapee==ariane) {
if(gs(ARIANE_IN_TRAP)) {
say('\n"You wouldn\'t dare," says Ariane.');
} else {
say('"Mind where you point that," says Ariane.');
}
} else if(zapee==fraf) {
say("\nFraf reaches over with a tree-trunk arm and silently pushes the staff aside.");
sgs(STAFF_POINTED_AT, 0);
} else if(zapee==miranda) {
say('\n"I\'d advise against pointing that at me," says Miranda.');
} else if(zapee==hellhound && heroloc()==personloc(staunton)) {
say('\n"Excellent," says Staunton. "Now say the magic word \'[[ gs(MAGIC_WORD) ]]\'."');
get_point_for(HEARD_MAGIC_WORD);
}
// nobody else remarks, oh well
}
}
function say_magic_word() {
get_point_for(HEARD_MAGIC_WORD);
if(!in_inv(staff)) {
say("Nothing happens.");
}
else if(!gs(STAFF_POINTED_AT) || personloc(Person[gs(STAFF_POINTED_AT)])!=heroloc()) {
say("A jet of purplish flame shoots out of the top of the staff. Just as well you weren\'t pointing it at anyone.");
} else {
say("A jet of purplish flame shoots out of the end of the staff");
var zapee = Person[gs(STAFF_POINTED_AT)];
if(zapee==staunton) {
say(" and catches Staunton in the face. He rises a foot off the floor, his hair stands on end, and he's gone.");
get_point_for(STAUNTON_DEAD);
set_personloc(staunton, nowhere);
minion_cackle();
} else if(zapee==hellhound) {
say(" and hits the hellhound. It emits a bewildered whine as it implodes in a splash of ectoplasm.");
if(personloc(staunton)==heroloc()) {
say("\"Thank you,\" says Staunton, taking back his staff.");
give_person(staunton, staff);
take_away(staff);
sgs(TAKEN_STAUNTONS_STAFF, 0);
get_point_for(STAUNTON_FREE);
}
get_point_for(HELLHOUND_DEAD);
set_personloc(hellhound, nowhere);
} else if(zapee==ariane) {
if(gs(ARIANE_IN_TRAP)) {
say(" and catches Ariane in the chest. Her mouth is an 'O' of surprise as her body vanishes \
in a shower of pink sparkles.");
ariane_killed_in_trap();
} else {
die(". Ariane steps out of the way, draws her bow, notches an arrow, and skewers you.");
}
} else if(zapee==miranda) {
die(". Miranda bows her head and closes her eyes. The jet arcs around the back of her head in a U-turn, \
and catches you in the stomach.");
} else say(" towards " + zapee.fullname + ", and misses wildly.");
}
}
/*** end STAFF ***/
/*** begin T-SHIRT ***/
th('tshirt',
'a T-shirt',
true,
market,
'A short-sleeved, buttonless shirt of white cotton. It reads: "I TRIED TO OVERTHROW ZAPDORF THE SORCERER, AND ALL I GOT \
WAS MY SOUL SUCKED OUT THROUGH MY NOSE".',
{},
null);
tshirt.shortname = 'T-shirt';
/*** end T-SHIRT ***/
/*** begin tile ***/
th('tile',
'a [[ gs(TILE_GOLD) ? "gold" : "lead" ]] tile',
false,
nowhere,
'A thin sheet of [[ gs(TILE_GOLD) ? "brilliant yellow gold" : "dull grey lead" ]], about six inches square.',
{
},
null);
/*** end tile ***/
/*** begin waybread ***/
th("waybread",
"a piece of waybread",
false,
elf_trap_room,
"A thin sheet of coffee-coloured wafer, about six inches square, with a texture something like shortbread. \
It's an elven delicacy, which everyone else considers healthy, nutritious, and revolting.",
{
eat: '*eat_waybread()'
},
null);
function eat_waybread() {
say('With some trepidation, you munch down the waybread. It tastes like a cross between \
pumpernickel bread and cardboard. Yuck.');
if(personloc(ariane)==heroloc()) {
say('\nAriane\'s lip trembles. "You utter git," she says. "You don\'t even like it!"');
inc_score(); // get_point_for(teased_ariane)
}
take_away(waybread);
}
/*** end waybread ***/
/*
* Food for the pantry (keep together)
*/
th('artichoke', // doesn't really exist!
'an artichoke',
false,
nowhere,
'A spiky green vegetable.',
{},
null);
th('banana',
'a banana',
false,
pantry,
"Yellow and crescent-shaped.",
{
eat: "*eat_banana();",
open: "*eat_banana();",
bananaskin: "*eat_banana();" // "peel banana"
},
null);
function eat_banana() {
say("You peel and eat the banana. Delicious!");
take_away(banana);
give_hero(bananaskin);
get_point_for(BANANA_PEELED);
}
th('broccoli',
'some broccoli',
false,
pantry,
"A head of leafy, crunchy, fresh broccoli.",
{
eat: "[[ take_away(broccoli) ]]You chomp down the brocolli in one bite. Yum!",
},
null);
th('cabbage',
'a cabbage',
false,
pantry,
"A wrinkly green cabbage, smelling slightly earthy.",
{
eat: "[[ take_away(cabbage) ]]You tear the cabbage leaf from leaf and devour it. Yum!",
smell : "It smells like mud."
},
null);
th('cheese',
'a piece of cheese',
false,
pantry,
"A lump of hard yellow cheese with holes in.",
{
eat : "[[ take_away(cheese) ]]You chomp down the cheese in two bites. Delicious!",
smell : "It's powerful stuff."
},
null);
/*th('chicken', // too weird and different from the other foods
'a chicken',
false,
pantry,
'A plump chicken carcass, already beheaded and plucked.',
{
eat: "What, raw? No chance.",
talk: "Chickens aren't great conversationalists at the best of times, but this one's positively surly. \
Perhaps it's annoyed about having had its feathers and head removed."
},
null); */
th('sugar',
'a sugar cube',
false,
pantry,
"A small cube of fine white sugar.",
{
eat: "You throw the sugar cube in the air and catch it in your mouth. Yum!",
smell : "It smells sweet."
},
null);
th('tomato',
'a tomato',
false,
pantry,
"A juicy red tomato. Knowledge is knowing it's a fruit; wisdom is not getting into tedious semantic arguments.",
{
eat : "[[ take_away(tomato) ]]You swallow the tomato in one gulp. Yum!"
},
null);
pantryFoods = [tomato,cheese,broccoli,cabbage,sugar,banana];
/*
* End food
*/
/*** begin money (keep last, but before helmet) ***/
th('money',
'some money',
false,
hut,
'You have [[ numberToWords(gs(MONEY_LEFT)) ]] zorkmid[[ gs(MONEY_LEFT) == 1 ? "" : "s" ]] left. [[ money_comment() ]]',
{ 'talk' : "Turns out money doesn't talk.",
'count' : "*thingsee(money)" }
);
function money_comment() {
var moneyLeft = gs(MONEY_LEFT);
if(gs(MONEY_LEFT) > 6) {
say("You're rich!");
} else if(gs(MONEY_LEFT) > 4) {
say("Not much, but it should get you through the week.");
} else if(gs(MONEY_LEFT) > 2) {
say("Tight, but you'll manage.");
} else {
say("Better watch the pennies.");
}
}
// spend n zorkmids. return true if successful. take away the 'money' object if it falls to zero.
function spend(n) {
var moneyleft = gs(MONEY_LEFT);
if(!in_inv(money)) {
say("You haven't got any money.");
return false;
}
if(n > MONEY_LEFT) {
say("You haven't got enough money. You've only got [[ numberToWords(moneyleft) ]] zorkmids.");
return false;
} else {
sgs(MONEY_LEFT, gs(MONEY_LEFT) - 1);
if(gs(MONEY_LEFT) == 0) {
take_away(money);
}
return true;
}
}
/*** end money ***/
/*
* helmet - keep very last
*/
//th(name,fullname,wearable,firstplace,description,uses,daemon)
th('helmet',
'a horned helmet',
true,
nowhere,
"A full-face helmet of dark metal, with a pair of great barbed horns and a stylised skull motif. \
There is no doubt that whoever wears this helmet wishes it to be known that they are an evil sorcerer. \
It\'s about a size nine, maybe nine and a half.",
{
take: take_helmet,
wear: wear_helmet
},
null);
function take_helmet() {
return go_for_helmet(); // defined in porspec.js with the rest of the ending stuff
}
function wear_helmet() {
wear(helmet);
say(' You feel a powerful darkness.');
get_point_for(WORN_HELMET);
wear_helmet_at_ending();
}