/*
 *
 * Aunts and Butlers
 *
 * Places
 *
 * code and data dealing with 'the map'
 *
 */

Place = new Object;
NUM_PLCS = 0;
function pl(name,fullname,description,append,sights,special,exits,hExits)
{
	Place[++NUM_PLCS] = new Object;
	Place[NUM_PLCS].id = NUM_PLCS;
	Place[NUM_PLCS].name = name;
	Place[NUM_PLCS].fullname = fullname;
	Place[NUM_PLCS].description = description;
	Place[NUM_PLCS].append = append;
	Place[NUM_PLCS].sights = sights;
	Place[NUM_PLCS].special = special;
	Place[NUM_PLCS].exits = exits;
	Place[NUM_PLCS].hExits = hExits;
	eval(name + ' = Place[' + NUM_PLCS + '];');
}

pl('nowhere',
'nowhere',
'You\'re nowhere! You shouldn\'t be here!',
'',
'',
'',
'');

pl('bedroom',
'Your bedroom',
'Your bedroom is large and rather bare. The only furniture is a \
pine bed, and a mirror. The floor is bare \
boards, since you sold the carpet ages ago.',
'',
'mirror::You meet the gaze of a wiry, bleary-eyed gentleman with a twee little moustache \
and a worn check suit[[ list_worn_in_parens() ]]. You\'re quite handsome, \
in a roguish, greasy, perpetually-hung-over sort of way.\
/bed::A bare pine bed. It\'s not too comfortable but that\'s okay, \
because most nights you don\'t so much nod off as pass out.',
'break.mirror::No. That\'s bad luck.\
/open.mirror::You meet the gaze of a wiry, bleary-eyed gentleman with a twee little moustache \
and a worn check suit[[ list_worn_in_parens() ]]. You\'re quite handsome, \
in a roguish, greasy, perpetually-hung-over sort of way.',
'north::top_of_stairs',
'out::north');

pl('top_of_stairs',
'Top of stairs',
'A wide, redwood staircase leads down toward the foyer and, well, \
you\'re at the top of it. Your bedroom door is just to the south.',
'',
'stairs::[[stairs_desc]]',
'',
'south::bedroom.down::lobby',
'in::south');
stairs_desc = 'Probably home to a well-developed community of woodworm, \
but the stairs look safe enough.';

pl('lobby',
'Foyer',
'This is your foyer, the first room visitors see when they enter your house, and, \
unless you can\'t help it, the last. A redwood staircase leads upwards from a shabby \
greenish carpet; the walls are grimy except for the occasional slightly less grimy \
rectangle where a treasured family portrait has been sold off. The front door \
is in the south wall, and interior doors lead east and west.',
'',
'stairs::[[stairs_desc]]',
'',
'south::porch.east::drawing_room.west::servants_quarters.up::top_of_stairs',
'out::south');

pl('drawing_room',
'Drawing room',
'As one descends through the social classes, one finds rooms like this being called the \
living room, the sitting room and (shudder) the lounge. Here in civilisation we \
call it a drawing room. Not a pencil in sight, but there you are. \
It is, by your standards, a well-kept room, large, with a velvet armchair in one \
corner and a grand piano in another.',
'*if(personloc(solicitor)==drawing_room) {win_game();} else if(gs(DONE_MURDER)==1 && gs(SEEN_MURDER)!=1) { see_murder(); }',
'piano::A huge, three-legged beast that belonged to your father, built from wood \
dredged from the smoking remains of endangered rainforests and ivory hacked from the \
bleeding carcasses of majestic African animals. You keep it for the air of culture \
it lends to the room.\
/armchair::A plush armchair in indigo velvet-silk: soft, accommodating, and entirely uncomfortable.',
'learn.piano::Are you quite mad?\
/learn.play.piano::Are you quite mad?\
/play.piano::*play_piano()\
/west::*leave_drawing();/out::*leave_drawing();',
'west::lobby',
'out::west');
function leave_drawing()
{
	var mTime = gs(MURDER_TIMER)
	if(gs(DONE_MURDER)==0 || mTime==0)
	{
		set_heroloc(lobby);
		look();
		return;
	}
	
	if(mTime<=2 && personloc(virgule)==heroloc())
		say('Cousin Virgule holds you back.\n\
"Naw, cuz, we\'re in this together, ain\'t we?"')
	else if(personloc(plank)==heroloc())
		say('Sergeant Plank grabs you and pulls you back.\n\
"You\'re goin\' nowhere, mate.\"');
}
function see_murder()
{
	say('\n"Ampers, buddy," says Cousin Virgule, his shotgun smoking gently, \
"I done a bad thing."');
	
	sgs(SEEN_MURDER, 1);
	sgs(MURDER_TIMER, 1);
}
function play_piano()
{
	say(' *plink* *plunk* *plonk* *PER-lunk!*');
	if(personloc(cedilla)==drawing_room)
		say('\n"Dear me!" says Aunt Cedilla. "I hope you can do better than that!"');
	if(personloc(butler)==drawing_room)
		say('\n"Really, sir," says the butler, "that is not expedient to the situation."');
	if(personloc(virgule)==drawing_room)
		say('\nCousin Virgule is like, "Cut that out!"');
	if(personloc(plank)==drawing_room)
		say('\n"Cut that out, Fodge," says Sergeant Plank. "You\'re in enough trouble as it is."');
}

function win_game()
{
	inc_score();

	die('\n"Mr. Fodge," says the solicitor. "I represent the estate of Miss Cedilla Fodge. We have \
located her will, and it would seem she has bequeathed her entire fortune to yourself. The money will \
be in your bank account tomorrow morning. Good day."\n\
He prances out. The butler shimmers in, with a bottle of champagne on a silver salver.\n\
"Congratulations, sir," he says. "You appear to have won. Refreshment?"', 'You are rich');
	winner = true;
}


// (name,fullname,description,append,sights,special,exits,hExits)
pl('scullery',
'Scullery',
'You are in a tiny scullery. The floor and walls are marble-tiled and \
absolutely filthy. Water drips steadily down from a hole in the unmaintained slate \
roof.',
'',
'ceiling::[[scullery.holedesc]]\
/water::[[scullery.holedesc]]\
/hole::[[scullery.holedesc]]',
'take.water.teacup::*fill_cup();\
/take.water.in.teacup::*fill_cup();\
/take.water::You\'ll have to tell me how.',
'south::servants_quarters',
'out::south'
)
scullery.holedesc = 'You\'ve been meaning to get that done for years. Well, actually \
you haven\'t been bothered in the least, but you\'ve been sort of meaning to mean to \
fix it. Dirty grey water drips stubbornly through the hole, even though it hasn\'t \
rained for a fortnight.'

pl('servants_quarters',
'Servants\' quarters',
'These are the long-abandoned lodgings of the household staff of Fodge Manor, \
stripped almost completely bare by the mass-exodus of those staff a few years \
ago, when you finally admitted to them that you couldn\'t pay their wages. \
The bunks, wallpaper, the carpets - everything has gone, except for a large trunk \
which lies at an odd angle in the middle of the floor.[[ gs(TRUNK_OPEN)==1 ? \
" Its lid is open, revealing a cast-iron staircase leading down." : " Its lid is shut." ]]',
'*set_trunk_exits()',
'trunk::Perhaps the trunk was too heavy for the fleeing servants to take with them. \
Its lid is [[gs(TRUNK_OPEN)==1 ? "open, revealing a cast-iron staircase leading down" : "shut fast"]].\
/stairs::[[gs(TRUNK_OPEN)==1 ? "Oh, you know. Just an ordinary eldritch cast-iron staircase." : "Nothing special."]]',
'move.trunk::It won\'t budge.\
/get.trunk::It\'s too heavy.\
/kick.trunk::You succeed only in stubbing your toe.\
/open.trunk::*open_trunk();\
/shout.password::*sayPassword();', // say.password caught in anywhere_special()
'north::scullery.east::lobby',
'out::east'
);
function set_trunk_exits()
{
	if(gs(OPENED_TRUNK)==0)
	{
		servants_quarters.exits = 'north::scullery.east::lobby';
		servants_quarters.hExits = 'out::east';
	}
	else
	{
		servants_quarters.exits = 'north::scullery.east::lobby.down::below_stairs'
		servants_quarters_hExits = 'out::east.in::down'
	}
}
function open_trunk()
{
	// todo: later on, the trunk IS open, and allows exit downstairs.

	if(true)
	{
		say('The trunk seems to be locked shut. You do, however, notice a small \
inscription on the lock: \"SAY PASSWORD AND ENTER.\"');
	}
}
function sayPassword()
{
	say('"Password," you say, correctly rhyming the first syllable with \'farce\'.')
	if(heroloc() == servants_quarters)
		say('\nA muffled voice, crackling like a gramophone record, replies, "Push off, toff!"');

}

