!% -SD

Constant Story "Be Productive";
Constant Headline "^A game about work ethic^
		^By Vincent Zeng^^";
!Release 1; 
Release 2;
Include "Parser";
Include "VerbLib";
Include "Grammar";
Include "Menus";

Constant MAX_TURNS = 50;
Constant No_score;

!=== classes

Class Room
	with	cant_go
			"You can't go that way.",
		each_turn [;
			if (turns >= MAX_TURNS) {
				deadflag = 3;
				"^The bell sounds to conclude work. The door to your workstation unlocks. The drone arrives to take you to your sleeping quarters. ^
				^You produced ", productivity.productsCompleted, " products. Ask yourself if you are proud, and return again in the morning."; 
			}

			if (random(6) == 1) {
				print "^The monitor beeps.^";
				font off;
				box "!!REMAIN PRODUCTIVE!!";
				font on;
			}
		],
		before [;
			Listen:
				if (noun == false)
				"An anxious buzzing.";
			Smell:
				if (noun == false)
				"An impatient tapping.";
			Wait:
				if (noun == false)
				"The monitor blinks impatiently.";
		],
	has	light;

Class Product (MAX_TURNS)
	with	description
		"A completed product.",
		name 'product' 'complete',
		plural "products",
		short_name "product",
		before [;
			Take:
				"Leave it there for the drones.";
			Examine:
			default:
				"Not for you to worry about.";
		],
	has	;

Class PartA (MAX_TURNS)
	with	description
		"A whirlfly for assembly. It has a notch for a stargrab.",
		name 'whirlfly' 'fly' 'whirl',
		plural "whirlflies",
		short_name "whirlfly",
		before [new_product;
			Take:
				"You hold it uselessly in one hand for a moment, then put it back down. You'll need both hands free to assemble parts.";
			Tie, Insert:
				if (second ofclass PartB) {
					new_product = Product.create();
					move new_product to location;
					print "^You make a new product and let it drop to the floor.^";
					productivity.productsCompleted++;

					remove self;
					remove second;
					return true;
				} else {
					"Those aren't compatible.";
				}
			Listen:
				"A quiet whirling sound that you can only hear if you get very close.";
			Taste:
				"A slight tang of escamism.";
			Smell:
				"A void.";
			Think:
				"It's a smaller part of a larger whole. It wants to be combined with a stargrab.";
		],
		after [;
		!	Drop:
		!		self.short_name = "dropped whirlfly";
		!		self.plural = "dropped whirlflies";
		!	Take:
		!		self.short_name = "part";
		!		self.plural = "parts";
		],
	has	;

Class PartB (MAX_TURNS)
	with 	description
		"A stargrab for assembly. It has a protrusion for a whirlfly.",
		name 'stargrab' 'star' 'grab',
		plural "stargrabs",
		short_name "stargrab",
		before [new_product;
			Take:
				"You hold it uselessly in one hand for a moment, then put it back down. You'll need both hands free to assemble parts.";
			Tie, Insert:
				if (second ofclass PartA) {
					new_product = Product.create();
					move new_product to location;
					print "^You make a new product and let it drop to the floor.^";
					productivity.productsCompleted++;

					remove self;
					remove second;
					return true;
				} else {
					"Those aren't compatible.";
				}
			Listen: 
				"A desperate pulsing.";
			Taste:
				"The worst you've ever tasted.";
			Smell:
				"Infinity.";
			Think:
				"It's a smaller part of a larger whole. It wants to be combined with a whirlfly.";
		],
	has	;

Class PartC (MAX_TURNS)
	with 	description
		"A jumpbolt for assembly. It doesn't seem to fit anything.",
		name 'bolt' 'jump' 'jumpbolt',
		plural "jumpbolts",
		short_name "jumpbolt",
		before [;
			Take:
				"You hold it uselessly in one hand for a moment, then put it back down. You'll need both hands free to assemble parts.";
			Tie, Insert:
				"Those aren't compatible.";
			Listen: 
				"A long pause.";
			Taste:
				"Hopeful and familiar.";
			Smell:
				"Mysterious.";
			Think:
				"It's a smaller part of a larger whole, but you can't quite figure out why it's here.";
		],
	has	;
Class Readout
	with	before [;
			Examine:
				style reverse;
				font off;
			default:
				"Just read it.";
		],
		after [;
			Examine:
				font on;
				style roman;
		],
	has	;

Class Concept
	with	before [;
			Examine:
			Think:
				print_ret (string) self.description;
			default:
				"...";
		],
		found_in [;
			return true;
		],
	has	scenery;

!=== rooms

Room workstation "Your workstation" 
	with	description
		"The room is small and distraction-free. The conveyor belt gently whirs from an opening in one wall to an opening in the other, under the flickering monitor that faces you. The door is behind you, securely closed.",
		before [;
			Look:
			Jump, Sing, Go, Exit, Desperate, Sleep, Open, Strong, Mild, Attack, Climb, Dig, Eat, Rub, Pray:
			!default:
				font off;
				box "!!DO NOT ENGAGE IN UNPRODUCTIVE BEHAVIORS!!";
				font on;
				"The monitor sounds an ugly note before you can manage that.";
		],
	has	;