pl('porch',
'Front porch',
'A rickety wooden structure welcomes guests into Fodge Manor with all the \
hospitality you wish to convey, i.e. none at all. A narrow street leads southward \
toward the centre of Bickering village.',
'*get_suitcase()',
'suitcase::*(gs(GOT_SUITCASE)==1) ? thingsee(suitcase) : say(suitcase.description)',
'take.suitcase::[[ (gs(GOT_SUITCASE)!=1) ? \"=No, Ampersand! I will not have a nephew of \
mine doing servants\' work!\" : take(suitcase) ]]\
/south::*leave_manor()/out::*leave_manor();\
/knock::You\'re not in.',
'north::lobby.south::village_green', // XXX - maybe add another 'road' room between here and village green?
'in::north.out::south');
function leave_manor()
{
	if(gs(GOT_SUITCASE)==0)
		say('Aunt Cedilla bars your way. \"Fetch your butler at once!\"')
	else if(gs(DONE_TEA)==0)
		say('Aunt Cedilla\'s voice from inside the Manor calls you back.\n\
"You\'re going nowhere until I have had my tea."')
	else
	{
		if(personloc(cedilla)==drawing_room && !worn(tailcoat))
			say('From inside the Manor, Aunt Cedilla calls after you: \
"Don\'t be long, Ampersand!"\n\n');

		set_heroloc(village_green);
		look();
	}
}
function get_suitcase()
{
	if(heroloc() == porch && worn(tailcoat) && gs(GOT_SUITCASE)!=1)
	{
		give_hero(suitcase);
		sgs(GOT_SUITCASE, 1);
		inc_score();
		say('\n"So there you are at last," barks Aunt Cedilla. She has evidently \
mistaken you for a butler.\n\
"Take this, and then report to your master demanding fifteen lashes for your \
tardiness. And tell him I shall be in the drawing room awaiting a cup of tea."\n\
She shoves her suitcase into your chest, and paces into the Manor.');

		set_personloc(cedilla, drawing_room);
	}
	return '';
}


pl('village_green',
'Village Green',
'This patch of neatly-mown grass, about twenty yards square, is the social centre \
of the village of Bickering, Home Counties. Some sticks protrude from the lawn \
where local urchins have been playing cricket, and a few horses-and-carts trundle \
past.',
'*person_follow(virgule, outside_station, village_green); virguleLeaves(); person_follow(alf, leafy_path, village_green)',
'horse::Rickety horse-drawn carts haul essential goods into Bickering from London. \
Or possibly away from Bickering, towards London. Working-class stuff; you\'ve \
never had to worry about it.',
'play.cricket::You\'re out of practice.',
'north::porch.northeast::leafy_path.south::outside_station.west::outside_police',
'');

pl('outside_station',
'Outside station',
'Bickering\'s south road ends at the entrance to the village railway station[[ \
gs(STATION_CLOSED)==1 ? ", which is now permanently closed." : \
". A turnstile leads in." \
]]', // todo
'*person_follow(virgule, station, outside_station); setStationExits();',
'',
'south::*enterStation();\
/in::*enterStation();/south::*enterStation();',
'north::village_green.in::station',
'south::in'
);
function setStationExits()
{
	if(gs(STATION_CLOSED)==1)
		outside_station.exits = 'north::village_green'
	else
		outside_station.exits = 'north::village_green.in::station';
}
function enterStation()
{
	if(gs(STATION_CLOSED)==1)
		say('The railway station is now permanently closed.')
	else
	{
		set_heroloc(station);
		look();
	}
}


pl('station',
'Railway station',
'You are in Bickering railway station, a typical small-village stop on the British transport \
network. Because this is the early part of the twentieth century, it\'s in fairly \
good condition. Posters and notices line the clean walls. The noise and smoke of steam-powered \
trains waft towards you from the south.',
'*person_follow(virgule, platform, station)',
'portrait::[[station.posterDesc]]/sign::[[station.posterDesc]]',
'north::*leaveStation();/out::*leaveStation();',
'out::outside_station.south::platform',
'north::out'
);
station.posterDesc = 'One particular notice catches your attention. It reads:\n\
DUE TO UNACCEPTABLE QUANTITIES OF LEAVES ON LINES IN THIS AREA, BICKERING STATION \
WILL SHORTLY BE CLOSING FOREVER. BRITISH RAIL OFFERS NO APOLOGY FOR THE \
WIDESPREAD INCONVENIENCE THIS WILL NO DOUBT CAUSE.';
function leaveStation()
{
	var doLeave = true;
	
	if(visited(platform))
	{
		if(gs(VIRG_ARRIVED)!=1)
		{
			// player shouldn't leave the station yet. Warn him.
			
			if(butlerWarn('Your kinsman\'s train is due to arrive \
imminently. It would be courteous to await his arrival in the station.',
			   WARNED_LEAVESTN))
			   	doLeave = false
			   else
			   	doLeave = true;
		}
		else
			// Virgule arrived, so it's okay to leave
			doLeave = true;
		
//		if(gs(VIRG_ARRIVED)!=1 && gs(NO_WARNINGS)!=1 && gs(WARNED_LEAVESTN)!=1)
//		{
//			butlerWarn('Your kinsman\'s train is due to arrive imminently. \
//It would be courteous to await his arrival in the station.');
//			sgs(WARNED_LEAVESTN, 1);
//			doLeave = false;
//		}
//		else
//		{
//			say('As you leave the station, a misguided government closes it permanently \
//	behind you, dooming your village to half a century of economic and social stagnation \
//	before it finally gets obliterated by the M25.\n\n');
//			sgs(STATION_CLOSED, 1);
//			doLeave = true;
//		}
	}
	if(doLeave)
	{
		if(visited(platform))
		{
			// Close the station
			say('As you leave the station, a misguided government closes it permanently \
	behind you, dooming your village to half a century of economic and social stagnation \
	before it finally gets obliterated by the M25 motorway.\n\n');
			sgs(STATION_CLOSED, 1);
			
			// Note, the player already got a point when Virgule arrived
		}

		set_heroloc(outside_station);
		look();
	}
}

var TR_APPR = true; // train approaching or departing
pl('platform',
'Platform',
'[[ (TR_APPR = (gs(VIRG_ARRIVED)!=1)), "" ]]\
A low, paved platform beside a single-track railway, just south of the station building. \
There is a [[TR_APPR ? "strong" : "weak"]] smell of coal-smoke and you hear the \
[[TR_APPR ? "approaching" : "distant, diminishing"]] noise of a steam-engine.',
'', // virgule's arrival 'fused' in by anwhere_do();
'railway::Single-track, narrow-gauge, and shiny, cutting a more-or-less straight \
line from London to Bickering, and continuing westward into the unchartered wilds of \
Wales, where square-jawed empire-building Englishmen continue in their attempts to \
spread civilisation.',
'south::*crossRails();',
'north::station',
'out::north.in::north' // either might be 'intuitive' depending on whose intuition
);
function crossRails()
{
	if(!butlerWarn('Walking upon railway tracks is a notoriously perilous \
activity, and I believe there is a train due shortly.', WARNED_CROSSRAILS))
	{
		die('You hop off the platform onto the tracks, and you are instantly \
struck by the 11.02 from London Euston to Llanpwllhlellgwn, causing severe disruption.');
		// or Paddington
	}
}
function virguleArrives() // called from anywhere_do
{
	// You can be anywhere when this happens, although if you've ever
	// left the station, it'll be closed and you'll have just made the
	// game unwinnable by not waiting for Virgule.
	//
	// So, you get a point (more of an acknowledgement that the game is
	// another few percent complete, than a reward for an achievement)
	// if you're still in the station.
	
	var amploc = heroloc();
	if(amploc==platform)
	{
		say('\nAn express train, drawn by a huge iron steam engine, \
draws up to the platform and stops. A door opens and Cousin Virgule emerges, a \
shotgun under his arm. He rushes up to you and says - as well as you can discern \
through his ridiculous accent - "Howdy, cousin!"\n\
The train releases a cloud of steam and chuffs powerfully off.');
		set_personloc(virgule, platform);
		inc_score();
	}
	else if(amploc==station)
	{
		say('\nYou hear a train pulling up, a door slamming, and a train \
pulling away again. In another moment, Cousin Virgule arrives from the south, a \
shotgun under his arm. He rushes up to you and says - as far as you can make out \
through his ridiculous accent - "Howdy, cousin!"');
		set_personloc(virgule, station);
		inc_score();
	}
	else
	{
		// Bummer.
		say('\nFrom the distant south, you hear the chuffing of \
a steam train, followed by some muffled American swearing.');
	}
	
	sgs(VIRG_ARRIVED, 1)
}


pl('outside_police',
'Outside police station',
'Bickering\'s west road ends just outside the small, brick shack that serves \
as the local police station. Its door is open and a light is on inside, \
but it\'s somehow uninviting. Blocks of flats line the road on the north and \
south side.',
'*person_follow(alf, village_green, outside_police);',
'',
'',
'east::village_green.in::police',
'west::in');

pl('police',
'Police station',
'A typical village police station, geared to sleepy rural life and clearly not \
designed to cope with any emergency greater than a lost hat or the occasional \
cat-up-tree crisis. There is a single desk in a corner, piled with paperwork and \
a box marked "LOST PROPERTY".',
'*person_follow(alf, outside_police, police);',
'paperwork::Actually they\'re all copies of the same one piece of paperwork, but it\'s had to be \
filled out in centriplicate.\
/box::A cubical cardboard box, marked LOST PROPERTY.',
'open.box::*open_lost_property();\
/take.box::Sergeant Plank stops you. "Not so fast, sonny."',
'out::outside_police.north::cell',
'east::out'
);
function open_lost_property()
{
	if(gs(GOT_HAT)==1)
	{
		say('There\'s nothing else in the lost-property box.');
	}
	else
	{
		inc_score();
		set_thingloc(hat, police);
		say('Opening the lost-property box reveals an ugly hat.');
		sgs(GOT_HAT, 1);
	}
}

pl('cell',
'Gaol cell',
'A tiny, dark, stinking cell lined with porcelain tiled walls, dented here \
and there where experiments in cat-swinging have failed.',
'*person_follow(alf, police, cell); if(gs(DONE_MURDER)==1 && gs(DONE_PIGEON)==0) tell_gaolbreak();',
'',
'smell::The cell continues to stink of its previous inhabitants and their \
various by-products.',
'south::police',
'out::south'
);
function tell_gaolbreak()
{
	say('\n"Good afternoon, sir," says the butler, with a bow. "Should you wish \
to express gratitude for my earlier intervention, might I request that you \
inform an acquaintance of mine, a Northerner named Alf, of the situation. This \
pigeon will lead you to him."\n\
He raises a hand and a carrier pigeon flits out of his cuff and begins circling \
your head.');
	sgs(DONE_PIGEON, 1);
	sgs(GOT_PIGEON, 1);
	inc_score();
}

pl('leafy_path',
'Leafy path',
'A leaf-covered country lane with hedgerows at the edges bends round from the \
southwest to the north. There is a friendly wooden signpost here.',
'*sgs(NORTH_OF_BRIDLE, 0); person_follow(alf, bridleway, leafy_path);',
'sign::It\'s one of those tryingly cutesy signposts with sections shaped like arms \
with pointing fingers. One arm points southwest, reading "BICKERING"; another \
points north, reading - convincingly enough - "THE NORTH".',
'',
'north::bridleway.southwest::village_green',
'');

pl('bridleway',
'Bridleway',
'A wide, shady, earthy brown path, fringed by neat hedgerows, runs north-south. \
The sweet chirping of insects and the stench of fresh manure drift in from the \
miles of farmland around you. The bridleway continues out of sight in either \
direction.',
'*sgs(NORTH_OF_DIVIDE, 0); person_follow(alf, divide, bridleway);',
'',
'north::*bridleNorth();\
/south::*bridleSouth();\
/smell::Euch. Well, that\'s the English countryside for you.\
/west::The hedgerows block your way.\
/northwest::The hedgerows block your way.\
/southwest::The hedgerows block your way.\
/east::The hedgerows block your way.\
/northeast::The hedgerows block your way.\
/southeast::The hedgerows block your way.',
'north::divide.south::leafy_path',
'');
function bridleNorth()
{
	if(gs(NORTH_OF_BRIDLE)==0) say('You follow the bridleway for what seems like hours...\n\n')
	// So you\'ve just walked from the Home Counties to Yorkshire, maybe 250 miles. Hmmm.
	set_heroloc(divide);
	look();
}
function bridleSouth()
{
	if(gs(NORTH_OF_BRIDLE)==1) say('You follow the bridleway for what seems like hours...\n\n')
	set_heroloc(leafy_path);
	look();
}

pl('divide',
'The Divide',
'[[ gs(NORTH_OF_DIVIDE)==1 ? divide.fromNorthDesc : divide.fromSouthDesc ]]',
'*sgs(NORTH_OF_BRIDLE, 1); person_follow(alf, maze1, divide);',
'divide::An infinitely thin, yet clearly visible, dotted line of the kind more \
usually found on cornflakes packets near a slogan such as "CUT HERE". It runs \
straight across the soil-or-is-it-tarmac and up the insides of the hedges-or-are-\
they-walls, sharply separating the two sections with no discernible gap. The \
overall effect is as if is two completely different worlds have been stitched \
together with black thread.',
'north::*mazewarn();',
'north::maze1.south::bridleway',
'');
divide.fromSouthDesc = 'The bridleway changes abruptly into a narrow, macadammed \
alleyway leading north, the hedgerows replaced by red brick walls. A dotted line \
runs east-west along the ground, clearly separating the two sections of path.';
divide.fromNorthDesc = 'The alleyway changes abruptly into a wide, earthy bridleway \
leading south, the red brick walls replaced by hedgerows. A dotted line runs \
east-west along the ground, clearly separating the two sections of path.';
function mazewarn()
{
	if(!butlerWarn('Beyond this divide lies the industrial wasteland of the North of \
England, a notoriously uncivilised part of our nation. Poverty, peril, and freeze-dried gravy \
await those who tread there. I do not feel you are yet ready to venture into such a \
barbaric region.', WARNED_MAZE))
	{
		set_heroloc(maze1);
		look();
	}
}