Object station	"workstation" workstation
	with 	description
		"A small space next to a monitor and a conveyor belt for you to do your work.",
		name 'station' 'workstation' 'room',
		before [;
			Think:
				"You've been assigned to this workstation for as long as you can remember. Even though it is supposed to be functionally identical to every other workstation, there is something about it that is undoutably yours. The smells and sounds that drift through are subtle, but can never be completely erradicated.";
		],
	has	scenery;

Object stool "stool" workstation
	with	description
		"A solid piece of metal rising from the floor, contoured to support limbs not critical for work.",
		name 'stool' 'metal' 'chair' 'seat',
		initial
		"You are comfortable on your stool.",
		before [;
			Taste: 
				"You can't bend over far enough to taste it.";
			Smell:
				"You can't bend over far enough to smell it.";
			Listen:
				"Silent and steady.";
			Think:
				"Sometimes you're not sure if the stool has been matched to you, or if you have been matched to the stool.";
		],
	has	static supporter enterable;

Object conveyorbelt "conveyor belt" workstation
	with	description
		"A 6-inch wide nonslip-textured belt that feeds from right to left.",
		name 'belt' 'conveyor',
		each_turn[ new_part part;
			if (random(3) <= 1) {
				part = random(3);	

				switch (part) {
					1:
						new_part = PartA.create();
						style bold;
						print "^A new whirlfly appears on the belt.^";
						style roman;
					2:
						new_part = PartB.create();
						style bold;
						print "^A new stargrab appears on the belt.^";
						style roman;
					3:	
						new_part = partC.create();
						style bold;
						print "^A new jumpbolt appears on the belt.^";
						style roman;
				}

				move new_part to self;
				rtrue;
			}
		],
		before [;
			Listen:
				"It hums impatiently as it moves.";
			Smell:
				"Anxious movement whistles past your nose.";
			Taste: 
				"You'd hurt yourself if you tried.";
			Think:
				"You're not sure how long the belt extends beyond your room. Something about it always feels unfair to you.";
			Touch:
				"You pull back your hand before you make contact. It might hurt.";
		],
	has	static scenery supporter transparent;

Object floor "floor" workstation
	with	description
		"Polished white tile.",
		name 'floor' 'ground' 'tile',
		before [;
			Listen:
				"Clicking noises reverberate.";
			Smell:
				"Like the bottoms of your feet, or the tread of the drone.";
			Taste:
				"Don't do that.";
			Think:
				"Such a stable, supportive thing in your life.";
		],
	has	scenery;

Object ceiling "ceiling" workstation
	with	description
		"Prisitine white plaster, out of your reach.",
		name 'ceiling' 'roof' 'plaster',
		before [;
			Listen:
				"A distant thrum.";
			Smell, Taste:
				"If only you could reach.";
			Think:
				"How high does the ceiling reach? Have you ever tried to touch it?";
			Touch:
				"It's out of reach. You've never been tall enough.";
		],
	has	scenery;

Object walls "walls" workstation
	with	description
		"Pristine white plaster everywhere you look.",
		name 'wall' 'walls' 'plaster',
		before [;
			Listen:
				"A muffled chatter.";
			Smell:
				"Clean.";
			Taste:
				"Don't do that.";
			Think:
				"You're glad the walls contain you.";
		],
	has	scenery;

Object lightsource "light" workstation
	with	description
		"A crisp, neutral glow that produces ideal ilumination.",
		name 'light',
		before [;
			Think:
				"If there was no light, no one would be able to see you.";
		],
	has	scenery;

Object air "air" workstation
	with	description
		"Calculated freshness.",
		name 'air' 'atmosphered',
		before [;
			Think:
				"It's good.";
		],
	has	scenery;

Object stationdoor "door" workstation
	with	description
		"The door out of your workstation. You know that's where the drone comes from.",
		name 'door' 'exit',
		before [;
			Think:
				"You wouldn't even consider trying to operate the door without authority.";
		],
		door_dir n_to,
	has	door lockable locked scenery static openable;

Object left_opening "left side opening" workstation
	with	description
		"A 6-inch by 4-inch hole into which the conveyor belt feeds.",
		name 'left' 'opening' 'side' 'hole',
		before [;
			Listen:
				"A cozy hum.";
			Smell:
				"An expected scent.";
			Enter:
				"Too small.";
			Think:
				"You've never wondered where this goes.";
		],
	has	scenery;

Object right_opening "right side opening" workstation
	with	description
		"A 6-inch by 4-inch hole from which the conveyor belt feeds.",
		name 'right' 'opening' 'side' 'hole',
		before [;
			Listen:
				"A gentle hum.";
			Smell:
				"A comforting scent.";
			Enter:
				"Too small.";
			Think:
				"You've never wondered where this comes from.";
		],
	has	scenery;

Object monitor "monitor" workstation
	with	description
		"A small, glowing screen embedded in the wall that displays your current directive and a report of your productivity.",
		name 'monitor' 'screen' 'display' 'computer',
		initial
		"The monitor awaits your activity.",
		before [;
			Think:
				"Isn't is wonderful how informative and observant it is?";
			Listen:
				"It waits silently.";
			Smell:
				"It waits.";
			Taste: 
				"It waits.";
			Touch:
				"It's warm.";
		],
	has	static light transparent;