/**********************************************************************
 *                                                                    *
 *                                                                    *
 *                             THE MAZE                               *
 *                                                                    *
 *                                                                    *
 **********************************************************************
 *
 * This isn't a really nasty old-school maze: it's not very big, exits
 * are listed, and there are no false reverses.
 *
 * In fact, the maze is certainly fatal (after a few moves) if you
 * enter it before it's 'time' to do so in the game - before the murder
 * of Aunt Cedilla - and trivial afterwards (the pigeon shows you the
 * way). It's really just in there to be funny.
 *
 * The player is warned explicitly upon entering the maze that it's
 * "not time yet", so he can go on if he likes, but he should know that
 * the solution to egtting through the maze is not brute-force.
 * (The solution to getting BACK does involve remembering the way
 * through!)
 *
 *   19 -- 18 -- 20    14 -- 13
 *          |     |           |
 *   15 --- 5    Alf    9    12
 *    |     |           |     |
 *   16     3 --- 4 --- 6    11
 *    |     |           |     |
 *   17     2 --- 1     8 -- 10
 *                |
 *                |
 *        north-south-divide
 */

// the correct way to go from any spot in the maze - used by the pigeon
var MAZESOLUTION = new Array('',
'west', 'north', 'north', 'west', 'north',	// 1-5
'west', '', 'north', 'south', 'west',		// 6-10
'south', 'south', 'south', 'east', 'east',	// 11-15
'north', 'north', 'east', 'east', 'south'	// 16-20
)

var MAZEDESC = 'You are in a maze of twisty red-brick alleyways, all alike.';
var MAZEAPPEND = '[[mazeDie(), ""]]';

// DEATH IN THE NORTH, and how pigeons and Alf prevent it.
// a single array (for ease of coding), in clumps of four - a threat, how it kills you,
// how the pigeon prevents it, and how Alf prevents it.
var mazeDeaths = new Array(
'A pack of rabid [[pick(2)==0 ? "whippets" : "ferrets"]] comes hurtling towards you \
out of nowhere',
', and tramples you to dust.',
'. The pigeon gives a mighty coo, distracting them, leads them away down a side \
alley, and returns alone a moment later.',
'. Alf produces a stick from his overalls, and flings it over a wall. The creatures \
follow it out of sight.',

'A cloth-capped, red-flag-waving Bolshevist approaches you, and judges from your lack of \
smell that you are a no-good, freeloading bourgeois \
scumbag.',
' He proceeds to club you to death with a chimney-brush.',
' He notices, however, that since you have a pigeon you can\'t be all bad, gives you \
a brotherly nod, and moves on.',
' Luckily, a quiet noise from Alf is enough to pacify him, and he moves on.',

'Blinded by a cloud of smog, you stumble down a disused mine-shaft',
' and plummet to your doom.',
'. The pigeon swoops after you, grabs you in its talons by the collar, and airlifts \
you to the surface.',
'. Alf manages to react just in time, and pulls you to back to safety.',

'A serial killer leaps out, ',
'effects an expert murder upon your person, and buries you on the nearest moor.',
'but is driven away by a tactically ingenious aerial assault from the pigeon.',
'spots Alf, gives him an embarrassed wave, tries not to look like a serial killer, \
and moseys off.'

// more! more!
)

// things which can happen in the maze, but don't kill you
var NORTH_NOISES = new Array(
'A teenage girl wearing a ridiculous amount of make-up skips happily past, dole-cheque in hand.',
'In the distance, a voice sings "Ilkley Moor Bar T\'at."',
'A stench of cheap gravy wafts by, almost making you retch.',
'Everything feels grim for a moment.',
'Icy rain buckets down for a few seconds.'
);

function mazeDie()
{
	if(gs('gameover')!=1)
	{

		var pigeonHere = (gs(GOT_PIGEON)==1);
		var alfHere = (personloc(alf)==heroloc());
		if(pick(5) > 0)
		{

			// some insignificant Northern event, sometimes.
			var noiseNum = pick(NORTH_NOISES.length * 3);
		
			if(noiseNum < NORTH_NOISES.length)
				say('\n' + NORTH_NOISES[noiseNum]);
		
			return '';
		}
	
		var deathNum = pick(mazeDeaths.length / 4);
		var i = deathNum * 4;
		if(pigeonHere)
			say('\n' + mazeDeaths[i] + mazeDeaths[i + 2]);
		else if(alfHere)
			say('\n' + mazeDeaths[i] + mazeDeaths[i + 3]);
		else
		{
			// can't use die(), we're in the middle of a description
			DEATHSTRING = '\n' + mazeDeaths[i] + mazeDeaths[i + 1];
			die(DEATHSTRING);
//			sgs('gameover', 1);
		}
	
		return '';
	}
}

pl('maze1', 'The North', MAZEDESC, '[[sgs(NORTH_OF_DIVIDE, 1), ""]][[person_follow(alf, maze2, maze1)]]' + MAZEAPPEND, '', '',
'west::maze2.south::divide',
'');
pl('maze2', 'The North', MAZEDESC, '[[person_follow(alf, maze3, maze2)]]' + MAZEAPPEND, '', '',
'north::maze3.east::maze1',
'');
pl('maze3', 'The North', MAZEDESC, '[[person_follow(alf, maze5, maze3)]]' + MAZEAPPEND, '', '',
'north::maze5.east::maze4.south::maze2',
'');
pl('maze4', 'The North', MAZEDESC, MAZEAPPEND, '', '',
'east::maze6.west::maze3',
'');
pl('maze5', 'The North', MAZEDESC, '[[person_follow(alf, maze18, maze5)]]' + MAZEAPPEND, '', '',
'north::maze18.south::maze3.west::maze15',
'');
pl('maze6', 'The North', MAZEDESC, MAZEAPPEND, '', '',
'north::maze9.south::maze8.west::maze4',
'');
// There is no maze7.
pl('maze8', 'The North', MAZEDESC, MAZEAPPEND, '', '',
'north::maze6.east::maze10',
'');
pl('maze9', 'The North', MAZEDESC, MAZEAPPEND, '', '',
'south::maze6',
'');
pl('maze10', 'The North', MAZEDESC, MAZEAPPEND, '', '',
'north::maze11.west::maze8',
'');
pl('maze11', 'The North', MAZEDESC, MAZEAPPEND, '', '',
'north::maze12.south::maze10',
'');
pl('maze12', 'The North', MAZEDESC, MAZEAPPEND, '', '',
'north::maze13.south::maze11',
'');
pl('maze13', 'The North', MAZEDESC, MAZEAPPEND, '', '',
'south::maze12.west::maze14',
'');
pl('maze14', 'The North', MAZEDESC, MAZEAPPEND, '', '',
'east::maze13',
'');
pl('maze15', 'The North', MAZEDESC, MAZEAPPEND, '', '',
'east::maze5.south::maze16',
'');
pl('maze16', 'The North', MAZEDESC, MAZEAPPEND, '', '',
'north::maze15.south::maze17',
'');
pl('maze17', 'The North', MAZEDESC, MAZEAPPEND, '', '',
'north::maze16',
'');
pl('maze18', 'The North', MAZEDESC, '[[person_follow(alf, maze20, maze18)]]' + MAZEAPPEND, '', '',
'east::maze20.south::maze5.west::maze19',
'');
pl('maze19', 'The North', MAZEDESC, MAZEAPPEND, '', '',
'east::maze18',
'');
pl('maze20', 'The North', MAZEDESC, '[[if(gs(ALF_FOLLOW)==1) person_follow(alf, thenorth, maze20)]]' + MAZEAPPEND, '', '',
'west::maze18.south::thenorth',
'');

// It is actually possible to get here early, though unlikely and useless.
pl('thenorth',
'Rag-and-bone yard',
'The maze gives way to a cramped clearing. The air is dense with a smog of coal-dust \
and whippet fumes. Upturned tea-chests and piles of scrap metal litter the yard.',
'*if(gs(GOT_PIGEON)==1) alf_gets_message();',
'',
'',
'north::maze20',
'out::north');



/*
 * Below Stairs
 *
 */


pl('below_stairs',
'Below Stairs',
'A long, stone-walled, torchlit tunnel leads south, the high walls lined with hundreds \
of portraits. A cast-iron staircase leads up towards a wholly more ordinary-looking \
light.',
'',
'portrait::The walls of the corridor are covered from floor to ceiling with large portraits \
in gilded frames, of the kind usually reserved for royals and prime ministers. The subjects of \
these particular portraits, though, are more unusual - every one depicts some kind of servant in \
an act of menial duty. Here, a gardener pruning a hedge; here, a cook carefully arranging a pile of \
hors d\'oeuvres into a miniature replica of the Palace of Westminster; here, a chambermaid \
polishing the nails of some faceless noblewoman painted carefully out-of-focus.\
[[butler_comment_on_portraits() ]]\
/stairs::Oh, you know. Just an ordinary eldritch cast-iron staircase.',
'',
'south::service_nw.up::servants_quarters',
'out::up'
);
function butler_comment_on_portraits()
{
	if(personloc(butler)!=heroloc())
		return ''
	else
		return('\n"This place," says the butler behind you, "is the domain of these people. \
Not rulers nor owners nor thinkers nor artists; simply those who serve."');
}

//function pl(name,fullname,description,append,sights,special,exits,hExits)
pl('service_nw',
'Northwest service corridor',
'A corridor with polished floors, wood-panelled walls and an arched marble ceiling \
curves from the north to the southeast, with stairs leading gently upwards to the west.',
'*get_card()',
'',
'west::*fall_backwards();move();/up::*fall_backwards();move();',
'north::below_stairs.southeast::servants_hall.west::london_street',
'up::west'
)

pl('london_street',
'London street',
'There is so much fog around your head that you can only be in London. The \
clopping of hooves and the ding-dings of omnibuses tell you that you are beside \
some busy road, but you cannot tell which one. Close enough to make out are \
the entrance to a luxury apartment building, and the staircase into an Underground \
station.',
'',
'fog::Thick, choking smog characteristic of the Metropolis. It makes you feel \
rather patriotic, in an asthmatic way.',
'east::*fall_forwards();move();/down::*fall_forwards();move();',
'in::oldmaid_towers.down::service_nw',
'north::in.east::down');

pl('oldmaid_towers',
'Oldmaid Towers',
'You are in the entrance hall of a plush-looking residential building, with glass doors. \
A red-carpeted stairway leads up to the flats, and there is a reception desk in a corner, \
to which a notice is attached.',
'',
'sign::"OLDMAID TOWERS, SW1. STRICT DRESS CODE FOR CALLERS."',
'up::*enter_flat();/in::*enter_flat();',
'out::london_street.up::aunts_flat',
'south::out.in::up'
);
function enter_flat()
{
  var numClothes = 0;
  for(var i=1; i<=NUM_THNG; ++i) if(worn(Thing[i]))
    ++numClothes;
  
  if(numClothes >= 9)
  {
    say('A doorman in a buttoned navy-blue uniform pops up from behind the desk, \
    doffs his cap, and disappears.\n\
You climb the stairs, and pass through an apartment door marked "FODGE".\n\n');
    move();
  }
  else
  {
    say('A doorman in a buttoned navy-blue uniform pops up from behind the desk, \
and calls you back.\n\
"I am sorry, sir," he says, "but all callers to our residents must be dressed to the nines. \
You" - he looks you up and down - "are dressed ' + dressedToThe[numClothes] + '."\n\
He disappears behind the desk.');
  }
}
var dressedToThe = new Array(
'to the nothings','only to the ones','only to the twos','only to the threes','only to the fours',
'only to the fives','only to the sixes','only to the sevens','only to the eights','to the nines'
);

pl('aunts_flat',
'Aunt\'s flat',
'You recognise this as Aunt Cedilla\'s Georgian spinster pad. It is one long, narrow \
room with a militaristically-made bed along one wall, and a square window opposite.',
'',
'bed::A thin, single bed with a lone black velvet blanket, and a faint aunt-shaped \
groove down the middle.\
/window::A poky, sill-less, half-open window with net curtains. It overlooks a \
section of railway, from which the chuffing of steam-engines can occasionally be heard.\
/railway::There is a section of railway below the window. The occasional chuff \
tells you that it is in regular use, but you can\'t see any trains at the very \
moment.',
'drop.bone.window::*kill_dog();\
/drop.bone.out.window::*kill_dog();\
/drop.bone.through.window::*kill_dog();\
/throw.bone.through.window::*kill_dog();\
/throw.bone.window::*kill_dog();\
/throw.bone.out.window::*kill_dog()\
/open.window::It\'s stuck half-open.\
/close.window::It\'s stuck half-open.\
/look.through.window::*sightsee("window");\
/look.out.window::*sightsee("window");\
/take.will::*take_will();',
'out::oldmaid_towers',
'down::out'
);
function take_will()
{
	if(personloc(gladstone)==heroloc())
		say('Gladstone, determined to defend his mistress\'s possessions, \
bites you savagely on the wrist. The will flutters to the floor.')
	else
		take(will);
}
function kill_dog()
{
	if(!in_inv(bone))
		say('You aren\'t carrying the bone.')
	else
	{
		inc_score();
		take_away(bone);
		set_personloc(gladstone, nowhere);
		say('You hurl the squeaky rubber bone through the window. Gladstone eagerly \
jumps after it. Chuff, chuff, yelp, squeak.');
	}
}

pl('servants_hall',
'Servants\' Hall',
'A huge hall, with a glass domed ceiling supported on stone pillars. The \
place is packed with people - servants, anyway - of all kinds: butlers, \
gardeners, cooks, maids, and several other \
varieties whose clothes you don\'t recognise, bustling against each other \
in a mayhem of individual paths. Tunnels lead off in all directions.',
'',
'crowd::Servants are like zebras. In a sufficiently large \
crowd, it\'s difficult to tell where one ends and the next begins. They all \
look suitably busy - far too busy to take any notice of you, at any rate.',
'look.butler::*see_butler_in_hall()',
'northeast::service_ne.east::service_e.southeast::service_se.south::service_s.southwest::service_sw.west::service_w.northwest::service_nw.north::service_n',
''
)
function get_card()
{
	if(thingloc(letter)==aunts_flat && thingloc(will)!=aunts_flat && gs(RIPPED_LETTER)==1 && gs(GOT_CARD)==0)
	{
		inc_score();
		sgs(GOT_CARD, 1);
		say('\nThe butler sidles up to you from nowhere in particular.\n\
"Excuse me, sir,"  he says, handing you a visiting-card. "This gentleman is waiting for you in your drawing-room. It is apparently a matter \
of some great import."');
		give_hero(card);
		set_personloc(butler, heroloc());
		set_personloc(solicitor, drawing_room);
	}
}
function see_butler_in_hall()
{
  if(personloc(butler)==heroloc())
    personsee(butler)
  else
    sightsee('crowd');
}
var crowd_servants = new Array( // used in ampspec/anywhere_do()
// Just for fun: these are all nameless descriptions of particular servants
// in literature. I don't expect people to recognise all or any of them, but
// it helps me write a lot of them and give them all miniature characters
'A valet in a bowler hat, carrying a pair of Etonian-coloured spats and a match,', // Jeeves
'A fat butler, swigging surreptitiously from a bottle of cooking-sherry,', // Beach
'A half-naked black slave, carrying a paddle,', // Jim (Huckleberry Finn)
'A wild-eyed gardener, humming some strange song about bankers\' clerks,', // 
// Mad Gardener ("Sylvie and Bruno", Lewis Carroll)
'A skinny office-boy in shirtsleeves, carrying a stapler,', // Gareth
'A sad metal person, carrying a bucket of water,', // Marvin
'A gruff-looking valet, carrying a few cucumbers,', // Lane (Earnest)
'A short, elf-like creature, muttering to itself,', // Dobby
'A thin, stooped, middle-aged housekeeper, carrying a teapot and an enormous plate \
of sandwiches,', // Mrs. Doyle
'A clownish eunuch in sacking trousers', // Peter the Eunuch
'A robot with an oddly-shaped plastic head, carrying a feather-duster,', // Kryten
'Some sort of hunched anthropomorphic duck, carrying a ketchup bottle,',
// Igor (Duckula)
'A hunched dwarf, carrying what looks like a pickled cauliflower,', // Igor
'An attractive housekeeper in a gold tailcoat', // Columbia
'A very tall chap with a square head and a butler\'s uniform', // Lurch
'An old butler with a grey moustache, carrying a bat-like mask,', // Alfred 
'A short, fat Spanish squire with a barber\'s basin on his head', // Sancho Panza
'A black manservant in a straw skirt, with a bone through his nose,', // Man Friday
'A bent, wiry manservant carrying a frying-pan', // Albert (Discworld)
'A trundling black cube, with an emerald set in it,', // Triage
'A landlady, carrying a bendy pipe and a deerstalker,', // Mrs. Hudson
'A harassed-looking Catalan waiter, carrying a moose\'s head,' // Manuel
)
function fall_backwards()
{
  say('You feel like you are falling backwards...\n\n')
}
function fall_forwards()
{
  say('You feel like you are falling forwards...\n\n')
}