Readout productivity "productivity" monitor
	with	description
		"| CURRENT PRODUCTIVITY:                                      | ",
		name 'productivity' 'current' 'progress' 'meter' 'report',
		productsCompleted 0,
		before [;
			Think:
				print_ret "You wonder how much work you should do.";
		],
		after [;
			Examine:
				print "|      ";
				print self.productsCompleted;
				if (self.productsCompleted < 10){
					print " ";
				}
				print "                                                    | ";
				font on;
				style roman;
		],
	has	;

Readout directive "directive" monitor
	with	description
		"|  HELLO. YOUR PARTS FOR ASSEMBLY WILL AUTOMATICALLY APPEAR. |
		^|  PLEASE PRODUCE AS MANY PRODUCTS AS YOU ARE ABLE.          |
		^|  FOR ASSISTANCE, REFER TO THE HELPER DRONE.                | ",
		name 'directive' 'instructions' 'order' 'orders' 'instruction',
		before [;
			Think:
				"You better do as the directive requires.";
		],
	has	;

Object drone "drone" workstation
	with	description 
		"It's not here.",
		name 'drone' 'robot' 'helper' 'assistance',
		before [;
			Think:
				"The drone does exactly what the drone does.";
			default:
				"The drone's not here.";
		],
	has	concealed;

Object limbs "limbs" workstation
	with	description
		"You have four limbs, but only two of them are critical for work. The other two dangle uselessly over the edge of the stool.",
		name 'limbs' 'limb' 'leg' 'legs' 'foot' 'feet' 'arm' 'arms' 'hand' 'hands' 'wrist' 'wrists',
		before [;
			Think:
				"What nice things to have.";
		],
	has	scenery;

Concept work "work" 
	with	description
		"There is little to do besides work. This is your life as it exists.",
		name 'work' 'duty' 'task' 'project' 'exist',
	has	;

Concept yourlife "life"
	with	description
		"Your life is work. Your life is free.",
		name 'life',
	has	;

Concept freedom "freedom"
	with	description
		"You are free to choose. You are free to do as you wish. You are free to work. You are free to be happy.",
		name 'free' 'freedom' 'choice' 'wish' 'desire' 'choose',
	has	;

Concept happy "happiness"
	with	description
		"You are as happy as you think you are.",
		name 'happy' 'joy' 'happiness' 'bliss',
	has	;

Concept thinking "thought"
	with	description
		"Thought is free. You can think.",
		name 'think' 'thought' 'mind',
	has	;

Concept information "information"
	with	description
		"The monitor is the only authorized source of information.",
		name 'information' 'info' 'authority' 'authorized',
	has 	;

Concept observation "observation"
	with	description
		"The monitor is the only true observer.",
		name 'observation' 'observe' 'watcher' 'watch' 'them' 'they',
	has	;

Concept activity "activity"
	with	description
		"There is always someting that could be done.",
		name 'activity' 'busy' 'movement',
	has	;

!=== extra grammar

Verb 'flail' 'panic' 'thrash' 'curse' 'scream' 'yell' 'holler'
	* -> Desperate;

[ DesperateSub;
	print_ret "...";
];

Verb 'combine' 'notch' 'assemble' 'make'
	* noun 'with' noun -> Tie 
	* noun 'and' noun -> Tie
	* noun 'to' noun -> Tie;

Verb 'consider' 'ponder' 'wonder' 'cogitate'
	* 'about' noun -> Think
	* noun -> Think;

Verb 'help' 'info' 'about' 'why' 'how' 'what' 'hints' 'spoiler' 'credits' 'walkthrough'
	* -> About;

[ AboutSub;
	turns--;
	about_menu.select();
];

Menu about_menu "Be Productive";
Option -> "ABOUT"
	with 	description
		"This is a small game about how much you are willing to work.^
		^Originally put together as a submission to Method&Apparatus (http://methodandapparat.us) Fall 2014.";
Option -> "GAMEPLAY"
	with	description
		"Standard interactive fiction controls apply here. ^
		^You can examine your surroundings by typing 'look' (abbreviated as 'l'), or examine specific objects by typing 'x (object)'.^
		^Your non-visual senses are applicable as well; you can 'smell (object)' and 'listen to (object)' and 'taste (object)'.^
		^You can also 'consider (object)' or 'attach (object) to (object)'.^
		^Time is always passing.";
Option -> "SPOILERS"
	with	description
		"There are three different types of objects that will appear on the belt. Type 'combine (one object) with (another object)' to make a new thing.^
		^The only objects that can combine are the stargrab and the whirlfly.^
		^The drone never arrives.^
		^The only person who cares what your productivity value is is you. There is no real 'win' state.";
Option -> "CREDITS"
	with	description
		"Vincent Zeng is hvincent@@64modgethanc.com; bugs and reactions are welcome through email.";

!=== initialization

[ Initialise ;
	location = stool;
	player.description = "You don't need to worry about yourself.";
	];