pl('service_n',
'North service corridor',
'Square, low-ceilinged corridors with smooth beige walls and strip-lighting form \
a Y-shaped junction.',
'',
'',
'northeast::*enter_starship();\
/northwest::*fall_forwards();move();',
'south::servants_hall.northwest::office.northeast::starship',
''
);
function enter_starship()
{
	if(gs(STARSHIP_EXPLOSION_OVER)==1)
		say('The northeast corridor ends in a closed, handleless door that refuses to \
open.')
	else
	{
		fall_forwards();
		say('A door slides open as you pass through it, and closes automatically \
behind you.\n\n');
		move();
	}
}

// Some "time travel" places have a reflective surface for some
// Quantum Leap-esque fun.
pl('starship',
'Starship',
'This is a small room lined with reflective metal panelling, like \
the steerage quarters on a cheap steamship. In a corner of the floor there is a \
black circle, and on one wall there is a red button. A great, complex machine takes \
up most of the rest of the room.',
'',
'mirror::A plastic service robot looks back at you from the reflective \
panelling, its actions mimicking yours exactly.\
/panel::A plastic service robot looks back at you from the reflective \
panelling, its actions mimicking yours exactly.\
/machine::*describe_drive()\
/circle::A black circle, two feet in diameter.\
/button::A big red button just asking to be pushed.\
/teleporter::And what the devil is that?',
// note: "put haggis on circle" is parsed as "wear haggis circle"!
'stand.circle::*stand_in_circle();\
/stand.in.circle::*stand_in_circle();\
/stand.on.circle::*stand_in_circle();\
/in.circle::*stand_in_circle();\
/take.in.circle::*stand_in_circle();\
/take.on.circle::*stand_in_circle();\
/move.button::*do_teleporter();\
/drop.haggis.in.circle::*put_haggis_on_circle();\
/wear.haggis.circle::*put_haggis_on_circle();\
/drop.haggis.circle::*put_haggis_on_circle();\
/drop.haggis::*drop_haggis();\
/take.collar::*take_collar();\
/look.collar::*examine_collar();\
/southwest::*fall_backwards();move();/out::*fall_backwards();move();',
'out::service_n',
'southwest::out');
function examine_collar()
{
	if(gs(GOT_COLLAR)==0)
		say(collar.description)
	else
		thingsee(collar);
}
function take_collar()
{
	if(personloc(fatty)==heroloc())
	{
		say('Commander Fatty stops you. "[[ gs(FATTY_ON_CIRCLE) ? \
"Mfmmff mfmm fmffm mf\' mmfm mmfmmmfmf!" : "Dinnae mess aboot wi\' thon stardrive!" ]]" \
he snaps.');
	}
	else if(gs(GOT_COLLAR)==0)
	{
		inc_score();
		sgs(GOT_COLLAR, 1);
		say('You remove the trilatinum-splorex collar from the stardrive. The room begins \
to vibrate gently.');
		give_hero(collar);
		sgs(STARSHIP_EXPLODING, 1);
	}
}
var starship_explosion_warnings = new Array(
'A mid-Atlantic voice from nowhere warns: "Explosive decompression in five seconds."',
'A mid-Atlantic voice from nowhere warns: "Explosive decompression in four seconds."',
'A mid-Atlantic voice from nowhere warns: "Explosive decompression in three seconds."',
'A mid-Atlantic voice from nowhere warns: "Explosive decompression in two seconds."',
'A mid-Atlantic voice from nowhere warns: "Explosive decompression in one second. It is now safe to switch off your starship."'
);
function starship_explode()
{
	if(heroloc()==starship)
	{
		die('\nThe walls rupture, and you pop out into a freezing inky void.\n\
Contrary to much pulp science-fiction, exposure to the vacuum of space \
does not immediately turn the human body inside out and freeze-dry it. \
If you were rescued within a couple of minutes, you\'d probably get away \
with nothing worse than blindness, deafness, severe internal haemorrhaging, \
and irreparable brain damage. All a bit academic, alas, because you are not rescued.');
	}
	else
	{
		say('\nYou hear the muffled sound of a starship exploding in the distant future.');
	}
}

function describe_drive()
{
	say('How peculiar - you have no idea how you know all this...\n\
The machine is a Megawarp Gamma stardrive, the standard engine used on Endeavour \
Class interstellar craft.[[ gs(GOT_COLLAR)==0 ? " At its center is the trilatinum-splorex \
collar, the vital component that makes hyperspace travel possible." : " Obviously it \
doesn\'t work, because it is missing its trilatium-splorex collar." ]]');
}
function stand_in_circle() // bit of a copout, but there you go.
{
	if(personloc(fatty)==heroloc())
		say('You step towards the circle, but Commander Fatty hauls \
you back. "You\'re no\' teleportin\' nowhere, pal."');
	else
		say('You stand in the circle for a few seconds, but it feels a bit \
pointless. You can\'t reach the button from there, anyway.');
}
function drop_haggis()
{
	if(in_inv(haggis) && !butlerWarn('Ownership of that haggis puts you at a certain advantage \
over the Commander. Perhaps there is some more precise location in which it could \
be placed, turning the situation to your advantage.', WARNED_FEEDFATTY))
	{
		drop(haggis);
		// that might fail, so check haggis is here
		if(thingloc(haggis)==heroloc())
		{
			say('\n');
			feed_fatty();
		}
	}
	else if(!in_inv(haggis))
		say('You haven\'t got the haggis.');
}
function put_haggis_on_circle()
{
	if(!in_inv(haggis))
		say('You haven\'t got the haggis');
	else
	{
		take_away(haggis);
		say('You place the haggis in the middle of the black circle.\n\
"Haggis!" cries Commander Fatty. He bounds over onto the circle, scoops the haggis up \
greedily, stuffs the whole thing into his mouth and begins munching noisily.');
		sgs(FATTY_ON_CIRCLE, 1);
		inc_score();
	}
}
function do_teleporter()
{
	say('There is an unrealistic sound effect, and a cylinder of white light shoots \
up from the black circle')

	if(gs(FATTY_ON_CIRCLE)==1)
	{
		say(', engulfing Commander Fatty.\n\
"Whit the -- I havnae programmed in a destination!" he begins. "I\'ll be..."\n\
His voice fades away as the light dissipates, and he is no longer there.');
		sgs(FATTY_ON_CIRCLE, 0);
		set_personloc(fatty, nowhere);
		inc_score();
	}
	
	else
	{
		say('. But nothing else happens, and the light dissipates.');
		if(personloc(fatty)==heroloc())
		{
			say('\n"Quit messin\' aboot wi\' that," snaps Commander Fatty.');
		}
	}

}

//pl(name,fullname,description,append,sights,special,exits,hExits)
pl('office',
'Office',
'This is a characterless office with fluorescent lights and blue panelled carpeting. It contains \
one desk, empty except for a funny sort of white plastic typewriter. There is a dial on the wall.',
'',
'typewriter::A white plastic typewriter attached by a cable to something that looks like one \
of those Baird televisor machines. Reflected on the screen is a miserable-looking office boy, \
his actions mimicking yours exactly.\
/dial::A turnable dial marked "THERMOSTAT".',
'type::*use_computer()\
/turn.dial::*turn_dial()\
/turn.up.dial::*turn_dial()\
/turn.on.dial::*turn_dial()\
/turn.down.dial::*turn_dial()\
/take.tie::*take_tie()\
/look.tie::*examine_tie()\
/southeast::*fall_backwards();move();/out::*fall_backwards();move();',
'southeast::service_n',
'out::southeast'
);

function examine_tie()
{
	if(gs(GOT_TIE)==0)
		say(tie.description)
	else
		thingsee(tie);
}

function take_tie()
{
	if(gs(GOT_TIE)==0)
		say('You make a lunge at the typist\'s tie, but he evades you.')
	else
		take(tie);
}

function turn_dial()
{
	say('You spin the dial in a random direction. The room gets somewhat hotter.');
	if(gs(GOT_TIE)==0)
	{
		inc_score();
		sgs(GOT_TIE, 1);
		say('\nThe typist starts sweating, removes his tie, throws it on the floor, \
and continues clacking away at the keys.');
		set_thingloc(tie, office);
	}
}

function use_computer()
{
	if(personloc(typist)==heroloc())
		say('The typist waves you away irritably.')
	else
		say('You\'re not a secretary!');
}

pl('service_sw',
'Southwest service corridor',
'A corridor of grimy plaster. The air is thick with dust.',
'',
'',
'southwest::*fall_backwards();move();',
'southwest::mill.northeast::servants_hall',
'');

pl('mill',
'Mill',
'A long, wide hallway with a floor and ceiling of dusty pine planks, \
and walls of bare plaster. Several looms loom along the south wall, clicking gently to \
themselves in the absence of their operators. Through a large \
[[ gs(MILL_WINDOWOPEN)==0 ? "closed" : "open" ]] rectangular window opposite them, \
you can make out the spokes of a great wooden wheel.',
'',
'machine::Cats\'-cradles of wood, wire and wool, clicking rhythmically, evidently powered \
by some unseen mechanism.\
/wheel::Visible through the [[ gs(MILL_WINDOWOPEN)==1 ? "open" : "closed" ]] window is \
a wooden wheel, perhaps thirty feet in diameter, kept spinning by the trickle of a stream \
at the far side (so the spokes on this side are moving upwards.)\
/window::*sightsee("wheel")',
'open.window::*open_mill_window()\
/close.window::*close_mill_window()\
/take.wheel::*grab_wheel()\
/take.on.wheel::*grab_wheel()\
/wear.wheel::*grab_wheel()\
/up.wheel::*grab_wheel()\
/up.on.wheel::*grab_wheel()\
/out.window::*grab_wheel()\
/up.out.window::*grab_wheel()\
/through.window::*grab_wheel()\
/up.through.window::*grab_wheel()\
/look.out.window::*sightsee("wheel")\
/look.through.window::*sightsee("wheel")\
/north::*grab_wheel()\
/northeast::*fall_forwards();move();/out::*fall_forwards();move();',
'northeast::service_sw',
'out::northeast');
function open_mill_window()
{
	if(gs(MILL_WINDOWOPEN)==1)
		say('The window is already open.')
	else
	{
		inc_score();
		sgs(MILL_WINDOWOPEN, 1);
		say('The window opens easily, then sticks.');
	}
}
function close_mill_window()
{
	if(gs(MILL_WINDOWOPEN)==1)
		say('No chance. The thing\'s stuck fast.')
	else
		say('The window is already closed.');
}
function grab_wheel()
{
	if(gs(MILL_WINDOWOPEN)==0)
		say('The window isn\'t open.')
	else
	{
		
		if(gs(DONE_WHEEL)==0)
		{
			inc_score();
			sgs(DONE_WHEEL, 1);
		}
	

		say('You reach through the window and grab hold of one of the wooden spokes. \
It\'s moving rather faster than you thought. In an instant, you are whipped off your feet \
and catapulted some unknown distance through the fog...\n\
You land unceremoniously on a tiled, slippery roof.[[ gs(GOT_STOVEPIPE)==1 ? "" : \
" A stovepipe sticks out from between the tiles nearby, slowly exhaling a thin stream of black smoke."]]');
		set_heroloc(roof);
	}
}

// pl(name,fullname,description,append,sights,special,exits,hExits)
pl('roof',
'Roof',
'You are standing - just - on a sloped roof of black slate tiles, wet and rather slippery in the \
cold drizzly air. A stovepipe sticks out from between the tiles nearby, slowly exhaling a thin stream \
of black smoke.',
'',
'',
'down::*fall_off_roof();\
/jump::*fall_off_roof();\
/take.stovepipe::*grab_stovepipe();',
'',
'');

var roof_falling_messages = new Array(
'You are having trouble keeping your balance.',
'You can hardly stay upright on the slippery tiles.',
'Your feet begin to slip on the wet slate...',
'You can barely keep your footing...'
);

function fall_off_roof()
{
	sgs(FALL_OFF_ROOF, 0);
	say('You lose your footing completely, and slide off the edge of the roof...\n\
You fall forwards, towards a glass dome - one pane briefly opens, and you plunge through - you land \
hard, but with as much dignity as possible, at the feet of the waiting butler.\n\
"Pardon my not presuming to break your fall, sir," he says. "I considered it a liberty."\n\ \
You are back in the Servants\' Hall.');
	set_personloc(butler, servants_hall);
	set_heroloc(servants_hall);
}

function grab_stovepipe()
{
	if(gs(GOT_STOVEPIPE)==1) // treat as normal "take stovepipe" command
		take(stovepipe)
	else
	{
		inc_score();
		say('I say, that\'s a clever idea! Fending off your impending peril \
by grabbing hold of the stovepipe - sheer genius! Oh, it\'s snapped off.');
		give_hero(stovepipe);
		sgs(GOT_STOVEPIPE, 1);
	}
}

pl('service_w',
'West service corridor',
'A broad corridor, with a rickety wooden floor and a cloth canopy.',
'',
'',
'west::*fall_backwards();move();',
'east::servants_hall.west::deville',
''
);

pl('deville',
'Deville, TX',
'A tiny township in the middle of a vast, beating desert. There are a few shacks \
dotted around, only one of which is of any interest, being marked "TAVERN". To the \
east is the open back of a canopied wagon.',
'*get_jerkin()',
'wagon::One of those semi-cylindrical cloth caravans on a wooden base, although it \
does look rather longer than you\'d expect.\
/desert::Big, flat, sandy, hot and - here we come to the nub or gist - deserted.\
/shack::The only shack worth bothering about is marked "TAVERN" above a pair of \
stable-like swing doors.',
'east::*enter_wagon();\
/in.wagon::*enter_wagon();\
/up.in.wagon::*enter_wagon()\
/take.in.wagon::*enter_wagon()\
/up.wagon::*enter_wagon()\
/up.on.wagon::enter_wagon()\
/northwest::*cross_desert()\
/north::*cross_desert()\
/northeast::*cross_desert()\
/southwest::*cross_desert()\
/southwest::*cross_desert()\
/southeast::*cross_desert()\
/east::*fall_forwards();move();',
'in::tavern.east::wagon',
'west::in'
);
function get_jerkin()
{
	if(gs(DONE_SPIT)==1 && gs(GOT_JERKIN)==0)
	{
		inc_score();
		say('\nIn a burst of fresh giggling, a natty jerkin flutters down from an upstairs \
window of the tavern, and lands on the ground.');
		set_thingloc(jerkin, deville);
		sgs(GOT_JERKIN, 1);
	}
}
function cross_desert()
{
	say('You have enough trouble getting across Hyde Park on a balmy day. You\'d never survive an actual desert.');
}
function enter_wagon()
{
	fall_forwards();
	set_heroloc(service_w);
	look();
}

pl('tavern',
'Tavern',
'A low-ceilinged, creaky tavern. Fast, joplinesque music cranks out of an unmanned \
pianola in the corner, beside which there stands a steel spittoon. A flight of stairs \
leads upwards.',
'*if(gs(DONE_SPIT)==1) {say(" A giggling noise is emanating from the ceiling.")}',
'piano::A free-standing pianola, plonking out a jolly tune all by itself.\
/spittoon::A steel vase, about a quarter full of murky liquid.',
'spit::*spit()\
/up::*upstairs_in_tavern()\
/take.jerkin::*take_jerkin()\
/look.jerkin::*examine_jerkin()',
'out::deville.up::tavern',
'east::out'
);
function take_jerkin()
{
	if(gs(DONE_SPIT)==0)
		say('There\'s no safe way to get it off the prone cowboy.')
	else
		take(jerkin);
}
function examine_jerkin()
{
	if(gs(DONE_SPIT)==0)
		say(jerkin.description)
	else
		thingsee(jerkin);
}
function upstairs_in_tavern()
{
	if(gs(DONE_SPIT)==1)
		say('It would be rude to interrupt.')
	else
		say('An attractive young lady, in an outfit that would turn a few heads at \
Covent Garden, stops you at the top of the stairs. "No more freebies," she says. \
"You oughta be watchin\' the bar." You trudge back down.');
}
function spit()
{
	say('All those contests at public school were not wasted. You take a good run-up, \
position your face at an optimal angle, compensate for draughts and air pressure, and - with \
a great, reverberating B\'DOINK! - in it goes.');
	if(gs(DONE_SPIT)==0)
	{
		inc_score();
		sgs(DONE_SPIT, 1);
		say('\nThe noise awakens the cowboy. \"Say, barkeep, that\'s good spittin\',\" he says with admiration. Then, \
"Geez, I\'ve overslept - must be high time for my appointment with Miss Kitty!"\n\
He rushes upstairs. Moments later, a giggling noise begins to emanate from the ceiling.');
		set_personloc(cowboy, nowhere);
	}
}


pl('service_e',
'East service corridor',
'A dark, east-west corridor built of sandstone blocks, with hieroglyphic patterns on the walls.',
'',
'hieroglyphic::*describe_hieroglyphics();\
/wall::*describe_hieroglyphics();',
'east::*fall_backwards();move();',
'east::embalmers_chamber.west::servants_hall',
'');
function describe_hieroglyphics()
{
	say('A sort of stylised comic-strip telling the life-stories of various persons \
with animals\' heads, walking in a rather peculiar way.');
}

pl('embalmers_chamber',
'Embalmer\'s Chamber',
'The east-west corridor bulges out into a dark little octagonal room. You have the impression that tons \
of sandstone are bearing down on you. Amphorae line the walls.[[ gs(PUSHED_EMBALMER)==1 ? \
" There is a closed sarcophagus here." : "" ]]',
'*embalmer_talk()',
'amphora::Rows of pottery jars, with rather unsubtle hieroglyphics depicting the parts of your body \
that they are designed to contain.\
/sarcophagus::An oversize stone sarcophagus with a heavy gold lid. It is \
[[ gs(PUSHED_EMBALMER)==1 ? "closed, and making some muffled angry noises" : "open" ]].',
'drop.organ::You much, much prefer your organs where they are.\
/close.sarcophagus::*close_sarcophagus();\
/open.sarcophagus::*open_sarcophagus();\
/in.sarcophagus::*enter_sarcophagus();\
/take.in.sarchophagus::*enter_sarcophagus();\
/east::*enter_treasure_chamber();\
/west::*fall_forwards();move();',
'east::treasure_chamber.west::service_e',
'');
function enter_treasure_chamber()
{
	if(gs(PUSHED_EMBALMER)==0)
		say('"The inner sanctum isn\'t for slaves," snaps the embalmer, blocking \
your way.')
	else
		move();
}
function close_sarcophagus()
{
	if(gs(PUSHED_EMBALMER)==1)
		say('The sarcophagus is already closed.')
	else
		say('The lid is far too heavy.');
}
function open_sarcophagus()
{
	if(gs(PUSHED_EMBALMER)==0)
		say('The sarcophagus is already open.')
	else
		say('The lid is far too heavy.');
}
function enter_sarcophagus()
{
	if(gs(PUSHED_EMBALMER)==1)
		say('The sarcophagus is closed.')
	else
		say('The embalmer stops you. "You\'re not the one going in there."');
}
function embalmer_talk()
{
	if(gs(EMBALMER_TALKED)==0)
	{
		sgs(EMBALMER_TALKED, 1);
		say('\n"Ah," says the embalmer. "There you are. I expect you\'ll be anxious to join \
your master in the afterlife. Put your organs in those jars, please."');
	}
}


pl('treasure_chamber',
'Treasure chamber',
'The corridor opens out into a round, brightly-lit room - a treasure chamber! Not that it\'s \
particularly well stocked.',
'',
'',
'',
'west::embalmers_chamber',
'out::west'
);

pl('service_ne',
'Northeast service corridor',
'A corridor of irregular stone, winding slightly.',
'',
'',
'northeast::*fall_backwards();move();',
'northeast::cave.southwest::servants_hall',
'');

pl('cave',
'Cave',
'You are in a gloomy cave. It feels awfully lonely. From far off come the sounds of \
giant reptiles eating each other.[[ gs(GOT_FLOWER)==0 ? " A lone flower grows out of the \
stony floor." : "" ]]',
'',
'',
'look.flower::*examine_flower();\
/take.flower::*take_flower();\
/southwest::*fall_forwards();move();\
/out::*fall_forwards();move();',
'southwest::service_ne',
'out::southwest'
);
function examine_flower()
{
	if(gs(GOT_FLOWER)==0)
		say(flower.description)
	else
		thingsee(flower);
}
function take_flower()
{
	if(gs(GOT_FLOWER)==0)
	{
		inc_score();
		say('You pluck the flower from the cave floor.');
		give_hero(flower);
		sgs(GOT_FLOWER, 1);
	}
	else
		take(flower);
	
}

pl('service_se',
'Southeast service corridor',
'A corridor lined in canvas, with grass underfoot.',
'',
'',
'southeast::*fall_backwards();move();',
'northwest::servants_hall.southeast::jousting_field',
'');

pl('jousting_field',
'Jousting field',
'You stand at the edge of a muddy, grassy area surrounded by a crowd of spectators. You can hear \
the rumble of hooves in the distance.',
'',
'crowd::The crowd is composed mainly of bearded men in tunics and tights, and skinny women in \
strange conical hats.',
'northwest::*fall_forwards();move();',
'northwest::service_se',
'');

pl('service_s',
'South service corridor',
'A half-timbered corridor, painted white with black wooden beams.',
'',
'',
'south::*fall_backwards();move();',
'north::servants_hall.south::globe',
'');

pl('globe',
'Shakespeare in Glove',
'You stand in a great octagonal open-topped wooden building with a stage along one side.',
'',
'stage::A low, wooden stage, with nothing on it at the moment.',
'north::*fall_forwards();move();/out::*fall_forwards();move();',
'north::service_s',
'out::north'
);

