zmachine experiments
This commit is contained in:
parent
0f284531db
commit
741df9f5b8
|
@ -51,6 +51,7 @@ The IDE uses custom forks for many of these, found at https://github.com/sehugg?
|
|||
* https://github.com/floooh/chips
|
||||
* https://github.com/DrGoldfire/Z80.js
|
||||
* http://www.twitchasylum.com/jsvecx/
|
||||
* https://github.com/curiousdannii/ifvms.js/
|
||||
|
||||
### Compilers
|
||||
|
||||
|
@ -60,6 +61,7 @@ The IDE uses custom forks for many of these, found at https://github.com/sehugg?
|
|||
* https://github.com/batari-Basic/batari-Basic
|
||||
* https://www.veripool.org/wiki/verilator
|
||||
* http://mcpp.sourceforge.net/
|
||||
* http://www.ifarchive.org/indexes/if-archiveXinfocomXcompilersXinform6.html
|
||||
|
||||
### Assemblers/Linkers
|
||||
|
||||
|
|
47
css/ui.css
47
css/ui.css
|
@ -568,4 +568,49 @@ div.asset_toolbar {
|
|||
font-family: "Andale Mono", "Menlo", "Lucida Console", monospace;
|
||||
font-size: 10pt;
|
||||
line-height: 1.2;
|
||||
}
|
||||
}
|
||||
.transcript {
|
||||
background-color: #fff;
|
||||
width: 100%;
|
||||
padding: 1.25em;
|
||||
user-select: text;
|
||||
font-family: Verdana, Geneva, sans-serif;
|
||||
}
|
||||
.transcript-line {
|
||||
line-height: 1.5;
|
||||
min-height: 1em;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.transcript-style-1 {
|
||||
font-style: italic;
|
||||
}
|
||||
.transcript-style-2 {
|
||||
white-space: pre-wrap; /* css-3 */
|
||||
font-family: "Andale Mono", "Menlo", "Lucida Console", monospace;
|
||||
line-height: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
.transcript-style-4 {
|
||||
font-weight: bold;
|
||||
}
|
||||
.transcript-style-8 { /* input */
|
||||
font-weight: bold;
|
||||
font-variant: small-caps;
|
||||
color: #6666ff;
|
||||
background-color: #eeeeff;
|
||||
padding: 0.25em;
|
||||
padding-left: 0.5em;
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
.transcript-reverse {
|
||||
background-color: #666;
|
||||
color: #ddd;
|
||||
}
|
||||
.transcript-input {
|
||||
margin:1%;
|
||||
font-weight: bold;
|
||||
font-variant: small-caps;
|
||||
color: #6666ff;
|
||||
background-color: #eeeeff;
|
||||
}
|
||||
|
|
@ -218,6 +218,7 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
|||
<li><a class="dropdown-item" href="?platform=atari8-5200.mame">Atari 5200 (MAME)</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=vector-ataricolor">Atari Color Vector (6502)</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=markdown">Markdown</a></li>
|
||||
<li><a class="dropdown-item" href="?platform=zmachine">Z-Machine (Inform 6)</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -311,6 +312,7 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
|||
<!-- emulator video -->
|
||||
<div id="emuscreen">
|
||||
</div>
|
||||
<!-- for Javatari only -->
|
||||
<div id="javatari-div" style="float:center;margin:10px;display:none">
|
||||
<div id="javatari-screen" style="margin: 0 auto; box-shadow: 2px 2px 10px rgb(60, 60, 60);"></div>
|
||||
<div id="javatari-console-panel" style="margin: 0 auto; box-shadow: 2px 2px 10px rgb(60, 60, 60);"></div>
|
||||
|
@ -538,6 +540,7 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
|||
<script src="codemirror/mode/gas/gas.js"></script>
|
||||
<script src="src/codemirror/6502.js"></script>
|
||||
<script src="src/codemirror/bataribasic.js"></script>
|
||||
<script src="src/codemirror/inform6.js"></script>
|
||||
<link rel="stylesheet" href="css/codemirror.css">
|
||||
<script src="codemirror/addon/edit/matchbrackets.js"></script>
|
||||
<script src="codemirror/addon/search/search.js"></script>
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,873 @@
|
|||
! ----------------------------------------------------------------------------
|
||||
! Adventureland 961111 One of the standard Inform 6 example games
|
||||
!
|
||||
! Designed by Scott Adams: c. 1979
|
||||
! Ported to Inform: 16.10.94
|
||||
! Slightly corrected: 11.5.96
|
||||
! Modernised to Inform 6 and library 6/1 or later: 11.11.96
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Constant Story "ADVENTURELAND";
|
||||
Constant Headline
|
||||
"^An Interactive Classic by Scott Adams (circa 1979/80)^";
|
||||
|
||||
Release 1;
|
||||
Serial "961111";
|
||||
|
||||
Constant MAX_CARRIED = 6;
|
||||
Constant MAX_SCORE = 100;
|
||||
|
||||
Replace BurnSub;
|
||||
|
||||
Include "Parser";
|
||||
Include "VerbLib";
|
||||
|
||||
Global genie_gifts;
|
||||
Global dark_warning;
|
||||
|
||||
Class Treasure
|
||||
with depositpoints 7,
|
||||
after
|
||||
[; Take: if (location==Inside_Stump) "Taken!";
|
||||
Drop: if (location==Inside_Stump) "Safely deposited.";
|
||||
];
|
||||
|
||||
Class Sign
|
||||
with name "sign",
|
||||
short_name
|
||||
[; print "sign reads- ", (object) self; rtrue;
|
||||
],
|
||||
has static;
|
||||
|
||||
Class ScottRoom
|
||||
with initial
|
||||
[; give self ~visited;
|
||||
],
|
||||
describe
|
||||
[ i c d; print (string) self.description;
|
||||
print "^^Obvious exits: ";
|
||||
for (i=n_to: i<=d_to: i++)
|
||||
if (self.i ~= 0) c++;
|
||||
if (c==0) print "none!";
|
||||
else
|
||||
{ for (i=n_to: i<=d_to: i++)
|
||||
if (self.i ~= 0)
|
||||
{ if (d++>0) print ", ";
|
||||
if (i==n_to) print "North";
|
||||
if (i==s_to) print "South";
|
||||
if (i==e_to) print "East";
|
||||
if (i==w_to) print "West";
|
||||
if (i==u_to) print "Up";
|
||||
if (i==d_to) print "Down";
|
||||
}
|
||||
print ".";
|
||||
}
|
||||
new_line;
|
||||
c=0; d=0;
|
||||
objectloop (i in self)
|
||||
if (i ~= player) { c++; give i concealed; }
|
||||
if (c==0) rtrue;
|
||||
print "^You can also see: ";
|
||||
objectloop (i in self)
|
||||
if (i ~= player)
|
||||
{ if (d++>0) print " - "; PrintShortName(i);
|
||||
}
|
||||
new_line; rtrue;
|
||||
];
|
||||
|
||||
[ GamePreRoutine i c d;
|
||||
if (action~=##Inv) rfalse;
|
||||
c=0; d=0;
|
||||
objectloop (i in player) c++;
|
||||
if (c==0) "You're carrying nothing.";
|
||||
print "You're carrying:^";
|
||||
objectloop (i in player)
|
||||
{ if (d++>0) print " - "; PrintShortName(i);
|
||||
}
|
||||
new_line; rtrue;
|
||||
];
|
||||
|
||||
[ GamePostRoutine i;
|
||||
if (action==##Look)
|
||||
objectloop (i in location)
|
||||
if (i ~= player && i has concealed)
|
||||
give i ~concealed;
|
||||
rfalse;
|
||||
];
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! Into Adventureland...
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
ScottRoom Lake_Shore "Lakeside"
|
||||
with description "You're on the shore of a lake.",
|
||||
n_to Forest, s_to Lake_Shore, w_to Dismal_Swamp,
|
||||
d_to Quicksand,
|
||||
before
|
||||
[; Swim: "Below you and before the lake is quicksand.";
|
||||
],
|
||||
has light;
|
||||
Object -> water "water"
|
||||
with name "water", article "some",
|
||||
before
|
||||
[; Drink: "Boy, that really hit the spot.";
|
||||
Take: if (bottle notin player)
|
||||
"You have nothing in which to carry the water.";
|
||||
<<Fill bottle>>;
|
||||
Insert: if (second == bottle) <<Fill bottle>>;
|
||||
"You have nothing in which to carry the water.";
|
||||
Receive: if (noun == bottle) <<Fill bottle>>;
|
||||
remove noun; CDefArt(noun); " washes away into the lake.";
|
||||
],
|
||||
has scenery;
|
||||
Treasure -> "*GOLDEN FISH*"
|
||||
with name "gold" "golden" "fish",
|
||||
each_turn
|
||||
[; if (self notin player) rfalse;
|
||||
if (net notin player && random(100) <= 75)
|
||||
{ move self to Lake_Shore;
|
||||
"^The fish escape back to the lake.";
|
||||
}
|
||||
if ((water_in_the_bottle notin bottle
|
||||
|| bottle notin player) && random(100)<=50)
|
||||
{ remove self; move dead_fish to player;
|
||||
"^Too dry. Fish die.";
|
||||
}
|
||||
];
|
||||
Object -> axe "rusty axe (magic word- BUNYON -on it)"
|
||||
with name "rusty" "axe",
|
||||
description "The magic word BUNYON is written on the haft.";
|
||||
Sign -> "NO SWIMMING ALLOWED";
|
||||
Object dead_fish "dead fish"
|
||||
with name "dead" "fish"
|
||||
has edible;
|
||||
|
||||
ScottRoom Quicksand "Bog"
|
||||
with description "You're in a quick-sand bog.",
|
||||
before
|
||||
[; Swim: if (child(player)==nothing)
|
||||
{ PlayerTo(Lake_Shore); rtrue; }
|
||||
"Something's too heavy.";
|
||||
],
|
||||
has light;
|
||||
Treasure -> ox "*SMALL STATUE OF A BLUE OX*"
|
||||
with name "ox" "blue" "small" "statue";
|
||||
|
||||
ScottRoom Forest "Forest"
|
||||
with description "You're in a forest.",
|
||||
n_to Forest, s_to Forest, e_to Sunny_Meadow, w_to Forest,
|
||||
u_to trees
|
||||
has light;
|
||||
Object -> trees "trees"
|
||||
with name "tree" "trees",
|
||||
before
|
||||
[; Climb: <<Enter self>>;
|
||||
],
|
||||
door_to Up_Oak, door_dir u_to
|
||||
has open door static;
|
||||
|
||||
ScottRoom Up_Oak "Branch"
|
||||
with description "You're in a branch on the top of an old oak tree.^
|
||||
To the east you see a meadow beyond a lake.",
|
||||
d_to Forest,
|
||||
has light;
|
||||
|
||||
ScottRoom Sunny_Meadow "Meadow"
|
||||
with description "You're in a sunny meadow.",
|
||||
n_to Lake_Shore, s_to Dismal_Swamp, e_to Lake_Shore,
|
||||
w_to Forest,
|
||||
has light;
|
||||
Object -> dragon "sleeping Dragon"
|
||||
with name "dragon" "sleeping" "sleepy",
|
||||
before
|
||||
[; WakeOther: deadflag=1; "The dragon wakes!";
|
||||
],
|
||||
life
|
||||
[; Order, Answer, Ask: "Shh! You don't want to wake the dragon.";
|
||||
Give: "The dragon is too drowsy to notice.";
|
||||
ThrowAt: if (noun==axe)
|
||||
{ move axe to location; "The dragon isn't bothered."; }
|
||||
],
|
||||
each_turn
|
||||
[; if (mud in location && random(100)<=50)
|
||||
{ deadflag=1;
|
||||
"Dragon smells something - awakens - attacks you!";
|
||||
}
|
||||
],
|
||||
has animate;
|
||||
Sign -> "IN SOME CASES MUD IS GOOD, IN OTHERS...";
|
||||
Treasure eggs "*DRAGON EGGS* (very rare)"
|
||||
with name "dragon" "eggs" "very" "rare", depositpoints 12;
|
||||
Object gore "smoking hole - pieces of dragon and gore"
|
||||
with name "gore" "hole" "dragon" "smoking"
|
||||
has static;
|
||||
|
||||
ScottRoom Hidden_Grove "Grove"
|
||||
with description "You're in a hidden grove.",
|
||||
n_to Forest, e_to Dismal_Swamp, w_to Forest,
|
||||
has light;
|
||||
Treasure -> "*JEWELLED FRUIT*"
|
||||
with name "jewelled" "jewel" "fruit",
|
||||
after
|
||||
[; Eat: "Boy that really hit the spot!"; ],
|
||||
has edible;
|
||||
Sign -> "PAUL'S PLACE";
|
||||
|
||||
ScottRoom Dismal_Swamp "Dismal Swamp"
|
||||
with description "You're in a dismal swamp.",
|
||||
n_to Sunny_Meadow, s_to Dismal_Swamp, e_to Dismal_Swamp,
|
||||
w_to Hidden_Grove, in_to 0, u_to cypress_tree
|
||||
has light;
|
||||
Object -> cypress_tree "cypress tree"
|
||||
with name "cypress" "tree",
|
||||
before
|
||||
[; Climb: <<Enter self>>;
|
||||
Cut: if (axe notin player) rfalse;
|
||||
remove self; move tree_remains to Dismal_Swamp;
|
||||
Dismal_Swamp.in_to = tree_remains;
|
||||
Dismal_Swamp.u_to = 0;
|
||||
print "TIMBER..";
|
||||
if (keys in Tree_Top)
|
||||
{ remove keys;
|
||||
". Something fell from the treetop and vanished!";
|
||||
}
|
||||
".";
|
||||
],
|
||||
door_to Tree_Top, door_dir u_to
|
||||
has open door static;
|
||||
|
||||
Object -> mud "evil smelling mud"
|
||||
with name "evil" "smelling" "mud", article "some",
|
||||
after
|
||||
[ f; Take:
|
||||
if (infected_bites in player) { remove infected_bites; f=1; }
|
||||
if (chigger_bites in player) { remove chigger_bites; f=1; }
|
||||
if (f==1) "Boy that really hit the spot!";
|
||||
],
|
||||
each_turn
|
||||
[; if (self notin player) rtrue;
|
||||
if (random(100)<=5 &&
|
||||
(bottle notin player || water_in_the_bottle notin bottle))
|
||||
{ move self to Dismal_Swamp;
|
||||
"The mud dried up and fell off.";
|
||||
}
|
||||
];
|
||||
|
||||
Object -> gas "swamp gas"
|
||||
with name "swamp" "gas", article "some",
|
||||
before
|
||||
[; Take:
|
||||
if (distended_bladder in player) "Bladder full already.";
|
||||
if (wine_bladder notin player) "You have nothing suitable.";
|
||||
<<Insert self wine_bladder>>;
|
||||
Insert:
|
||||
if (second == distended_bladder) "The bladder's full.";
|
||||
if (second ~= wine_bladder)
|
||||
"That won't hold gas.";
|
||||
move distended_bladder to player; remove wine_bladder;
|
||||
itobj = distended_bladder;
|
||||
"The bladder distends with swamp gas.";
|
||||
],
|
||||
has static;
|
||||
Object -> slime "floating patch of oily slime"
|
||||
with name "patch" "oil" "slime" "oily",
|
||||
before
|
||||
[; Take: brass_lantern.time_left=125; give brass_lantern general;
|
||||
remove self; move brass_lantern to player;
|
||||
"Magic oil attracts magic lamp. Lamp is now full.";
|
||||
],
|
||||
has static;
|
||||
Object -> chiggers "chiggers"
|
||||
with name "chiggers", article "a swarm of",
|
||||
daemon
|
||||
[; if (chigger_bites in player && mud notin player && random(100)<=10)
|
||||
{ remove chigger_bites; move infected_bites to player;
|
||||
"^Your chigger bites are now infected.";
|
||||
}
|
||||
if (infected_bites in player && random(100)<=8)
|
||||
{ deadflag=1;
|
||||
"^The bites have rotted your whole body.";
|
||||
}
|
||||
if (infected_bites notin player
|
||||
&& chigger_bites notin player
|
||||
&& slime in location && mud notin player
|
||||
&& random(100)<=5)
|
||||
{ move chigger_bites to player;
|
||||
"^You're bitten by chiggers.";
|
||||
}
|
||||
if (infected_bites notin player
|
||||
&& chigger_bites notin player
|
||||
&& chiggers in player
|
||||
&& random(100)<=30)
|
||||
{ move chigger_bites to player;
|
||||
"^You're bitten by chiggers.";
|
||||
}
|
||||
];
|
||||
Object chigger_bites "chigger bites"
|
||||
with name "chigger" "bites", article "some",
|
||||
before [; "The bites are annoying. Perhaps medicine would help?"; ];
|
||||
Object infected_bites "infected chigger bites"
|
||||
with name "chigger" "bites" "infected", article "some",
|
||||
before [; "The bites are frightening. Get medicine!"; ];
|
||||
|
||||
Object tree_remains "hollow stump and remains of a felled tree"
|
||||
with name "tree" "stump" "hollow" "remains",
|
||||
door_to Inside_Stump, door_dir in_to
|
||||
has open door static;
|
||||
|
||||
ScottRoom Tree_Top "Tree Top"
|
||||
with description "You're in the top of a tall cypress tree.",
|
||||
d_to Dismal_Swamp,
|
||||
has light;
|
||||
|
||||
Object -> "spider web with writing on it"
|
||||
with name "spider" "web" "writing",
|
||||
description "~CHOP IT DOWN!~",
|
||||
before
|
||||
[; Take: deadflag=1; "You're bitten by a spider.";
|
||||
];
|
||||
Object -> keys "ring of skeleton keys"
|
||||
with name "keys" "ring" "skeleton" "keyring";
|
||||
|
||||
ScottRoom Inside_Stump "Inside Stump"
|
||||
with description "You're in a large hollow damp stump in the swamp.",
|
||||
n_to Dismal_Swamp, s_to Dismal_Swamp, e_to Dismal_Swamp,
|
||||
w_to Dismal_Swamp, u_to Dismal_Swamp, d_to Root_Chamber,
|
||||
has light;
|
||||
Sign -> "LEAVE TREASURE HERE - (say 'SCORE')";
|
||||
Object -> bottle "the bottle"
|
||||
with name "bottle" "jar" "flask",
|
||||
short_name
|
||||
[; if (water_in_the_bottle in self) { print "bottle of water"; rtrue; }
|
||||
if (bees in self) { print "bottle of bees"; rtrue; }
|
||||
print "empty bottle"; rtrue;
|
||||
],
|
||||
before
|
||||
[ x; LetGo:
|
||||
if (noun in bottle)
|
||||
"You're holding that already (in the bottle).";
|
||||
Receive:
|
||||
if (noun==water or bees) <<Fill self>>;
|
||||
"That won't go in the bottle.";
|
||||
Fill:
|
||||
if (child(bottle)~=0)
|
||||
"The bottle is full already.";
|
||||
if (water in location)
|
||||
{ move water_in_the_bottle to bottle;
|
||||
"The bottle is now full of water.";
|
||||
}
|
||||
if (bees in location)
|
||||
{ move bees to bottle;
|
||||
"The bottle is now full of bees.";
|
||||
}
|
||||
"There is nothing here with which to fill the bottle.";
|
||||
Empty: if (child(bottle)==0) "The bottle is already empty!";
|
||||
x=child(bottle);
|
||||
remove x;
|
||||
if (x==bees)
|
||||
{ move x to location; "You release the bees.";
|
||||
}
|
||||
"Your bottle is now empty and the ground is now wet.";
|
||||
],
|
||||
has container open;
|
||||
|
||||
Object -> brass_lantern "old fashioned lamp"
|
||||
with name "lamp" "fashioned" "lamp", article "an",
|
||||
power 125,
|
||||
time_left 0,
|
||||
daemon
|
||||
[ t; if (self hasnt on) { StopDaemon(self); rtrue; }
|
||||
t=--(self.power);
|
||||
if (t==0) give self ~on ~light;
|
||||
if (self in player or location)
|
||||
{ if (t==0) "Your lamp has run out of power.";
|
||||
if (t==30) "Your lamp is getting dim.";
|
||||
}
|
||||
],
|
||||
before
|
||||
[; Examine: print "It is a shiny brass lamp";
|
||||
if (self hasnt on)
|
||||
". It is not currently lit.";
|
||||
if (self.power < 30)
|
||||
", glowing dimly.";
|
||||
", glowing brightly.";
|
||||
Burn: <<SwitchOn self>>;
|
||||
Rub: if (self has on) "No! It's too hot.";
|
||||
if (self hasnt general) "Nothing happens.";
|
||||
switch(++genie_gifts)
|
||||
{ 1: move ring to location;
|
||||
"A glowing genie appears -
|
||||
drops something - then vanishes.";
|
||||
2: move bracelet to location;
|
||||
"A glowing genie appears -
|
||||
drops something - then vanishes.";
|
||||
3: if (ring in Inside_Stump)
|
||||
score=score-ring.depositpoints;
|
||||
remove ring; move player to Misty_Room;
|
||||
"A genie appears - says ~boy you're selfish~ - takes
|
||||
something - then vanishes!";
|
||||
4: if (bracelet in Inside_Stump)
|
||||
score=score-bracelet.depositpoints;
|
||||
remove bracelet; move player to Misty_Room;
|
||||
"A genie appears - says ~boy you're selfish~ - takes
|
||||
something - then vanishes!";
|
||||
default: "Nothing happens.";
|
||||
}
|
||||
SwitchOn: if (self.power <= 0) "It's run out.";
|
||||
Receive, Open:
|
||||
"You can't put things in the lamp.";
|
||||
],
|
||||
after
|
||||
[; SwitchOn: give self light; StartDaemon(self);
|
||||
"Flameless lamp now on.";
|
||||
SwitchOff: give self ~light;
|
||||
],
|
||||
has switchable;
|
||||
|
||||
Treasure ring "*DIAMOND RING*"
|
||||
with name "diamond" "ring";
|
||||
Treasure bracelet "*DIAMOND BRACELET*"
|
||||
with name "diamond" "bracelet";
|
||||
|
||||
Object water_in_the_bottle "bottled water" bottle
|
||||
with name "bottled" "water" "h2o", article "some",
|
||||
before
|
||||
[; Drink: remove water_in_the_bottle; <<Drink water>>;
|
||||
],
|
||||
description "It looks like ordinary water to me.";
|
||||
|
||||
ScottRoom Root_Chamber "Root Chamber"
|
||||
with description "You're in a root chamber under the stump.",
|
||||
u_to Inside_Stump, d_to dark_hole,
|
||||
has light;
|
||||
Object -> dark_hole "dark hole"
|
||||
with description "Leading below.",
|
||||
door_dir d_to,
|
||||
door_to Semidark_Hole
|
||||
has open door static;
|
||||
Treasure -> "*POT OF RUBIES*"
|
||||
with name "pot" "of" "rubies";
|
||||
|
||||
ScottRoom Semidark_Hole "Hole"
|
||||
with description "You're in a semi-dark hole by the root chamber.",
|
||||
u_to Root_Chamber, d_to root_door
|
||||
has light;
|
||||
Object -> root_door "the door"
|
||||
with name "door",
|
||||
short_name
|
||||
[; if (self has locked) { print "locked door"; rtrue; }
|
||||
if (self has open)
|
||||
{ print "open door with a hallway beyond"; rtrue; }
|
||||
print "closed door"; rtrue;
|
||||
],
|
||||
before
|
||||
[; ThrowAt:
|
||||
if (second==axe)
|
||||
{ give self ~locked ~lockable ~openable open;
|
||||
"Lock shatters!";
|
||||
}
|
||||
],
|
||||
door_to Long_Hall, door_dir d_to, with_key keys
|
||||
has static door openable lockable locked;
|
||||
|
||||
ScottRoom Long_Hall "Hall"
|
||||
with description "You're in a long down-sloping hall.",
|
||||
u_to Semidark_Hole, d_to Large_Cavern;
|
||||
|
||||
ScottRoom Large_Cavern "Cavern"
|
||||
with description "You're in a large cavern.",
|
||||
n_to Hive, s_to Royal_Anteroom, w_to Memory_RAM,
|
||||
u_to Long_Hall, d_to Maze1;
|
||||
|
||||
ScottRoom Hive "Octagonal Hive"
|
||||
with description "You're in a large 8-sided room.",
|
||||
s_to Large_Cavern;
|
||||
Treasure -> "*ROYAL HONEY*"
|
||||
with name "royal" "honey", article "some",
|
||||
before
|
||||
[; Take:
|
||||
if (bees in location && mud notin player)
|
||||
{ deadflag=1; "Bees sting you."; }
|
||||
Drop:
|
||||
if (bear in location)
|
||||
{ remove self; give bear general;
|
||||
"The bear eats the honey and falls asleep.";
|
||||
}
|
||||
],
|
||||
has edible;
|
||||
Object -> bees "large African bees"
|
||||
with name "large" "african" "bees", article "a swarm of",
|
||||
before
|
||||
[; Take:
|
||||
if (mud notin player)
|
||||
{ deadflag=1; "Bees sting you."; }
|
||||
if (bottle in player) <<Fill bottle>>;
|
||||
"You have nothing to carry the bees in.";
|
||||
Drop:
|
||||
if (self in bottle
|
||||
&& dragon in location)
|
||||
{ move self to location;
|
||||
move eggs to location; remove dragon;
|
||||
"The bees attack the dragon which gets up and flies away...";
|
||||
}
|
||||
if (self in bottle
|
||||
&& bear in location)
|
||||
{ move self to location;
|
||||
give bear ~general; deadflag=1;
|
||||
"Bees madden the bear. Bear then attacks you!";
|
||||
}
|
||||
],
|
||||
each_turn
|
||||
[; #IFNDEF DEBUG;
|
||||
! A completely unfair rule! And in the original the bees are lost.
|
||||
if (self in bottle && random(100)<=8)
|
||||
{ move self to Hive; "^The bees in the bottle all suffocated."; }
|
||||
#ENDIF;
|
||||
if (self in bottle) rfalse;
|
||||
if (self in location && mud notin player && mud notin location &&
|
||||
random(100)<=8)
|
||||
{ deadflag=1; "Bees sting you."; }
|
||||
];
|
||||
|
||||
ScottRoom Royal_Anteroom "Anteroom"
|
||||
with description "You're in a royal anteroom.",
|
||||
n_to Large_Cavern, u_to Royal_Chamber;
|
||||
Object -> wine_bladder "empty wine bladder"
|
||||
with name "empty" "wine" "bladder",
|
||||
before
|
||||
[; Fill: if (gas notin location)
|
||||
"The bladder could only just hold a vapour nowadays.";
|
||||
<<Insert gas self>>;
|
||||
];
|
||||
Object distended_bladder "distended gas bladder"
|
||||
with name "distended" "gas" "bladder",
|
||||
before
|
||||
[; Open: move wine_bladder to parent(self); remove self;
|
||||
"Gas dissipates!";
|
||||
];
|
||||
|
||||
ScottRoom Maze1 "Maze"
|
||||
with description "You're in a maze of pits.",
|
||||
n_to Maze2, s_to Maze4, e_to Maze4, d_to Maze2;
|
||||
|
||||
ScottRoom Maze2 "Maze"
|
||||
with description "You're in a maze of pits.",
|
||||
w_to Maze3, u_to Maze1;
|
||||
Object -> flint_and_steel "flint and steel"
|
||||
with name "flint" "steel";
|
||||
|
||||
ScottRoom Maze3 "Maze"
|
||||
with description "You're in a maze of pits.",
|
||||
n_to Maze6, s_to Maze1, e_to Maze2, w_to Maze5,
|
||||
u_to Maze5, d_to Maze6;
|
||||
Object -> "scratchings"
|
||||
with name "scratchings", article "strange",
|
||||
short_name "strange scratchings on rock reveals- ALADDIN WAS HERE",
|
||||
has static;
|
||||
|
||||
ScottRoom Maze4 "Maze"
|
||||
with description "You're in a maze of pits.",
|
||||
n_to Maze1, e_to Maze2, w_to Maze1, u_to Maze2;
|
||||
|
||||
ScottRoom Maze5 "Maze"
|
||||
with description "You're in a maze of pits.",
|
||||
s_to Maze6, u_to Maze3, d_to Maze6;
|
||||
|
||||
ScottRoom Maze6 "Maze"
|
||||
with description "You're in a maze of pits.",
|
||||
n_to Maze6, s_to Maze1, e_to Maze1, w_to Maze4,
|
||||
u_to Maze3, d_to Chasm_Bottom;
|
||||
Treasure -> rug "*THICK PERSIAN RUG*"
|
||||
with name "thick" "persian" "rug" "carpet";
|
||||
Object -> "arrow pointing down"
|
||||
with name "arrow"
|
||||
has static;
|
||||
|
||||
ScottRoom Chasm_Bottom "Chasm"
|
||||
with description "You're in a bottom of a chasm. Above 2 ledges.
|
||||
One has a bricked up window.",
|
||||
u_to Maze6;
|
||||
Treasure -> net "*GOLDEN NET*"
|
||||
with name "gold" "golden" "net";
|
||||
Sign -> "MAGIC WORD IS AWAY. X LA -(rest of sign is missing)";
|
||||
Object -> lava "the lava"
|
||||
with name "stream" "of" "lava",
|
||||
short_name
|
||||
[; print "stream of lava";
|
||||
if (self has general) print " with a brick dam";
|
||||
rtrue;
|
||||
],
|
||||
description
|
||||
[; if (self hasnt general)
|
||||
"There's something there all right! Maybe you should go there?";
|
||||
"Just more dammed lava.";
|
||||
],
|
||||
before
|
||||
[; Enter, Push, Pull, Take: "NO! It's too hot.";
|
||||
],
|
||||
has static;
|
||||
Treasure firestone "*FIRESTONE* (cold now)"
|
||||
with name "firestone", depositpoints 11;
|
||||
|
||||
ScottRoom Narrow_Ledge_1 "Ledge"
|
||||
with description "You're on a narrow ledge by a chasm.
|
||||
Across the chasm is a throne room.",
|
||||
before
|
||||
[; Jump: if (firebricks in player)
|
||||
{ deadflag=1; "Oh no! Something was too heavy!"; }
|
||||
print "You leap across the chasm...^";
|
||||
PlayerTo(Narrow_Ledge_2); rtrue;
|
||||
],
|
||||
w_to Royal_Chamber;
|
||||
|
||||
ScottRoom Royal_Chamber "Royal Chamber"
|
||||
with description "You're in the Royal Chamber.",
|
||||
d_to Royal_Anteroom, e_to 0;
|
||||
Object -> bricked_window "bricked-up window"
|
||||
with name "window" "bricked" "brick" "bricks"
|
||||
has static;
|
||||
Object holed_window "bricked up window with a hole in it - beyond is a ledge"
|
||||
with name "window" "bricked" "hole" "ledge",
|
||||
door_dir e_to, door_to Narrow_Ledge_1
|
||||
has static door open;
|
||||
Object firebricks "loose fire bricks"
|
||||
with name "loose" "fire" "bricks", article "some",
|
||||
after
|
||||
[; Take: "Taken. (Heavy!)";
|
||||
Drop: if (location~=Chasm_Bottom) rfalse;
|
||||
remove self; give lava general;
|
||||
move firestone to location;
|
||||
"The bricks dam the lava, revealing a *FIRESTONE*!";
|
||||
];
|
||||
|
||||
ScottRoom Narrow_Ledge_2 "Ledge"
|
||||
with description
|
||||
"You're on a narrow ledge by the throne room-across chasm-ledge.",
|
||||
before
|
||||
[; Sing:
|
||||
if (bear in location && bear hasnt general)
|
||||
{ move dead_bear to Chasm_Bottom;
|
||||
remove bear;
|
||||
"The bear got startled and fell off the ledge!";
|
||||
}
|
||||
Jump: print "You leap across the chasm...^";
|
||||
PlayerTo(Narrow_Ledge_1); rtrue;
|
||||
],
|
||||
e_to
|
||||
[; if (bear in location && bear hasnt general)
|
||||
"The bear won't let you!";
|
||||
return Throne_Room;
|
||||
];
|
||||
Treasure -> mirror "*MAGIC MIRROR*"
|
||||
with name "magic" "mirror",
|
||||
side_up 0,
|
||||
before
|
||||
[; Take:
|
||||
if (bear in location && bear hasnt general)
|
||||
"The bear won't let you!";
|
||||
],
|
||||
after
|
||||
[; Drop:
|
||||
if (rug in location)
|
||||
{ print "Mirror lands softly on the rug - lights up and says:^";
|
||||
self.side_up++;
|
||||
if (self.side_up % 2 == 1)
|
||||
"*DRAGON STINGS* and fades. I don't get it - hope you do.";
|
||||
"Don't waste *HONEY*. Get mad instead. Dam lava!";
|
||||
}
|
||||
remove self; move broken_glass to location;
|
||||
"The mirror hits the floor and shatters into a million pieces!";
|
||||
];
|
||||
Object -> bear "the bear"
|
||||
with name "thin" "black" "bear",
|
||||
short_name
|
||||
[; if (self has general) { print "sleeping bear"; rtrue; }
|
||||
print "thin black bear"; rtrue;
|
||||
],
|
||||
before
|
||||
[; WakeOther: give self ~general; "The bear rouses!^";
|
||||
],
|
||||
life
|
||||
[; Ask, Order, Answer: <<Sing>>;
|
||||
Attack, ThrowAt:
|
||||
if (self has general) <WakeOther self>;
|
||||
remove mirror; move broken_glass to location;
|
||||
"Oh no...Bear dodges...CRASH!";
|
||||
],
|
||||
has animate;
|
||||
Object broken_glass "broken glass"
|
||||
with name "broken" "glass" "jagged" "fragments", article "some";
|
||||
Object dead_bear "dead bear"
|
||||
with name "dead" "bear" "black" "thin"
|
||||
has static;
|
||||
|
||||
ScottRoom Throne_Room "Throne Room"
|
||||
with description "You're in a throne room.",
|
||||
w_to Narrow_Ledge_2;
|
||||
Treasure -> "*GOLD CROWN*"
|
||||
with name "gold" "golden" "crown";
|
||||
|
||||
ScottRoom Real_Trouble "Trouble!"
|
||||
with description
|
||||
"I think you're in real trouble. Here's a guy with a pitchfork!^^
|
||||
You lost *ALL* treasures.",
|
||||
initial
|
||||
[; deadflag=3;
|
||||
],
|
||||
has light;
|
||||
|
||||
ScottRoom Memory_RAM "Ugly Place"
|
||||
with description
|
||||
"You're in the memory RAM of an IBM-PC. You took a wrong turn!",
|
||||
e_to Large_Cavern,
|
||||
has light;
|
||||
Sign -> "To the Architects - TSURRIS";
|
||||
|
||||
ScottRoom Misty_Room "Misty Room"
|
||||
with description "You're in a large misty room with strange letters
|
||||
over the exits.",
|
||||
s_to Real_Trouble, e_to Forest, w_to Real_Trouble,
|
||||
u_to Up_Oak, d_to Real_Trouble,
|
||||
has light;
|
||||
Sign -> "LIMBO. FIND RIGHT EXIT AND LIVE AGAIN!";
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! A soupcon of code
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
[ Initialise;
|
||||
location=Forest; score = 0;
|
||||
|
||||
StartDaemon(chiggers);
|
||||
|
||||
"^^^^^A voice booms out ...^
|
||||
Treasures have an * in their name. Say 'SCORE'^
|
||||
If you need a hint on something, try 'HELP'.^";
|
||||
];
|
||||
|
||||
[ TimePasses i;
|
||||
if (location ~= Inside_Stump) rfalse;
|
||||
|
||||
score=0;
|
||||
objectloop (i in Inside_Stump && i ofclass Treasure)
|
||||
score = score + i.depositpoints;
|
||||
|
||||
if (score ~= 100) rfalse;
|
||||
|
||||
deadflag=2;
|
||||
"Congratulations! By finding and depositing all 13 *TREASURES*, you
|
||||
have solved Scott Adams's ~Adventureland~ and it remains only to say
|
||||
that...";
|
||||
];
|
||||
|
||||
[ AfterLife;
|
||||
if (deadflag==3) { deadflag=1; rfalse; }
|
||||
remove chigger_bites; remove infected_bites;
|
||||
deadflag=0; PlayerTo(Misty_Room);
|
||||
];
|
||||
|
||||
[ PrintRank; "."; ];
|
||||
|
||||
[ DarkToDark;
|
||||
if (dark_warning==0)
|
||||
{ dark_warning=1; "It is now pitch dark.
|
||||
If you proceed you will likely fall into a pit.";
|
||||
}
|
||||
if (random(4) == 1)
|
||||
{ deadflag=1;
|
||||
"You fell into a pit and broke every bone in your body!";
|
||||
}
|
||||
rfalse;
|
||||
];
|
||||
|
||||
[ BunyonSub;
|
||||
if (axe notin player) "Nothing happens.";
|
||||
if (ox in player or location)
|
||||
{ move ox to Hidden_Grove;
|
||||
move axe to Hidden_Grove;
|
||||
"Something you're holding vibrated and...";
|
||||
}
|
||||
if (player notin Quicksand)
|
||||
{ move axe to Hidden_Grove;
|
||||
print "Something you're holding vibrated and...";
|
||||
<<Inv>>;
|
||||
}
|
||||
"Nothing happens.";
|
||||
];
|
||||
|
||||
[ TsurrisSub;
|
||||
if (location ~= Memory_RAM) "Nothing happens.";
|
||||
"A voice booms out...^
|
||||
May all your teeth but one fall out, and may that one give you toothache.^
|
||||
(You can't help feeling you have stumbled on a private quarrel which is
|
||||
nothing to do with your game.)";
|
||||
];
|
||||
|
||||
[ BurnSub;
|
||||
if (flint_and_steel notin player)
|
||||
"You have nothing to strike a light with.";
|
||||
if (noun==gas) "Gas needs to be contained before it will burn.";
|
||||
if (noun==distended_bladder)
|
||||
{ if (noun in player)
|
||||
{ remove noun; deadflag=1; "Gas bladder blew up in your hands!";
|
||||
}
|
||||
remove noun;
|
||||
print "Gas bladder blew up!^";
|
||||
if (dragon in location)
|
||||
{ remove dragon; move gore to location;
|
||||
"The dragon has been blown to bits!";
|
||||
}
|
||||
if (bricked_window in location)
|
||||
{ remove bricked_window;
|
||||
move holed_window to location; move firebricks to location;
|
||||
Royal_Chamber.e_to = holed_window;
|
||||
"The bricked window has been blown to bits!";
|
||||
}
|
||||
rtrue;
|
||||
}
|
||||
"That won't ignite.";
|
||||
];
|
||||
|
||||
[ HelpSub;
|
||||
print "A voice booms out...^";
|
||||
print "Try: LOOK,JUMP,SWIM,CLIMB,THROW,FIND,GO,TAKE,INVENTORY,SCORE.^";
|
||||
if (chigger_bites in player || infected_bites in player)
|
||||
"Medicine is good for bites.";
|
||||
if (location == Quicksand) "You may need magic words here.";
|
||||
if (location == Sunny_Meadow)
|
||||
"Only 3 things will wake the dragon. One of them is dangerous!";
|
||||
if (location == Hive)
|
||||
"Read the sign in the meadow!";
|
||||
if (location == Maze1 or Maze2 or Maze3
|
||||
|| location == Maze4 or Maze5 or Maze6)
|
||||
"You may need magic words here.";
|
||||
if (location == Royal_Chamber) "Blow it up. Try the swamp.";
|
||||
];
|
||||
|
||||
[ AwaySub;
|
||||
if (rug notin player || location~=Maze3) "Nothing happens.";
|
||||
print "Something you're holding vibrates, and...^";
|
||||
PlayerTo(Sunny_Meadow);
|
||||
];
|
||||
|
||||
[ FindSub;
|
||||
"A voice booms out...^Find it yourself.";
|
||||
];
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! Grammar: the usual grammar and some extensions
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Include "Grammar";
|
||||
|
||||
Extend "cut"
|
||||
* "up" noun -> Cut
|
||||
* "down" noun -> Cut;
|
||||
|
||||
Verb "bunyon" * -> Bunyon;
|
||||
Verb "away" * -> Away;
|
||||
Verb "tsurris" * -> Tsurris;
|
||||
Verb "help" * -> Help;
|
||||
Verb "find" * special -> Find;
|
||||
|
||||
! ----------------------------------------------------------------------------
|
|
@ -0,0 +1,469 @@
|
|||
! Through the Looking-Glass
|
||||
! An Inform tutorial by Gareth Rees
|
||||
! All rights given away
|
||||
! Version 3
|
||||
!
|
||||
! 5/1/2003 - Updated to Inform 6.21 Library 6/10
|
||||
!
|
||||
|
||||
Constant Story "THROUGH THE LOOKING GLASS";
|
||||
Constant Headline "^An Interactive Tutorial^by Gareth Rees^";
|
||||
|
||||
Include "parser";
|
||||
Include "verblib";
|
||||
Include "grammar";
|
||||
|
||||
[ Initialise;
|
||||
location = Drawing_Room;
|
||||
StartDaemon(white_kitten);
|
||||
StartDaemon(black_kitten);
|
||||
print "^^^^^It's a cold winter day outside, but in the
|
||||
looking-glass house it's summer. All you need to do is
|
||||
pretend there's a way of getting through into it
|
||||
somehow...^^";
|
||||
];
|
||||
|
||||
[ UntangleSub; "What curious ideas you have!"; ];
|
||||
|
||||
[ ReflectSub;
|
||||
if (second ~= mirror) "What a strange idea!";
|
||||
if (noun == hearth or mirror || (player notin mantelpiece &&
|
||||
player notin armchair))
|
||||
"You can't see that in the looking-glass.";
|
||||
print "The looking-glass ";
|
||||
if (noun == player) print "Alice";
|
||||
else PrintShortName(noun);
|
||||
if (player in mantelpiece) " looks very misty and blurred.";
|
||||
print " looks just like the real ";
|
||||
if (noun == player) print "Alice";
|
||||
else PrintShortName(noun);
|
||||
" only all reversed, left for right.";
|
||||
];
|
||||
|
||||
Extend "look"
|
||||
* "at" noun "in" noun -> Reflect;
|
||||
|
||||
Extend "examine"
|
||||
* noun "in" noun -> Reflect;
|
||||
|
||||
Verb "roll" "untangle" "wind"
|
||||
* noun -> Untangle
|
||||
* "up" noun -> Untangle
|
||||
* noun "up" -> Untangle;
|
||||
|
||||
Object Drawing_Room "Drawing room"
|
||||
has light
|
||||
with name "snow",
|
||||
description "The gentle sound of snow against the window pane
|
||||
suggests that it's cold outside, and you're glad to be
|
||||
here in the warmth. The drawing-room is reflected in the
|
||||
large looking-glass on the wall above the mantelpiece,
|
||||
and a very comfortable room it is too, with a warm
|
||||
hearth, a soft rug and an arm-chair that you can curl up
|
||||
and sleep in.",
|
||||
before [;
|
||||
if (player in mantelpiece && (action == ##Exit ||
|
||||
(action == ##Go && noun == d_obj or out_obj)))
|
||||
"That's not the way to get down from a mantelpiece!";
|
||||
if (player in mantelpiece &&
|
||||
action ~= ##Examine or ##Enter or ##Go &&
|
||||
action ~= ##ThrownAt or ##ThrowAt or ##Reflect)
|
||||
if ((noun > 0 && noun notin mantelpiece &&
|
||||
noun ~= mantelpiece or mirror && noun notin player) ||
|
||||
(second > 0 && second notin mantelpiece &&
|
||||
second ~= mantelpiece or mirror && second notin player))
|
||||
"Not from up here you can't!";
|
||||
];
|
||||
|
||||
Object red_queen "red queen"
|
||||
has female
|
||||
with name "red" "queen",
|
||||
describe [;
|
||||
if (white_kitten.state == 1 || black_kitten.state == 1)
|
||||
rtrue;
|
||||
],
|
||||
description "She's a fierce little chess piece.",
|
||||
after [;
|
||||
Take:
|
||||
if (white_kitten.state == 1)
|
||||
white_kitten.state = 3;
|
||||
if (black_kitten.state == 1)
|
||||
black_kitten.state = 3;
|
||||
PutOn,Transfer,Insert:
|
||||
if (second == chess_board)
|
||||
"Alone on the chess board, the red queen is monarch of
|
||||
all she surveys.";
|
||||
];
|
||||
|
||||
Object chess_board "chess board" Drawing_Room
|
||||
has supporter
|
||||
with name "chess" "board" "checker" "chequer" "chessboard",
|
||||
initial "An abandoned chess board lies on the floor.",
|
||||
description "It's left here from the game you were playing
|
||||
just now, but the pieces are all missing - the kittens
|
||||
will insist on playing with them.";
|
||||
|
||||
Object hearth "hearth" Drawing_Room
|
||||
has scenery
|
||||
with name "hearth" "fire" "place" "fireplace";
|
||||
|
||||
Object rug "rug" Drawing_Room
|
||||
has concealed static supporter enterable
|
||||
! general if you've found the red queen under it
|
||||
with name "hearthrug" "hearth-rug" "rug" "indian" "arabian" "beautiful"
|
||||
"soft",
|
||||
description "It's a beautiful rug, made in some far off
|
||||
country, perhaps India or Araby, wherever those might
|
||||
be.",
|
||||
before [;
|
||||
Take: "The rug is much too large and heavy for you to carry.";
|
||||
Push,Pull: "But a hearth-rug is meant to be next to the
|
||||
hearth!";
|
||||
LookUnder:
|
||||
if (player in mantelpiece || player in armchair)
|
||||
"You're unable to reach the rug from here.";
|
||||
if (player in self)
|
||||
"You try to lift up a corner of the rug, but fail. After
|
||||
a while, you realise that this is because you are
|
||||
standing on it. How curious the world is!";
|
||||
if (self hasnt general) {
|
||||
give self general;
|
||||
move red_queen to player;
|
||||
"You lift up a corner of the rug and, peering
|
||||
underneath, discover the red queen from the chess
|
||||
set.";
|
||||
}
|
||||
];
|
||||
|
||||
Object armchair "arm-chair" Drawing_Room
|
||||
has static concealed supporter enterable
|
||||
! general if its by the mantelpiece
|
||||
with name "arm" "chair" "armchair" "arm-chair",
|
||||
description [;
|
||||
print "It's a huge arm-chair, the perfect place for a kitten
|
||||
or a little girl to curl up in and doze. It has been
|
||||
pushed over to the ";
|
||||
if (self has general) "fireplace.";
|
||||
"window.";
|
||||
],
|
||||
before [ i;
|
||||
Push,Pull:
|
||||
if (player notin Drawing_Room)
|
||||
print_ret "You'll have to get off ", (the) parent(player),
|
||||
" first.";
|
||||
if (white_kitten in player || black_kitten in player)
|
||||
"Not with a kitten in your arms!";
|
||||
if (white_kitten.state == 3) i = white_kitten;
|
||||
else if (black_kitten.state == 3) i = black_kitten;
|
||||
if (i ~= 0)
|
||||
print_ret "You are about to start moving the chair when you
|
||||
notice that ", (the) i, " is right in the way. It's a
|
||||
good thing you spotted it, or you would have squashed
|
||||
flat the poor little thing.";
|
||||
if (self has general) {
|
||||
give self ~general;
|
||||
"You push the arm-chair away from the hearth.";
|
||||
}
|
||||
give self general;
|
||||
"You push the arm-chair over to the hearth.";
|
||||
Climb,Enter:
|
||||
move player to armchair;
|
||||
"You jump into the warm and comfortable arm-chair.";
|
||||
];
|
||||
|
||||
Object mantelpiece "mantelpiece" Drawing_Room
|
||||
has concealed supporter enterable
|
||||
with name "mantel" "mantelpiece",
|
||||
description "It's higher off the ground than your head, but
|
||||
it looks wide enough and sturdy enough to support you.",
|
||||
before [;
|
||||
Enter,Climb:
|
||||
if (player notin armchair)
|
||||
"The mantelpiece is much too high to climb up onto.";
|
||||
if (armchair hasnt general)
|
||||
"You can't reach the mantelpiece from here.";
|
||||
if (children(player) > 0)
|
||||
"Your hands are too full.";
|
||||
move player to mantelpiece;
|
||||
"You scramble up onto the mantelpiece.";
|
||||
PutOn,LetGo:
|
||||
if (player notin self && (player notin armchair ||
|
||||
armchair hasnt general))
|
||||
"The mantelpiece is so high that you can't reach.";
|
||||
];
|
||||
|
||||
Object mirror "looking-glass" Drawing_Room
|
||||
has static concealed
|
||||
with name "mirror" "looking" "glass" "looking-glass",
|
||||
description [;
|
||||
if (player in mantelpiece)
|
||||
"Strangely, the glass is beginning to melt away,
|
||||
just like a bright silvery mist.";
|
||||
if (player in armchair)
|
||||
"In the looking-glass you can see the drawing-room of
|
||||
the looking-glass house. What you can see is very
|
||||
much the same as this drawing-room, only all
|
||||
reversed, left for right. But you are sure that out
|
||||
of the corners of the glass, where you can't see, the
|
||||
looking-glass world is quite different from yours.";
|
||||
"In the looking-glass you can see the ceiling of the
|
||||
drawing-room of the looking-glass house. It looks much
|
||||
the same as the ceiling of your drawing-room.";
|
||||
],
|
||||
before [;
|
||||
if (action ~= ##Examine or ##ThrownAt or ##Reflect &&
|
||||
player notin mantelpiece)
|
||||
"You can't reach the looking-glass from where you're
|
||||
standing.";
|
||||
Touch,Pull,Push:
|
||||
"Your hand goes right through the silvery mist!";
|
||||
ThrownAt: "You don't want seven years' bad luck, do you?";
|
||||
Enter:
|
||||
! Really, move Alice to the looking-glass house.
|
||||
deadflag = 2;
|
||||
"Your hand goes right through the silvery mist, and in
|
||||
another moment the rest of you follows, and you are
|
||||
through the glass...";
|
||||
];
|
||||
|
||||
Object worsted "ball of worsted" Drawing_Room
|
||||
! general if its in a tangle
|
||||
with name "ball" "of" "worsted" "fine" "blue" "wool",
|
||||
describe [;
|
||||
if (white_kitten.state ~= 2 &&
|
||||
black_kitten.state ~= 2)
|
||||
"^A discarded ball of worsted lies on the floor here.";
|
||||
rtrue;
|
||||
],
|
||||
description [;
|
||||
if (self has general)
|
||||
"It's in a terrible tangle. All that time you spent
|
||||
rolling it up, and now look at it!";
|
||||
"It's a ball of fine blue wool, all rolled up in preparation
|
||||
for some embroidery.";
|
||||
],
|
||||
before [;
|
||||
Untangle:
|
||||
give self ~general;
|
||||
"You're as quick as can be at rolling up balls of wool,
|
||||
though you say so yourself! Soon it's neat and tidy again.";
|
||||
],
|
||||
after [;
|
||||
Take:
|
||||
if (white_kitten.state == 2)
|
||||
white_kitten.state = 3;
|
||||
if (black_kitten.state == 2)
|
||||
black_kitten.state = 3;
|
||||
];
|
||||
|
||||
Object chess_pieces "chess pieces" Drawing_Room
|
||||
has scenery
|
||||
with parse_name [ w colour n;
|
||||
w = NextWord();
|
||||
if (w == 'white' or 'red') {
|
||||
n ++;
|
||||
colour = w;
|
||||
w = NextWord();
|
||||
}
|
||||
if (w == 'pawn' or 'rook' or 'castle' ||
|
||||
w == 'knight' or 'horse' or 'bishop' ||
|
||||
w == 'king' || (w == 'queen' &&
|
||||
(colour == 'white' || rug hasnt general))) return n + 1;
|
||||
return 0;
|
||||
],
|
||||
before [;
|
||||
"Alas, that chess piece seems to be missing. Those
|
||||
naughty kittens!";
|
||||
];
|
||||
|
||||
Object window "window" Drawing_Room
|
||||
has scenery
|
||||
with name "window" "pane",
|
||||
description "Outside the window it's snowing gently, and you're
|
||||
glad to be in here in the warmth.",
|
||||
before [;
|
||||
Open: "You wouldn't want to catch a chill, would you? Better
|
||||
leave the window shut.";
|
||||
Search: <<Examine self>>;
|
||||
];
|
||||
|
||||
Property other_kitten;
|
||||
Property state; ! 1=red queen, 2=ball of wool, 3=arm-chair, 0=held
|
||||
|
||||
Class Kitten_Class
|
||||
has animate
|
||||
! general if it's been described this turn
|
||||
with parse_name [ w ok n;
|
||||
do {
|
||||
ok = 0;
|
||||
w = NextWord();
|
||||
if (w == 'kittens' or 'cats') {
|
||||
ok = 1; n++; parser_action=##PluralFound;
|
||||
}
|
||||
if (w == 'kitten' or 'kitty' or 'cat' ||
|
||||
w == ((self.&name)-->0)) {
|
||||
ok = 1; n++;
|
||||
}
|
||||
} until (ok == 0);
|
||||
return n;
|
||||
],
|
||||
state 3,
|
||||
describe [ i;
|
||||
switch (self.state) {
|
||||
1: print_ret "^A ", (name) self, " is playing with the red
|
||||
queen.";
|
||||
2: print_ret "^A ", (name) self, " is playing with a ball of
|
||||
worsted.";
|
||||
3: if (self has general) rtrue;
|
||||
if ((self.other_kitten).state == 3) {
|
||||
i = self.other_kitten;
|
||||
give i general;
|
||||
"^Two kittens, one white and one black, are playing
|
||||
together by the arm-chair.";
|
||||
}
|
||||
print_ret "^A ", (name) self, " is playing by the
|
||||
arm-chair.";
|
||||
default: rtrue;
|
||||
}
|
||||
],
|
||||
description [;
|
||||
print_ret "What a beautiful kitten ", (the) self, " is. Why,
|
||||
it's quite definitely your favourite of the pair, and
|
||||
much prettier than that naughty ", (name)
|
||||
self.other_kitten, ".";
|
||||
],
|
||||
life [;
|
||||
Ask,Answer,Order:
|
||||
print_ret (The) self, " twitches its whiskers and looks at
|
||||
you with such a clever expression that you are certain it
|
||||
understands every word you are saying.";
|
||||
Kiss:
|
||||
print_ret "You give ", (the) self, " a little kiss on its
|
||||
nose, and it looks sweetly and demurely at you.";
|
||||
Attack: "You would never do such a beastly thing to such
|
||||
a defenceless little animal!";
|
||||
Show:
|
||||
print_ret (The) self, " bats a paw at ", (the) noun, ".";
|
||||
Give,ThrowAt:
|
||||
if (noun ~= red_queen or worsted) {
|
||||
if (action == ##ThrowAt) {
|
||||
move noun to Drawing_Room;
|
||||
print "You toss ", (the) noun, " onto the floor, but ",
|
||||
(the) self;
|
||||
}
|
||||
else print (The) self;
|
||||
print_ret " just examines ", (the) noun, " with a
|
||||
quizzical expression.";
|
||||
}
|
||||
print "You toss ", (the) noun, " onto the floor and ", (the) self;
|
||||
if (self in player)
|
||||
print " squirms out of your grasp and";
|
||||
move noun to Drawing_Room;
|
||||
move self to Drawing_Room;
|
||||
print " scampers after it";
|
||||
if (noun == worsted) {
|
||||
give worsted general;
|
||||
self.state = 2;
|
||||
print ", quickly turning the neat ball into a tangle";
|
||||
}
|
||||
else self.state = 1;
|
||||
".";
|
||||
],
|
||||
before [;
|
||||
Take:
|
||||
if (self.other_kitten in player)
|
||||
"You can't hold two kittens at once!";
|
||||
self.state = 0;
|
||||
move self to player;
|
||||
print_ret "You pick up ", (the) self, ". What a beautiful
|
||||
creature it is!";
|
||||
],
|
||||
after [;
|
||||
Drop:
|
||||
self.state = 3;
|
||||
move self to Drawing_Room;
|
||||
print_ret (The) self, " squirms out of your arms and scampers
|
||||
away.";
|
||||
Transfer,PutOn,Insert:
|
||||
self.state = 3;
|
||||
print (The) self, " jumps off ", (the) parent(self);
|
||||
move self to Drawing_Room;
|
||||
", landing lightly on the floor before scampering away.";
|
||||
],
|
||||
daemon [ i;
|
||||
give self ~general;
|
||||
self.number = 1 - self.number;
|
||||
if (self.number == 1 || random(3) == 2) rtrue;
|
||||
new_line;
|
||||
print (The) self;
|
||||
switch (self.state) {
|
||||
0: switch(random(5)) {
|
||||
1: " mews plaintively.";
|
||||
2: " purrs quietly to itself.";
|
||||
3: " purrs contentedly to itself.";
|
||||
4: " rubs its ears against you.";
|
||||
5: move self to Drawing_Room;
|
||||
self.state = 3;
|
||||
" squirms out of your arms and scampers away.";
|
||||
}
|
||||
1: switch (random(5)) {
|
||||
1: " bats at the red queen with its paw.";
|
||||
2: " stops playing and sits up, pretending to be
|
||||
innocent of any kittenish tendancies.";
|
||||
3: " knocks the red queen across the floor and chases
|
||||
after it.";
|
||||
4: " stops to wash itself.";
|
||||
5: " bites the red queen and shakes it to make sure that
|
||||
it's dead.";
|
||||
}
|
||||
2: give worsted general;
|
||||
switch (random(5)) {
|
||||
1: " bats at the ball of worsted with its paw.";
|
||||
2: " pushes the ball of worsted across the floor and
|
||||
chases after it.";
|
||||
3: " leaps onto the ball of worsted and grapples bravely
|
||||
with it.";
|
||||
4: " jumps into the ball of worsted and gets tangled up
|
||||
in a mess of threads.";
|
||||
5: " stops playing and scratches its ears.";
|
||||
}
|
||||
3: if ((self.other_kitten).state == 3 && random(2) == 1) {
|
||||
i = random(5);
|
||||
switch (i) {
|
||||
1: print " chases after ";
|
||||
2: print " jumps on top of ";
|
||||
3: print " washes ";
|
||||
4: print " scampers around the arm-chair and ";
|
||||
5: print " bats at ";
|
||||
}
|
||||
print (the) self.other_kitten;
|
||||
switch (i) {
|
||||
1,3: ".";
|
||||
2: " and they roll around on the floor.";
|
||||
4: " chases after it.";
|
||||
5: " with its paw.";
|
||||
}
|
||||
}
|
||||
switch (random(5)) {
|
||||
1: " scampers after a speck of dust.";
|
||||
2: " rolls around on the floor.";
|
||||
3: " sits up and washes its tail.";
|
||||
4: " scratches its head on the arm-chair.";
|
||||
5: " chases its tail.";
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
Object white_kitten "white kitten" Drawing_Room
|
||||
class Kitten_Class
|
||||
with name "white",
|
||||
number 0,
|
||||
other_kitten black_kitten;
|
||||
|
||||
Object black_kitten "black kitten" Drawing_Room
|
||||
class Kitten_Class
|
||||
with name "black",
|
||||
number 1,
|
||||
other_kitten white_kitten;
|
||||
|
||||
End;
|
|
@ -0,0 +1,458 @@
|
|||
! -----------------------------------------------------------------------------
|
||||
Constant Story "Alone on The Ice";
|
||||
|
||||
Constant Headline
|
||||
"^Inform for New Writers^
|
||||
~Alone on The Ice~ - a sample game/tutorial
|
||||
by Ethan Dicks - Last Compiled: 23-Feb-1998^";
|
||||
|
||||
Release 1;
|
||||
Serial "980223";
|
||||
|
||||
! The game is meant to be experimented with, so we always define:
|
||||
Constant DEBUG;
|
||||
|
||||
! --------------------------------------------------------------------------
|
||||
|
||||
! Put your "replaces" here to re-write parts of the Inform libraries
|
||||
|
||||
Include "Parser";
|
||||
|
||||
! --------------------------------------------------------------------------
|
||||
! Out on the open ice, every object that might be dropped out there needs to
|
||||
! have a property to store its "coordinate". Forgetting this could cause
|
||||
! serious bugs.
|
||||
Property ICELOC 0; ! coordinate of Object in ice field.
|
||||
|
||||
! --------------------------------------------------------------------------
|
||||
|
||||
Include "VerbLib";
|
||||
|
||||
! --------------------------------------------------------------------------
|
||||
!
|
||||
! It all starts here --+
|
||||
! |
|
||||
! v
|
||||
[ Initialise;
|
||||
location = HUT1;
|
||||
|
||||
thedark.description = "There is nothing here but whiteness. If you move
|
||||
from this spot, you are likely to be hopelessly lost";
|
||||
|
||||
"You awake from a dreamless sleep to silence. You look around the room
|
||||
for Tom, your campmate; he isn't here. Of all the places to go for a
|
||||
walk by yourself, the middle of the Antarctic plateau isn't one of them.
|
||||
Despite your training to stay put and wait for him to come back, you
|
||||
decide to go after him. It's just the two of you here, and no planes
|
||||
due for weeks.";
|
||||
];
|
||||
|
||||
! --------------------------------------------------------------------------
|
||||
!
|
||||
! Things - the elements of our interactive world
|
||||
!
|
||||
! --------------------------------------------------------------------------
|
||||
|
||||
Object HUT1 "A small scientific observation hut"
|
||||
with description "This cramped insulated box has been your home for
|
||||
several months now. There is little in here but
|
||||
some equipment for monitoring the weather and two
|
||||
cots.",
|
||||
n_to DOOR1,
|
||||
has light;
|
||||
|
||||
!----
|
||||
Object -> DOOR1 "freezer door" ! An ordinary two-sided door (as implemented
|
||||
! in the Inform Designer's Manual, chpt. 12).
|
||||
with description "There is a door in the wall of the hut, nearly as wide
|
||||
as the wall. It is large, white and heavy. It does
|
||||
not appear to have a doornob, as such, but more of a
|
||||
plunger like you'd find on the inside of a meat locker.",
|
||||
name "white" "freezer" "door",
|
||||
when_closed [; rfalse; ],
|
||||
when_open "The door has been carelessly left open and the cold,
|
||||
antarctic wind is blowing into the hut, unabated.",
|
||||
door_to [; if (location==CAMP14) return HUT1; return CAMP14; ],
|
||||
door_dir [; if (location==CAMP14) return n_to; return s_to; ],
|
||||
found_in HUT1 CAMP14,
|
||||
has static door openable;
|
||||
|
||||
!----
|
||||
Object -> NOTE "goodbye note"
|
||||
with initial "There is a piece of paper taped to the door here.",
|
||||
inven "A note from your campmate.",
|
||||
name "note" "paper" "piece",
|
||||
ICELOC 0,
|
||||
before [; Examine: "The paper appears torn hastily from a notebook, the
|
||||
writing nearly illegible. It reads:^^Went to get
|
||||
some smokes. Be back soon.^^^^ --Tom";
|
||||
],
|
||||
|
||||
has ~static; ! make sure it's portable
|
||||
|
||||
!----
|
||||
Object -> BOOK "survival guide"
|
||||
with name "book" "survival" "guide",
|
||||
initial "A survival guide lies discarded in the corner.",
|
||||
ICELOC 0,
|
||||
before [; Examine: "It's a standard issue guide to survival in Antarctica.
|
||||
You got it on your first day here. On the back cover
|
||||
is a list of important safety tips:
|
||||
^ Black flags mark hazards - do not approach.
|
||||
^ Orange flags mean safe travel.
|
||||
^ Stick to the flagged routes.
|
||||
^ Travel in pairs (I guess Tom forgot that one).
|
||||
^ In a white-out, sit down and wait it out.^";
|
||||
],
|
||||
has ~static; ! make sure it's portable
|
||||
|
||||
!----
|
||||
Object CAMP14 "Weather Observation Post 14"
|
||||
with description "Behind the sign that reads, ~The United States Welcomes
|
||||
you to Observation Post 14,~ lies your camp: an orange
|
||||
eight-foot by eight-foot box that you call home. There
|
||||
is a line of orange trail-marker flags heading off in
|
||||
the distance to the north. The rest is whiteness",
|
||||
s_to DOOR1,
|
||||
n_to
|
||||
[;
|
||||
! Drop the player at the starting poing
|
||||
PlayerTo(ICE,1); ! Put the player in the "ice room" Object
|
||||
IGOTO(52); ! Set the starting location (middle of the south edge)
|
||||
rtrue; ! Tell the parser that it worked.
|
||||
],
|
||||
has light;
|
||||
|
||||
!----
|
||||
Object CAMP9 "Weather Observation Post 9"
|
||||
with description "This is another field camp, the sign here tells you,
|
||||
~The United States Welcomes you to Observation Post 9~.
|
||||
The flagged route goes south from here.",
|
||||
n_to DOOR2,
|
||||
s_to
|
||||
[;
|
||||
! Drop the player at the starting poing
|
||||
PlayerTo(ICE,1); ! Put the player in the "ice room" Object
|
||||
IGOTO(12); ! Set the starting location (middle of the north edge)
|
||||
rtrue; ! Tell the parser that it worked.
|
||||
],
|
||||
has light;
|
||||
|
||||
!----
|
||||
Object HUT2 "A small scientific observation hut"
|
||||
with description "This looks like a duplicate of your own observation hut,
|
||||
down to the scuff marks on the floor.",
|
||||
|
||||
s_to ICE2,
|
||||
n_to DOOR2,
|
||||
has light;
|
||||
|
||||
!----
|
||||
Object -> DOOR2 "freezer door" ! An ordinary two-sided door (as implemented
|
||||
! in the Inform Designer's Manual, chpt. 12).
|
||||
with description "There is a familiar looking door in the wall of the hut,
|
||||
with a familiar looking opening plunger.",
|
||||
name "white" "freezer" "door",
|
||||
when_closed [; rfalse; ],
|
||||
when_open "The door has been carelessly left open and the cold,
|
||||
antarctic wind is blowing into the hut, unabated.",
|
||||
door_to [; if (location==CAMP9) return HUT2; return CAMP9; ],
|
||||
door_dir [; if (location==CAMP9) return n_to; return s_to; ],
|
||||
found_in HUT2 CAMP9,
|
||||
has static door openable;
|
||||
|
||||
!----
|
||||
Object -> TOM "your campmate, Tom"
|
||||
with name "Tom",
|
||||
description "Tom, the only other person for a hundred miles, is here,
|
||||
smoking the foulest smelling cigarettes you have ever
|
||||
smelled - Penguin Slims",
|
||||
has proper animate;
|
||||
|
||||
! In order to create the illusion of an enormous expanse of rooms without
|
||||
! having to create one object per location, we simulate a large area with
|
||||
! two real rooms and an array. One room (ICE) contains the Player object
|
||||
! at all times. The other (ICE2), is a temporary holding area for the
|
||||
! objects that are located in various places throughout the virtual space.
|
||||
! We use the "ICELOC" property to remember where in the greater area an
|
||||
! object was the last time the Player saw it.
|
||||
!
|
||||
Object ICE "Out on the open ice"
|
||||
with name "ICE",
|
||||
description
|
||||
[; IWHERE(); ],
|
||||
|
||||
before
|
||||
[; Go:
|
||||
! Check to see if we are at an exit space, otherwise, just move
|
||||
! around the virtual area.
|
||||
return IEXIT();
|
||||
],
|
||||
|
||||
! Since we don't move from object to object, all roads lead back here. The
|
||||
! only way out is through specially marked spaces.
|
||||
n_to ICE, s_to ICE, e_to ICE, w_to ICE,
|
||||
ne_to ICE, nw_to ICE, se_to ICE, u_to ICE, sw_to ICE,
|
||||
d_to ICE,
|
||||
|
||||
has light static container;
|
||||
|
||||
! We need a place to stash things that get left out on the ice
|
||||
Object ICE2 "Ice Box" with name "ICE2", description "Ice Box", has light;
|
||||
|
||||
! ----------------------------------------
|
||||
! Let's leave a trail for Player to follow
|
||||
!
|
||||
Class Flag
|
||||
with description "trail flag",
|
||||
name "marker" "flag" "bamboo" "pole",
|
||||
initial
|
||||
[;
|
||||
"There is ", (a) self, " trail-marker flag here, fluttering
|
||||
at the end of a bamboo pole";
|
||||
],
|
||||
After
|
||||
[; Take: print "You pull the flag from the snow"; ],
|
||||
|
||||
has ~static; ! Let's let the player pick up and move the flags around.
|
||||
|
||||
! Now, create several instances of the flags and stick them in the holding room
|
||||
Class Orange_Flag class Flag with name "orange", article "an";
|
||||
Class Black_Flag class Flag with name "black", article "a";
|
||||
|
||||
Orange_Flag O1 "orange flag" ICE2 with plural "orange flags", ICELOC 12;
|
||||
Orange_Flag O2 "orange flag" ICE2 with plural "orange flags", ICELOC 20;
|
||||
Orange_Flag O3 "orange flag" ICE2 with plural "orange flags", ICELOC 28;
|
||||
Orange_Flag O4 "orange flag" ICE2 with plural "orange flags", ICELOC 36;
|
||||
Orange_Flag O5 "orange flag" ICE2 with plural "orange flags", ICELOC 44;
|
||||
Orange_Flag O6 "orange flag" ICE2 with plural "orange flags", ICELOC 52;
|
||||
|
||||
Black_Flag BL1 "black flag" ICE2 with plural "black flags", ICELOC 53;
|
||||
Black_Flag BL2 "black flag" ICE2 with plural "black flags", ICELOC 45;
|
||||
Black_Flag BL3 "black flag" ICE2 with plural "black flags", ICELOC 37;
|
||||
Black_Flag BL4 "black flag" ICE2 with plural "black flags", ICELOC 29;
|
||||
! ----------------------------------------
|
||||
|
||||
Global IPLAYER=52; ! Current location of Player on the ice
|
||||
|
||||
!----------
|
||||
! Virtual room array
|
||||
! This array is a grid representation of the ice field. Different numbers
|
||||
! represent the kind of terrain found in a particular "location". To make
|
||||
! life easier for the programmer, positive numbers are inaccessible, zero
|
||||
! is flat and level, and negative numbers are used for features such as exits
|
||||
! and moveable ice blocks (not implemented in this tutorial).
|
||||
!
|
||||
! It's best to list this out in table form:
|
||||
! 1 is impassable barrier (crevasse)
|
||||
! -1 is movable block of ice (Not Implemented Yet)
|
||||
! -2 is the passage to the north exit
|
||||
! -3 is the passage to the south exit
|
||||
|
||||
Array IVEC --> 0 1 1 1 (-2) 1 1 1 1
|
||||
1 0 0 0 0 0 0 1
|
||||
1 0 0 0 0 0 0 1
|
||||
1 0 0 0 0 1 0 1
|
||||
1 0 0 0 0 1 0 1
|
||||
1 0 0 0 0 1 0 1
|
||||
1 0 0 0 0 1 0 1
|
||||
1 1 1 (-3) 1 1 1;
|
||||
|
||||
! Note the north-south crevasse to the east of the expected path of the Player.
|
||||
|
||||
! ----------------------------------------
|
||||
! Walking around on the ice field
|
||||
|
||||
! NB: n_obj is 7. The array has dummy entries to match the array element
|
||||
! number with the direction object number. The elements/directions
|
||||
! follow the order N, S, E, W, NE, NW, SE, SW. If this changes, this
|
||||
! array and it's supporting code must be redesigned. This may not
|
||||
! be the best way to do this, but it does work.
|
||||
!
|
||||
! These numbers are based on an 8x8 grid. A grid of a different size would
|
||||
! generate different numbers (i.e., a 4x4 grid would see -4 for -8, -3 for
|
||||
! -7, -5 for -9, etc.)
|
||||
Array IEXITS --> 0 0 0 0 0 0 0 (-8) 8 1 (-1) (-7) (-9) 9 7;
|
||||
|
||||
!
|
||||
! IEXIT - let the player exit the ice field
|
||||
!
|
||||
[ IEXIT;
|
||||
! Check to see if the player is in the right place and moving in the right
|
||||
! direction (up).
|
||||
if (IPLAYER==12 or 52) {
|
||||
! Is there a way up here? (N.B.: for this example, there always is).
|
||||
if ((IVEC-->(IPLAYER + IEXITS-->noun)) == -2) {
|
||||
print "You scramble up the trail and onto the plateau.^";
|
||||
give ICE ~visited;
|
||||
Playerto(CAMP9,2);
|
||||
rtrue;
|
||||
}
|
||||
else if ((IVEC-->(IPLAYER + IEXITS-->noun)) == -3) {
|
||||
print "You scramble up the trail and back to camp.^";
|
||||
give ICE ~visited;
|
||||
Playerto(CAMP14,2);
|
||||
rtrue;
|
||||
}
|
||||
}
|
||||
|
||||
if (noun==u_obj) {
|
||||
print "There is nothing but flat, featureless ice here. Nothing to
|
||||
climb";
|
||||
return 3;
|
||||
}
|
||||
|
||||
! Don't let them go down, ever.
|
||||
if (noun==d_obj) {
|
||||
print "That's not a good idea.";
|
||||
return 3;
|
||||
}
|
||||
|
||||
! If the intended space is empty, let the player move there
|
||||
if (IVEC-->(IPLAYER + IEXITS-->noun)==0) {
|
||||
return IGOTO(IPLAYER + IEXITS-->noun);
|
||||
}
|
||||
|
||||
! There must be a barrier. Stop them from moving.
|
||||
print "In the nick of time, you step back from the edge of a yawning
|
||||
crevasse.";
|
||||
return 3;
|
||||
];
|
||||
|
||||
|
||||
!------
|
||||
! "Move" to new ice room
|
||||
|
||||
[ IGOTO FX x y;
|
||||
|
||||
! Forget we were ever here. This keeps the descriptions fresh.
|
||||
give ICE ~visited;
|
||||
|
||||
! Move stuff out of the old location into the storage space
|
||||
x = child(ICE);
|
||||
while (x) {
|
||||
y=sibling(x);
|
||||
if ( (x hasnt concealed) && (x ~= Player) ) {
|
||||
x.ICELOC=IPLAYER; ! Remember where it came from
|
||||
move x to ICE2; ! Stash it
|
||||
}
|
||||
x = y;
|
||||
}
|
||||
|
||||
! "move" player to the new location
|
||||
IPLAYER=FX;
|
||||
|
||||
! Pull stuff from the storage space to the new location, if it belongs here
|
||||
x = child(ICE2);
|
||||
while (x) {
|
||||
y=sibling(x);
|
||||
! see if this Object belongs in our new location
|
||||
if (x.ICELOC == IPLAYER) {
|
||||
x.ICELOC=0; ! Forget where it used to be
|
||||
move x to ICE; ! Put it back in here
|
||||
}
|
||||
x = y;
|
||||
}
|
||||
|
||||
<Look>;
|
||||
give ICE ~visited;
|
||||
return 3;
|
||||
];
|
||||
|
||||
! ----------------------------------------
|
||||
!
|
||||
! Describe location out on the open ice.
|
||||
!
|
||||
[ IWHERE N W S E num_crevasse crevasse_dir;
|
||||
N = IVEC-->(IPLAYER - 8);
|
||||
S = IVEC-->(IPLAYER + 8);
|
||||
E = IVEC-->(IPLAYER + 1);
|
||||
W = IVEC-->(IPLAYER - 1);
|
||||
|
||||
! print "This is Ice Room #", IPLAYER, ".^";
|
||||
|
||||
! See if Player is somewhere safe or not
|
||||
if ( ON_FLAGGED_ROUTE(IPLAYER) )
|
||||
print "You are on the flagged route. ";
|
||||
else
|
||||
print "You are out on the open ice, a dangerous thing. ";
|
||||
|
||||
! Count the crevasses and remember which direction they are in
|
||||
if (N == 1) { num_crevasse++; crevasse_dir = crevasse_dir + 1; }
|
||||
if (S == 1) { num_crevasse++; crevasse_dir = crevasse_dir + 2; }
|
||||
if (E == 1) { num_crevasse++; crevasse_dir = crevasse_dir + 4; }
|
||||
if (W == 1) { num_crevasse++; crevasse_dir = crevasse_dir + 8; }
|
||||
|
||||
! If there are any crevasses, warn Player
|
||||
if (num_crevasse) {
|
||||
print "There ";
|
||||
if (num_crevasse == 1) ! How many?
|
||||
print "is a crevasse to the ";
|
||||
else
|
||||
print "are crevasses to the ";
|
||||
|
||||
if (N == 1) {
|
||||
print "north";
|
||||
num_crevasse--;
|
||||
if (num_crevasse == 1)
|
||||
print " and ";
|
||||
else if (num_crevasse > 1)
|
||||
print ", ";
|
||||
}
|
||||
|
||||
if (S == 1) {
|
||||
print "south";
|
||||
num_crevasse--;
|
||||
if (num_crevasse == 1)
|
||||
print " and ";
|
||||
else if (num_crevasse > 1)
|
||||
print ", ";
|
||||
}
|
||||
|
||||
if (E == 1) {
|
||||
print "east";
|
||||
num_crevasse--;
|
||||
if (num_crevasse == 1)
|
||||
print " and ";
|
||||
else if (num_crevasse > 1)
|
||||
print ", ";
|
||||
}
|
||||
|
||||
if (W == 1)
|
||||
print "west";
|
||||
|
||||
print ".";
|
||||
}
|
||||
|
||||
print "^";
|
||||
|
||||
! Let's thrown in a colorful phrase, just for fun...
|
||||
if (IPLAYER==36)
|
||||
print "(If Nowhere has a Middle, this is it.)^";
|
||||
|
||||
! Describe the exits, if present
|
||||
if (N==-2)
|
||||
print "There is a plateau to the north here. There appears to be a way to
|
||||
scramble up to it that avoids the crevasse.";
|
||||
|
||||
if (S==-3)
|
||||
print "You can see your camp up and to the south.^";
|
||||
|
||||
];
|
||||
|
||||
!
|
||||
! Check to see if Player is on the route
|
||||
!
|
||||
! To-do: Check for an undisturbed flag along the route
|
||||
!
|
||||
[ ON_FLAGGED_ROUTE location;
|
||||
if (location == 12 or 20 or 28 or 36 or 44 or 52)
|
||||
rtrue;
|
||||
|
||||
rfalse;
|
||||
];
|
||||
|
||||
!----
|
||||
! Define verbs here...
|
||||
|
||||
Include "Grammar";
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,5 @@
|
|||
|
||||
[ Main;
|
||||
print "Hello, World!^";
|
||||
];
|
||||
|
|
@ -0,0 +1,213 @@
|
|||
! ------------------------------------------------------------------------------
|
||||
! Inform for New Writers
|
||||
!
|
||||
! The House - Version 1
|
||||
!
|
||||
! Last Modified: David Cornelson - 03-Jan-1998
|
||||
!
|
||||
! This work is freely offered to the Public Domain. - DAC 12-12-2015
|
||||
!
|
||||
! ------------------------------------------------------------------------------
|
||||
|
||||
!
|
||||
! Q: What are these lines that begin with exclamation points?
|
||||
!
|
||||
! A: In an Inform program, you may want to place comments or notes before
|
||||
! portions of code so that when you make changes, you will remember what
|
||||
! you were thinking when you originally wrote the code. It's a great way
|
||||
! to "document" your program so that others can understand it as well.
|
||||
!
|
||||
! Any characters following an exclamation point is considered a comment.
|
||||
! The comment ends when you move to a new line.
|
||||
!
|
||||
|
||||
!
|
||||
! The constant "Story" contains the name of your story, in this case,
|
||||
! "The House". The word "Constant" is an Inform statement that signifies that
|
||||
! a token (variable) will have a single, unchangable value within the program.
|
||||
! "Story" is the token name and "The House" is the value. Anytime you reference
|
||||
! "Story" in your program, it will have the value "The House".
|
||||
!
|
||||
! The double-quote is used to represent a "string". A string is a type of data that
|
||||
! contains letters and words. (As opposed to numbers). A string must begin with
|
||||
! a double-quote and end with a double-quote.
|
||||
!
|
||||
! The semi-colon tells Inform that this statement is complete. You need a
|
||||
! semi-colon to end all Inform statements.
|
||||
!
|
||||
Constant Story "The House";
|
||||
|
||||
!
|
||||
! The constant "Headline" contains the initial banner at the beginning of your
|
||||
! game. In this Headline, there are three separate lines.
|
||||
!
|
||||
! The first line is "Inform for New Writers"
|
||||
! The second line is "The House - Version 1"
|
||||
! The third line is "By New Writer (1998) - Last Compiled: 03-Jan-1998"
|
||||
!
|
||||
! The carat "^" character is used to tell Inform that you want to move to a new
|
||||
! line. This is called the newline character. Each time the newline character is
|
||||
! placed into a string, the game will move to a new line.
|
||||
!
|
||||
! Here is another example:
|
||||
!
|
||||
! print "Once upon a time^there was a little bear^^that was all alone.^";
|
||||
!
|
||||
! This example will be printed on your screen as...
|
||||
!
|
||||
! Once upon a time
|
||||
! there was a little bear
|
||||
!
|
||||
! that was all alone.
|
||||
!
|
||||
! Each newline character caused a break in the text and started at the beginning
|
||||
! of a new line.
|
||||
!
|
||||
Constant Headline
|
||||
"^Inform for New Writers^
|
||||
The House - Version 1^
|
||||
By New Writer (1998) - Last Compiled: 03-Jan-1998^";
|
||||
|
||||
!
|
||||
! This constant tells Inform what the maximum score of your game will be.
|
||||
! Currently, we have it set to 100.
|
||||
!
|
||||
Constant MAX_SCORE 100;
|
||||
|
||||
!
|
||||
! This constant is the last compile date and can be set by the Inform compiler.
|
||||
!
|
||||
Serial "980103";
|
||||
|
||||
!
|
||||
! This constant is set by you and tells which release of your game you are
|
||||
! working on. It's a good idea to make backups of your program on a regular
|
||||
! basis. When you have completed your game, start incrementing the Release value
|
||||
! every time you fix bugs or make changes so that players know which release
|
||||
! works and which one doesn't.
|
||||
!
|
||||
Release 1;
|
||||
|
||||
!
|
||||
! The Include statement allows Inform to open other files that are important to
|
||||
! your program. The following files, "Parser" and "VerbLib" are the foundation
|
||||
! of the Inform parser. DON'T REMOVE THESE LINES!!!
|
||||
!
|
||||
Include "Parser";
|
||||
Include "VerbLib";
|
||||
|
||||
!-------------------------------------------------------------------------------
|
||||
! Initialise
|
||||
!
|
||||
! The following "function" is the first portion of code executed by Inform when
|
||||
! your game is played. You want to place a statement in this function that will
|
||||
! set the first location of the player. We will add more to this section in later
|
||||
! versions of "The House".
|
||||
!-------------------------------------------------------------------------------
|
||||
|
||||
! FUNCTIONS: Portions of your code will will be in what are called "functions".
|
||||
! The syntax of a function is as follows:
|
||||
!
|
||||
! [ function_name argument argument;
|
||||
! ...your code...
|
||||
! ...your code...
|
||||
! ...your code...
|
||||
! ];
|
||||
!
|
||||
! Arguments are values passed when calling the function. More
|
||||
! information on functions is available in later versions of
|
||||
! "The House".
|
||||
!
|
||||
|
||||
[ Initialise;
|
||||
|
||||
!
|
||||
! Our first location is the Sidewalk. Inform has a variable that we can set that
|
||||
! just happens to be named "location".
|
||||
!
|
||||
! Sidewalk is a location, but in Inform it is an "Object". When we define the
|
||||
! object Sidewalk it will have a unique value associated with it. So, when we
|
||||
! set location equal to Sidewalk, the location variable now contains the object
|
||||
! value of Sidewalk.
|
||||
!
|
||||
location = Sidewalk;
|
||||
|
||||
];
|
||||
|
||||
!
|
||||
! The following function is called by Inform when the player types SCORE or when
|
||||
! the player ends the game. As you can see, each range of points has a different
|
||||
! string printed. You can modify this function to suit your own story. Remember,
|
||||
! the constant MAX_SCORE contains the value that is used by Inform to represent
|
||||
! "You have scored <score> out of <MAX_SCORE>", so you want both the Constant
|
||||
! and this function to be synchronized.
|
||||
!
|
||||
[ PrintRank;
|
||||
print ", earning you the rank of ";
|
||||
if (score >= 100) "the greatest.";
|
||||
if (score >= 80) "above average.";
|
||||
if (score >= 60) "average.";
|
||||
if (score >= 40) "below average.";
|
||||
if (score >= 20) "the barely living.";
|
||||
"the living dead.";
|
||||
];
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! Locations
|
||||
!
|
||||
! In this section we will define our locations. These are "Objects" to Inform
|
||||
! and contain the following elements.
|
||||
!
|
||||
! - object name
|
||||
! The object name represents the variable or handle of the object.
|
||||
! - short description
|
||||
! The short description is the description printed in bold before the
|
||||
! normal description.
|
||||
! - initial description
|
||||
! The initial description is printed only once when the location is first
|
||||
! entered by the player.
|
||||
! - normal description
|
||||
! The normal description is printed everytime the player enters the location.
|
||||
! - directional properties (tells which direction player can move) (optional)
|
||||
! These include n_to, ne_to, e_to, up_to, in_to, etc. and are followed by
|
||||
! another location object name.
|
||||
! - properties
|
||||
! Properties are functions that you can add to an object that help determine
|
||||
! events and actions.
|
||||
! - attributes
|
||||
! Attributes are True/False values that help you remember certain states of
|
||||
! an object or event, such as whether the lights are on or not. The positive
|
||||
! value is represented as "light" and the negative would be "~light". There
|
||||
! are standard attributes used by Inform and you can add your own as well.
|
||||
!
|
||||
! Actually, there's more than this, but we'll add the complicated stuff later!
|
||||
!
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
!
|
||||
! Define the object "Sidewalk"
|
||||
!
|
||||
! Object Name: Sidewalk
|
||||
! Short Description: "Sidewalk"
|
||||
! Initial Description: none
|
||||
! Normal Description: "You are standing on the sidewalk in front of a house."
|
||||
! Attributes: light
|
||||
!
|
||||
! The Sidewalk is the first location of our game and includes a description
|
||||
! and when we enter it, it will have light.
|
||||
!
|
||||
Object Sidewalk "Sidewalk"
|
||||
with description
|
||||
"You are standing on the sidewalk in front of a house.",
|
||||
has light;
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! Grammar
|
||||
!
|
||||
! The grammar section includes the file "Grammar" and will later include
|
||||
! extensions to the standard grammar library.
|
||||
!
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Include "Grammar";
|
||||
|
|
@ -0,0 +1,175 @@
|
|||
! ------------------------------------------------------------------------------
|
||||
! Inform for New Writers
|
||||
!
|
||||
! The House - Version 2
|
||||
!
|
||||
! Last Modified: David Cornelson - 04-Jan-1998
|
||||
!
|
||||
! This work is freely offered to the Public Domain. - DAC 12-12-2015
|
||||
!
|
||||
! ------------------------------------------------------------------------------
|
||||
|
||||
Constant Story "The House";
|
||||
|
||||
Constant Headline
|
||||
"^Inform for New Writers^
|
||||
The House - Version 2^
|
||||
By New Writer (1998) - Last Compiled: 04-Jan-1998^";
|
||||
|
||||
Constant MAX_SCORE 100;
|
||||
Serial "980104";
|
||||
|
||||
Release 1;
|
||||
|
||||
Include "Parser";
|
||||
Include "VerbLib";
|
||||
|
||||
!-------------------------------------------------------------------------------
|
||||
! Initialise
|
||||
!
|
||||
!-------------------------------------------------------------------------------
|
||||
|
||||
[ Initialise;
|
||||
|
||||
location = Sidewalk;
|
||||
|
||||
];
|
||||
|
||||
[ PrintRank;
|
||||
print ", earning you the rank of ";
|
||||
if (score >= 100) "the greatest.";
|
||||
if (score >= 80) "above average.";
|
||||
if (score >= 60) "average.";
|
||||
if (score >= 40) "below average.";
|
||||
if (score >= 20) "the barely living.";
|
||||
"the living dead.";
|
||||
];
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! Locations
|
||||
!
|
||||
! In this section we will define our locations. These are "Objects" to Inform
|
||||
! and contain the following elements.
|
||||
!
|
||||
! - object name
|
||||
! The object name represents the variable or handle of the object.
|
||||
! - short description
|
||||
! The short description is the description printed in bold before the
|
||||
! normal description.
|
||||
! - initial description
|
||||
! The initial description is printed only once when the location is first
|
||||
! entered by the player.
|
||||
! - normal description
|
||||
! The normal description is printed everytime the player enters the location.
|
||||
! - directional properties (tells which direction player can move) (optional)
|
||||
! These include n_to, ne_to, e_to, up_to, in_to, etc. and are followed by
|
||||
! another location object name.
|
||||
! - properties
|
||||
! Properties are functions that you can add to an object that help determine
|
||||
! events and actions.
|
||||
! - attributes
|
||||
! Attributes are True/False values that help you remember certain states of
|
||||
! an object or event, such as whether the lights are on or not. The positive
|
||||
! value is represented as "light" and the negative would be "~light". There
|
||||
! are standard attributes used by Inform and you can add your own as well.
|
||||
!
|
||||
! Actually, there's more than this, but we'll add the complicated stuff later!
|
||||
!
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Object Sidewalk "Sidewalk"
|
||||
with description
|
||||
"You are standing on the sidewalk in front of a house to the west.",
|
||||
w_to Front_Porch,
|
||||
has light;
|
||||
|
||||
!
|
||||
! VERSION 2 - Adding more locations to your Inform program
|
||||
!
|
||||
! We're going to take one small step in this version. Let's add a bunch of
|
||||
! locations so that the player can move around a little bit.
|
||||
!
|
||||
! Notice that in the Sidewalk Object definition we added a direction in the
|
||||
! description "to the west" and we added the directional property "w_to"
|
||||
! that leads to the "Front_Porch" location that we defined below.
|
||||
!
|
||||
! If you follow these examples you will see how locations are "connected"
|
||||
! or "mapped" together with the directional properties. Feel free to change
|
||||
! then around so that they connect in different ways.
|
||||
!
|
||||
! Q: In the "Front_Porch" definition, the description continues over two
|
||||
! lines. Is this okay?
|
||||
!
|
||||
! A: Inform allows you to extend statements over multiple lines as you
|
||||
! need. You may need to write code that extends over multiple lines
|
||||
! but mostly it will be descriptions as in "Front_Porch". You don't
|
||||
! need to add any extra characters to tell Inform that you've jumped
|
||||
! to the next line either...Inform will figure that out when it compiles.
|
||||
!
|
||||
|
||||
Object Front_Porch "Front Porch"
|
||||
with description
|
||||
"This is the front porch of the house. There is an open door
|
||||
leading inside to the west.",
|
||||
e_to Sidewalk,
|
||||
w_to Foyer,
|
||||
in_to Foyer,
|
||||
has light;
|
||||
|
||||
Object Foyer "Foyer"
|
||||
with description
|
||||
"You are standing in the foyer of the house. It seems as though
|
||||
you can go up a staircase, northwest, or back out the front
|
||||
door to the east.",
|
||||
out_to Front_Porch,
|
||||
e_to Front_Porch,
|
||||
nw_to Hallway,
|
||||
u_to Upper_Hallway,
|
||||
has light;
|
||||
|
||||
Object Hallway "Hallway"
|
||||
with description
|
||||
"You are in the hallway on the first floor of the house. The
|
||||
foyer is southeast and the kitchen is west of here.",
|
||||
se_to Foyer,
|
||||
w_to Kitchen,
|
||||
has light;
|
||||
|
||||
Object Kitchen "Kitchen"
|
||||
with description
|
||||
"This is the kitchen of the house. A hallway can be seen to the
|
||||
east.",
|
||||
e_to Hallway,
|
||||
has light;
|
||||
|
||||
Object Upper_Hallway "Upper Hallway"
|
||||
with description
|
||||
"This is the second floor hallway. Rooms can be seen north and
|
||||
south and a staircase leads down.",
|
||||
n_to North_Bedroom,
|
||||
s_to South_Bedroom,
|
||||
d_to Foyer,
|
||||
has light;
|
||||
|
||||
Object North_Bedroom "North Bedroom"
|
||||
with description
|
||||
"This is a bedroom on the north side of the house.",
|
||||
s_to Upper_Hallway,
|
||||
has light;
|
||||
|
||||
Object South_Bedroom "South Bedroom"
|
||||
with description
|
||||
"This is a bedroom on the south side of the house.",
|
||||
n_to Upper_Hallway,
|
||||
has light;
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! Grammar
|
||||
!
|
||||
! The grammar section includes the file "Grammar" and will later include
|
||||
! extensions to the standard grammar library.
|
||||
!
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Include "Grammar";
|
||||
|
|
@ -0,0 +1,284 @@
|
|||
! ------------------------------------------------------------------------------
|
||||
! Inform for New Writers
|
||||
!
|
||||
! The House - Version 3
|
||||
!
|
||||
! Last Modified: David Cornelson - 22-Jan-1998
|
||||
!
|
||||
! This work is freely offered to the Public Domain. - DAC 12-12-2015
|
||||
!
|
||||
! ------------------------------------------------------------------------------
|
||||
|
||||
Constant DEBUG;
|
||||
|
||||
Constant Story "The House";
|
||||
|
||||
Constant Headline
|
||||
"^Inform for New Writers^
|
||||
The House - Version 3^
|
||||
By New Writer (1998) - Last Compiled: 22-Jan-1998^";
|
||||
|
||||
Constant MAX_SCORE 100;
|
||||
Serial "980122";
|
||||
|
||||
Release 2;
|
||||
|
||||
Include "Parser";
|
||||
Include "VerbLib";
|
||||
|
||||
!-------------------------------------------------------------------------------
|
||||
! Initialise
|
||||
!
|
||||
!-------------------------------------------------------------------------------
|
||||
|
||||
[ Initialise;
|
||||
|
||||
location = Sidewalk;
|
||||
|
||||
];
|
||||
|
||||
[ PrintRank;
|
||||
print ", earning you the rank of ";
|
||||
if (score >= 100) "the greatest.";
|
||||
if (score >= 80) "above average.";
|
||||
if (score >= 60) "average.";
|
||||
if (score >= 40) "below average.";
|
||||
if (score >= 20) "the barely living.";
|
||||
"the living dead.";
|
||||
];
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! Locations
|
||||
!
|
||||
! In this section we will define our locations. These are "Objects" to Inform.
|
||||
!
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Object Sidewalk "Sidewalk"
|
||||
with description
|
||||
"You are standing on the sidewalk in front of a house to the west.",
|
||||
w_to Front_Porch,
|
||||
has light;
|
||||
|
||||
!
|
||||
! Notice we changed the w_to and in_to properties to reflect our new door.
|
||||
! We changed the description to reflect our new doors as well...
|
||||
!
|
||||
|
||||
Object Front_Porch "Front Porch"
|
||||
with description
|
||||
"This is the front porch of the house. There are two doors
|
||||
leading inside. The door on the left leads west and the
|
||||
door on the right leads northwest.",
|
||||
e_to Sidewalk,
|
||||
w_to Left_Front_Door,
|
||||
in_to Left_Front_Door,
|
||||
nw_to Right_Front_Door,
|
||||
has light;
|
||||
|
||||
!
|
||||
! VERSION 3 - Adding a door
|
||||
!
|
||||
! Inform allows you to create special objects that represent doors. Doors
|
||||
! are simply objects with special "properties" and "attributes".
|
||||
!
|
||||
! A "property" is a function that can be listed in the "Object" statement.
|
||||
! For instance, "e_to" and "w_to" are properties.
|
||||
!
|
||||
! Properties that are used for doors are:
|
||||
!
|
||||
! - door_to Tells Inform where the door leads if 'entered'.
|
||||
!
|
||||
! - door_dir Tells Inform which direction the door faces.
|
||||
!
|
||||
! - when_open The description of the door when open.
|
||||
!
|
||||
! - when_closed The description of the door when closed.
|
||||
!
|
||||
! - found_in A list of locations where the door resides.
|
||||
!
|
||||
! - with_key Specify which object is needed to lock and unlock door.
|
||||
!
|
||||
! Attributes that are used for doors:
|
||||
!
|
||||
! - static OR Tells Inform that the door cannot be carried.
|
||||
! - scenery Tells Inform that the door cannot be carried
|
||||
! and also is not mentioned in normal location
|
||||
! descriptions.
|
||||
!
|
||||
! - door Mandatory...tells Inform this object is a door.
|
||||
!
|
||||
! - open Current state of door. To make the door start
|
||||
! 'closed', then give the object the attribute
|
||||
! ~open.
|
||||
!
|
||||
! - lockable Can be locked.
|
||||
!
|
||||
! - locked Starts out locked. Give it ~locked to start
|
||||
! it as unlocked.
|
||||
!
|
||||
! NOTE: A few of the properties and attributes above can be used with other
|
||||
! objects. The only ones specific to a door object are the 'door_to'
|
||||
! and 'door_dir' properties and the 'door' attribute.
|
||||
|
||||
!
|
||||
! NOTE ABOUT THE TILDE CHARACTER:
|
||||
! In evaluations of variables, the tilde character, ~, signifies
|
||||
! 'not' or 'false value of'.
|
||||
! When you see ~=, this means "not equal to".
|
||||
! When you see ~attribute, this means "the false value of attribute".
|
||||
!
|
||||
! The tilde character, ~, has another use. Inside a string, if you
|
||||
! want to print a double-quote, you would use the tilde. For example:
|
||||
!
|
||||
! print "John said, ~Run spot run!~";
|
||||
!
|
||||
! ...would print...
|
||||
!
|
||||
! John said, "Run spot run!"
|
||||
!
|
||||
|
||||
!
|
||||
! We have two front doors built into our house, one leading to the
|
||||
! foyer, and the other leading to the den.
|
||||
!
|
||||
! The left door is a one way door that has no lock. You can enter
|
||||
! the door to the west.
|
||||
!
|
||||
! The right door is a two-way door that is lockable. The key is
|
||||
! located in the north bedroom. You enter the door to the northwest.
|
||||
!
|
||||
! Q: What is the '->' used for?
|
||||
!
|
||||
! A: This symbol tells Inform that this object is located 'within' the most recent
|
||||
! location definition.
|
||||
!
|
||||
! If two arrows are used, then the object is within the most recent -> object.
|
||||
!
|
||||
! The 'Left_Front_Door' is a 'child' of the 'Front_Porch' and the
|
||||
! 'Front_Porch' is the 'parent' of 'Left_Front_Door'.
|
||||
|
||||
Object -> Left_Front_Door "left front door"
|
||||
with name "left" "front" "door",
|
||||
description
|
||||
"The left front door is made of brass.",
|
||||
when_open "The left front door is open.",
|
||||
when_closed "The left front door is closed.",
|
||||
door_to Foyer,
|
||||
door_dir w_to,
|
||||
has static door openable;
|
||||
|
||||
!
|
||||
! The two-way door has 'functions' for the door_to and door_dir properties
|
||||
! because you can start on the front porch or the den. The same is true for
|
||||
! the directions, you can either be going through the door northwest or
|
||||
! southeast.
|
||||
!
|
||||
! These are 'embedded functions'. They don't need a name or arguments so
|
||||
! you place a semi-colon immediately after the first bracket. The end of
|
||||
! the function is signified by the closing bracket. You separate embedded
|
||||
! functions the same way you separate other properties, with a comma.
|
||||
!
|
||||
! The 'if' statement within both of the embedded functions is used to
|
||||
! determine which location you are starting in for the two-way door.
|
||||
!
|
||||
! The determination is calculated by comparing the 'location' variable
|
||||
! (which Inform ALWAYS sets to the players current location) and the
|
||||
! Front_Porch. If this is true, the first statement (until the semi-colon)
|
||||
! is executed. If it's false (the player is NOT in the Front_Porch) then
|
||||
! the second statement is executed.
|
||||
!
|
||||
! Notice the 'found_in' property lists both the Front_Porch and Den. This
|
||||
! is so you can 'see' the doors in both of these locations.
|
||||
!
|
||||
|
||||
Object Right_Front_Door "right front door"
|
||||
with name "right" "front" "door",
|
||||
description
|
||||
"The right front door is made of wood.",
|
||||
when_open "The right front door is open.",
|
||||
when_closed "The right front door is closed.",
|
||||
door_to [; if (location==Front_Porch) return Den; return Front_Porch; ],
|
||||
door_dir [; if (location==Front_Porch) return nw_to; return se_to; ],
|
||||
found_in Front_Porch Den,
|
||||
with_key right_key,
|
||||
has static door openable lockable locked;
|
||||
|
||||
Object Den "Den"
|
||||
with description
|
||||
"You are in the den of the house.",
|
||||
se_to Right_Front_Door,
|
||||
out_to Right_Front_Door,
|
||||
has light;
|
||||
|
||||
Object Foyer "Foyer"
|
||||
with description
|
||||
"You are standing in the foyer of the house. It seems as though
|
||||
you can go up a staircase, northwest, or back out the front
|
||||
door to the east.",
|
||||
out_to Front_Porch,
|
||||
e_to Front_Porch,
|
||||
nw_to Hallway,
|
||||
u_to Upper_Hallway,
|
||||
has light;
|
||||
|
||||
Object Hallway "Hallway"
|
||||
with description
|
||||
"You are in the hallway on the first floor of the house. The
|
||||
foyer is southeast and the kitchen is west of here.",
|
||||
se_to Foyer,
|
||||
w_to Kitchen,
|
||||
has light;
|
||||
|
||||
Object Kitchen "Kitchen"
|
||||
with description
|
||||
"This is the kitchen of the house. A hallway can be seen to the
|
||||
east.",
|
||||
e_to Hallway,
|
||||
has light;
|
||||
|
||||
Object Upper_Hallway "Upper Hallway"
|
||||
with description
|
||||
"This is the second floor hallway. Rooms can be seen north and
|
||||
south and a staircase leads down.",
|
||||
n_to North_Bedroom,
|
||||
s_to South_Bedroom,
|
||||
d_to Foyer,
|
||||
has light;
|
||||
|
||||
Object North_Bedroom "North Bedroom"
|
||||
with description
|
||||
"This is a bedroom on the north side of the house.",
|
||||
s_to Upper_Hallway,
|
||||
has light;
|
||||
|
||||
!
|
||||
! This is the 'key' for the right front door. There are no directions
|
||||
! or attributes since it's a just a simple object.
|
||||
!
|
||||
! I placed the key here to keep these examples building a workable game.
|
||||
! You can move the key anywhere you like though by cutting this line and
|
||||
! pasting it 'below' any other location object.
|
||||
!
|
||||
! Remember, this is the object listed in 'with_key' in the right_door
|
||||
! object, so it's the only way to unlock that door.
|
||||
!
|
||||
|
||||
Object -> right_key "right key" with name "right" "key";
|
||||
|
||||
Object South_Bedroom "South Bedroom"
|
||||
with description
|
||||
"This is a bedroom on the south side of the house.",
|
||||
n_to Upper_Hallway,
|
||||
has light;
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! Grammar
|
||||
!
|
||||
! The grammar section includes the file "Grammar" and will later include
|
||||
! extensions to the standard grammar library.
|
||||
!
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Include "Grammar";
|
||||
|
|
@ -0,0 +1,422 @@
|
|||
! ------------------------------------------------------------------------------
|
||||
! Inform for New Writers
|
||||
!
|
||||
! The House - Version 4
|
||||
!
|
||||
! Last Modified: David Cornelson - 22-Jan-1998
|
||||
!
|
||||
! This work is freely offered to the Public Domain. - DAC 12-12-2015
|
||||
!
|
||||
! ------------------------------------------------------------------------------
|
||||
|
||||
Constant DEBUG;
|
||||
|
||||
Constant Story "The House";
|
||||
|
||||
Constant Headline
|
||||
"^Inform for New Writers^
|
||||
The House - Version 4^
|
||||
By New Writer (1998) - Last Compiled: 22-Jan-1998^";
|
||||
|
||||
Constant MAX_SCORE 100;
|
||||
Serial "980122";
|
||||
|
||||
Release 2;
|
||||
|
||||
Include "Parser";
|
||||
Include "VerbLib";
|
||||
|
||||
!-------------------------------------------------------------------------------
|
||||
! Initialise
|
||||
!
|
||||
!-------------------------------------------------------------------------------
|
||||
|
||||
[ Initialise;
|
||||
|
||||
location = Sidewalk;
|
||||
|
||||
];
|
||||
|
||||
[ PrintRank;
|
||||
print ", earning you the rank of ";
|
||||
if (score >= 100) "the greatest.";
|
||||
if (score >= 80) "above average.";
|
||||
if (score >= 60) "average.";
|
||||
if (score >= 40) "below average.";
|
||||
if (score >= 20) "the barely living.";
|
||||
"the living dead.";
|
||||
];
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! Locations
|
||||
!
|
||||
! In this section we will define our locations. These are "Objects" to Inform.
|
||||
!
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Object Sidewalk "Sidewalk"
|
||||
with description
|
||||
"You are standing on the sidewalk in front of a house to the west.",
|
||||
w_to Front_Porch,
|
||||
has light;
|
||||
|
||||
Object Front_Porch "Front Porch"
|
||||
with description
|
||||
"This is the front porch of the house. There are two doors
|
||||
leading inside. The door on the left leads west and the
|
||||
door on the right leads northwest.",
|
||||
e_to Sidewalk,
|
||||
w_to Left_Front_Door,
|
||||
in_to Left_Front_Door,
|
||||
nw_to Right_Front_Door,
|
||||
has light;
|
||||
|
||||
Object -> Left_Front_Door "left front door"
|
||||
with name "left" "front" "door",
|
||||
description
|
||||
"The left front door is made of brass.",
|
||||
when_open "The left front door is open.",
|
||||
when_closed "The left front door is closed.",
|
||||
door_to Foyer,
|
||||
door_dir w_to,
|
||||
has static door openable;
|
||||
|
||||
Object Right_Front_Door "right front door"
|
||||
with name "right" "front" "door",
|
||||
description
|
||||
"The right front door is made of wood.",
|
||||
when_open "The right front door is open.",
|
||||
when_closed "The right front door is closed.",
|
||||
door_to [; if (location==Front_Porch) return Den; return Front_Porch; ],
|
||||
door_dir [; if (location==Front_Porch) return nw_to; return se_to; ],
|
||||
found_in Front_Porch Den,
|
||||
with_key right_key,
|
||||
has static door openable lockable locked;
|
||||
|
||||
!
|
||||
! VERSION 4 - Cause and Effect. Things happen based on what a player does.
|
||||
!
|
||||
! In this version of The House, we're going to add an object, the rock, and
|
||||
! a place where the rock is useful. Unlike version 3 where Inform provides
|
||||
! a special 'door' object, we must provide our own logic to 'handle' the rock.
|
||||
!
|
||||
! To do this, we're going to use what are called 'code blocks'. A code block is a
|
||||
! group of statements that combine to handle one particular piece of logic
|
||||
!
|
||||
! Code blocks contain a decision and/or a loop. A decision is handled by one of two
|
||||
! Inform statements, the 'if' statement and the 'switch' statement. We'll talk about
|
||||
! the 'switch' statement and 'loops' in later versions of The House.
|
||||
!
|
||||
! DECISION STATEMENTS
|
||||
!
|
||||
! THE 'if' STATEMENT
|
||||
!
|
||||
! The 'if' statement contains a comparison of variables, numbers, and/or text that
|
||||
! provides a true or false result. Based on either result (true or false) another
|
||||
! code block is written to handle the decision.
|
||||
!
|
||||
! For example:
|
||||
!
|
||||
! if (1==1) {
|
||||
! print "True";
|
||||
! } else {
|
||||
! print "False";
|
||||
! }
|
||||
!
|
||||
! In the above example, the word "True" will be printed because the comparison of
|
||||
! 1 to 1 is a true statement, 1 certainly does equal 1. If we changed the comparison
|
||||
! to:
|
||||
!
|
||||
! if (1==2) {
|
||||
! print "True";
|
||||
! } else {
|
||||
! print "False";
|
||||
! }
|
||||
!
|
||||
! ...then "False" would be printed because 1 does not equal 2.
|
||||
!
|
||||
! Here are some more examples of valid 'if' statements...
|
||||
!
|
||||
! eggs=2;
|
||||
! if (eggs<2) {
|
||||
! print "You don't have enough eggs!";
|
||||
! } else {
|
||||
! print "You have enough eggs!";
|
||||
! }
|
||||
!
|
||||
! The above 'if' statement asks if the variable 'eggs' is less than two. If the value
|
||||
! is less than two, print "You don't have enough eggs!", otherwise Inform will print
|
||||
! "You have two eggs, just enough!" (which is the case since we set the variable 'eggs'
|
||||
! to 2 before the 'if' statement).
|
||||
!
|
||||
! eggs=2;
|
||||
! bacon=4;
|
||||
! if (eggs<2) {
|
||||
! print "You don't have enough eggs!";
|
||||
! if (bacon<4) {
|
||||
! print "You don't have enough bacon either!";
|
||||
! } else {
|
||||
! print "You have four strips of bacon though!";
|
||||
! }
|
||||
! } else {
|
||||
! print "You enough eggs!";
|
||||
! if (bacon<4) {
|
||||
! print "You don't have enough bacon though!";
|
||||
! } else {
|
||||
! print "You have four strips of bacon too!";
|
||||
! }
|
||||
! }
|
||||
!
|
||||
! In the above example, things get more complicated. I'll rewrite it in english so
|
||||
! that you can understand what is happening. Many programmers start out writing
|
||||
! things in english and they call it 'pseudocode'.
|
||||
!
|
||||
! set eggs to 2
|
||||
! set bacon to 4
|
||||
!
|
||||
! if there are less than two eggs then
|
||||
! print "You don't have enough eggs!"
|
||||
! if there are less than four bacon then
|
||||
! print "You don't have enough bacon either!"
|
||||
! else
|
||||
! print "You have four strips of bacon though!"
|
||||
! end if
|
||||
! else
|
||||
! print "You enough eggs!"
|
||||
! if there are less than four bacon then
|
||||
! print "You don't have enough bacon though!"
|
||||
! else
|
||||
! print "You have four strips of bacon too!"
|
||||
! end if
|
||||
! end if
|
||||
!
|
||||
! Questions: Q: Why is there a double equal sign in the 'if' statement?
|
||||
!
|
||||
! A: Inform will set variables with one equals sign "=" and compare them
|
||||
! when you put two equals signs "==" together. This is important to
|
||||
! remember and can cause a lot of 'bugs' in your code. Another exanple
|
||||
! explaining this is:
|
||||
!
|
||||
! if (eggs=2) print "There are two eggs.";
|
||||
!
|
||||
! This statement will ALWAYS BE TRUE because eggs is being SET to 2, NOT
|
||||
! compared.
|
||||
!
|
||||
! Q: What are the squiggly brackets, '{' and '}', for?
|
||||
!
|
||||
! A: They signify the beginning and end of an 'if' statement code block.
|
||||
! You need them to group more than one statement together. The left
|
||||
! squiggly bracket begin the code block and the right squiggly bracket
|
||||
! ends the code block.
|
||||
!
|
||||
! NOTE: You only need the brackets if you have more than one statement
|
||||
! in the resulting code block. Another example might be:
|
||||
!
|
||||
! if (eggs==2) {
|
||||
! print "There are a pair of eggs.";
|
||||
! bacon=4;
|
||||
! }
|
||||
! else
|
||||
! print "There are ", eggs, " eggs.";
|
||||
!
|
||||
! In the above example, squiggly brackets were only needed for
|
||||
! the 'true' code block because we have two statements where
|
||||
! there is only one statement for the 'false' code block.
|
||||
!
|
||||
! Q: What are the symbols for 'if' statement comparisons?
|
||||
!
|
||||
! A: They are as follows: ~= not equal
|
||||
! == equal
|
||||
! < less than
|
||||
! <= less than or equal
|
||||
! > greater than
|
||||
! >= greater than or equal
|
||||
! && and
|
||||
! || or
|
||||
!
|
||||
! The '&&' and '||' symbols are used to combine comparisons. For example:
|
||||
!
|
||||
! if (eggs==2 && bacon==4) print "You have two eggs and four bacon!";
|
||||
!
|
||||
! if (eggs==2 || bacon==4) print "You have either 2 eggs or 4 bacon!";
|
||||
!
|
||||
|
||||
!
|
||||
! Okay, now let's apply our knowledge of the 'if' statement and write an embedded function
|
||||
! that will handle our rock.
|
||||
!
|
||||
! We've placed the rock in the den, but we're going to put the action in the backyard
|
||||
! which is a location we're adding in this version of The House. Skip down by the kitchen for
|
||||
! more...
|
||||
!
|
||||
|
||||
|
||||
Object Den "Den"
|
||||
with description
|
||||
"You are in the den of the house.",
|
||||
se_to Right_Front_Door,
|
||||
out_to Right_Front_Door,
|
||||
has light;
|
||||
|
||||
!
|
||||
! This is our rock object.
|
||||
!
|
||||
! We've added the property 'before' with the arguments 'PutOn','Insert', and
|
||||
! 'ThrowAt:'. When the rock is thrown at or in anything, this function is executed.
|
||||
!
|
||||
! In this case, the object being thrown, rock or keys, is the value of the Inform
|
||||
! variable 'noun'. If noun equals the object 'Rock', then the true code block is
|
||||
! executed, otherwise the false code block is executed.
|
||||
!
|
||||
! Q: Why is the statement 'rtrue' placed at the end of both code blocks?
|
||||
!
|
||||
! A: Normally, the Inform parser handles the action of an object being thrown at
|
||||
! something else. This is the default processing. If you throw the 'right key'
|
||||
! around The House or at the pond, you'll see the 'default' Inform processing.
|
||||
!
|
||||
! Since we wanted special processing for the rock, we handled the actions on
|
||||
! our own through our code. But at the end of handling the thrown rock, we have
|
||||
! to let the Inform parser know that we took care of everything and not to do
|
||||
! anything.
|
||||
!
|
||||
! If we return true, Inform understands and leaves everything alone.
|
||||
! If we return false, Inform will execute the default processing.
|
||||
!
|
||||
! By the way, rtrue and rfalse are shortcuts to the statements:
|
||||
!
|
||||
! return true;
|
||||
! return false;
|
||||
!
|
||||
!
|
||||
! Q: Why is the variable 'second' being compared to the object name 'Pond'?
|
||||
!
|
||||
! A: The variable 'second' is an Inform variable set to the second noun of
|
||||
! of a players statement. For example:
|
||||
!
|
||||
! > THROW ROCK AT POND
|
||||
!
|
||||
! In this statement, 'rock' is the first noun and Inform determines the object
|
||||
! value for 'rock' and sets the variable 'noun' to that value. For the noun
|
||||
! 'pond', Inform determines the object value and sets this in the variable
|
||||
! 'second'.
|
||||
!
|
||||
! Q: Why is '(the)' before 'second' in the print statement below?
|
||||
!
|
||||
! A: This is to force Inform to print the article 'the' before the word. In any
|
||||
! object, you can define the article property with a value, such as "the",
|
||||
! "your", "an", or "some", so that Inform understands how to refer to the
|
||||
! object in sentences.
|
||||
!
|
||||
|
||||
Object -> Rock "rock"
|
||||
with name "rock",
|
||||
description
|
||||
"It's smooth and flat, perfect for skipping in a pond.",
|
||||
before [; Insert,PutOn,ThrowAt:
|
||||
if (second==Pond) {
|
||||
print "The rock skips across the water several times and sinks.
|
||||
Amazingly, after a few moments, the rock washes up at
|
||||
your feet. Wow, what an undertow!^";
|
||||
move Rock to Backyard;
|
||||
rtrue;
|
||||
!
|
||||
! Replace rock so that player can try it again....
|
||||
!
|
||||
} else {
|
||||
print "You throw the rock at ",(the) second, " and bounces
|
||||
back into your stomach. Ouch! That hurt.^";
|
||||
rtrue;
|
||||
}
|
||||
];
|
||||
|
||||
Object Foyer "Foyer"
|
||||
with description
|
||||
"You are standing in the foyer of the house. It seems as though
|
||||
you can go up a staircase, northwest, or back out the front
|
||||
door to the east.",
|
||||
out_to Front_Porch,
|
||||
e_to Front_Porch,
|
||||
nw_to Hallway,
|
||||
u_to Upper_Hallway,
|
||||
has light;
|
||||
|
||||
Object Hallway "Hallway"
|
||||
with description
|
||||
"You are in the hallway on the first floor of the house. The
|
||||
foyer is southeast and the kitchen is west of here.",
|
||||
se_to Foyer,
|
||||
w_to Kitchen,
|
||||
has light;
|
||||
|
||||
!
|
||||
! We've added out_to and w_to for a connection to the backyard as well as
|
||||
! changing the description to help the player know what's going on.
|
||||
!
|
||||
|
||||
Object Kitchen "Kitchen"
|
||||
with description
|
||||
"This is the kitchen of the house. A hallway can be seen to the
|
||||
east and an open doorway to the west leads out to the backyard.",
|
||||
e_to Hallway,
|
||||
w_to Backyard,
|
||||
out_to Backyard,
|
||||
has light;
|
||||
|
||||
!
|
||||
! This is our new location. Notice we added the name "yard" in case the player
|
||||
! abbreviates their commands.
|
||||
!
|
||||
Object Backyard "Backyard"
|
||||
with name "yard",
|
||||
description
|
||||
"This is the backyard behind the house. There is a pond here.",
|
||||
e_to Kitchen,
|
||||
in_to Kitchen,
|
||||
has light;
|
||||
|
||||
!
|
||||
! This is where we plan to use the rock....
|
||||
!
|
||||
|
||||
Object -> Pond "pond"
|
||||
with name "pond" "water",
|
||||
description
|
||||
"It's a small pond, but wide enough to skip rocks.",
|
||||
has static concealed container open;
|
||||
|
||||
Object Upper_Hallway "Upper Hallway"
|
||||
with description
|
||||
"This is the second floor hallway. Rooms can be seen north and
|
||||
south and a staircase leads down.",
|
||||
n_to North_Bedroom,
|
||||
s_to South_Bedroom,
|
||||
d_to Foyer,
|
||||
has light;
|
||||
|
||||
Object North_Bedroom "North Bedroom"
|
||||
with description
|
||||
"This is a bedroom on the north side of the house.",
|
||||
s_to Upper_Hallway,
|
||||
has light;
|
||||
|
||||
!
|
||||
! Added the article "the"...
|
||||
!
|
||||
Object -> right_key "right key" with name "right" "key", article "the";
|
||||
|
||||
Object South_Bedroom "South Bedroom"
|
||||
with description
|
||||
"This is a bedroom on the south side of the house.",
|
||||
n_to Upper_Hallway,
|
||||
has light;
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! Grammar
|
||||
!
|
||||
! The grammar section includes the file "Grammar" and will later include
|
||||
! extensions to the standard grammar library.
|
||||
!
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Include "Grammar";
|
||||
|
|
@ -0,0 +1,333 @@
|
|||
! ------------------------------------------------------------------------------
|
||||
! Inform for New Writers
|
||||
!
|
||||
! The House - Version 5
|
||||
!
|
||||
! Last Modified: David Cornelson - 22-Jan-1998
|
||||
!
|
||||
! This work is freely offered to the Public Domain. - DAC 12-12-2015
|
||||
!
|
||||
! ------------------------------------------------------------------------------
|
||||
|
||||
Constant Story "The House";
|
||||
|
||||
Constant Headline
|
||||
"^Inform for New Writers^
|
||||
The House - Version 5^
|
||||
By New Writer (1998) - Last Compiled: 22-Jan-1998^";
|
||||
|
||||
Constant MAX_SCORE 100;
|
||||
Serial "980122";
|
||||
|
||||
Release 2;
|
||||
|
||||
Include "Parser";
|
||||
Include "VerbLib";
|
||||
|
||||
!-------------------------------------------------------------------------------
|
||||
! Initialise
|
||||
!
|
||||
!-------------------------------------------------------------------------------
|
||||
|
||||
[ Initialise;
|
||||
|
||||
location = Sidewalk;
|
||||
|
||||
];
|
||||
|
||||
[ PrintRank;
|
||||
print ", earning you the rank of ";
|
||||
if (score >= 100) "the greatest.";
|
||||
if (score >= 80) "above average.";
|
||||
if (score >= 60) "average.";
|
||||
if (score >= 40) "below average.";
|
||||
if (score >= 20) "the barely living.";
|
||||
"the living dead.";
|
||||
];
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! Locations
|
||||
!
|
||||
! In this section we will define our locations. These are "Objects" to Inform.
|
||||
!
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
!
|
||||
! VERSION 5 - Adding a container to your game, functions, verbs, and death.
|
||||
!
|
||||
! In many cases you will want an object to be able to contain other objects.
|
||||
! This may be as simple as creating a 'backpack' that will contain your school
|
||||
! papers, apple, and pencil sharpener. In a more complex definition, a container
|
||||
! could be a chasm, a bottomless pit, refrigerator, or a television.
|
||||
!
|
||||
! We're going to create a simple container and a complex container.
|
||||
!
|
||||
! The simple container is probably very familiar to you. It's a mailbox amd it's
|
||||
! right here in front of the house. It contains a letter that can be read as well.
|
||||
!
|
||||
|
||||
Object Sidewalk "Sidewalk"
|
||||
with description
|
||||
"You are standing on the sidewalk in front of a house to the west.",
|
||||
w_to Front_Porch,
|
||||
has light;
|
||||
|
||||
!
|
||||
! Add the mailbox with open and closed descriptions.
|
||||
!
|
||||
Object -> Mailbox "mailbox"
|
||||
with name "mailbox" "box",
|
||||
when_open "There is an open mailbox here.",
|
||||
when_closed "There is a closed mailbox here.",
|
||||
has static container openable;
|
||||
|
||||
!
|
||||
! Add 'legible' attribute to distinguish something that can be 'read'.
|
||||
! This is determined in the verb extension located in the grammar
|
||||
! section at the end of this file.
|
||||
!
|
||||
Attribute legible;
|
||||
|
||||
!
|
||||
! And here is the letter, which can be consulted, read, or torn up. If it's
|
||||
! torn up, the letter is removed from the game, never to be seen again.
|
||||
!
|
||||
Object -> -> Letter "letter"
|
||||
with name "letter" "paper",
|
||||
description
|
||||
"The letter is a simple page of notebook paper.",
|
||||
before [; Consult,Read: "The letter contains a vague story about an evil couch,
|
||||
but you can't make out anymore detail. Interesting
|
||||
little tidbit though.";
|
||||
Tear: remove Letter;
|
||||
"You rip the letter into tiny pieces that blow away in the wind.";
|
||||
]
|
||||
has legible;
|
||||
|
||||
Object Front_Porch "Front Porch"
|
||||
with description
|
||||
"This is the front porch of the house. There are two doors
|
||||
leading inside. The door on the left leads west and the
|
||||
door on the right leads northwest.",
|
||||
e_to Sidewalk,
|
||||
w_to Left_Front_Door,
|
||||
in_to Left_Front_Door,
|
||||
nw_to Right_Front_Door,
|
||||
has light;
|
||||
|
||||
Object -> Left_Front_Door "left front door"
|
||||
with name "left" "front" "door",
|
||||
description
|
||||
"The left front door is made of brass.",
|
||||
when_open "The left front door is open.",
|
||||
when_closed "The left front door is closed.",
|
||||
door_to Foyer,
|
||||
door_dir w_to,
|
||||
has static door openable;
|
||||
|
||||
Object Right_Front_Door "right front door"
|
||||
with name "right" "front" "door",
|
||||
description
|
||||
"The right front door is made of wood.",
|
||||
when_open "The right front door is open.",
|
||||
when_closed "The right front door is closed.",
|
||||
door_to [; if (location==Front_Porch) return Den; return Front_Porch; ],
|
||||
door_dir [; if (location==Front_Porch) return nw_to; return se_to; ],
|
||||
found_in Front_Porch Den,
|
||||
with_key right_key,
|
||||
has static door openable lockable locked;
|
||||
|
||||
Object Den "Den"
|
||||
with description
|
||||
"You are in the den of the house. The living room is west of hear
|
||||
and the front porch is to the southeast.",
|
||||
se_to Right_Front_Door,
|
||||
out_to Right_Front_Door,
|
||||
w_to Living_Room,
|
||||
has light;
|
||||
|
||||
Object -> Rock "rock"
|
||||
with name "rock",
|
||||
description
|
||||
"It's smooth and flat, perfect for skipping in a pond.",
|
||||
before [; Insert,PutOn,ThrowAt:
|
||||
if (second==Evil_Couch) rfalse; ! Allow the rock to be eaten by couch
|
||||
if (second==Pond) {
|
||||
print "The rock skips across the water several times and sinks.
|
||||
Amazingly, after a few moments, the rock washes up at
|
||||
your feet. Wow, what an undertow!^";
|
||||
move Rock to Backyard;
|
||||
rtrue;
|
||||
!
|
||||
! Replace rock so that player can try it again....
|
||||
!
|
||||
} else {
|
||||
print "You can't throw the rock at ",(the) second, ".^";
|
||||
rtrue;
|
||||
}
|
||||
];
|
||||
|
||||
Object Living_Room "Living Room"
|
||||
with name "living" "room",
|
||||
description
|
||||
"This is the living room of the house. The den is to the east.",
|
||||
e_to Den,
|
||||
has light;
|
||||
|
||||
!
|
||||
! And here is our evil couch. Anything put on or in the couch will be
|
||||
! 'eaten', including you. In fact, by setting the 'deadflag' to 1,
|
||||
! Inform is informed to 'end' the game because you have died.
|
||||
!
|
||||
! Notice we used the 'before' property and the 'Enter' and 'Receive'
|
||||
! verbs to handle the action.
|
||||
!
|
||||
Object -> Evil_Couch "couch"
|
||||
with name "couch" "sofa",
|
||||
when_open "There is a filthy, worn down couch here.",
|
||||
before [; Enter: deadflag=1;
|
||||
"You are eaten by the couch.";
|
||||
Receive: remove noun;
|
||||
"The couch eats ", (the) noun, " and belches.";
|
||||
],
|
||||
has static container open enterable;
|
||||
|
||||
Object Foyer "Foyer"
|
||||
with description
|
||||
"You are standing in the foyer of the house. It seems as though
|
||||
you can go up a staircase, northwest, or back out the front
|
||||
door to the east.",
|
||||
out_to Front_Porch,
|
||||
e_to Front_Porch,
|
||||
nw_to Hallway,
|
||||
u_to Upper_Hallway,
|
||||
has light;
|
||||
|
||||
Object Hallway "Hallway"
|
||||
with description
|
||||
"You are in the hallway on the first floor of the house. The
|
||||
foyer is southeast and the kitchen is west of here.",
|
||||
se_to Foyer,
|
||||
w_to Kitchen,
|
||||
has light;
|
||||
|
||||
Object Kitchen "Kitchen"
|
||||
with description
|
||||
"This is the kitchen of the house. A hallway can be seen to the
|
||||
east and an open doorway to the west leads out to the backyard.",
|
||||
e_to Hallway,
|
||||
w_to Backyard,
|
||||
out_to Backyard,
|
||||
has light;
|
||||
|
||||
Object Backyard "Backyard"
|
||||
with name "yard",
|
||||
description
|
||||
"This is the backyard behind the house. There is a pond here.",
|
||||
e_to Kitchen,
|
||||
in_to Kitchen,
|
||||
has light;
|
||||
|
||||
Object -> Pond "pond"
|
||||
with name "pond" "water",
|
||||
description
|
||||
"It's a small pond, but wide enough to skip rocks.",
|
||||
has static concealed container open;
|
||||
|
||||
Object Upper_Hallway "Upper Hallway"
|
||||
with description
|
||||
"This is the second floor hallway. Rooms can be seen north and
|
||||
south and a staircase leads down.",
|
||||
n_to North_Bedroom,
|
||||
s_to South_Bedroom,
|
||||
d_to Foyer,
|
||||
has light;
|
||||
|
||||
Object North_Bedroom "North Bedroom"
|
||||
with description
|
||||
"This is a bedroom on the north side of the house.",
|
||||
s_to Upper_Hallway,
|
||||
has light;
|
||||
|
||||
Object -> right_key "right key" with name "right" "key", article "the";
|
||||
|
||||
Object South_Bedroom "South Bedroom"
|
||||
with description
|
||||
"This is a bedroom on the south side of the house.",
|
||||
n_to Upper_Hallway,
|
||||
has light;
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
!
|
||||
! Functions
|
||||
!
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
!
|
||||
! Added function ReadSub so that the property 'before' can use it. The default,
|
||||
! if there is no 'before read', is to examine the object.
|
||||
!
|
||||
[ ReadSub; <<Examine noun>>; ];
|
||||
|
||||
[ TearSub; "You can't tear that"; ];
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! Grammar
|
||||
!
|
||||
! The grammar section includes the file "Grammar" and will later include
|
||||
! extensions to the standard grammar library.
|
||||
!
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Include "Grammar";
|
||||
|
||||
!
|
||||
! We also have to extend the read grammar to call ReadSub
|
||||
! by default.
|
||||
!
|
||||
! We're using the 'Extend' statment because the word "read" is already defined
|
||||
! in the grammar file included above. This adds our usage.
|
||||
!
|
||||
! The 'first' tag is used to indicate to Inform that this usage of the word
|
||||
! "read" should be the first one checked. Without 'first', the "read" word
|
||||
! will not work the way we want it to because the default usage will get
|
||||
! called and will not handle our code properly.
|
||||
!
|
||||
! 'legible' is the attribute we created and by placing it here, we're telling
|
||||
! Inform that this attribute must be present in the object to call this usage
|
||||
! of the word "read".
|
||||
!
|
||||
Extend "read" first * legible -> Read;
|
||||
|
||||
!
|
||||
! We've also added the ability to 'tear' an object. Notice
|
||||
! we had to specify 'noun' and then direct the default to
|
||||
! TearSub.
|
||||
!
|
||||
! By the way, the 'Sub' is added on automatically by Inform.
|
||||
!
|
||||
! The word 'noun' tells Inform that the word "tear" must be followed by a
|
||||
! noun, otherwise Inform will reply, "What do you want to tear?".
|
||||
!
|
||||
Verb "tear" * noun -> Tear;
|
||||
!
|
||||
! Q: I'm really confused! Inform uses the words "first", "second", and "noun".
|
||||
! Can you explain the difference again?
|
||||
!
|
||||
! A: Sure.
|
||||
!
|
||||
! 'first' is a flag used in the grammar statement "Extend" so that the
|
||||
! new usage is called before previously defined usages. Without this
|
||||
! flag, an older usage might get called and your code may not work.
|
||||
!
|
||||
! 'second' is a variable that Inform sets if there is a second noun in
|
||||
! the player's statement.
|
||||
!
|
||||
! 'noun' is a variable that Inform sets if there are any nouns in the
|
||||
! player's statement. It gets set to the first noun found.
|
||||
!
|
||||
! > THROW ROCK AT POND
|
||||
!
|
||||
! ^ ^
|
||||
! noun second
|
||||
!
|
|
@ -0,0 +1,384 @@
|
|||
! ------------------------------------------------------------------------------
|
||||
! Inform for New Writers
|
||||
!
|
||||
! The House - Version 6
|
||||
!
|
||||
! Last Modified: David Cornelson - 31-Jan-1998
|
||||
!
|
||||
! This work is freely offered to the Public Domain. - DAC 12-12-2015
|
||||
!
|
||||
! ------------------------------------------------------------------------------
|
||||
|
||||
Constant Story "The House";
|
||||
|
||||
Constant Headline
|
||||
"^Inform for New Writers^
|
||||
The House - Version 6^
|
||||
By New Writer (1998) - Last Compiled: 31-Jan-1998^";
|
||||
|
||||
Constant MAX_SCORE 100;
|
||||
Serial "980131";
|
||||
|
||||
Release 1;
|
||||
|
||||
Include "Parser";
|
||||
Include "VerbLib";
|
||||
|
||||
!-------------------------------------------------------------------------------
|
||||
! Initialise
|
||||
!
|
||||
!-------------------------------------------------------------------------------
|
||||
|
||||
!
|
||||
! VERSION 6 - Adding a non-playing character or daemon to your game
|
||||
!
|
||||
! We are going to add a little pink Jarbigruen to our game, His name is Snark
|
||||
! and he tends to be a little inquisitive. In this version of 'The House', he
|
||||
! won't really 'do' anything but sit in your arms and blabber a few
|
||||
! phrases, which of course you can add to at your discretion.
|
||||
!
|
||||
! The first thing to do is create the object for Snark. We're going to put him
|
||||
! in the mailbox. This means that after the '-> Mailbox' object, we need to add
|
||||
! '-> -> Snark' to tell Inform that he is a child object of the mailbox.
|
||||
!
|
||||
! The Snark daemon will be started the first time you open the mailbox.
|
||||
|
||||
[ Initialise;
|
||||
|
||||
location = Sidewalk;
|
||||
|
||||
];
|
||||
|
||||
[ PrintRank;
|
||||
print ", earning you the rank of ";
|
||||
if (score >= 100) "the greatest.";
|
||||
if (score >= 80) "above average.";
|
||||
if (score >= 60) "average.";
|
||||
if (score >= 40) "below average.";
|
||||
if (score >= 20) "the barely living.";
|
||||
"the living dead.";
|
||||
];
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! Locations
|
||||
!
|
||||
! In this section we will define our locations. These are "Objects" to Inform.
|
||||
!
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Object Sidewalk "Sidewalk"
|
||||
with description
|
||||
"You are standing on the sidewalk in front of a house to the west.",
|
||||
w_to Front_Porch,
|
||||
has light;
|
||||
|
||||
Object -> Mailbox "mailbox"
|
||||
with name "mailbox" "box",
|
||||
|
||||
!
|
||||
! The 'before' property is used to 'catch' verb commands before Inform
|
||||
! handles them. In this case, we're going to catch the verb 'Open'.
|
||||
!
|
||||
! If Snark is in the Mailbox (which he is at the initial start of the
|
||||
! game) then we execute some special code.
|
||||
!
|
||||
! We are writing a 'function'. Remember that functions may have arguments
|
||||
! which would be defined before the semi-colon. This is important to
|
||||
! Inform so don't forget to begin the 'before' function with the bracket
|
||||
! AND the semi-colon.
|
||||
!
|
||||
! Each verb you intend to 'catch' is started simply by the verb followed
|
||||
! by a colon. The verb's execution ends with the next verb or at the end
|
||||
! of the function.
|
||||
!
|
||||
before [; Open: !
|
||||
! This function has a special behavior if Snark is
|
||||
! in the mailbox, which he is in the beginning.
|
||||
!
|
||||
if (Snark in Mailbox) {
|
||||
|
||||
StartDaemon(Snark);
|
||||
move Snark to player;
|
||||
give Mailbox open;
|
||||
|
||||
print "~Hey! It's about time! Why are you piddling
|
||||
around out there? Don't you know I need air? Who
|
||||
do you think you are anyway, some big adventurer
|
||||
or something? Pullllease!~, exclaims a small pink
|
||||
thing from the mailbox.^^~Hi. I'm Snark, the
|
||||
Jarbigruen!~, he cries in a high-pitched voice
|
||||
and then leaps from the mailbox into your
|
||||
arms.^";
|
||||
rtrue;
|
||||
}
|
||||
!
|
||||
! This is where the default behavior is executed for
|
||||
! the verb open. We don't have to 'do' anything and
|
||||
! Inform will know to execute the default processing.
|
||||
!
|
||||
],
|
||||
when_open "There is an open mailbox here.",
|
||||
when_closed "There is a closed mailbox here.",
|
||||
has static container openable;
|
||||
|
||||
! SNARK, THE JARBIGRUEN
|
||||
!
|
||||
! Snark has a lot of different names you can refer to him with so we have to
|
||||
! put these in the 'name' property. Each name is separated by a space.
|
||||
!
|
||||
Object -> -> Snark "small pink Jarbigruen"
|
||||
with name "snark" "jarbigruen" "alien" "monster" "thing",
|
||||
description
|
||||
"Snark, a little pink Jarbigruen, stands approximately ten
|
||||
centimeters tall, has two legs, two arms with tiny little hands,
|
||||
a wide-eyed face, and a tuft of yellowish hair on his head.",
|
||||
|
||||
!
|
||||
! We want Snark to stay with the player so we catch a 'drop'
|
||||
! and 'Insert' before Inform can let that happen.
|
||||
!
|
||||
! Except if it's the couch...that's handled differently...
|
||||
!
|
||||
before [; Drop,Insert: if (second == Evil_Couch) {
|
||||
print "You drop Snark onto the couch and the
|
||||
cushions begin to smother him slowly,
|
||||
until he completely disappears. After
|
||||
a few seconds you hear strange noises
|
||||
and, ** POP **, a pink ball is spit out
|
||||
of the couch back into your arms!^^
|
||||
Snark looks up at you and winks,
|
||||
~Jarbigruen's don't go down very easy,
|
||||
I guess.~^";
|
||||
rtrue;
|
||||
}
|
||||
print "~Hey! I'm not going anywhere without you!~,
|
||||
Snark says.^";
|
||||
rtrue;
|
||||
],
|
||||
|
||||
!
|
||||
! The daemon property is central to handling the characterization
|
||||
! of Snark, the Jarbigruen. For each turn the player takes, this
|
||||
! property is called.
|
||||
!
|
||||
! We're not going to do anything complex at this point. Just to
|
||||
! show that Snark is alive and kinking, we're going to add random
|
||||
! conversation from Snark. We're also adding the 'switch' statement.
|
||||
!
|
||||
! The 'switch' statement is used to differentiate different values
|
||||
! of a variable or expression. For each possible value, you can
|
||||
! code a different set of instructions.
|
||||
!
|
||||
! The random(10) function will return, randomly, a number from
|
||||
! 1 to 10. You can make this number anything you like.
|
||||
!
|
||||
! We're only giving Snark responses for half of the random numbers
|
||||
! so he isn't talking all of the time.
|
||||
!
|
||||
daemon [; switch (random(10)) {
|
||||
1: "Snark says, ~Isn't it great to be here!~";
|
||||
3: "Snark looks up at you with a glint in his eye and
|
||||
tickles you.";
|
||||
5: "Snark says, ~You are an excellent adventurer!~";
|
||||
7: "Snark cries, ~Stop it! Your holding me too tight!~";
|
||||
9: "Snark rifles through your pockets and sighs,
|
||||
~Got any candy?~";
|
||||
}
|
||||
],
|
||||
has animate;
|
||||
|
||||
Attribute legible;
|
||||
|
||||
Object -> -> Letter "letter"
|
||||
with name "letter" "paper",
|
||||
description
|
||||
"The letter is a simple page of notebook paper.",
|
||||
before [; Consult,Read: "The letter contains a vague story about an evil couch,
|
||||
but you can't make out anymore detail. Interesting
|
||||
little tidbit though.";
|
||||
Tear: remove Letter;
|
||||
"You rip the letter into tiny pieces that blow away in the wind.";
|
||||
]
|
||||
has legible;
|
||||
|
||||
Object Front_Porch "Front Porch"
|
||||
with description
|
||||
"This is the front porch of the house. There are two doors
|
||||
leading inside. The door on the left leads west and the
|
||||
door on the right leads northwest.",
|
||||
e_to Sidewalk,
|
||||
w_to Left_Front_Door,
|
||||
in_to Left_Front_Door,
|
||||
nw_to Right_Front_Door,
|
||||
has light;
|
||||
|
||||
!
|
||||
! I've added the attribute 'open' to both of the doors. I figured we'd
|
||||
! had that lesson and there was no need to repeat it. Both doors will
|
||||
! be open at the start of the game. You can still close them and lock
|
||||
! the right one with the key though.
|
||||
!
|
||||
Object -> Left_Front_Door "left front door"
|
||||
with name "left" "front" "door",
|
||||
description
|
||||
"The left front door is made of brass.",
|
||||
when_open "The left front door is open.",
|
||||
when_closed "The left front door is closed.",
|
||||
door_to Foyer,
|
||||
door_dir w_to,
|
||||
has static door openable open;
|
||||
|
||||
Object Right_Front_Door "right front door"
|
||||
with name "right" "front" "door",
|
||||
description
|
||||
"The right front door is made of wood.",
|
||||
when_open "The right front door is open.",
|
||||
when_closed "The right front door is closed.",
|
||||
door_to [; if (location==Front_Porch) return Den; return Front_Porch; ],
|
||||
door_dir [; if (location==Front_Porch) return nw_to; return se_to; ],
|
||||
found_in Front_Porch Den,
|
||||
with_key right_key,
|
||||
has static door openable lockable locked open;
|
||||
|
||||
Object Den "Den"
|
||||
with description
|
||||
"You are in the den of the house. The living room is west of hear
|
||||
and the front porch is to the southeast.",
|
||||
se_to Right_Front_Door,
|
||||
out_to Right_Front_Door,
|
||||
w_to Living_Room,
|
||||
has light;
|
||||
|
||||
Object -> Rock "rock"
|
||||
with name "rock",
|
||||
description
|
||||
"It's smooth and flat, perfect for skipping in a pond.",
|
||||
before [; Insert,PutOn,ThrowAt:
|
||||
if (second==Evil_Couch) rfalse; ! Allow the rock to be eaten by couch
|
||||
if (second==Pond) {
|
||||
print "The rock skips across the water several times and sinks.
|
||||
Amazingly, after a few moments, the rock washes up at
|
||||
your feet. Wow, what an undertow!^";
|
||||
move Rock to Backyard;
|
||||
rtrue;
|
||||
} else {
|
||||
print "You can't throw the rock at ",(the) second, ".^";
|
||||
rtrue;
|
||||
}
|
||||
];
|
||||
|
||||
Object Living_Room "Living Room"
|
||||
with name "living" "room",
|
||||
description
|
||||
"This is the living room of the house. The den is to the east.",
|
||||
e_to Den,
|
||||
has light;
|
||||
|
||||
!
|
||||
! And here is our evil couch. Anything put on or in the couch will be
|
||||
! 'eaten', including you. In fact, by setting the 'deadflag' to 1,
|
||||
! Inform is informed to 'end' the game because you have died.
|
||||
!
|
||||
! Notice we used the 'before' property and the 'Enter' and 'Receive'
|
||||
! verbs to handle the action.
|
||||
!
|
||||
Object -> Evil_Couch "couch"
|
||||
with name "couch" "sofa",
|
||||
when_open "There is a filthy, worn down couch here.",
|
||||
before [; Enter: deadflag=1;
|
||||
"You are eaten by the couch. As you flail for your last few
|
||||
seconds, you see Snark beating on the couch trying to save
|
||||
you, to no avail.";
|
||||
Receive: remove noun;
|
||||
"The couch eats ", (the) noun, " and belches.";
|
||||
],
|
||||
has static container open enterable;
|
||||
|
||||
Object Foyer "Foyer"
|
||||
with description
|
||||
"You are standing in the foyer of the house. It seems as though
|
||||
you can go up a staircase, northwest, or back out the front
|
||||
door to the east.",
|
||||
out_to Front_Porch,
|
||||
e_to Front_Porch,
|
||||
nw_to Hallway,
|
||||
u_to Upper_Hallway,
|
||||
has light;
|
||||
|
||||
Object Hallway "Hallway"
|
||||
with description
|
||||
"You are in the hallway on the first floor of the house. The
|
||||
foyer is southeast and the kitchen is west of here.",
|
||||
se_to Foyer,
|
||||
w_to Kitchen,
|
||||
has light;
|
||||
|
||||
Object Kitchen "Kitchen"
|
||||
with description
|
||||
"This is the kitchen of the house. A hallway can be seen to the
|
||||
east and an open doorway to the west leads out to the backyard.",
|
||||
e_to Hallway,
|
||||
w_to Backyard,
|
||||
out_to Backyard,
|
||||
has light;
|
||||
|
||||
Object Backyard "Backyard"
|
||||
with name "yard",
|
||||
description
|
||||
"This is the backyard behind the house. There is a pond here.",
|
||||
e_to Kitchen,
|
||||
in_to Kitchen,
|
||||
has light;
|
||||
|
||||
Object -> Pond "pond"
|
||||
with name "pond" "water",
|
||||
description
|
||||
"It's a small pond, but wide enough to skip rocks.",
|
||||
has static concealed container open;
|
||||
|
||||
Object Upper_Hallway "Upper Hallway"
|
||||
with description
|
||||
"This is the second floor hallway. Rooms can be seen north and
|
||||
south and a staircase leads down.",
|
||||
n_to North_Bedroom,
|
||||
s_to South_Bedroom,
|
||||
d_to Foyer,
|
||||
has light;
|
||||
|
||||
Object North_Bedroom "North Bedroom"
|
||||
with description
|
||||
"This is a bedroom on the north side of the house.",
|
||||
s_to Upper_Hallway,
|
||||
has light;
|
||||
|
||||
Object -> right_key "right key" with name "right" "key", article "the";
|
||||
|
||||
Object South_Bedroom "South Bedroom"
|
||||
with description
|
||||
"This is a bedroom on the south side of the house.",
|
||||
n_to Upper_Hallway,
|
||||
has light;
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
!
|
||||
! Functions
|
||||
!
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
[ ReadSub; <<Examine noun>>; ];
|
||||
|
||||
[ TearSub; "You can't tear that"; ];
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! Grammar
|
||||
!
|
||||
! The grammar section includes the file "Grammar" and will later include
|
||||
! extensions to the standard grammar library.
|
||||
!
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Include "Grammar";
|
||||
|
||||
Extend "read" first * legible -> Read;
|
||||
|
||||
Verb "tear" * noun -> Tear;
|
|
@ -0,0 +1,381 @@
|
|||
! ------------------------------------------------------------------------------
|
||||
! Inform for New Writers
|
||||
!
|
||||
! The House - Version 7
|
||||
!
|
||||
! Last Modified: David Cornelson - 01-Feb-1998
|
||||
!
|
||||
! This work is freely offered to the Public Domain. - DAC 12-12-2015
|
||||
!
|
||||
! ------------------------------------------------------------------------------
|
||||
|
||||
Constant Story "The House";
|
||||
|
||||
Constant Headline
|
||||
"^Inform for New Writers^
|
||||
The House - Version 7^
|
||||
By New Writer (1998) - Last Compiled: 01-Feb-1998^";
|
||||
|
||||
Constant MAX_SCORE 100;
|
||||
Serial "980201";
|
||||
|
||||
Release 1;
|
||||
|
||||
Include "Parser";
|
||||
Include "VerbLib";
|
||||
|
||||
!-------------------------------------------------------------------------------
|
||||
! Initialise
|
||||
!
|
||||
!-------------------------------------------------------------------------------
|
||||
|
||||
[ Initialise;
|
||||
|
||||
location = Sidewalk;
|
||||
|
||||
];
|
||||
|
||||
[ PrintRank;
|
||||
print ", earning you the rank of ";
|
||||
if (score >= 100) "the greatest.";
|
||||
if (score >= 80) "above average.";
|
||||
if (score >= 60) "average.";
|
||||
if (score >= 40) "below average.";
|
||||
if (score >= 20) "the barely living.";
|
||||
"the living dead.";
|
||||
];
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! Locations
|
||||
!
|
||||
! In this section we will define our locations. These are "Objects" to Inform.
|
||||
!
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Object Sidewalk "Sidewalk"
|
||||
with description
|
||||
"You are standing on the sidewalk in front of a house to the west.",
|
||||
w_to Front_Porch,
|
||||
has light;
|
||||
|
||||
Object -> Mailbox "mailbox"
|
||||
with name "mailbox" "box",
|
||||
|
||||
before [; Open: if (Snark in Mailbox) {
|
||||
|
||||
StartDaemon(Snark);
|
||||
move Snark to player;
|
||||
give Mailbox open;
|
||||
|
||||
print "~Hey! It's about time! Why are you piddling
|
||||
around out there? Don't you know I need air? Who
|
||||
do you think you are anyway, some big adventurer
|
||||
or something? Pullllease!~, exclaims a small pink
|
||||
thing from the mailbox.^^~Hi. I'm Snark, the
|
||||
Jarbigruen!~, he cries in a high-pitched voice
|
||||
and then leaps from the mailbox into your
|
||||
arms.^";
|
||||
rtrue;
|
||||
}
|
||||
],
|
||||
when_open "There is an open mailbox here.",
|
||||
when_closed "There is a closed mailbox here.",
|
||||
has static container openable;
|
||||
|
||||
Object -> -> Snark "small pink Jarbigruen"
|
||||
with name "snark" "jarbigruen" "alien" "monster" "thing",
|
||||
description
|
||||
"Snark, a little pink Jarbigruen, stands approximately ten
|
||||
centimeters tall, has two legs, two arms with tiny little hands,
|
||||
a wide-eyed face, and a tuft of yellowish hair on his head.",
|
||||
|
||||
before [; Drop,Insert: if (second == Evil_Couch) {
|
||||
print "You drop Snark onto the couch and the
|
||||
cushions begin to smother him slowly,
|
||||
until he completely disappears. After
|
||||
a few seconds you hear strange noises
|
||||
and, ** POP **, a pink ball is spit out
|
||||
of the couch back into your arms!^^
|
||||
Snark looks up at you and winks,
|
||||
~Jarbigruen's don't go down very easy,
|
||||
I guess.~^";
|
||||
rtrue;
|
||||
}
|
||||
print "~Hey! I'm not going anywhere without you!~,
|
||||
Snark says.^";
|
||||
rtrue;
|
||||
],
|
||||
daemon [; switch (random(10)) {
|
||||
1: "Snark says, ~Isn't it great to be here!~";
|
||||
3: "Snark looks up at you with a glint in his eye and
|
||||
tickles you.";
|
||||
5: "Snark says, ~You are an excellent adventurer!~";
|
||||
7: "Snark cries, ~Stop it! Your holding me too tight!~";
|
||||
9: "Snark rifles through your pockets and sighs,
|
||||
~Got any candy?~";
|
||||
}
|
||||
],
|
||||
has animate;
|
||||
|
||||
Attribute legible;
|
||||
|
||||
Object -> -> Letter "letter"
|
||||
with name "letter" "paper",
|
||||
description
|
||||
"The letter is a simple page of notebook paper.",
|
||||
before [; Consult,Read: "The letter contains a vague story about an evil couch,
|
||||
but you can't make out anymore detail. Interesting
|
||||
little tidbit though.";
|
||||
Tear: remove Letter;
|
||||
"You rip the letter into tiny pieces that blow away in the wind.";
|
||||
]
|
||||
has legible;
|
||||
|
||||
Object Front_Porch "Front Porch"
|
||||
with description
|
||||
"This is the front porch of the house. There are two doors
|
||||
leading inside. The door on the left leads west and the
|
||||
door on the right leads northwest.",
|
||||
e_to Sidewalk,
|
||||
w_to Left_Front_Door,
|
||||
in_to Left_Front_Door,
|
||||
nw_to Right_Front_Door,
|
||||
has light;
|
||||
|
||||
!
|
||||
! VERSION 7 - Using a Class statement to create a group of common objects
|
||||
!
|
||||
! There are times when building your game that you begin building the same
|
||||
! types of objects over and over. You end up copying code all over the place
|
||||
! and maintaining this code becomes a search and replace chase scene.
|
||||
!
|
||||
! Well, in some instances, there is a better way. We have to discuss a little
|
||||
! bit of methodology first though.
|
||||
!
|
||||
! Most games hsouldn't be written like 'The House'. You should write out as much
|
||||
! of your story and physical world as possible. When you have a fairly complete
|
||||
! view of this world, you break down all of aspects into objects.
|
||||
!
|
||||
! If we designed the current version of 'The House' this way, it would look
|
||||
! something like this...
|
||||
!
|
||||
! ----------------------------
|
||||
!
|
||||
! Sidewalk -> Mailbox -> Snark
|
||||
! -> Letter
|
||||
!
|
||||
! Front Porch -> Left Door
|
||||
! -> Right Door
|
||||
!
|
||||
! Foyer
|
||||
!
|
||||
! Den -> Rock
|
||||
!
|
||||
! Living Room -> Evil Couch
|
||||
!
|
||||
! Hallway
|
||||
!
|
||||
! Upper Hallway
|
||||
!
|
||||
! North Bedroom -> Key
|
||||
!
|
||||
! South Bedroom
|
||||
!
|
||||
! Kitchen
|
||||
!
|
||||
! Backyard -> Pond
|
||||
!
|
||||
! ----------------------------
|
||||
!
|
||||
! You will likely want to do this BEFORE you begin programming your game. The reason
|
||||
! is that you may be able to reduce some of your coding by locating similar objects.
|
||||
!
|
||||
! Q: What two objects in 'The House' are alike?
|
||||
!
|
||||
! A: The doors
|
||||
!
|
||||
! Correct. We are going to rewrite the two door objects, but first we're going to create
|
||||
! a class for the foundation of their definition.
|
||||
!
|
||||
|
||||
Class Front_Door
|
||||
with name "front" "door",
|
||||
has static door openable open;
|
||||
|
||||
!
|
||||
! And now we'll change the each door object to become a subset of this class.
|
||||
! Notice that we can leave out the names and attributes in the class. These
|
||||
! are 'inherited' by the newly defined objects.
|
||||
!
|
||||
! In this example, we didn't reduce our code all that much. But in many cases
|
||||
! you will reduce your code. A good use of this is when you have an NPC or
|
||||
! non-playing character that you want to be seen as learning. You can create
|
||||
! a base class object with rudimentary actions and change to other objects
|
||||
! when the NPC is supposed to be 'smarter'.
|
||||
!
|
||||
! Class Base_Snark ...
|
||||
!
|
||||
! Base_Snark Snark_1 ...
|
||||
! Base_Snark Snark_2 ...
|
||||
! Base_Snark Snark_3 ...
|
||||
!
|
||||
! Anything you define in the class object, is inherited by the continuing
|
||||
! objects. If you redefine something, such as an attribute or property,
|
||||
! then the new definition supercedes the class definition.
|
||||
!
|
||||
|
||||
Front_Door -> Left_Front_Door "left front door"
|
||||
with name "left",
|
||||
description
|
||||
"The left front door is made of brass.",
|
||||
when_open "The left front door is open.",
|
||||
when_closed "The left front door is closed.",
|
||||
door_to Foyer,
|
||||
door_dir w_to;
|
||||
|
||||
Front_Door -> Right_Front_Door "right front door"
|
||||
with name "right",
|
||||
description
|
||||
"The right front door is made of wood.",
|
||||
when_open "The right front door is open.",
|
||||
when_closed "The right front door is closed.",
|
||||
door_to [; if (location==Front_Porch) return Den; return Front_Porch; ],
|
||||
door_dir [; if (location==Front_Porch) return nw_to; return se_to; ],
|
||||
found_in Front_Porch Den,
|
||||
with_key right_key,
|
||||
has lockable locked;
|
||||
|
||||
Object Den "Den"
|
||||
with description
|
||||
"You are in the den of the house. The living room is west of hear
|
||||
and the front porch is to the southeast.",
|
||||
se_to Right_Front_Door,
|
||||
out_to Right_Front_Door,
|
||||
w_to Living_Room,
|
||||
has light;
|
||||
|
||||
Object -> Rock "rock"
|
||||
with name "rock",
|
||||
description
|
||||
"It's smooth and flat, perfect for skipping in a pond.",
|
||||
before [; Insert,PutOn,ThrowAt:
|
||||
if (second==Evil_Couch) rfalse; ! Allow the rock to be eaten by couch
|
||||
if (second==Pond) {
|
||||
print "The rock skips across the water several times and sinks.
|
||||
Amazingly, after a few moments, the rock washes up at
|
||||
your feet. Wow, what an undertow!^";
|
||||
move Rock to Backyard;
|
||||
rtrue;
|
||||
} else {
|
||||
print "You can't throw the rock at ",(the) second, ".^";
|
||||
rtrue;
|
||||
}
|
||||
];
|
||||
|
||||
Object Living_Room "Living Room"
|
||||
with name "living" "room",
|
||||
description
|
||||
"This is the living room of the house. The den is to the east.",
|
||||
e_to Den,
|
||||
has light;
|
||||
|
||||
Object -> Evil_Couch "couch"
|
||||
with name "couch" "sofa",
|
||||
when_open "There is a filthy, worn down couch here.",
|
||||
before [; Enter: deadflag=1;
|
||||
"You are eaten by the couch. As you flail for your last few
|
||||
seconds, you see Snark beating on the couch trying to save
|
||||
you, to no avail.";
|
||||
Receive: remove noun;
|
||||
"The couch eats ", (the) noun, " and belches.";
|
||||
],
|
||||
has static container open enterable;
|
||||
|
||||
Object Foyer "Foyer"
|
||||
with description
|
||||
"You are standing in the foyer of the house. It seems as though
|
||||
you can go up a staircase, northwest, or back out the front
|
||||
door to the east.",
|
||||
out_to Front_Porch,
|
||||
e_to Front_Porch,
|
||||
nw_to Hallway,
|
||||
u_to Upper_Hallway,
|
||||
has light;
|
||||
|
||||
Object Hallway "Hallway"
|
||||
with description
|
||||
"You are in the hallway on the first floor of the house. The
|
||||
foyer is southeast and the kitchen is west of here.",
|
||||
se_to Foyer,
|
||||
w_to Kitchen,
|
||||
has light;
|
||||
|
||||
Object Kitchen "Kitchen"
|
||||
with description
|
||||
"This is the kitchen of the house. A hallway can be seen to the
|
||||
east and an open doorway to the west leads out to the backyard.",
|
||||
e_to Hallway,
|
||||
w_to Backyard,
|
||||
out_to Backyard,
|
||||
has light;
|
||||
|
||||
Object Backyard "Backyard"
|
||||
with name "yard",
|
||||
description
|
||||
"This is the backyard behind the house. There is a pond here.",
|
||||
e_to Kitchen,
|
||||
in_to Kitchen,
|
||||
has light;
|
||||
|
||||
Object -> Pond "pond"
|
||||
with name "pond" "water",
|
||||
description
|
||||
"It's a small pond, but wide enough to skip rocks.",
|
||||
has static concealed container open;
|
||||
|
||||
Object Upper_Hallway "Upper Hallway"
|
||||
with description
|
||||
"This is the second floor hallway. Rooms can be seen north and
|
||||
south and a staircase leads down.",
|
||||
n_to North_Bedroom,
|
||||
s_to South_Bedroom,
|
||||
d_to Foyer,
|
||||
has light;
|
||||
|
||||
Object North_Bedroom "North Bedroom"
|
||||
with description
|
||||
"This is a bedroom on the north side of the house.",
|
||||
s_to Upper_Hallway,
|
||||
has light;
|
||||
|
||||
Object -> right_key "right key" with name "right" "key", article "the";
|
||||
|
||||
Object South_Bedroom "South Bedroom"
|
||||
with description
|
||||
"This is a bedroom on the south side of the house.",
|
||||
n_to Upper_Hallway,
|
||||
has light;
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
!
|
||||
! Functions
|
||||
!
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
[ ReadSub; <<Examine noun>>; ];
|
||||
|
||||
[ TearSub; "You can't tear that"; ];
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! Grammar
|
||||
!
|
||||
! The grammar section includes the file "Grammar" and will later include
|
||||
! extensions to the standard grammar library.
|
||||
!
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Include "Grammar";
|
||||
|
||||
Extend "read" first * legible -> Read;
|
||||
|
||||
Verb "tear" * noun -> Tear;
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,691 @@
|
|||
!==============================================================================!
|
||||
! The Inform Designer's Manual (16May97) includes various references to a
|
||||
! sample game called "Ruins", which unfortunately is not supplied with the
|
||||
! compiler. This file attempts to knit together several of the fragments from
|
||||
! the DM into a small but complete game, intended primarily as an example for
|
||||
! novices of a typical way to use Inform features, and as a starting point
|
||||
! for experimentation.
|
||||
!
|
||||
! In order to keep the game manageably small, the following references from
|
||||
! the DM have been omitted:
|
||||
! parrot, low mist, chasm, pumice-stone ball, glyphs, dictionary,
|
||||
! food rations, sodium lamp, cage.
|
||||
! Other items have been changed as necessary for simplicity and consistency.
|
||||
!
|
||||
! Object definitions explicitly state the name of their parent object (if
|
||||
! appropriate), rather than using the "->" construct.
|
||||
!
|
||||
! Once you've played the game and (hopefully) understood how it works, you
|
||||
! are strongly encouraged to try modifying or extending it. For instance:
|
||||
! - add the low mist in the Forest and Square_Chamber. In the DM it smells of
|
||||
! broth, so perhaps you should provide a source for the smell (or just
|
||||
! change the description)?
|
||||
! - implement the parrot, perhaps having it fly into the Forest once the plane
|
||||
! has departed?
|
||||
! - extend the number of rooms. There's a suggestion that you could Down from
|
||||
! the Shrine, or perhaps you could add a dark passage leading West from the
|
||||
! Corridor?
|
||||
! - if the passage is dark, perhaps a lamp would be useful?
|
||||
! - if you've got a lamp, the maze in the Web becomes much less daunting
|
||||
! (and the descriptions will need beefing up too). So perhaps it's the lamp
|
||||
! rather than the bangle which you find on your exit from the darkened Web?
|
||||
! - the DM is a bit unclear about the role(!) of the pumice-stone ball, but
|
||||
! it seems to need pushing into the chasm. Maybe it blocks the gap and
|
||||
! allows you to cross to the other side (in order to reach the bangle)?
|
||||
! - there are a couple of daemons in the example, but no timer. How about
|
||||
! extending the Honeycomb so that if dropped it prints a warning and starts
|
||||
! a timer causing itself to melt unless picked up again within two turns?
|
||||
!
|
||||
! Of course, it isn't worth spending too long on Ruins, since it's only a
|
||||
! somewhat dull and well-visited example. As soon as you start to feel
|
||||
! comfortable with the way that an Inform game is constructed...
|
||||
!
|
||||
! ...have a go at writing one of your own. Good luck!
|
||||
|
||||
!==============================================================================!
|
||||
! Every game needs a Story and Headline, and must include Parser and VerbLib.
|
||||
! As DM <20>§7 except: Release, Serial and MAX_SCORE defined.
|
||||
!
|
||||
Constant Story "RUINS";
|
||||
Constant Headline
|
||||
"^An Interactive Worked Example^
|
||||
Copyright (c) 1995 by Graham Nelson.^
|
||||
Revisited 1998 by Roger Firth.^";
|
||||
|
||||
Release 2;
|
||||
Serial "981117";
|
||||
Constant MAX_SCORE 100;
|
||||
|
||||
Include "Parser";
|
||||
Include "VerbLib";
|
||||
|
||||
!==============================================================================!
|
||||
! Every game needs an Initialise routine, whose primary role is to set the
|
||||
! player's location (i.e. you) at the start of the game.
|
||||
! As DM <20>§7 and 19 except: StartDaemon() call added, no TitlePage().
|
||||
!
|
||||
[ Initialise;
|
||||
location = Forest;
|
||||
thedark.description =
|
||||
"The darkness of ages presses in on you, and you feel claustrophobic.";
|
||||
StartDaemon(Packing_Case);
|
||||
"^^^^^Days of searching, days of thirsty hacking through the briars of
|
||||
the forest, but at last your patience was rewarded. A discovery!^";
|
||||
];
|
||||
|
||||
!==============================================================================!
|
||||
! As DM <20>§20. PrintRank, if defined, is called when printing the score.
|
||||
!
|
||||
[ PrintRank;
|
||||
print ", earning you the rank of ";
|
||||
switch (score) {
|
||||
0 to 9: "humble rainforest Tourist.";
|
||||
10 to 39: "Investigator.";
|
||||
40 to 69: "Acquisitor.";
|
||||
70 to 99: "Archaeologist.";
|
||||
100: "Master Archaeologist.";
|
||||
}
|
||||
];
|
||||
|
||||
!==============================================================================!
|
||||
! As DM <20>§11 except: daemon added, to bring the immovable crate at the start,
|
||||
! and take it (and you) away at the end.
|
||||
!
|
||||
Object Packing_Case "packing case"
|
||||
with name 'packing' 'case' 'crate' 'box' 'strongbox',
|
||||
initial
|
||||
"Your packing case rests here, ready for you to hold any important
|
||||
cultural finds you might make, for shipping back to civilisation.",
|
||||
description
|
||||
"A stout wooden crate, only slightly battered by its fall through
|
||||
the branches.",
|
||||
before [;
|
||||
PushDir, Remove, Take:
|
||||
"The case is too heavy to bother moving, as long as your
|
||||
expedition is still incomplete.
|
||||
It'll probably have to be taken out by helicopter.";
|
||||
],
|
||||
number 0, ! <-- used by the daemon
|
||||
daemon [;
|
||||
switch (++self.number) {
|
||||
!-- Start of game
|
||||
1: "^You hear the distant drone of an aeroplane.";
|
||||
2: "^The plane is much louder, and seems to be flying very
|
||||
low. Terrified birds rise in screeching flocks.";
|
||||
3: move self to Forest;
|
||||
if (location == Forest)
|
||||
"^You involuntarily crouch as the plane flies directly
|
||||
overhead, seemingly only inches above the treetops.
|
||||
With a loud thump, something drops heavily to the
|
||||
ground.";
|
||||
"^Even underground, the engine roar is deafening.
|
||||
Then there's a dull thump overhead and a little dust
|
||||
falls from the ceiling.";
|
||||
4: StopDaemon(self);
|
||||
"^The roar dies away; calm returns to the forest.";
|
||||
!-- End of game
|
||||
5: "^A deep throbbing noise can be heard.";
|
||||
6: "^A helicopter appears, hovering overhead.";
|
||||
7: StopDaemon(self);
|
||||
remove self;
|
||||
deadflag = 2; ! <-- You win!
|
||||
"^The helicopter lowers a rope; you tie it around the
|
||||
packing case, which is hauled up into the air,
|
||||
then a rope ladder comes dangling down.
|
||||
With one last look around the clearing, you climb the
|
||||
ladder into the waiting craft.
|
||||
Back to civilisation, and a decent pint of Brakspear's!";
|
||||
}
|
||||
],
|
||||
has container open openable static;
|
||||
|
||||
!==============================================================================!
|
||||
! As DM <20>§8 except: started endgame processing when all treasure has been
|
||||
! found. Added Bangle and Ruby treasures. "Undiscovered" is useful when
|
||||
! ensuring that treasures can't be found twice.
|
||||
!
|
||||
Class Treasure
|
||||
with cultural_value 10,
|
||||
before [;
|
||||
Remove, Take:
|
||||
if (self in Packing_Case)
|
||||
"Unpacking such a priceless artifact had best wait
|
||||
until the Metropolitan Museum can do it.";
|
||||
],
|
||||
after [;
|
||||
Insert:
|
||||
if (second == Packing_Case) {
|
||||
score = score + self.cultural_value;
|
||||
print "Safely packed away.^";
|
||||
}
|
||||
if (score == MAX_SCORE) {
|
||||
StartDaemon(Packing_Case);
|
||||
"^The case is full, and you're feeling really homesick.
|
||||
Now, how to get out of here?";
|
||||
}
|
||||
rtrue; ! <-- print nothing further
|
||||
];
|
||||
|
||||
Object Undiscovered "hidden treasure room"
|
||||
with description "How the heck did you get here!?.";
|
||||
|
||||
Treasure Statuette "pygmy statuette" Undiscovered
|
||||
with name 'pygmy' 'statuette' 'statue' 'mayan' 'snake' 'spirit',
|
||||
description
|
||||
"A menacing, almost cartoon-like statuette of a pygmy spirit
|
||||
with an enormous snake around its neck.";
|
||||
|
||||
Treasure Bangle "silver bangle" Undiscovered
|
||||
with name 'silver' 'bangle' 'bracelet' 'ring',
|
||||
cultural_value 20,
|
||||
description "An intricately chased piece of jewellery.";
|
||||
|
||||
Treasure Ruby "blood-red ruby" Undiscovered
|
||||
with name 'blood' 'red' 'blood-red' 'ruby' 'stone' 'jewel',
|
||||
cultural_value 30,
|
||||
description "A vivid red jewel, as large as a hen's egg.";
|
||||
|
||||
Treasure Honeycomb "lump of wax" Undiscovered
|
||||
with name 'ancient' 'honeycomb' 'old' 'honey' 'comb' 'wax' 'lump',
|
||||
cultural_value 40,
|
||||
description
|
||||
"On closer examination, the lump appears to be an old honeycomb.",
|
||||
after [;
|
||||
Eat:
|
||||
"Perhaps the most expensive meal of your life.
|
||||
The honey tastes odd, perhaps because it was used to store the
|
||||
entrails of the king buried here, but still like honey.";
|
||||
],
|
||||
has edible;
|
||||
|
||||
!==============================================================================!
|
||||
! Not in the DM as such, but useful (a) to distinguish room definitions from
|
||||
! those of ordinary objects in the file, and (b) to provide light everywhere
|
||||
! (unless overruled). See DM <20>§3.8.
|
||||
!
|
||||
Class Room
|
||||
has light;
|
||||
|
||||
!==============================================================================!
|
||||
! As DM <20>§7 and 10.
|
||||
!
|
||||
Room Forest "Dark Forest"
|
||||
with name 'forest' 'jungle' 'clearing' 'olive' 'tree' 'trees' 'midges',
|
||||
description
|
||||
"In this tiny clearing, the pine-needle carpet is broken by
|
||||
stone-cut steps leading down into the darkness.
|
||||
Dark olive trees crowd in on all sides, the air steams with
|
||||
warm recent rain, midges hang in the air.",
|
||||
d_to Stone_Steps,
|
||||
u_to
|
||||
"The trees are spiny and you'd cut your hands to ribbons
|
||||
trying to climb them.",
|
||||
cant_go
|
||||
"The rainforest-jungle is dense, and you haven't hacked through it
|
||||
for days to abandon your discovery now.
|
||||
Really, you need a good few artifacts to take back to civilisation
|
||||
before you can justify giving up the expedition.";
|
||||
|
||||
!==============================================================================!
|
||||
! As DM <20>§7 and 8 except: added discovery of Statuette on picking the
|
||||
! mushroom.
|
||||
!
|
||||
Object Mushroom "speckled mushroom" Forest
|
||||
with name 'speckled' 'mushroom' 'fungus' 'toadstool',
|
||||
initial
|
||||
"A speckled mushroom grows out of the sodden earth,
|
||||
on a long stalk.",
|
||||
description
|
||||
"The mushroom is capped with blotches,
|
||||
and you aren't at all sure it's not a toadstool.",
|
||||
before [;
|
||||
Eat:
|
||||
if (random(100) > 30)
|
||||
"You nibble at one corner,
|
||||
but the curious taste repels you.";
|
||||
deadflag = 1; ! <-- You die!
|
||||
"The tiniest nibble is enough.
|
||||
It was a toadstool, and a poisoned one at that!";
|
||||
],
|
||||
after [;
|
||||
Drop:
|
||||
"The mushroom drops to the ground, battered slightly.";
|
||||
Take:
|
||||
if (self has general)
|
||||
"You pick up the slowly-disintegrating mushroom.";
|
||||
give self general;
|
||||
move Statuette to location;
|
||||
"You stoop to pick the mushroom, neatly cleaving its thin stalk.
|
||||
As you straighten up, you notice what looks like a
|
||||
snake in the grass.";
|
||||
],
|
||||
has edible;
|
||||
|
||||
!==============================================================================!
|
||||
! As DM <20>§7 and 8 except: replaced "first feet" by cobwebs.
|
||||
!
|
||||
Object Stone_Steps "stone-cut steps" Forest
|
||||
with name 'stone' 'stone-cut' 'steps' 'stairs' 'cobwebs',
|
||||
description [;
|
||||
print "The cracked and worn steps descend into a dim chamber. ";
|
||||
if (Square_Chamber has visited)
|
||||
"The filmy cobwebs which once spanned the entrance
|
||||
now hang in tatters.";
|
||||
else
|
||||
"Cobwebs form a flimsy barrier,
|
||||
unlikely to impede your descent.";
|
||||
],
|
||||
door_to Square_Chamber, door_dir d_to,
|
||||
has door open scenery;
|
||||
|
||||
!==============================================================================!
|
||||
! As DM <20>§10 except: added examination of floor, word on east lintel,
|
||||
! insect trails when mushroom bursts.
|
||||
!
|
||||
Room Square_Chamber "Square Chamber"
|
||||
with name 'square' 'chamber' 'sand' 'dust' 'lintel' 'lintels' 'lintelled'
|
||||
'east' 'south' 'doorways' 'doors' 'steps',
|
||||
description
|
||||
"A sunken, gloomy stone chamber, ten yards across,
|
||||
whose floor is covered with fine sandy dust.
|
||||
A shaft of sunlight cuts in from the steps above,
|
||||
giving the chamber a diffuse light, but in the shadows low
|
||||
lintelled doorways to east and south
|
||||
lead into the deeper darkness of the Temple.",
|
||||
before [;
|
||||
Drop:
|
||||
if (noun == mushroom)
|
||||
<<Insert Mushroom Sunlight>>;
|
||||
Examine:
|
||||
if (noun == d_obj) {
|
||||
if (Trails in location)
|
||||
<<Examine Trails>>;
|
||||
"Only your own footprints disturb the dust.";
|
||||
}
|
||||
Go: if (noun == e_obj) {
|
||||
print "As you move into the eastern shadows, you seem to
|
||||
glimpse the word SENE scratched on the lintel,
|
||||
but before you can stop to inspect it more closely,
|
||||
you find yourself in...^";
|
||||
rfalse; ! <-- continue with the regular action
|
||||
}
|
||||
Insert:
|
||||
if ((noun == Mushroom) && (second == Sunlight)) {
|
||||
remove Mushroom;
|
||||
move Trails to location;
|
||||
"You drop the mushroom on the floor, in the glare of the
|
||||
shaft of sunlight.
|
||||
It bubbles obscenely, distends and then bursts into a
|
||||
hundred tiny insects which run for the darkness in every
|
||||
direction, leaving strange trails in the sandy floor.
|
||||
No trace of fungus remain.";
|
||||
}
|
||||
],
|
||||
u_to Forest,
|
||||
e_to Inner_Web,
|
||||
s_to Corridor;
|
||||
|
||||
!==============================================================================!
|
||||
! As DM <20>§10.
|
||||
!
|
||||
Object Sunlight "shaft of sunlight" Square_Chamber
|
||||
with name 'shaft' 'of' 'sunlight' 'sun' 'light' 'beam' 'sunbeam' 'ray'
|
||||
'rays' 'sun^s',
|
||||
description
|
||||
"The shaft of sunlight glimmers motes of dust in the air,
|
||||
making it seem almost solid.",
|
||||
before [;
|
||||
Examine, Search:
|
||||
;
|
||||
default:
|
||||
"It's only an insubstantial shaft of sunlight.";
|
||||
],
|
||||
has scenery;
|
||||
|
||||
!==============================================================================!
|
||||
! Not in the DM as such, but useful because employed twice. It seemed easier
|
||||
! to have two sets of carvings rather just one plus a lot of if... tests.
|
||||
! See DM <20>§3.8.
|
||||
!
|
||||
Class Carved
|
||||
with name 'carved' 'inscription' 'inscriptions' 'carving' 'carvings'
|
||||
'group' 'of',
|
||||
initial "Carved inscriptions crowd the walls and ceiling.",
|
||||
has container open pluralname static;
|
||||
|
||||
!==============================================================================!
|
||||
! As DM <20>§10 except: changed to include insect trails suggesting a carving,
|
||||
! and pressable carving which reveals cavity.
|
||||
!
|
||||
Carved Carvings "carved inscriptions" Square_Chamber
|
||||
with description [;
|
||||
print "The carvings cut deep into the rocks from which the
|
||||
chamber is built, forming swirling sinuous patterns.";
|
||||
if (cavity in self)
|
||||
print " In the middle of one wall, a small cavity can be seen.";
|
||||
new_line;
|
||||
],
|
||||
before [;
|
||||
Push:
|
||||
"Pressing the carved rock walls at random is unlikely
|
||||
to be revealing.";
|
||||
Touch:
|
||||
"The carvings are warm and smooth to the touch.";
|
||||
];
|
||||
|
||||
Carved Other_Carvings "carved inscriptions"
|
||||
with description
|
||||
"You stare at a group of carvings in the middle of one wall,
|
||||
uncannily resembling the insects' trail left in the sand,
|
||||
and feel your hand reaching out in that direction.",
|
||||
before [;
|
||||
Push:
|
||||
remove Other_Carvings;
|
||||
move Carvings to location;
|
||||
move Cavity to Carvings;
|
||||
"The carvings slide inwards, revealing a small cavity.";
|
||||
Touch:
|
||||
"The carvings seems to shift slightly under your hand.
|
||||
Perhaps with a little more pressure...?";
|
||||
];
|
||||
|
||||
Object Cavity "cavity among the carvings"
|
||||
with name 'cavity' 'hole' 'deep' 'gloomy',
|
||||
description
|
||||
"The cavity, a few inches across, is deep and gloomy.",
|
||||
has container open static;
|
||||
|
||||
Object Trails "trails in the sand"
|
||||
with name 'trail' 'trails' 'sand' 'sandy' 'pattern' 'insect' 'insects',
|
||||
initial "Strange trails swirl on the sandy floor.",
|
||||
description [;
|
||||
if (self has general) {
|
||||
remove Carvings;
|
||||
move Other_Carvings to location;
|
||||
give self ~general;
|
||||
}
|
||||
"The insect trails seem to resemble one particular group of
|
||||
carvings on the wall.";
|
||||
],
|
||||
has general pluralname static;
|
||||
|
||||
!==============================================================================!
|
||||
! A Web room is implied at DM <20>§10, but not defined. Here, it's implemented
|
||||
! as a simple dark maze of two rooms, once of which is home to the
|
||||
! scuttling claws described in Example 37. The Bangle is here.
|
||||
!
|
||||
Class Maze
|
||||
class Room,
|
||||
with name 'dark' 'darkness' 'web',
|
||||
description "Without a light, you'll never see anything here!",
|
||||
cant_go
|
||||
"Blundering around in the dark, it's impossible to tell
|
||||
which direction is which.",
|
||||
has ~light;
|
||||
|
||||
Maze Inner_Web "Web of Darkness"
|
||||
with se_to Outer_Web,
|
||||
ne_to Inner_Web,
|
||||
n_to Inner_Web, s_to Inner_Web, e_to Inner_Web, w_to Inner_Web,
|
||||
nw_to Inner_Web, sw_to Inner_Web,
|
||||
u_to Inner_Web, d_to Inner_Web;
|
||||
|
||||
Maze Outer_Web "Web of Darkness"
|
||||
with se_to Outer_Web,
|
||||
ne_to Square_Chamber,
|
||||
n_to Inner_Web, s_to Inner_Web, e_to Inner_Web, w_to Inner_Web,
|
||||
nw_to Inner_Web, sw_to Inner_Web,
|
||||
u_to Inner_Web, d_to Inner_Web,
|
||||
before [;
|
||||
Go: if ((noun == ne_obj) && (Bangle in Undiscovered)) {
|
||||
move Bangle to player;
|
||||
print "Sensing a slight draught you move in that direction,
|
||||
stumbling over something lying on the ground in the dark.
|
||||
Almost inadvertently you grab it before gratefully
|
||||
emerging into the gloomy chamber.^";
|
||||
rfalse; ! <-- continue with the regular action
|
||||
}
|
||||
];
|
||||
|
||||
!==============================================================================!
|
||||
! As DM Ex.37 except: daemon runs only in the Inner_Web room.
|
||||
!
|
||||
Object Tiny_Claws "sound of tiny claws" thedark
|
||||
with name 'tiny' 'claws' 'sound' 'of' 'scuttling' 'scuttle' 'things'
|
||||
'creatures' 'insects' 'monsters',
|
||||
article "the",
|
||||
initial "Somewhere, tiny claws are scuttling.",
|
||||
description "Without a light, you'll never see anything here!",
|
||||
before [;
|
||||
Attack: "They easily avoid your flailing about in the dark.";
|
||||
Listen: "How intelligent they sound, for mere insects.";
|
||||
Smell: "You can smell only your own fear.";
|
||||
Taste, Touch:
|
||||
"You wouldn't want to. Really.";
|
||||
default:
|
||||
"The creatures evade you, chittering.";
|
||||
],
|
||||
number 0, ! <-- used by the daemon
|
||||
each_turn [; StartDaemon(self); ],
|
||||
daemon [;
|
||||
if (real_location ~= Inner_Web) { ! location just has "thedark"
|
||||
self.number = 0;
|
||||
StopDaemon(self);
|
||||
rtrue; ! <-- ?
|
||||
}
|
||||
switch(++self.number) {
|
||||
1: "^The scuttling draws a little nearer,
|
||||
and your breathing grows load and hoarse.";
|
||||
2: "^The perspiration of terror runs off your brow.
|
||||
The creatures are almost here!";
|
||||
3: "^You feel a tickling at your extremities and kick outward,
|
||||
shaking something chitinous off.
|
||||
Their sound alone is a menacing rasp.";
|
||||
4: deadflag = 1; ! <-- You die!
|
||||
"^Suddenly there is a tiny pain, of a hypodermic-sharp
|
||||
fang at your calf.
|
||||
Almost at once your limbs go into spasm, your shoulders
|
||||
and knee-joints lock, your tongue swells...";
|
||||
}
|
||||
];
|
||||
|
||||
!==============================================================================!
|
||||
! As DM <20>§12 except: added the moss concealing the Ruby.
|
||||
!
|
||||
Room Corridor "Stooped Corridor"
|
||||
with name 'low' 'stooped' 'corridor',
|
||||
description
|
||||
"A low, square-cut corridor, running north to south,
|
||||
stooping over you.
|
||||
Patches of moss emit a faint green fluorescent glow,
|
||||
just enough that you can see your surroundings.",
|
||||
n_to Square_Chamber,
|
||||
s_to Stone_Door,
|
||||
has ;
|
||||
|
||||
Object Moss "mossy patches" Corridor
|
||||
with name 'moss' 'mossy' 'patches' 'green' 'fluorescent' 'glow' 'clumps',
|
||||
description [;
|
||||
if (Ruby in Undiscovered)
|
||||
"The moss grows in rough clumps, surprisingly thick in places.
|
||||
Is that a hint of red hidden among all the greenery?";
|
||||
"The moss, now somewhat raggy, grows in rough clumps.";
|
||||
],
|
||||
before [;
|
||||
Search:
|
||||
if (Ruby in Undiscovered) {
|
||||
move Ruby to location;
|
||||
"Something rolls from the moss onto the ground.";
|
||||
}
|
||||
],
|
||||
has pluralname scenery;
|
||||
|
||||
!==============================================================================!
|
||||
! As DM <20>§12. The key isn't actually defined in the DM.
|
||||
!
|
||||
Object Stone_Door "stone door"
|
||||
with name 'stone' 'door' 'big' 'massive' 'yellow',
|
||||
description "It's just a big stone door.",
|
||||
when_closed "The passage is barred by a massive door of yellow stone.",
|
||||
when_open "The massive yellow stone door is open.",
|
||||
door_to
|
||||
[; if (location == Corridor) return Shrine; return Corridor; ],
|
||||
door_dir
|
||||
[; if (location == Corridor) return s_to; return n_to; ],
|
||||
with_key Stone_Key,
|
||||
found_in Corridor Shrine,
|
||||
has door lockable locked openable static;
|
||||
|
||||
Object Stone_Key "huge iron key" Cavity
|
||||
with name 'huge' 'iron' 'key',
|
||||
description "It must be a pretty big door to need a key like this.";
|
||||
|
||||
!==============================================================================!
|
||||
! A Shrine room is implied at DM <20>§10, but not defined.
|
||||
!
|
||||
Room Shrine "Lofty Shrine"
|
||||
with name 'lofty' 'shrine' 'haze' 'hazy' 'craggy' 'walls' 'quartz',
|
||||
description
|
||||
"For an underground chamber, the Shrine is remarkably high,
|
||||
though its upper half is hazy and difficult to see clearly.
|
||||
The craggy walls are polished natural rock, in which tiny
|
||||
flecks of quartz catch the light of the flickering candle.",
|
||||
n_to Stone_Door;
|
||||
|
||||
!==============================================================================!
|
||||
! As DM <20>§14 except: added processing of objects placed on the altar.
|
||||
!
|
||||
Object Stone_Table "slab altar" Shrine
|
||||
with name 'stone' 'table' 'slab' 'altar' 'great',
|
||||
initial "A great stone slab of a table dominates the Shrine.",
|
||||
description
|
||||
"It's big enough to lie on, though in the circumstances
|
||||
that might prove to be a A Really Bad Idea.",
|
||||
after [;
|
||||
Enter:
|
||||
deadflag = 1; ! <-- You die!
|
||||
"With astonishing speed, the horror-struck priest plucks
|
||||
a bronze dagger from his tattered robe, and stabs you
|
||||
in your sacrilegious heart.";
|
||||
Receive:
|
||||
remove noun;
|
||||
switch (noun) {
|
||||
Stone_Key:
|
||||
move Honeycomb to player;
|
||||
"His eyes dimly agleam with gratitude, the priest takes
|
||||
the key and conceals it among his rags.
|
||||
Then, lifting the candle, he carefully detaches a large
|
||||
lump of the mottled wax, and gives it to you.";
|
||||
Honeycomb:
|
||||
move Honeycomb to player;
|
||||
"~For returning the key, that is yours to keep.~";
|
||||
}
|
||||
print "The priest takes ", (the) noun, " and conceals it
|
||||
among his rags.^";
|
||||
rtrue; ! <-- print nothing further
|
||||
],
|
||||
has enterable supporter static;
|
||||
|
||||
!==============================================================================!
|
||||
! Not in the DM as such, but added to provide light, and as a source for
|
||||
! the Honeycomb.
|
||||
!
|
||||
Object Candle "flickering candle" Stone_Table
|
||||
with name 'flickering' 'candle' 'flame',
|
||||
initial
|
||||
"A flickering candle at one end of the slab casts
|
||||
grotesque shadows on the walls.",
|
||||
description
|
||||
"The candle is little more than a crudely moulded lump of wax.
|
||||
Its texture is vaguely crystalline, with small fragments
|
||||
embedded within.",
|
||||
has static;
|
||||
|
||||
!==============================================================================!
|
||||
! As DM <20>§16 except: the priest deal in objects, not the dictionary.
|
||||
!
|
||||
Object Priest "mummified priest" Shrine
|
||||
with name 'mummified' 'priest' 'old' 'ancient' 'dessicated',
|
||||
initial
|
||||
"Behind the slab, a mummified priest stands waiting,
|
||||
barely alive at best, impossibly venerable.",
|
||||
description
|
||||
"He is dessicated and hangs together only by will-power.
|
||||
Though his first language is presumably local Mayan, you have
|
||||
the curious instinct that he will understand your speech.",
|
||||
life [;
|
||||
Answer:
|
||||
switch (noun) {
|
||||
'hello', 'hi', 'bye', 'goodbye', 'good-bye', 'cheerio',
|
||||
'thanks', 'thank', 'thankyou', 'you', 'cheers', 'ta':
|
||||
"Silently, carefully, the priest nods his head.";
|
||||
}
|
||||
"The priest coughs, and almost falls apart.";
|
||||
Ask:
|
||||
switch (second) {
|
||||
'king', 'tomb', 'shrine', 'temple', 'altar', 'slab':
|
||||
"~The King (life! propserity! happiness!) is buried
|
||||
deep under this Shrine, where you will never go.~";
|
||||
'silver', 'bangle', 'bracelet', 'ring',
|
||||
'blood', 'red', 'blood-red', 'ruby', 'stone', 'jewel',
|
||||
'pygmy', 'statuette', 'statue', 'mayan', 'snake', 'spirit':
|
||||
"~That is one of my people's sacred relics.~";
|
||||
'ancient', 'honeycomb', 'old', 'honey', 'comb', 'wax',
|
||||
'lump':
|
||||
"~That is the most sacred of all my people's relics.~";
|
||||
'huge', 'iron', 'key':
|
||||
if (parent(Stone_Key) == nothing)
|
||||
"~Now my people will be able to visit the Shrine.~";
|
||||
"~That has been lost for generations.
|
||||
My gratitude to anyone who returns it will be
|
||||
overwhelming.~";
|
||||
}
|
||||
"~You must find your own answer.~";
|
||||
Attack, Kiss:
|
||||
remove self;
|
||||
"The priest desiccates away into dust until nothing remains,
|
||||
not a breeze or a bone.";
|
||||
Give, Show:
|
||||
switch (noun) {
|
||||
Bangle, Ruby, Statuette:
|
||||
"~I would be grateful if you placed that before me.~";
|
||||
Honeycomb:
|
||||
"~For returning the key, that is yours to keep.~";
|
||||
Stone_Key:
|
||||
"~I would be profoundly grateful if you placed that
|
||||
before me.~";
|
||||
}
|
||||
"The priest is indifferent to earthly things.";
|
||||
Tell:
|
||||
"The priest has no interest in your sordid life.";
|
||||
ThrowAt:
|
||||
move noun to location;
|
||||
<<Attack self>>;
|
||||
],
|
||||
orders [;
|
||||
Go: "~I must not leave the Shrine.~";
|
||||
NotUnderstood:
|
||||
switch (noun) {
|
||||
'hello', 'hi', 'bye', 'goodbye', 'good-bye', 'cheerio',
|
||||
'thanks', 'thank', 'thankyou', 'you', 'cheers', 'ta':
|
||||
"Silently, carefully, the priest nods his head.";
|
||||
}
|
||||
"~You speak in riddles~";
|
||||
default:
|
||||
"~It is not your orders that I serve.~";
|
||||
],
|
||||
has animate;
|
||||
|
||||
!==============================================================================!
|
||||
! Every game needs to include the Grammar.
|
||||
!
|
||||
Include "Grammar";
|
||||
|
||||
!==============================================================================!
|
||||
! Added to enable you to "pick" the mushroom (as well as the usual "take",
|
||||
! "get", "pick up", etc). See DM <20>§26.
|
||||
!
|
||||
Extend "pick" * edible -> Take;
|
||||
|
||||
!==============================================================================!
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,994 @@
|
|||
Constant Story "RUINS";
|
||||
Constant Headline "^An Interactive Worked Example^
|
||||
Copyright (c) 1999 by Angela M. Horns.^";
|
||||
|
||||
! ---------------------------------------------------------------------------- !
|
||||
! This version recreated by Roger Firth in May 2001, using the simple
|
||||
! (albeit time-consuming) process of combining the various fragments
|
||||
! of "Ruins" quoted in Edition 4/1 of the Inform Designer's Manual.
|
||||
!
|
||||
! PLAYER
|
||||
! lamp,dictionary,map
|
||||
! GREAT PLAZA
|
||||
! | mushroom,packing-case,camera,newspaper,steps
|
||||
! |
|
||||
! |
|
||||
! SQUARE CHAMBER -------------------- WORMCAST
|
||||
! | inscriptions,sunlight,(key) eggsac
|
||||
! |
|
||||
! |
|
||||
! STOOPED CORRIDOR
|
||||
! | statuette,door
|
||||
! |
|
||||
! |
|
||||
! UPPER CANYON SHRINE
|
||||
! | ball / \ paintings,altar,mask,(priest)
|
||||
! | ---------- ----------
|
||||
! | / \
|
||||
! XIBALBÁ ANTECHAMBER
|
||||
! | stela | cage,skeletons,(warthog)
|
||||
! | |
|
||||
! | |
|
||||
! LOWER CANYON BURIAL SHAFT
|
||||
! | chasm honeycomb
|
||||
! |
|
||||
! |
|
||||
! PUMICE LEDGE
|
||||
! bone
|
||||
!
|
||||
! ---------------------------------------------------------------------------- !
|
||||
|
||||
Constant MAX_CARRIED = 7; ! Defined in DM4 §22
|
||||
Constant MAX_SCORE = 30; ! Defined in DM4 §22
|
||||
|
||||
Include "Parser";
|
||||
Include "VerbLib";
|
||||
|
||||
! ---------------------------------------------------------------------------- !
|
||||
! The TREASURE class definition.
|
||||
!
|
||||
! Defined in DM4 §5, modified in §23
|
||||
Class Treasure
|
||||
with before [;
|
||||
Take, Remove:
|
||||
if (self in packing_case)
|
||||
"Unpacking such a priceless artifact had best wait until
|
||||
the Carnegie Institution can do it.";
|
||||
if (self.photographed_in_situ == false)
|
||||
"This is the 1930s, not the bad old days. Taking an
|
||||
artifact without recording its context is simply looting.";
|
||||
Photograph:
|
||||
if (self has moved) "What, and fake the archaeological record?";
|
||||
if (self.photographed_in_situ) "Not again.";
|
||||
],
|
||||
after [;
|
||||
Insert:
|
||||
if (second == packing_case) {
|
||||
score = score + self.cultural_value;
|
||||
if (score == MAX_SCORE) {
|
||||
deadflag = 2;
|
||||
print_ret "As you carefully pack away ",
|
||||
(the) noun,
|
||||
" a red-tailed macaw flutters down from the
|
||||
tree-tops, feathers heavy in the recent rain,
|
||||
the sound of its beating wings almost
|
||||
deafening, stone falling against stone...
|
||||
As the skies clear, a crescent moon rises
|
||||
above a peaceful jungle. It is the end of
|
||||
March, 1938, and it is time to go home.";
|
||||
}
|
||||
"Safely packed away.";
|
||||
}
|
||||
Photograph:
|
||||
self.photographed_in_situ = true;
|
||||
],
|
||||
cultural_value 5,
|
||||
photographed_in_situ false;
|
||||
|
||||
! ---------------------------------------------------------------------------- !
|
||||
! The game beings in the GRAND PLAZA.
|
||||
!
|
||||
! Defined in DM4 §4, modified in §8, §9 and §23
|
||||
Object Forest "~Great Plaza~"
|
||||
with description
|
||||
"Or so your notes call this low escarpment of limestone, but the
|
||||
rainforest has claimed it back. Dark olive trees crowd in on all
|
||||
sides, the air steams with the mist of a warm recent rain, midges
|
||||
hang in the air. ~Structure 10~ is a shambles of masonry which
|
||||
might once have been a burial pyramid, and little survives
|
||||
except stone-cut steps leading down into darkness below.",
|
||||
d_to steps,
|
||||
in_to steps,
|
||||
u_to
|
||||
"The trees are spiny and you'd cut your hands to ribbons
|
||||
trying to climb them.",
|
||||
cant_go
|
||||
"The rainforest is dense, and you haven't hacked through it for days
|
||||
to abandon your discovery now. Really, you need a good few
|
||||
artifacts to take back to civilization before you can justify
|
||||
giving up the expedition.",
|
||||
before [; Listen: "Howler monkeys, bats, parrots, macaw."; ],
|
||||
has light;
|
||||
|
||||
! Defined in DM4 §4, modified in Exercise 1 and §23
|
||||
Object -> mushroom "speckled mushroom"
|
||||
with name 'speckled' 'mushroom' 'fungus' 'toadstool',
|
||||
initial
|
||||
"A speckled mushroom grows out of the sodden earth, on
|
||||
a long stalk.",
|
||||
description
|
||||
"The mushroom is capped with blotches, and you aren't
|
||||
at all sure it's not a toadstool.",
|
||||
after [;
|
||||
Take:
|
||||
if (self.mushroom_picked)
|
||||
"You pick up the slowly-disintegrating mushroom.";
|
||||
self.mushroom_picked = true;
|
||||
"You pick the mushroom, neatly cleaving its thin stalk.";
|
||||
Drop:
|
||||
"The mushroom drops to the ground, battered slightly.";
|
||||
Eat:
|
||||
steps.rubble_filled = false;
|
||||
"You nibble at one corner, unable to trace the source of an
|
||||
acrid taste, distracted by the flight of a macaw overhead
|
||||
which seems to burst out of the sun, the sound of the beating
|
||||
of its wings almost deafening, stone falling against stone.";
|
||||
],
|
||||
mushroom_picked false,
|
||||
has edible;
|
||||
|
||||
! Defined in DM4 §12
|
||||
Object -> packing_case "packing case"
|
||||
with name 'packing' 'case' 'box' 'strongbox',
|
||||
initial
|
||||
"Your packing case rests here, ready to hold any important
|
||||
cultural finds you might make, for shipping back to civilisation.",
|
||||
before [;
|
||||
Take, Remove, PushDir:
|
||||
"The case is too heavy to bother moving, as long as your
|
||||
expedition is still incomplete.";
|
||||
],
|
||||
has static container open openable;
|
||||
|
||||
! Defined in DM4 §6
|
||||
Object -> -> camera "wet-plate camera"
|
||||
with name 'wet-plate' 'plate' 'wet' 'camera',
|
||||
description
|
||||
"A cumbersome, sturdy, stubborn wooden-framed wet plate
|
||||
model: like all archaeologists, you have a love-hate
|
||||
relationship with your camera.";
|
||||
|
||||
! Defined in DM4 §23
|
||||
Object -> -> newspaper "month-old newspaper"
|
||||
with name 'times' 'newspaper' 'paper' 'month-old' 'old',
|
||||
description
|
||||
"~The Times~ for 26 February, 1938, at once damp and brittle
|
||||
after a month's exposure to the climate, which is much the way you
|
||||
feel yourself. Perhaps there is fog in London.
|
||||
Perhaps there are bombs.";
|
||||
|
||||
! Defined in DM4 §4, modified in §5 and §23
|
||||
Object -> steps "stone-cut steps"
|
||||
with name 'steps' 'stone' 'stairs' 'stone-cut' 'pyramid' 'burial'
|
||||
'structure' 'ten' '10',
|
||||
description [;
|
||||
if (self.rubble_filled)
|
||||
"Rubble blocks the way after only a few steps.";
|
||||
print "The cracked and worn steps descend into a dim
|
||||
chamber. Yours might ";
|
||||
if (Square_Chamber hasnt visited)
|
||||
print "be the first feet to tread";
|
||||
else
|
||||
print "have been the first feet to have trodden";
|
||||
" them for five hundred years. On the top step is
|
||||
inscribed the glyph Q1.";
|
||||
],
|
||||
door_to [;
|
||||
if (self.rubble_filled)
|
||||
"Rubble blocks the way after only a few steps.";
|
||||
return Square_Chamber;
|
||||
],
|
||||
door_dir d_to,
|
||||
rubble_filled true,
|
||||
has scenery door open;
|
||||
|
||||
! ---------------------------------------------------------------------------- !
|
||||
! The SQUARE CHAMBER.
|
||||
!
|
||||
! Defined in DM4 Exercise 2, modified in $8 and $9
|
||||
Object Square_Chamber "Square Chamber"
|
||||
with name 'lintelled' 'lintel' 'lintels' 'east' 'south' 'doorways',
|
||||
description
|
||||
"A sunken, gloomy stone chamber, ten yards across. A shaft of
|
||||
sunlight cuts in from the steps above, giving the chamber a
|
||||
diffuse light, but in the shadows low lintelled doorways to
|
||||
east and south lead into the deeper darkness of the Temple.",
|
||||
u_to Forest,
|
||||
e_to Wormcast,
|
||||
s_to Corridor,
|
||||
before [;
|
||||
Insert:
|
||||
if (noun == eggsac && second == sunlight) {
|
||||
remove eggsac;
|
||||
move stone_key to self;
|
||||
"You drop the eggsac into the glare of the shaft of
|
||||
sunlight. It bubbles obscenely, distends and then bursts
|
||||
into a hundred tiny insects which run in all directions
|
||||
into the darkness. Only spatters of slime and a curious
|
||||
yellow-stone key remain on the chamber floor.";
|
||||
}
|
||||
],
|
||||
has light;
|
||||
|
||||
! Defined in DM4 §8
|
||||
Object -> "carved inscriptions"
|
||||
with name 'carved' 'inscriptions' 'carvings' 'marks' 'markings' 'symbols'
|
||||
'moving' 'scuttling' 'crowd' 'of',
|
||||
initial
|
||||
"Carved inscriptions crowd the walls, floor and ceiling.",
|
||||
description
|
||||
"Each time you look at the carvings closely, they seem to be still.
|
||||
But you have the uneasy feeling when you look away that they're
|
||||
scuttling, moving about.
|
||||
Two glyphs are prominent: Arrow and Circle.",
|
||||
has static pluralname;
|
||||
|
||||
! Defined in DM4 §8
|
||||
Object -> sunlight "shaft of sunlight"
|
||||
with name 'shaft' 'of' 'sunlight' 'sun' 'light' 'beam' 'sunbeam'
|
||||
'ray' 'rays' 'sun^s' 'sunlit' 'air' 'motes' 'dust',
|
||||
description
|
||||
"Motes of dust glimmer in the shaft of sunlit air, so that it seems
|
||||
almost solid.",
|
||||
before [;
|
||||
Examine, Search:
|
||||
;
|
||||
default:
|
||||
"It's only an insubstantial shaft of sunlight.";
|
||||
],
|
||||
has scenery;
|
||||
|
||||
! ---------------------------------------------------------------------------- !
|
||||
! The STOOPED CORRIDOR.
|
||||
!
|
||||
! Defined in DM4 §13
|
||||
Object Corridor "Stooped Corridor"
|
||||
with description
|
||||
"A low, square-cut corridor, running north to south,
|
||||
stooping you over.",
|
||||
n_to Square_Chamber,
|
||||
s_to StoneDoor;
|
||||
|
||||
! Defined in DM4 §5
|
||||
Treasure -> statuette "pygmy statuette"
|
||||
with name 'snake' 'mayan' 'pygmy' 'spirit' 'precious' 'statuette',
|
||||
initial
|
||||
"A precious Mayan statuette rests here!",
|
||||
description
|
||||
"A menacing, almost cartoon-like statuette of a pygmy spirit
|
||||
with a snake around its neck.";
|
||||
|
||||
! Defined in DM4 §13
|
||||
Object -> StoneDoor "stone door"
|
||||
with name 'door' 'massive' 'big' 'stone' 'yellow',
|
||||
description
|
||||
"It's just a big stone door.",
|
||||
when_closed
|
||||
"The passage is barred by a massive door of yellow stone.",
|
||||
when_open
|
||||
"The great yellow stone door is open.",
|
||||
door_to [; if (self in Corridor) return Shrine; return Corridor; ],
|
||||
door_dir [; if (self in Shrine) return n_to; return s_to; ],
|
||||
with_key stone_key,
|
||||
found_in Corridor Shrine,
|
||||
has static door openable lockable locked;
|
||||
|
||||
! ---------------------------------------------------------------------------- !
|
||||
! The SHRINE.
|
||||
!
|
||||
! Defined in DM4 §23
|
||||
Object Shrine "Shrine"
|
||||
with description
|
||||
"This magnificent Shrine shows signs of being hollowed out from
|
||||
already-existing limestone caves, especially in the western of the
|
||||
two long eaves to the south.",
|
||||
n_to StoneDoor,
|
||||
se_to Antechamber,
|
||||
sw_to
|
||||
"The eaves taper out into a crevice which would wind further if it
|
||||
weren't jammed tight with icicles. The glyph of the Crescent is
|
||||
not quite obscured by ice.";
|
||||
|
||||
! Defined in DM4 §23
|
||||
Object -> paintings "paintings"
|
||||
with name 'painting' 'paintings' 'lord' 'captive',
|
||||
initial
|
||||
"Vividly busy paintings, of the armoured Lord trampling on a
|
||||
captive, are almost too bright to look at, the graffiti of an
|
||||
organised mob.",
|
||||
description
|
||||
"The flesh on the bodies is blood-red. The markers of the Long Count
|
||||
date the event to 10 baktun 4 katun 0 tun 0 uinal 0 kin, the sort
|
||||
of anniversary when one Lord would finally decapitate a captured
|
||||
rival who had been ritually tortured over a period of some years,
|
||||
in the Balkanised insanity of the Maya city states.",
|
||||
has static;
|
||||
|
||||
! Defined in DM4 §12 and §15
|
||||
Object -> stone_table "slab altar"
|
||||
with name 'stone' 'table' 'slab' 'altar' 'great',
|
||||
initial
|
||||
"A great stone slab of a table, or altar, dominates the Shrine.",
|
||||
has enterable supporter static;
|
||||
|
||||
! Defined in DM4 §11
|
||||
Treasure -> -> mask "jade mosaic face-mask"
|
||||
with name 'jade' 'mosaic' 'face-mask' 'mask' 'face',
|
||||
initial
|
||||
"Resting on the altar is a jade mosaic face-mask.",
|
||||
description
|
||||
"How exquisite it would look in the Museum.",
|
||||
after [;
|
||||
Wear:
|
||||
move priest to Shrine;
|
||||
if (location == Shrine)
|
||||
"Looking through the obsidian eyeslits of the mosaic mask,
|
||||
a ghostly presence reveals itself: a mummified calendrical
|
||||
priest, attending your word.";
|
||||
Disrobe:
|
||||
remove priest;
|
||||
],
|
||||
cultural_value 10,
|
||||
has clothing;
|
||||
|
||||
! ---------------------------------------------------------------------------- !
|
||||
! The UPPER/NORTH CANYON.
|
||||
!
|
||||
! Defined in DM4 §23
|
||||
Object Canyon_N "Upper End of Canyon"
|
||||
with description
|
||||
"The higher, broader northern end of the canyon rises only to an
|
||||
uneven wall of volcanic karst.",
|
||||
s_to Junction,
|
||||
d_to Junction,
|
||||
has light;
|
||||
|
||||
! Defined in DM4 §15, modified in Exercise 24 and §23
|
||||
Object -> huge_ball "huge pumice-stone ball"
|
||||
with name 'huge' 'pumice' 'pumice-stone' 'stone' 'ball',
|
||||
initial
|
||||
"A huge pumice-stone ball rests here, eight feet wide.",
|
||||
description
|
||||
"A good eight feet across, though fairly lightweight.",
|
||||
before [;
|
||||
PushDir:
|
||||
if (location == Junction && second == ne_obj)
|
||||
"The Shrine entrance is far less than eight feet wide.";
|
||||
AllowPushDir();
|
||||
rtrue;
|
||||
Pull, Push, Turn:
|
||||
"It wouldn't be so very hard to get rolling.";
|
||||
Take, Remove:
|
||||
"There's a lot of stone in an eight-foot sphere.";
|
||||
],
|
||||
after [;
|
||||
PushDir:
|
||||
if (second == n_obj) "You strain to push the ball uphill.";
|
||||
if (second == u_obj) <<PushDir self n_obj>>;
|
||||
if (second == s_obj) "The ball is hard to stop once underway.";
|
||||
if (second == d_obj) <<PushDir self s_obj>>;
|
||||
],
|
||||
has static;
|
||||
|
||||
! ---------------------------------------------------------------------------- !
|
||||
! The XIBALBÁ/JUNCTION.
|
||||
|
||||
! Defined in DM4 §23
|
||||
Object Junction "Xibalb@'a"
|
||||
with description
|
||||
"Fifty metres beneath rainforest, and the sound of water is
|
||||
everywhere: these deep, eroded limestone caves extend like
|
||||
taproots. A slither northeast by a broad collapsed column of
|
||||
ice-covered rock leads back to the Shrine, while a kind of canyon
|
||||
floor extends uphill to the north and downwards to south,
|
||||
pale white like shark's teeth in the diffused light from the
|
||||
sodium lamp above.",
|
||||
ne_to Shrine,
|
||||
n_to Canyon_N,
|
||||
u_to Canyon_N,
|
||||
s_to Canyon_S,
|
||||
d_to Canyon_S,
|
||||
has light;
|
||||
|
||||
! Defined in DM4 §23
|
||||
Treasure -> stela "stela"
|
||||
with name 'stela' 'boundary' 'stone' 'marker',
|
||||
initial
|
||||
"A modest-sized stela, or boundary stone, rests on a ledge
|
||||
at head height.",
|
||||
description
|
||||
"The carvings appear to warn that the boundary of Xibalb@'a,
|
||||
Place of Fright, is near. The Bird glyph is prominent.";
|
||||
|
||||
! ---------------------------------------------------------------------------- !
|
||||
! The LOWER/SOUTH CANYON.
|
||||
!
|
||||
! Defined in DM4 §23
|
||||
Object Canyon_S "Lower End of Canyon"
|
||||
with description
|
||||
"At the lower, and narrower, southern end, the canyon stops dead at
|
||||
a chasm of vertiginous blackness. Nothing can be seen or heard
|
||||
from below.",
|
||||
n_to Junction,
|
||||
u_to Junction,
|
||||
s_to "Into the chasm?",
|
||||
d_to nothing,
|
||||
has light;
|
||||
|
||||
! Defined in DM4 §12, modified in §21 and §23
|
||||
Object -> chasm "horrifying chasm"
|
||||
with name 'blackness' 'chasm' 'pit' 'horrifying' 'bottomless',
|
||||
before [;
|
||||
Enter:
|
||||
deadflag = 3;
|
||||
"You plummet through the silent void of darkness, cracking
|
||||
your skull against an outcrop of rock. Amidst the pain and
|
||||
redness, you dimly make out the God with the Owl-Headdress...";
|
||||
JumpOver:
|
||||
"It's far too wide.";
|
||||
],
|
||||
after [;
|
||||
Receive:
|
||||
remove noun;
|
||||
print_ret (The) noun,
|
||||
" tumbles silently into the darkness of the chasm.";
|
||||
Search:
|
||||
"The chasm is deep and murky.";
|
||||
],
|
||||
react_before [;
|
||||
Jump:
|
||||
<<Enter self>>;
|
||||
Go:
|
||||
if (noun == d_obj) <<Enter self>>;
|
||||
],
|
||||
each_turn [;
|
||||
if (huge_ball in parent(self)) {
|
||||
remove huge_ball;
|
||||
Canyon_S.s_to = On_Ball;
|
||||
Canyon_S.description =
|
||||
"The southern end of the canyon now continues onto the
|
||||
pumice-stone ball, wedged into the chasm.";
|
||||
"^The pumice-stone ball rolls out of control down the last few
|
||||
feet of the canyon before shuddering into the jaws of the
|
||||
chasm, bouncing back a little and catching you a blow on the
|
||||
side of the forehead. You slump forward, bleeding, and...
|
||||
the pumice-stone shrinks, or else your hand grows, because you
|
||||
seem now to be holding it, staring at Alligator, son of
|
||||
seven-Macaw, across the ball-court of the Plaza, the heads of
|
||||
his last opponents impaled on spikes, a congregation baying
|
||||
for your blood, and there is nothing to do but to throw anyway,
|
||||
and... but this is all nonsense,
|
||||
and you have a splitting headache.";
|
||||
}
|
||||
],
|
||||
has scenery open container;
|
||||
|
||||
! ---------------------------------------------------------------------------- !
|
||||
! The PUMICE LEDGE.
|
||||
!
|
||||
! Defined in DM4 §23
|
||||
Object On_Ball "Pumice-Stone Ledge"
|
||||
with description
|
||||
"An impromptu ledge formed by the pumice-stone ball, wedged into
|
||||
place in the chasm. The canyon nevertheless ends here.",
|
||||
n_to Canyon_S,
|
||||
d_to Canyon_S,
|
||||
u_to Canyon_S,
|
||||
has light;
|
||||
|
||||
! Defined in DM4 §23
|
||||
Treasure -> "incised bone"
|
||||
with name 'incised' 'carved' 'bone',
|
||||
initial
|
||||
"Of all the sacrificial goods thrown into the chasm, perhaps
|
||||
nothing will be reclaimed: nothing but an incised bone, lighter
|
||||
than it looks, which projects from a pocket of wet silt in the
|
||||
canyon wall.",
|
||||
description
|
||||
"A hand holding a brush pen appears from the jaws of Itzamn@'a,
|
||||
inventor of writing, in his serpent form.";
|
||||
|
||||
! ---------------------------------------------------------------------------- !
|
||||
! The ANTECHAMBER.
|
||||
!
|
||||
! Defined in DM4 §23
|
||||
Object Antechamber "Antechamber"
|
||||
with description
|
||||
"The southeastern eaves of the Shrine make a curious antechamber.",
|
||||
nw_to Shrine;
|
||||
|
||||
! Defined in DM4 Exercise 22, modified in Exercise 55
|
||||
Object -> cage "iron cage"
|
||||
with name 'iron' 'cage' 'bars' 'barred' 'frame' 'glyphs',
|
||||
description
|
||||
"The glyphs read: Bird Arrow Warthog.",
|
||||
inside_description [;
|
||||
if (self.floor_open)
|
||||
"From the floor of the cage, an open earthen pit cuts
|
||||
down into the burial chamber.";
|
||||
"The bars of the cage surround you.";
|
||||
],
|
||||
when_open
|
||||
"An iron-barred cage, large enough to stoop over inside, looms
|
||||
ominously here, its door open. There are some glyphs on the
|
||||
frame.",
|
||||
when_closed
|
||||
"The iron cage is closed.",
|
||||
after [;
|
||||
Enter:
|
||||
print "The skeletons inhabiting the cage come alive, locking
|
||||
bony hands about you, crushing and pummelling. You lose
|
||||
consciousness, and when you recover something grotesque
|
||||
and impossible has occurred...^";
|
||||
move warthog to Antechamber;
|
||||
remove skeletons;
|
||||
give self ~open;
|
||||
give warthog light;
|
||||
self.after = 0;
|
||||
ChangePlayer(warthog, 1);
|
||||
<<Look>>;
|
||||
],
|
||||
react_before [;
|
||||
Go:
|
||||
if (noun == d_obj && self.floor_open) {
|
||||
PlayerTo(Burial_Shaft);
|
||||
rtrue;
|
||||
}
|
||||
],
|
||||
floor_open false,
|
||||
has enterable transparent container openable open static;
|
||||
|
||||
! Defined in Exercise 55
|
||||
Object -> -> skeletons "skeletons"
|
||||
with name 'skeletons' 'skeleton' 'bone' 'skull' 'bones' 'skulls',
|
||||
article "deranged",
|
||||
has pluralname static;
|
||||
|
||||
! ---------------------------------------------------------------------------- !
|
||||
! The BURIAL SHAFT.
|
||||
!
|
||||
! Defined in Exercise 55
|
||||
Object Burial_Shaft "Burial Shaft"
|
||||
with description
|
||||
"In your eventual field notes, this will read:
|
||||
~A corbel-vaulted crypt with an impacted earthen plug as seal
|
||||
above, and painted figures conjecturally representing the Nine
|
||||
Lords of the Night. Dispersed bones appear to be those of one
|
||||
elderly man and several child sacrifices, while other funerary
|
||||
remains include jaguar paws.~ (In field notes, it is essential
|
||||
not to give any sense of when you are scared witless.)",
|
||||
n_to Wormcast,
|
||||
u_to [;
|
||||
cage.floor_open = true;
|
||||
self.u_to = self.opened_u_to;
|
||||
move selfobj to self;
|
||||
print "Making a mighty warthog-leap, you butt at the earthen-plug
|
||||
seal above the chamber, collapsing your world in ashes and
|
||||
earth. Something lifeless and terribly heavy falls on top of
|
||||
you: you lose consciousness, and when you recover, something
|
||||
impossible and grotesque has happened...^";
|
||||
ChangePlayer(selfobj);
|
||||
give warthog ~light;
|
||||
<<Look>>;
|
||||
],
|
||||
cant_go
|
||||
"The architects of this chamber were less than generous in
|
||||
providing exits. Some warthog seems to have burrowed in from the
|
||||
north, though.",
|
||||
before [; Jump: <<Go u_obj>>; ],
|
||||
opened_u_to [; PlayerTo(cage); rtrue; ],
|
||||
has light;
|
||||
|
||||
! Defined in DM4 §5
|
||||
Treasure -> honeycomb "ancient honeycomb"
|
||||
with name 'ancient' 'old' 'honey' 'honeycomb',
|
||||
article "an",
|
||||
initial
|
||||
"An exquisitely preserved, ancient honeycomb rests here!",
|
||||
description
|
||||
"Perhaps some kind of funerary votive offering.",
|
||||
after [;
|
||||
Eat:
|
||||
"Perhaps the most expensive meal of your life. The honey tastes
|
||||
odd, perhaps because it was used to store the entrails of the
|
||||
Lord buried here, but still like honey.";
|
||||
],
|
||||
has edible;
|
||||
|
||||
! ---------------------------------------------------------------------------- !
|
||||
! The WORMCAST.
|
||||
!
|
||||
! Defined in DM4 Exercises 7 and 8, modified in Exercise 54
|
||||
Object Wormcast "Wormcast"
|
||||
with description
|
||||
"A disturbed place of hollows carved like a spider's web, strands of
|
||||
empty space hanging in stone. The only burrows wide enough to crawl
|
||||
through begin by running northeast, south and upwards.",
|
||||
w_to Square_Chamber,
|
||||
s_to [;
|
||||
print "The wormcast becomes slippery around you, as though your
|
||||
body-heat is melting long hardened resins, and you shut your
|
||||
eyes tightly as you burrow through darkness.^";
|
||||
if (eggsac in player) return Square_Chamber;
|
||||
return random(Square_Chamber, Corridor, Forest);
|
||||
],
|
||||
ne_to [; return self.s_to(); ],
|
||||
u_to [; return self.s_to(); ],
|
||||
cant_go [;
|
||||
if (player ~= warthog)
|
||||
"Though you begin to feel certain that something lies behind
|
||||
and through the wormcast, this way must be an animal-run at
|
||||
best: it's far too narrow for your armchair-archaeologist's
|
||||
paunch.";
|
||||
print "The wormcast becomes slippery around your warthog body, and
|
||||
you squeal involuntarily as you burrow through the darkness,
|
||||
falling finally southwards to...^";
|
||||
PlayerTo(Burial_Shaft);
|
||||
rtrue;
|
||||
],
|
||||
after [;
|
||||
Drop:
|
||||
move noun to Square_Chamber;
|
||||
print_ret (The) noun,
|
||||
" slips through one of the burrows and is quickly
|
||||
lost from sight.";
|
||||
],
|
||||
has light;
|
||||
|
||||
! Defined in DM4 §23
|
||||
Object -> eggsac "glistening white eggsac",
|
||||
with name 'egg' 'sac' 'eggs' 'eggsac',
|
||||
initial
|
||||
"A glistening white eggsac, like a clump of frogspawn the size of a
|
||||
beach ball, has adhered itself to something in a crevice in one
|
||||
wall.",
|
||||
after [; Take: "Oh my."; ],
|
||||
react_before [;
|
||||
Go:
|
||||
if (location == Square_Chamber && noun == u_obj) {
|
||||
deadflag = true;
|
||||
"The moment that natural light falls upon the eggsac, it
|
||||
bubbles obscenely and distends. Before you can throw it
|
||||
away, it bursts into a hundred tiny, birth-hungry
|
||||
insects...";
|
||||
}
|
||||
];
|
||||
|
||||
! ---------------------------------------------------------------------------- !
|
||||
! These objects are moved into place as the game proceeds.
|
||||
!
|
||||
! Defined in DM4 §14, modified in §23
|
||||
Object sodium_lamp "sodium lamp"
|
||||
with name 'sodium' 'lamp' 'heavy',
|
||||
describe [;
|
||||
if (self has on)
|
||||
"^The sodium lamp squats on the ground, burning away.";
|
||||
"^The sodium lamp squats heavily on the ground.";
|
||||
],
|
||||
before [;
|
||||
Examine:
|
||||
print "It is a heavy-duty archaeologist's lamp, ";
|
||||
if (self hasnt on) "currently off.";
|
||||
if (self.battery_power < 10) "glowing a dim yellow.";
|
||||
"blazing with brilliant yellow light.";
|
||||
Burn:
|
||||
<<SwitchOn self>>;
|
||||
SwitchOn:
|
||||
if (self.battery_power <= 0)
|
||||
"Unfortunately, the battery seems to be dead.";
|
||||
if (parent(self) hasnt supporter && self notin location)
|
||||
"The lamp must be securely placed before being lit.";
|
||||
Take, Remove:
|
||||
if (self has on)
|
||||
"The bulb's too delicate and the metal handle's too hot
|
||||
to lift the lamp while it's switched on.";
|
||||
PushDir:
|
||||
if (location == Shrine && second == sw_obj)
|
||||
"The nearest you can do is to push the sodium lamp to the
|
||||
very lip of the Shrine, where the cave floor falls away.";
|
||||
AllowPushDir();
|
||||
rtrue;
|
||||
],
|
||||
after [;
|
||||
SwitchOn:
|
||||
give self light;
|
||||
SwitchOff:
|
||||
give self ~light;
|
||||
],
|
||||
daemon [;
|
||||
if (self hasnt on) return;
|
||||
if (--self.battery_power == 0) give self ~light ~on;
|
||||
if (self in location) {
|
||||
switch (self.battery_power) {
|
||||
10: "^The sodium lamp is getting dimmer!";
|
||||
5: "^The sodium lamp can't last much longer.";
|
||||
0: "^The sodium lamp fades and suddenly dies.";
|
||||
}
|
||||
}
|
||||
],
|
||||
battery_power 100,
|
||||
has switchable;
|
||||
|
||||
! Defined in DM4 §16
|
||||
Object dictionary "Waldeck's Mayan dictionary"
|
||||
with name 'dictionary' 'local' 'guide' 'book' 'mayan' 'waldeck'
|
||||
'waldeck^s',
|
||||
description
|
||||
"Compiled from the unreliable lithographs of the legendary raconteur
|
||||
and explorer ~Count~ Jean Frederic Maximilien Waldeck
|
||||
(1766??-1875), this guide contains what little is known of the
|
||||
glyphs used in the local ancient dialect.",
|
||||
before [ w1 w2 glyph;
|
||||
Consult:
|
||||
wn = consult_from;
|
||||
w1 = NextWord(); ! First word of subject
|
||||
w2 = NextWord(); ! Second word (if any) of subject
|
||||
if (consult_words==1 && w1~='glyph' or 'glyphs') glyph = w1;
|
||||
else if (consult_words==2 && w1=='glyph') glyph = w2;
|
||||
else if (consult_words==2 && w2=='glyph') glyph = w1;
|
||||
else "Try ~look up <name of glyph> in book~.";
|
||||
switch (glyph) {
|
||||
'q1': "(This is one glyph you have memorised!)^^
|
||||
Q1: ~sacred site~.";
|
||||
'crescent': "Crescent: believed pronounced ~xibalba~,
|
||||
though its meaning is unknown.";
|
||||
'arrow': "Arrow: ~journey; becoming~.";
|
||||
'skull': "Skull: ~death, doom; fate (not nec. bad)~.";
|
||||
'circle': "Circle: ~the Sun; also life, lifetime~.";
|
||||
'jaguar': "Jaguar: ~lord~.";
|
||||
'monkey': "Monkey: ~priest?~.";
|
||||
'bird': if (self.correct) "Bird: ~dead as a stone~.";
|
||||
"Bird: ~rich, affluent?~.";
|
||||
default: "That glyph is so far unrecorded.";
|
||||
}
|
||||
],
|
||||
correct false,
|
||||
has proper;
|
||||
|
||||
! Defined in DM4 §23
|
||||
Object map "sketch-map of Quintana Roo"
|
||||
with name 'map' 'sketch' 'sketch-map' 'quintana' 'roo',
|
||||
description
|
||||
"This map marks little more than the creek which brought you
|
||||
here, off the south-east edge of Mexico and into deepest
|
||||
rainforest, broken only by this raised plateau.";
|
||||
|
||||
! Defined in DM4 §23
|
||||
Object stone_key "stone key"
|
||||
with name 'stone' 'key';
|
||||
|
||||
! Defined in DM4 §17, modified in §18 and §23
|
||||
Object priest "mummified priest"
|
||||
with name 'mummified' 'priest',
|
||||
initial
|
||||
"Behind the slab, a mummified priest stands waiting,
|
||||
barely alive at best, impossibly venerable.",
|
||||
description
|
||||
"He is desiccated and hangs together only by will-power. Though his
|
||||
first language is presumably local Mayan, you have the curious
|
||||
instinct that he will understand your speech.",
|
||||
life [;
|
||||
Answer:
|
||||
"The priest coughs, and almost falls apart.";
|
||||
Ask: switch (second) {
|
||||
'dictionary', 'book':
|
||||
if (dictionary.correct == false)
|
||||
"~The ~bird~ glyph... very funny.~";
|
||||
"~A dictionary? Really?~";
|
||||
'glyph', 'glyphs', 'mayan', 'dialect':
|
||||
"~In our culture, the Priests are ever literate.~";
|
||||
'lord', 'tomb', 'shrine', 'temple':
|
||||
"~This is a private matter.~";
|
||||
'paintings':
|
||||
"The calendrical priest frowns. ~10 baktun, 4 katun,
|
||||
that makes 1,468,800 days since the beginning of time:
|
||||
in your calendar 19 January 909.~";
|
||||
'ruins':
|
||||
"~The ruins will ever defeat thieves. In the underworld,
|
||||
looters are tortured throughout eternity.~ A pause.
|
||||
~As are archaeologists.~";
|
||||
'web', 'wormcast':
|
||||
"~No man can pass the Wormcast.~";
|
||||
'xibalba':
|
||||
if (Shrine.sw_to == Junction)
|
||||
"The priest shakes his bony finger.";
|
||||
Shrine.sw_to = Junction;
|
||||
"The priest extends one bony finger southwest toward the
|
||||
icicles, which vanish like frost as he speaks. ~Xibalb@'a,
|
||||
the Underworld.~";
|
||||
}
|
||||
"~You must find your own answer.~";
|
||||
Tell:
|
||||
"The priest has no interest in your sordid life.";
|
||||
Attack, Kiss:
|
||||
remove self;
|
||||
"The priest desiccates away into dust until nothing remains,
|
||||
not a breeze nor a bone.";
|
||||
ThrowAt:
|
||||
move noun to location; <<Attack self>>;
|
||||
Show, Give:
|
||||
if (noun == dictionary && dictionary.correct == false) {
|
||||
dictionary.correct = true;
|
||||
"The priest reads a little of the book, laughing in a
|
||||
hollow, whispering way. Unable to restrain his mirth,
|
||||
he scratches in a correction somewhere before returning
|
||||
the book.";
|
||||
}
|
||||
if (noun == newspaper)
|
||||
"He looks at the date. ~12 baktun 16 katun 4 tun 1 uinal
|
||||
12 kin~, he declares before browsing the front page.
|
||||
~Ah. Progress, I see.~";
|
||||
"The priest is not interested in earthly things.";
|
||||
],
|
||||
orders [;
|
||||
Go:
|
||||
"~I must not leave the Shrine.~";
|
||||
NotUnderstood:
|
||||
"~You speak in riddles.~";
|
||||
default:
|
||||
"~It is not your orders I serve.~";
|
||||
],
|
||||
has animate;
|
||||
|
||||
! Defined in DM4 Exercise 53
|
||||
Object warthog "Warthog"
|
||||
with name 'wart' 'hog' 'warthog',
|
||||
initial
|
||||
"A warthog snuffles and grunts about in the ashes.",
|
||||
description
|
||||
"Muddy and grunting.",
|
||||
orders [;
|
||||
Go, Look, Examine, Smell, Taste, Touch, Search,Jump, Enter:
|
||||
rfalse;
|
||||
Eat:
|
||||
"You haven't the knack of snuffling up to food yet.";
|
||||
default:
|
||||
"Warthogs can't do anything so involved. If it weren't for the
|
||||
nocturnal eyesight and the lost weight, they'd be worse off
|
||||
all round than people.";
|
||||
],
|
||||
has animate proper;
|
||||
|
||||
! Defined in DM4 §8
|
||||
Object low_mist "low mist"
|
||||
with name 'low' 'swirling' 'mist',
|
||||
description "The mist has an aroma reminiscent of tortilla.",
|
||||
before [;
|
||||
Examine, Search:
|
||||
;
|
||||
Smell:
|
||||
<<Examine self>>;
|
||||
default:
|
||||
"The mist is too insubstantial.";
|
||||
],
|
||||
react_before [; Smell: if (noun == nothing) <<Smell self>>; ],
|
||||
found_in Square_Chamber Forest,
|
||||
has scenery;
|
||||
|
||||
! Defined in DM4 Exercise 46
|
||||
Object tiny_claws "sound of tiny claws" thedark
|
||||
with name 'tiny' 'claws' 'sound' 'of' 'scuttling' 'scuttle' 'things'
|
||||
'creatures' 'monsters' 'insects',
|
||||
article "the",
|
||||
initial
|
||||
"Somewhere, tiny claws are scuttling.",
|
||||
before [;
|
||||
Listen:
|
||||
"How intelligent they sound, for mere insects.";
|
||||
Touch, Taste:
|
||||
"You wouldn't want to. Really.";
|
||||
Smell:
|
||||
"You can only smell your own fear.";
|
||||
Attack:
|
||||
"They easily evade your flailing about.";
|
||||
default:
|
||||
"The creatures evade you, chittering.";
|
||||
],
|
||||
each_turn [; StartDaemon(self); ],
|
||||
daemon [;
|
||||
if (location ~= thedark) {
|
||||
self.turns_active = 0;
|
||||
StopDaemon(self);
|
||||
rtrue;
|
||||
}
|
||||
switch (++(self.turns_active)) {
|
||||
1: "^The scuttling draws a little nearer, and your breathing
|
||||
grows loud and hoarse.";
|
||||
2: "^The perspiration of terror runs off your brow. The
|
||||
creatures are almost here!";
|
||||
3: "^You feel a tickling at your extremities and kick outward,
|
||||
shaking something chitinous off. Their sound alone is a
|
||||
menacing rasp.";
|
||||
4: deadflag = true;
|
||||
"^Suddenly there is a tiny pain, of a hypodermic-sharp fang
|
||||
at your calf. Almost at once your limbs go into spasm, your
|
||||
shoulders and knee-joints lock, your tongue swells...";
|
||||
}
|
||||
],
|
||||
turns_active 0;
|
||||
|
||||
! ---------------------------------------------------------------------------- !
|
||||
! Utility routines.
|
||||
|
||||
! Defined in DM4 §4, modified in §21 and §23
|
||||
[ Initialise;
|
||||
TitlePage();
|
||||
location = Forest;
|
||||
move map to player;
|
||||
move sodium_lamp to player;
|
||||
move dictionary to player;
|
||||
StartDaemon(sodium_lamp);
|
||||
thedark.description =
|
||||
"The darkness of ages presses in on you, and you feel
|
||||
claustrophobic.";
|
||||
"^^^Days of searching, days of thirsty hacking through the briars of
|
||||
the forest, but at last your patience was rewarded. A discovery!^";
|
||||
];
|
||||
|
||||
! Defined in DM4 Exercise 123
|
||||
[ TitlePage i;
|
||||
@erase_window -1; print "^^^^^^^^^^^^^";
|
||||
i = 0->33; if (i > 30) i = (i-30)/2;
|
||||
style bold; font off; spaces(i);
|
||||
print " RUINS^";
|
||||
style roman; print "^^"; spaces(i);
|
||||
print "[Please press SPACE to begin.]^";
|
||||
font on;
|
||||
box "But Alligator was not digging the bottom of the hole"
|
||||
"Which was to be his grave,"
|
||||
"But rather he was digging his own hole"
|
||||
"As a shelter for himself."
|
||||
""
|
||||
"-- from the Popol Vuh";
|
||||
@read_char 1 -> i;
|
||||
@erase_window -1;
|
||||
];
|
||||
|
||||
! Defined in DM4 §22
|
||||
[ PrintRank;
|
||||
print ", earning you the rank of ";
|
||||
if (score == 30) "Director of the Carnegie Institution.";
|
||||
if (score >= 20) "Archaeologist.";
|
||||
if (score >= 10) "Curiosity-seeker.";
|
||||
if (score >= 5) "Explorer.";
|
||||
"Tourist.";
|
||||
];
|
||||
|
||||
! Defined in DM4 §21
|
||||
[ DeathMessage;
|
||||
if (deadflag == 3) print "You have been captured";
|
||||
];
|
||||
|
||||
! ---------------------------------------------------------------------------- !
|
||||
|
||||
Include "Grammar";
|
||||
|
||||
! Defined in DM4 §6
|
||||
[ PhotographSub;
|
||||
if (camera notin player) "Not without the use of your camera.";
|
||||
if (noun == player) "Best not. You haven't shaved since Mexico.";
|
||||
if (children(player) > 1)
|
||||
"Photography is a cumbersome business, needing the use of both
|
||||
hands. You'll have to put everything else down.";
|
||||
if (location == Forest) "In this rain-soaked forest, best not.";
|
||||
if (location == thedark) "It is far too dark.";
|
||||
if (AfterRoutines()) return;
|
||||
print_ret "You set up the elephantine, large-format, wet-plate camera,
|
||||
adjust the sodium lamp and make a patient exposure of ",
|
||||
(the) noun, ".";
|
||||
];
|
||||
|
||||
Verb 'photograph'
|
||||
* noun -> Photograph;
|
||||
|
||||
! ---------------------------------------------------------------------------- !
|
|
@ -0,0 +1,942 @@
|
|||
! ----------------------------------------------------------------------------
|
||||
! Toyshop 961111 One of the standard Inform 6 example games
|
||||
!
|
||||
! This is not a real game. The main example game for Inform is "Advent",
|
||||
! a port of Colossal Cave. Since that's something of an antique, and most
|
||||
! of the objects in it are rather simple, this is a collection of more
|
||||
! exotic features and peculiar objects. Note that "Advent" has plenty of
|
||||
! interesting doors, a good lantern and bottled oil and water, so those
|
||||
! won't be part of the Toyshop.
|
||||
!
|
||||
! Needs Inform 6 with library 6/1 or later to compile.
|
||||
!
|
||||
! To win, simply find 6 interesting things to do and leave by the main exit!
|
||||
!
|
||||
! Object Is an example of...
|
||||
!
|
||||
! >SA satchel Container into which the game silently puts things
|
||||
! >HE helium balloon Something moving under the control of a daemon
|
||||
! >CA little red car Vehicle, and pushable from place to place
|
||||
! >PF padded floor Scenery present in several rooms at once
|
||||
! >GR hand grenade Timed events: a grenade and its pin
|
||||
! >MA matchbook Simple fire and matches; changing inventory styles
|
||||
! >WC white candles A stock of objects identical to each other
|
||||
! >GL white gloves Two independent objects which can behave as a pair
|
||||
! >CO green cone Easy before and after rules
|
||||
! >HW high window Starting and stopping daemons
|
||||
! >BC bolted cupboard A typical locked container (with key)
|
||||
! >GB glass box Container light can get through
|
||||
! >SB steel box Container light can't get through
|
||||
! >BL building blocks A complicated class definition; piles of objects
|
||||
! >CH Christopher Someone you can talk to, and persuade to do things
|
||||
! >OF Office Rules about moving in a particular direction
|
||||
! >TB toothed bag A container with ideas about what it will allow
|
||||
! >SL spirit level Something to put on top of things
|
||||
! >BB blackboard A blackboard to write messages on
|
||||
!
|
||||
! (The code is marked with >SA and so on for easy access with a text editor)
|
||||
! ----------------------------------------------------------------------------
|
||||
Constant DEBUG;
|
||||
Constant Story "TOYSHOP";
|
||||
Constant Headline "^An Interactive Demonstration^
|
||||
Copyright (c) 1994 by Graham Nelson. All rights given away.^";
|
||||
Release 4;
|
||||
Serial "961111"; ! This sets the serial date to the date of this source
|
||||
! file, not to the date of compilation.
|
||||
|
||||
! Now we serve notice to Inform that we do not wish to use the standard
|
||||
! routine for the Burn action, and will instead be defining our own:
|
||||
|
||||
Replace BurnSub;
|
||||
|
||||
! Next include the first of the three standard library files:
|
||||
|
||||
Include "Parser";
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! >SA Ungenerously, the player can only carry at most 4 things, but there's
|
||||
! a satchel to carry other things around in...
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Constant MAX_CARRIED = 4;
|
||||
Constant SACK_OBJECT = satchel;
|
||||
|
||||
Object satchel "satchel"
|
||||
with description "Big and with a smile painted on it.",
|
||||
name "satchel", article "your",
|
||||
when_closed "Your satchel lies on the floor.",
|
||||
when_open "Your satchel lies open on the floor.",
|
||||
has container open openable;
|
||||
|
||||
! We're going to use the most elaborate scoring system the
|
||||
! library provides (even though we're going to make the six tasks all
|
||||
! score only 1 point each), so we define all this...
|
||||
|
||||
Constant TASKS_PROVIDED;
|
||||
Constant NUMBER_TASKS = 6;
|
||||
Array task_scores -> 1 1 1 1 1 1;
|
||||
Constant MAX_SCORE = 6;
|
||||
|
||||
! And include the library of standard verbs and actions.
|
||||
|
||||
Include "VerbLib";
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! Off we go into the Toyshop...
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Class Toyroom
|
||||
has light;
|
||||
|
||||
Toyroom Toyshop "Toyshop"
|
||||
with description
|
||||
"The centre of a long east-west hall. Shelves are lined
|
||||
with toys, painted clowns face you from the walls and
|
||||
the floor is lightly padded with colourful mats. A doorway
|
||||
leads north, with a red warning triangle above it.",
|
||||
name "clowns" "painted" "shelves" "triangle",
|
||||
e_to East_End, w_to West_End, n_to Danger_Zone;
|
||||
|
||||
Object -> chair "high chair"
|
||||
with name "chair" "high"
|
||||
has supporter enterable;
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! >HE The balloon is completely self-contained as a piece of code, except
|
||||
! that it does not set itself going (though even this could have been
|
||||
! arranged): it is set going in the Initialise() routine.
|
||||
!
|
||||
! Notice that the "after" for Drop takes away the "moved" attribute.
|
||||
! This is one way to ensure that the "initial" message will always be
|
||||
! the one displayed. (Alternatively, we could have given it a "describe"
|
||||
! property.)
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Object -> balloon "helium balloon"
|
||||
with description "Blue, with a yellow smile.",
|
||||
name "helium" "balloon" "blue" "string",
|
||||
initial "A balloon nestles on the ceiling, its long string hanging.",
|
||||
before
|
||||
[; Attack: remove self; StopDaemon(self);
|
||||
"Easily, you burst the balloon. Pop!^^
|
||||
Shame it was irreplaceable, really.";
|
||||
],
|
||||
after
|
||||
[; Take: "You take the balloon by its string. It's buoyant!";
|
||||
Drop: give balloon ~moved;
|
||||
"The balloon rises gracefully to the ceiling.";
|
||||
],
|
||||
daemon
|
||||
[ from_room to_room;
|
||||
if (random(3)~=1) rfalse;
|
||||
from_room=parent(self);
|
||||
if (from_room==East_End or West_End) to_room=Toyshop;
|
||||
if (from_room==Toyshop)
|
||||
{ if (random(2)==1) to_room=East_End;
|
||||
else to_room=West_End;
|
||||
}
|
||||
if (to_room==0) rfalse;
|
||||
move self to to_room;
|
||||
if (location==from_room)
|
||||
"^A breeze blows the balloon away to the ", (name) to_room, ".";
|
||||
if (location==to_room)
|
||||
"^A breeze blows the balloon in from the ", (name) from_room, ".";
|
||||
];
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! >CA There are two exceptions to the ordinary before/after rules, for
|
||||
! vehicles and things which can be pushed from place to place: this car
|
||||
! demonstrates both at once.
|
||||
!
|
||||
! The "before" for PushDir (push in a named direction) must call
|
||||
! AllowPushDir and then return true to signify that the push is legal.
|
||||
!
|
||||
! The "before" for Go must return true to signify that travelling in
|
||||
! the object is legal. (Note that it must also be enterable.)
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Object -> car "little red car"
|
||||
with name "little" "red" "car" "kar1",
|
||||
description "Large enough to sit inside. Among the controls is a
|
||||
prominent on/off switch. The numberplate is KAR 1.",
|
||||
when_on "The red car sits here, its engine still running.",
|
||||
when_off "A little red car is parked here.",
|
||||
before
|
||||
[; PushDir: AllowPushDir(); rtrue;
|
||||
Go: if (car has on) { Achieved(1); "Brmm! Brmm!"; }
|
||||
print "(The ignition is off at the moment.)^";
|
||||
],
|
||||
after
|
||||
[; PushDir: "The car rolls very slowly as you push it.";
|
||||
],
|
||||
has switchable enterable static container open;
|
||||
|
||||
Object -> -> "small note"
|
||||
with name "small" "note",
|
||||
description
|
||||
" !!!! FROBOZZ MAGIC CAR COMPANY !!!!^
|
||||
^Hello, Driver!^
|
||||
^Instructions for use:^
|
||||
^Switch on the ignition and off you go!^
|
||||
^Warranty:^
|
||||
^This car is guaranteed against all defects for a period of
|
||||
76 milliseconds from date of purchase or until used,
|
||||
whichever comes first.^
|
||||
^Good Luck!";
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! >PF An example of an object spread across several (three) rooms:
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Object padded_floor "padded floor"
|
||||
with name "padded" "floor" "mats" "padding",
|
||||
description "To protect little children and adventurers.",
|
||||
before
|
||||
[; Take: "It is protected from little children and adventurers.";
|
||||
],
|
||||
found_in East_End Toyshop West_End
|
||||
has scenery;
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Toyroom Danger_Zone "Danger Zone"
|
||||
with description
|
||||
"This is the Danger Zone, which you should know better
|
||||
than to go into. A single door leads back south.",
|
||||
s_to Toyshop;
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! >GR A classic example of a timer (or, as some people call them and
|
||||
! appropriately so in this case, a fuse). To demonstrate stopping
|
||||
! a timer before the alarm (and for fun), there is also a pin:
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Object -> grenade "nasty-looking hand grenade"
|
||||
with name "hand" "grenade" "nasty" "nasty-looking",
|
||||
initial "A nasty-looking hand grenade (there is no other kind)
|
||||
rolls about irresponsibly on the floor.",
|
||||
description "Not recommended for children under 90.",
|
||||
before
|
||||
[; Pull: if (self has general) "Too late for that.";
|
||||
StartTimer(self, 5); give self general;
|
||||
move the_pin to player;
|
||||
"You pull the pin out, an irrevocable act.";
|
||||
],
|
||||
time_left 0,
|
||||
time_out
|
||||
[; deadflag=1;
|
||||
"^An immense explosion suddenly demolishes the toyshop!^^
|
||||
Will you never learn?";
|
||||
],
|
||||
has transparent;
|
||||
|
||||
Object -> -> the_pin "pin"
|
||||
with name "pin",
|
||||
description "The pin is designed to be easy to pull.",
|
||||
before
|
||||
[; Take, Pull: if (self in grenade) <<Pull grenade>>;
|
||||
Insert:
|
||||
if (self notin grenade && second==grenade)
|
||||
{ StopTimer(grenade); move self to grenade;
|
||||
give grenade ~general;
|
||||
"Amazing! You got the pin back into the grenade!";
|
||||
}
|
||||
];
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! >MA This is a matchbook of five matches, which is quite simple in that you
|
||||
! can only actually have one match at a time: otherwise, it's quite
|
||||
! a full implementation. Note that the inventory lines for the match
|
||||
! and the matchbook are coded here. Note also that the "match" object
|
||||
! returns to the book even when the book is empty, so that the parser
|
||||
! will still understand requests for matches - which the "before" rule,
|
||||
! which automatically removes matches when needed, can then turn down.
|
||||
!
|
||||
! The matchbook has a daemon whose job is to tidy up lost matches. One
|
||||
! might expect this rule to be coded with an "after" routine, to trap
|
||||
! the player dropping matches. But suppose there were a magpie in the
|
||||
! game, and it flew down and stole the match but left the matchbook!
|
||||
! As it happens there isn't, but this is better form.
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Object -> matchbook "matchbook"
|
||||
with name "matchbook" "book" "matches",
|
||||
number 5,
|
||||
before
|
||||
[; Burn: if (match has light)
|
||||
{ remove match; remove matchbook;
|
||||
"What a waste of matches!";
|
||||
}
|
||||
],
|
||||
invent
|
||||
[; if (inventory_stage==2)
|
||||
{ switch(self.number)
|
||||
{ 0: print " (empty)";
|
||||
1: print " (1 match left)";
|
||||
default: print " (", self.number, " matches left)";
|
||||
}
|
||||
}
|
||||
],
|
||||
description
|
||||
[; print "The cover advertisement reads
|
||||
~Curses - Adventure of a Lunchtime~. The book ";
|
||||
switch(self.number)
|
||||
{ 0: "is empty.";
|
||||
1: "has a single match left.";
|
||||
default:
|
||||
print_ret "contains ", self.number, " matches.";
|
||||
}
|
||||
],
|
||||
daemon
|
||||
[; if (match notin matchbook && match notin player)
|
||||
{ move match to matchbook;
|
||||
if (match has light)
|
||||
{ give match ~light; StopTimer(match); }
|
||||
StopDaemon(self);
|
||||
}
|
||||
],
|
||||
has transparent;
|
||||
|
||||
Object -> -> match "match"
|
||||
with parse_name
|
||||
[ i j; if (self has light) j='burning'; else j='unlit';
|
||||
while (NextWord()=='match' or j) i++;
|
||||
return i;
|
||||
],
|
||||
article "an",
|
||||
before
|
||||
[ i; if (self in matchbook)
|
||||
{ i=matchbook.number;
|
||||
if (i==0) "There are no matches left in the book.";
|
||||
i--; matchbook.number=i;
|
||||
move self to player; StartDaemon(matchbook);
|
||||
print "(taking a match from the book, which ";
|
||||
if (i==0) print "is now empty)^";
|
||||
if (i==1) print "has one more left)^";
|
||||
if (i>1) print "has ", i, " left)^";
|
||||
self.article = "an";
|
||||
}
|
||||
Take, Remove: if (self in player) "Done.";
|
||||
Burn:
|
||||
if (self has light) "The match is already alight.";
|
||||
if (matchbook notin player)
|
||||
"You need the matchbook to strike the match.";
|
||||
give self light; StartTimer(self, 2+random(3));
|
||||
self.article = "a";
|
||||
"You strike the match.";
|
||||
],
|
||||
short_name
|
||||
[; if (self has light) print "burning match";
|
||||
else print "unlit match";
|
||||
rtrue;
|
||||
],
|
||||
|
||||
time_left,
|
||||
time_out
|
||||
[; move self to matchbook; give self ~light;
|
||||
"^You drop the match as the flame reaches your finger.";
|
||||
];
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! >WC A box of eight candles.
|
||||
!
|
||||
! This is a simple way to code up duplicate objects. For one thing,
|
||||
! > take candles
|
||||
! does not quite behave as we would hope: it'll only pick up one candle
|
||||
! (though "> take four candles" will work). See the "Block" class
|
||||
! below for a way to make good.
|
||||
!
|
||||
! If we had needed a much greater number of candles, we could have used
|
||||
! object creation and destruction during play. See the "Ticket" class
|
||||
! from the "Balances" example game.
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Class Candle
|
||||
with name "wax" "candle" "candles",
|
||||
short_name "wax candle", plural "wax candles",
|
||||
description "It looks just like all the other candles.",
|
||||
before
|
||||
[; Burn: "Disappointingly, the wick refuses to burn."; ];
|
||||
|
||||
Object -> "grey tin box"
|
||||
with name "tin" "box" "grey",
|
||||
description
|
||||
"A grey tin box of ~Major's Candles~.",
|
||||
has container openable;
|
||||
|
||||
Candle -> ->;
|
||||
Candle -> ->;
|
||||
Candle -> ->;
|
||||
Candle -> ->;
|
||||
Candle -> ->;
|
||||
Candle -> ->;
|
||||
Candle -> ->;
|
||||
Candle -> ->;
|
||||
|
||||
Toyroom East_End "East End"
|
||||
with name "dolls" "nurses",
|
||||
description
|
||||
"The eastern end of the toyshop is pink, and dolls and
|
||||
nurses line the shelves right up to the high window.
|
||||
A dark doorway leads to a northern side chamber.",
|
||||
w_to Toyshop, n_to DarkRoom;
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! >GL The following example, suggested to the author by Richard Tucker,
|
||||
! demonstrates an apparently tricky case of objects with associated
|
||||
! sub-objects. The pair of white gloves behaves just like any other item
|
||||
! of clothing - but the player can also use the left and right gloves
|
||||
! independently, can take away or wear only one and so on. When they
|
||||
! come back together (even in a cupboard, say, or on a mantelpiece)
|
||||
! they are called a pair again.
|
||||
!
|
||||
! We can do this with only three objects, one daemon and one rule.
|
||||
!
|
||||
! When the gloves are together, and the player refers to an individual
|
||||
! glove, the before rule splits up the pair and starts the daemon.
|
||||
! Once active, the daemon tries every turn to re-join them into a pair.
|
||||
! (If it succeeds, it turns itself off.)
|
||||
!
|
||||
! Note that the "pair of gloves" object has the "general" attribute exactly
|
||||
! when the gloves are apart. Otherwise the pair-object contains both
|
||||
! glove objects, and has "transparent" so that the parser knows the player
|
||||
! can see and refer to them.
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Object -> gloves "white gloves"
|
||||
with article "a pair of",
|
||||
name "white" "gloves" "pair" "of",
|
||||
daemon
|
||||
[; if (parent(right_glove) ~= parent(left_glove)) return;
|
||||
if ((left_glove has worn && right_glove hasnt worn)
|
||||
|| (left_glove hasnt worn && right_glove has worn)) return;
|
||||
if (left_glove has worn) give gloves worn; else give gloves ~worn;
|
||||
move gloves to parent(right_glove); give gloves ~general;
|
||||
|
||||
move right_glove to gloves; move left_glove to gloves;
|
||||
give right_glove ~worn; give left_glove ~worn;
|
||||
|
||||
StopDaemon(self);
|
||||
],
|
||||
has clothing transparent;
|
||||
|
||||
Class Glove
|
||||
with article "the",
|
||||
name "white" "glove",
|
||||
before
|
||||
[; if (self notin gloves) rfalse;
|
||||
move left_glove to parent(gloves); move right_glove to parent(gloves);
|
||||
if (gloves has worn)
|
||||
{ give left_glove worn; give right_glove worn;
|
||||
}
|
||||
give gloves general; remove gloves;
|
||||
StartDaemon(gloves);
|
||||
],
|
||||
has clothing;
|
||||
|
||||
Glove -> -> left_glove "left glove"
|
||||
with description "White silk, monogrammed with a scarlet R.",
|
||||
name "left";
|
||||
Glove -> -> right_glove "right glove"
|
||||
with description "White silk, monogrammed with a scarlet T.",
|
||||
name "right";
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! ...and that's all: the "gloves" code is self-contained.
|
||||
!
|
||||
! Exercise for the reader: hide a (sharp) jewel inside the left glove.
|
||||
! (Alter the glove class to make them containers open only when not worn.
|
||||
! Add two "after" rules to warn the player if there's something sharp
|
||||
! to the touch, one for putting on the pair of gloves, one for putting on
|
||||
! an individual glove.)
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! >CO A traditional Inform example object:
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Object -> cone "green cone"
|
||||
with name "green" "cone" "emerald" "marzipan",
|
||||
describe
|
||||
[; if (cone has moved)
|
||||
"^A misshapen cone of green marzipan sits here.";
|
||||
"^Nearby is an emerald green cone, one foot high.";
|
||||
],
|
||||
description "The cone seems to be made of emerald-coloured
|
||||
marzipan.",
|
||||
before
|
||||
[; Eat: if (random(100) <= 30)
|
||||
{ deadflag = 1;
|
||||
"Unfortunately, you seem to be allergic to almonds.";
|
||||
}
|
||||
"You nibble at a corner of the cone.";
|
||||
],
|
||||
after
|
||||
[; Take: "Taken. (Your hands are smeared with marzipan.)";
|
||||
Drop: cone.description = "The cone is a vague green mess.";
|
||||
"The cone drops to the floor and sags a little.";
|
||||
],
|
||||
has edible;
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! >HW It's the draught from this slightly-concealed window which propels the
|
||||
! balloon:
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Object -> "high window"
|
||||
with name "high" "window",
|
||||
description
|
||||
[; print "A narrow, high window ";
|
||||
if (self has open) "through which a draught blows.";
|
||||
"which is closed.";
|
||||
],
|
||||
after
|
||||
[; Open: StartDaemon(balloon);
|
||||
Close: Achieved(2); StopDaemon(balloon);
|
||||
],
|
||||
has scenery openable open;
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! >BC A typical locked container, containing a rather pathetic prize...
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Object -> "bolted cupboard"
|
||||
with name "bolted" "cupboard",
|
||||
describe
|
||||
[; if (self hasnt open) "^A shut cupboard is bolted to one wall.";
|
||||
"^Bolted up on one wall is an open cupboard.";
|
||||
],
|
||||
with_key key
|
||||
has locked container openable lockable static;
|
||||
|
||||
Object -> -> "boiled sweet"
|
||||
with name "boiled" "sweet",
|
||||
after
|
||||
[; Eat: Achieved(0);
|
||||
"It takes an irritatingly long time to eat.";
|
||||
],
|
||||
has edible;
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! >GB This is really to demonstrate "transparent". Shutting up the glowing
|
||||
! >SB ball in the glass box does not make the room go dark: shutting it up
|
||||
! in the steel box does. Also, you can examine things in the glass box
|
||||
! even when the glass box is shut.
|
||||
! (Note also that the Dark Room is explicitly told not to have "light",
|
||||
! which it would otherwise inherit from the "Toyroom" class.)
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Toyroom DarkRoom "Dark Room"
|
||||
with description "A featureless storage room, hardly worth illumination.",
|
||||
cant_go "The only exit is back south.",
|
||||
s_to East_End
|
||||
has ~light;
|
||||
|
||||
Object -> "glass box with a lid"
|
||||
with name "glass" "box" "with" "lid"
|
||||
has container transparent openable open;
|
||||
|
||||
Object -> "steel box with a lid"
|
||||
with name "steel" "box" "with" "lid"
|
||||
has container openable open;
|
||||
|
||||
|
||||
Toyroom West_End "West End"
|
||||
with name "soldiers" "model" "aircraft" "planes",
|
||||
description
|
||||
"The western end of the toyshop is blue, and soldiers and
|
||||
model aircraft line the shelves. A small office lies to
|
||||
the south.",
|
||||
e_to Toyshop, s_to Office;
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! >BL The class Block provides for stackable building blocks.
|
||||
!
|
||||
! Note that with the "describe" routine missing, the game would still
|
||||
! correctly describe stacks of blocks: just a little less elegantly.
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Class Block
|
||||
with description "Just a child's building block, four inches on a side.",
|
||||
|
||||
! The parse_name routine below ensures that "take blocks"
|
||||
! works correctly:
|
||||
|
||||
parse_name
|
||||
[ i j;
|
||||
for (::)
|
||||
{ j=NextWord();
|
||||
if (j=='block' or 'cube' or 'building' or (self.name)) i++;
|
||||
else
|
||||
{ if (j=='blocks' or 'cubes')
|
||||
{ parser_action=##PluralFound; i++; }
|
||||
else return i;
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
describe
|
||||
[ c d e;
|
||||
d = child(self);
|
||||
while (d~=0 && d ofclass Block)
|
||||
{ c++; e=d; d=child(d); }
|
||||
if (c==0) rfalse;
|
||||
print "^There is a pile of building blocks here, ";
|
||||
while (c>=0)
|
||||
{ print (address) e.name; ! Sneaky: print the "name" out
|
||||
if (c>0) print " on "; ! using its dictionary address
|
||||
c--; e=parent(e);
|
||||
}
|
||||
".";
|
||||
],
|
||||
before
|
||||
[ c;
|
||||
PutOn:
|
||||
if (second ofclass Block)
|
||||
{ if (child(second)~=0 && child(second) ofclass Block)
|
||||
"There's no room on the top of one cube for two more, side
|
||||
by side.";
|
||||
}
|
||||
else
|
||||
print "(They're really intended
|
||||
to be piled on top of each other.)^";
|
||||
c=second; while (c ofclass Block) c=parent(c);
|
||||
if (c~=location or mantelpiece) "Too unsteady a base.";
|
||||
],
|
||||
after
|
||||
[ c stack;
|
||||
PutOn:
|
||||
stack=noun;
|
||||
while (parent(stack) ofclass Block) { stack=parent(stack); c++; }
|
||||
if (c<2)
|
||||
{ if (Chris has general) rtrue;
|
||||
rfalse;
|
||||
}
|
||||
if (c==2) "The pile of three cubes is unsteady, but viable.";
|
||||
if (Chris has general)
|
||||
{ Achieved(3);
|
||||
"^Expertly he keeps the pile of four cubes stable.";
|
||||
}
|
||||
stack=noun;
|
||||
while (parent(stack) ofclass Block)
|
||||
{ c=stack; stack=parent(stack); move c to location; }
|
||||
"The pile of four cubes wobbles, wobbles, steadies... and suddenly
|
||||
collapses!";
|
||||
Take:
|
||||
stack=child(noun); if (stack==0) rfalse;
|
||||
while (stack~=0)
|
||||
{ c=stack; stack=child(stack); move c to location; }
|
||||
"Your pile of cubes is collapsed as a result.";
|
||||
],
|
||||
has supporter;
|
||||
|
||||
Block -> "green cube"
|
||||
with name "green";
|
||||
Block -> "red cube"
|
||||
with name "red";
|
||||
Block -> "yellow cube"
|
||||
with name "yellow";
|
||||
Block -> "blue cube"
|
||||
with name "blue";
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! >CH A guest appearance by my cousin Christopher, aged six (*), who plays
|
||||
! with one thing at a time (easily forgetting which). Being "transparent"
|
||||
! (no reflection on him!) means the parser allows the player to examine
|
||||
! whatever he's playing with... but not to take it from him.
|
||||
! (* In 1993, when this game was first written.)
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Object -> Chris "Christopher"
|
||||
with name "child" "boy" "chris" "christopher",
|
||||
describe
|
||||
[; print "^A boy called Christopher sits here";
|
||||
if (child(Chris) ~= nothing)
|
||||
print ", playing with ", (a) child(Chris);
|
||||
".";
|
||||
],
|
||||
life
|
||||
[ x;
|
||||
Ask:
|
||||
switch(second)
|
||||
{ 'juggling', 'fluorescent', 'ball': "~That's mine!~";
|
||||
'helium', 'balloon': "Christopher yawns.";
|
||||
'cube', 'cubes': "~Bet I can make a higher tower than you.~";
|
||||
'toys', 'toyshop': "~Isn't it fabulous here?~";
|
||||
default: "~Dunno.~";
|
||||
}
|
||||
Answer:
|
||||
switch(noun)
|
||||
{ 'hello', 'hallo', 'hi':
|
||||
"~Hello,~ says Christopher cheerfully.";
|
||||
default: "Christopher seems preoccupied.";
|
||||
}
|
||||
Attack: remove self;
|
||||
"Christopher makes a run for it, effortlessly slipping past you!";
|
||||
Kiss: "~That's soppy, that is.~";
|
||||
Give:
|
||||
if (noun==balloon) "He's too bored by the balloon.";
|
||||
x=child(Chris);
|
||||
if (x~=0)
|
||||
{ move x to location;
|
||||
print "He forgets about ", (the) x, " and ";
|
||||
}
|
||||
else print "He ";
|
||||
print "eagerly grabs ", (the) noun; move noun to Chris; ".";
|
||||
],
|
||||
orders
|
||||
[; Drop: if (noun in Chris) "~Won't! It's mine!~";
|
||||
Take: "Christopher can't be bothered.";
|
||||
Give: if (second==player) "~Get your own!~";
|
||||
Go: "~But I like it here!~";
|
||||
PutOn: if (noun notin Chris) "He is mightily confused.";
|
||||
if (~~(noun ofclass Block && second ofclass Block))
|
||||
"He can't see the point of this.";
|
||||
print "Christopher leans over with great concentration
|
||||
and does so.^";
|
||||
move noun to player; give self general;
|
||||
<PutOn noun second>;
|
||||
give self ~general; rtrue;
|
||||
],
|
||||
each_turn
|
||||
[; if (random(3)~=1) rtrue;
|
||||
print "^Christopher ";
|
||||
switch(random(4))
|
||||
{ 1: "yawns."; 2: "frowns.";
|
||||
3: "stretches."; 4: "hums tonelessly.";
|
||||
}
|
||||
],
|
||||
has animate proper transparent;
|
||||
|
||||
Object "fluorescent juggling ball" Chris
|
||||
with initial "On the floor is a fluorescent juggling ball!",
|
||||
name "fluorescent" "juggling" "ball",
|
||||
description "It glows with soft light."
|
||||
has light;
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! >OF A simple movement rule.
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Toyroom Office "Office"
|
||||
with description
|
||||
"A small, grey office, with a broad stone mantelpiece.
|
||||
In the east wall is a doorway marked ~Exit~, and the Toyshop,
|
||||
of course, lies north.",
|
||||
cant_go "The Toyshop floor lies north.",
|
||||
n_to West_End,
|
||||
e_to
|
||||
[; if (score~=MAX_SCORE)
|
||||
"A gong sounds. ~You cannot leave the Toyshop until
|
||||
you have done six interesting things!~";
|
||||
deadflag=2;
|
||||
"A gong sounds. ~Congratulations! You may now leave the Toyshop
|
||||
and begin writing your own Inform game!~";
|
||||
];
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! >TB A somewhat acquisitive container... but it can be taught to behave.
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Object -> "toothed bag"
|
||||
with name "toothed" "bag",
|
||||
initial "In one corner is a curious, toothed bag.",
|
||||
description "A capacious bag with a toothed mouth.",
|
||||
before
|
||||
[; LetGo: "The bag defiantly bites itself
|
||||
shut on your hand until you desist.";
|
||||
],
|
||||
after
|
||||
[; Receive:
|
||||
if (noun==cone)
|
||||
{ self.before=0; self.after=0;
|
||||
"The bag wriggles interminably as it tries
|
||||
to eat the enormous mass of marzipan. That'll
|
||||
teach it.";
|
||||
}
|
||||
"The bag wriggles hideously as it swallows ", (the) noun, ".";
|
||||
],
|
||||
has container open;
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! >SL Which can be put on the mantelpiece: the first time this is done, the
|
||||
! game randomly decides which end is higher, and sticks to this decision.
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Object -> -> spirit_level "spirit level"
|
||||
with name "spirit" "level" "wood" "flask",
|
||||
number 0,
|
||||
description "A length of wood containing a flask of viscous
|
||||
green liquid, in which a bubble is trapped.",
|
||||
before
|
||||
[; Examine:
|
||||
if (spirit_level in mantelpiece)
|
||||
{ print "The bubble is at the ";
|
||||
if (self.number==1) "northeast end.";
|
||||
"southeast end.";
|
||||
}
|
||||
],
|
||||
after
|
||||
[; PutOn: if (second~=mantelpiece) rfalse;
|
||||
if (spirit_level hasnt general) self.number=random(2);
|
||||
give spirit_level general; Achieved(4);
|
||||
print "You put the spirit level on the mantelpiece,
|
||||
and the bubble slowly drifts towards the ";
|
||||
if (self.number==1) "northeast.";
|
||||
"southwest.";
|
||||
];
|
||||
|
||||
Object -> mantelpiece "mantelpiece"
|
||||
with name "mantel" "mantle" "piece" "mantelpiece"
|
||||
has scenery supporter;
|
||||
|
||||
Object -> -> key "iron key"
|
||||
with name "iron" "key", article "an";
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! >BB A blackboard which can be written on or wiped clear.
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
Object -> -> chalk "stick of chalk"
|
||||
with name "stick" "of" "chalk";
|
||||
|
||||
Array boardtext string 64;
|
||||
|
||||
Object -> blackboard "blackboard"
|
||||
with name "board" "blackboard" "black",
|
||||
describe
|
||||
[; <<Examine self>>; ],
|
||||
before
|
||||
[ i f;
|
||||
Examine:
|
||||
for (i=1:i<=boardtext->0:i++)
|
||||
if (boardtext->i~=' ' or 0) f=1;
|
||||
if (f==0)
|
||||
{ print "^The office blackboard is wiped clean.^";
|
||||
if (self hasnt general)
|
||||
{ give self general;
|
||||
"^[To write on it, try > write ~message...~]";
|
||||
}
|
||||
rtrue;
|
||||
}
|
||||
print "^The office blackboard bears the message:^ ";
|
||||
for (i=1:i<=boardtext->0:i++)
|
||||
{ f=boardtext->i;
|
||||
if (f~=0) print (char) f;
|
||||
}
|
||||
new_line; rtrue;
|
||||
Rub: for (i=1:i<=boardtext->0:i++) boardtext->i = ' ';
|
||||
"You wipe the blackboard clean.";
|
||||
],
|
||||
has static;
|
||||
|
||||
Global from_char; Global to_char;
|
||||
[ QuotedText i j f;
|
||||
i = WordAddress(wn++); i=i-buffer;
|
||||
if (buffer->i=='"')
|
||||
{ for (j=i+1:j<=(buffer->1)+1:j++)
|
||||
if (buffer->j=='"') f=j;
|
||||
if (f==0) return -1;
|
||||
from_char = i+1; to_char=f-1;
|
||||
if (from_char>to_char) return -1;
|
||||
while (buffer+f > WordAddress(wn)) wn++; wn++;
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
];
|
||||
|
||||
[ WriteSub i j;
|
||||
if (chalk notin player) "You're holding nothing to write with.";
|
||||
if (blackboard notin location) "The blackboard is elsewhere.";
|
||||
for (i=from_char,j=1:i<=to_char && j<boardtext->0:i++,j++)
|
||||
boardtext->j = buffer->i;
|
||||
for (:j<boardtext->0:j++) boardtext->j=0;
|
||||
Achieved(5);
|
||||
<<Examine blackboard>>;
|
||||
];
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! End of object definitions.
|
||||
! ----------------------------------------------------------------------------
|
||||
!
|
||||
! Routines and Entry Points
|
||||
!
|
||||
! (Fuller examples of which can be found in the "Advent" example game.)
|
||||
!
|
||||
! Initialise() just sets up the initial state of the game.
|
||||
! We are required to set "location" to the start location of the
|
||||
! player; the rest is optional.
|
||||
!
|
||||
! StartDaemon(balloon) starts the process which blows the balloon back
|
||||
! and forth.
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
[ Initialise;
|
||||
location=chair; move satchel to player;
|
||||
|
||||
print "^^^^^~What's so special about Inform,~ is the last thing you
|
||||
remember saying to the mad alchemist. Big mistake...^^";
|
||||
|
||||
StartDaemon(balloon);
|
||||
];
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! Print names of tasks out (when the library asks us to). Note that they
|
||||
! are numbered from 0 to NUMBER_TASKS-1.
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
[ PrintTaskName achievement;
|
||||
switch(achievement)
|
||||
{ 0: "eating a sweet";
|
||||
1: "driving the car";
|
||||
2: "shutting out the draught";
|
||||
3: "building a tower of four";
|
||||
4: "seeing which way the mantelpiece leans";
|
||||
5: "writing on the blackboard";
|
||||
}
|
||||
];
|
||||
|
||||
[ PrintRank;
|
||||
print ", earning you the rank of ";
|
||||
if (score >= 6) "Toyshop manager.";
|
||||
if (score >= 5) "management trainee.";
|
||||
if (score >= 4) "undergraduate.";
|
||||
if (score >= 3) "schoolchild.";
|
||||
if (score >= 2) "nursery-school child.";
|
||||
if (score >= 1) "toddler.";
|
||||
"newborn baby.";
|
||||
];
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! Now (as promised earlier) we provide the replacement for BurnSub,
|
||||
! specially adapted to the rules of the Toyshop:
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
[ BurnSub;
|
||||
if (match hasnt light) "You have no source of flame.";
|
||||
if (noun has animate) <<Attack noun>>;
|
||||
if (noun==padded_floor)
|
||||
{ deadflag=1;
|
||||
"A gong sounds, but before a sepulchral voice finishes clearing
|
||||
its throat, the whole padded floor goes up in an inferno.";
|
||||
}
|
||||
"A gong sounds, and a sepulchral, rather disappointed voice says:
|
||||
~It is forbidden to play with fire in the Toyshop.~";
|
||||
];
|
||||
|
||||
! ----------------------------------------------------------------------------
|
||||
! And we provide one new action, "Burst", which in fact just passes over to
|
||||
! "Attack", plus one for writing on the board:
|
||||
! ----------------------------------------------------------------------------
|
||||
|
||||
[ BurstSub; <<Attack noun>>; ];
|
||||
|
||||
Include "Grammar";
|
||||
|
||||
Verb "burst" "pop" "prick" "stab" "pierce"
|
||||
* noun -> Burst;
|
||||
|
||||
Verb "write" * QuotedText -> Write;
|
||||
|
||||
! ----------------------------------------------------------------------------
|
|
@ -0,0 +1,121 @@
|
|||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||
|
||||
(function(mod) {
|
||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||
mod(require("../../lib/codemirror"));
|
||||
else if (typeof define == "function" && define.amd) // AMD
|
||||
define(["../../lib/codemirror"], mod);
|
||||
else // Plain browser env
|
||||
mod(CodeMirror);
|
||||
})(function(CodeMirror) {
|
||||
"use strict";
|
||||
|
||||
// inform6 DASM syntax
|
||||
|
||||
CodeMirror.defineMode('inform6', function(_config, parserConfig) {
|
||||
var keywords1, keywords2;
|
||||
|
||||
var keywords_list = "box|break|continue|do|else|fonton|fontoff|for|give|if|jump|new_line|objectloop|print|print_ret|remove|return|rfalse|rtrue|spaces|string|styleroman|stylebold|styleunderline|stylereverse|stylefixed|switch|until|while|has|hasnt|with|in|notin|ofclass|provides|or".split("|");
|
||||
var directives_list = "Abbreviate|Array|Attribute|Class|Constant|Default|End|Endif|Extend|Global|Ifdef|Ifndef|Ifnot|Iftrue|Iffalse|Import|Include|Link|Lowstring|Message|Object|Property|Release|Replace|Serial|Switches|Statuslinescore|Statuslinetime|System_file|Verb|Zcharacter".toLowerCase().split("|");
|
||||
var properties_list = "add_to_scope|after|article|articles|before|cant_go|capacity|d_to|daemon|describe|description|door_dir|door_to|e_to|each_turn|found_in|grammar|in_to|initial|inside_description|invent|life|list_together|name|n_to|ne_to|number|nw_to|orders|out_to|parse_name|plural|react_after|react_before|s_to|se_to|short_name|short_name_indef|sw_to|time_left|time_out|u_to|w_to|when_closed|when_open|when_on|when_off|with_key".split("|");
|
||||
var attributes_list = "absent|animate|clothing|concealed|container|door|edible|enterable|female|general|light|lockable|locked|male|moved|neuter|open|openable|pluralname|proper|scenery|scored|static|supporter|switchable|talkable|transparent|visited|workflag|worn".split("|");
|
||||
var actions_list = "Pronouns|Quit|Restart|Restore|Save|Verify|ScriptOn|ScriptOff|NotifyOn|NotifyOff|Places|Objects|Score|FullScore|Version|LMode1|LMode2|LMode3|Look|Examine|Search|Inv|InvTall|InvWide|Take|Drop|Remove|PutOn|Insert|LetGo|Receive|Empty|EmptyT|Remove|Transfer|Go|Enter|GetOff|GoIn|Exit|Unlock|Lock|SwitchOn|SwitchOff|Open|Close|Disrobe|Wear|Eat|Wait|LookUnder|Listen|Taste|Touch|Pull|Push|Wave|Turn|PushDir|ThrowAt|ThrownAt|JumpOver|Tie|Drink|Fill|Attack|Swing|Blow|Rub|Set|SetTo|Buy|Climb|Squeeze|Burn|Dig|Cut|Consult|Tell|Answer|Ask|Give|Show|AskFor|WakeOther|Kiss|Sleep|Sing|WaveHands|Swim|Sorry|Strong|Mild|Jump|Think|Smell|Pray|VagueGo|Yes|No|Wake|Answer|Ask|Attack|Give|Kiss|Order|Show|Tell|ThrowAt|WakeOther".toLowerCase().split("|");
|
||||
|
||||
var directives = new Map();
|
||||
directives_list.forEach(function(s) { directives.set(s, 'keyword'); });
|
||||
keywords_list.forEach(function(s) { directives.set(s, 'keyword'); });
|
||||
properties_list.forEach(function(s) { directives.set(s, 'keyword'); });
|
||||
attributes_list.forEach(function(s) { directives.set(s, 'keyword'); });
|
||||
actions_list.forEach(function(s) { directives.set(s, 'keyword'); });
|
||||
|
||||
var numbers = /^([\da-f]+h|[0-7]+o|[01]+b|\d+d?)\b/i;
|
||||
|
||||
/*
|
||||
var type, content;
|
||||
function ret(tp, style, cont) {
|
||||
type = tp; content = cont;
|
||||
return style;
|
||||
}
|
||||
*/
|
||||
|
||||
function tokenBase(stream, state) {
|
||||
if (stream.eatSpace())
|
||||
return null;
|
||||
|
||||
var w;
|
||||
if (stream.eatWhile(/\w/)) {
|
||||
w = stream.current();
|
||||
var cur = w.toLowerCase();
|
||||
var style = directives.get(cur);
|
||||
if (style)
|
||||
return style;
|
||||
|
||||
if (numbers.test(w)) {
|
||||
return 'number';
|
||||
} else if (stream.match(numbers)) {
|
||||
return 'number';
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else if (stream.eat('!')) {
|
||||
stream.skipToEnd();
|
||||
return 'comment';
|
||||
} else if (stream.match(/\]|\[|\}|\{/)) {
|
||||
return 'bracket';
|
||||
} else if (stream.match(/\<\<|\>\>/)) {
|
||||
return 'bracket';
|
||||
} else if (stream.match(/[#]+\w+/)) {
|
||||
return 'number';
|
||||
} else if (stream.eat('"')) {
|
||||
state.tokenize = tokenString;
|
||||
return tokenString(stream, state);
|
||||
} else if (stream.eat('\'')) {
|
||||
return tokenString2(stream, state);
|
||||
} else if (stream.eat('$')) {
|
||||
if (stream.eatWhile(/[^;]/i))
|
||||
return 'number';
|
||||
} else {
|
||||
stream.next();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function tokenString(stream, state) {
|
||||
var ch;
|
||||
while (ch = stream.next()) {
|
||||
if (ch == '"') {
|
||||
state.tokenize = tokenBase;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return "string";
|
||||
}
|
||||
|
||||
function tokenString2(stream, state) {
|
||||
var ch;
|
||||
while (ch = stream.next()) {
|
||||
if (ch == "'") {
|
||||
state.tokenize = tokenBase;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return "meta";
|
||||
}
|
||||
|
||||
return {
|
||||
startState: function() {
|
||||
return {
|
||||
context: 0,
|
||||
tokenize: tokenBase
|
||||
};
|
||||
},
|
||||
token: function(stream, state) {
|
||||
return state.tokenize(stream, state);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/x-inform6", "inform6");
|
||||
|
||||
});
|
|
@ -191,6 +191,9 @@ export abstract class BasePlatform {
|
|||
this.recorder.recordFrame(this.saveState());
|
||||
}
|
||||
}
|
||||
inspect(sym: string) : string {
|
||||
return inspectSymbol((this as any) as Platform, sym);
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class BaseDebugPlatform extends BasePlatform {
|
||||
|
@ -352,23 +355,23 @@ export abstract class BaseDebugPlatform extends BasePlatform {
|
|||
return this.frameCount > frame0;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
inspect(sym: string) : string {
|
||||
if (!this.debugSymbols) return;
|
||||
var symmap = this.debugSymbols.symbolmap;
|
||||
var addr2sym = this.debugSymbols.addr2symbol;
|
||||
if (!symmap || !this.readAddress) return null;
|
||||
var addr = symmap["_"+sym] || symmap[sym]; // look for C or asm symbol
|
||||
if (!(typeof addr == 'number')) return null;
|
||||
var b = this.readAddress(addr);
|
||||
// don't show 2 bytes if there's a symbol at the next address
|
||||
if (addr2sym && addr2sym[addr+1] != null) {
|
||||
return "$"+hex(addr,4) + " = "+hex(b,2);
|
||||
} else {
|
||||
var b2 = this.readAddress(addr+1);
|
||||
var w = b | (b2<<8);
|
||||
return "$"+hex(addr,4) + " = "+hex(b,2)+" "+hex(b2,2)+" ($"+hex(w,2)+")";
|
||||
}
|
||||
export function inspectSymbol(platform : Platform, sym : string) : string {
|
||||
if (!platform.debugSymbols) return;
|
||||
var symmap = platform.debugSymbols.symbolmap;
|
||||
var addr2sym = platform.debugSymbols.addr2symbol;
|
||||
if (!symmap || !platform.readAddress) return null;
|
||||
var addr = symmap["_"+sym] || symmap[sym]; // look for C or asm symbol
|
||||
if (!(typeof addr == 'number')) return null;
|
||||
var b = platform.readAddress(addr);
|
||||
// don't show 2 bytes if there's a symbol at the next address
|
||||
if (addr2sym && addr2sym[addr+1] != null) {
|
||||
return "$"+hex(addr,4) + " = $"+hex(b,2)+" ("+b+" decimal)"; // unsigned
|
||||
} else {
|
||||
let b2 = platform.readAddress(addr+1);
|
||||
let w = b | (b2<<8);
|
||||
return "$"+hex(addr,4) + " = $"+hex(b,2)+" $"+hex(b2,2)+" ("+((w<<16)>>16)+" decimal)"; // signed
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -79,6 +79,7 @@ var TOOL_TO_SOURCE_STYLE = {
|
|||
'cmoc': 'text/x-csrc',
|
||||
'yasm': 'gas',
|
||||
'smlrc': 'text/x-csrc',
|
||||
'inform6': 'inform6',
|
||||
}
|
||||
|
||||
function gaEvent(category:string, action:string, label?:string, value?:string) {
|
||||
|
|
|
@ -62,6 +62,17 @@ function newDiv(parent?, cls? : string) {
|
|||
|
||||
const MAX_ERRORS = 200;
|
||||
|
||||
const MODEDEFS = {
|
||||
default: { theme: 'mbo' }, // NOTE: Not merged w/ other modes
|
||||
'6502': { isAsm: true },
|
||||
z80: { isAsm: true },
|
||||
jsasm: { isAsm: true },
|
||||
gas: { isAsm: true },
|
||||
inform6: { theme: 'cobalt' },
|
||||
markdown: { lineWrap: true },
|
||||
}
|
||||
|
||||
|
||||
export class SourceEditor implements ProjectView {
|
||||
constructor(path:string, mode:string) {
|
||||
this.path = path;
|
||||
|
@ -92,10 +103,12 @@ export class SourceEditor implements ProjectView {
|
|||
}
|
||||
|
||||
newEditor(parent:HTMLElement, isAsmOverride?:boolean) {
|
||||
var isAsm = isAsmOverride || this.mode=='6502' || this.mode =='z80' || this.mode=='jsasm' || this.mode=='gas'; // TODO
|
||||
var lineWrap = this.mode=='markdown';
|
||||
var modedef = MODEDEFS[this.mode] || MODEDEFS.default;
|
||||
var isAsm = isAsmOverride || modedef.isAsm;
|
||||
var lineWrap = modedef.lineWrap;
|
||||
var theme = modedef.theme || MODEDEFS.default.theme;
|
||||
this.editor = CodeMirror(parent, {
|
||||
theme: 'mbo',
|
||||
theme: theme,
|
||||
lineNumbers: true,
|
||||
matchBrackets: true,
|
||||
tabSize: 8,
|
||||
|
@ -525,12 +538,15 @@ export class ListingView extends DisassemblerView implements ProjectView {
|
|||
|
||||
refresh(moveCursor: boolean) {
|
||||
this.refreshListing();
|
||||
if (!this.assemblyfile || !platform.saveState) return;
|
||||
var state = lastDebugState || platform.saveState();
|
||||
var pc = state.c ? (state.c.EPC || state.c.PC) : 0;
|
||||
// load listing text into editor
|
||||
if (!this.assemblyfile) return;
|
||||
var asmtext = this.assemblyfile.text;
|
||||
var disasmview = this.getDisasmView();
|
||||
disasmview.setValue(asmtext);
|
||||
// go to PC
|
||||
if (!platform.saveState) return;
|
||||
var state = lastDebugState || platform.saveState();
|
||||
var pc = state.c ? (state.c.EPC || state.c.PC) : 0;
|
||||
if (pc >= 0 && this.assemblyfile) {
|
||||
var res = this.assemblyfile.findLineForOffset(pc, 15);
|
||||
if (res) {
|
||||
|
|
|
@ -763,7 +763,7 @@ var VerilogPlatform = function(mainElement, options) {
|
|||
}
|
||||
getDefaultExtension() { return ".v"; };
|
||||
|
||||
inspect(name) {
|
||||
inspect(name:string) : string {
|
||||
if (!gen) return;
|
||||
if (name && !name.match(/^\w+$/)) return;
|
||||
var val = gen[name];
|
||||
|
|
|
@ -0,0 +1,714 @@
|
|||
|
||||
import { Platform, BasePlatform, BaseDebugPlatform, Preset, EmuState, inspectSymbol } from "../common/baseplatform";
|
||||
import { PLATFORMS, EmuHalt } from "../common/emu";
|
||||
import { loadScript } from "../ide/ui";
|
||||
|
||||
const ZMACHINE_PRESETS = [
|
||||
{ id: 'hello.inf', name: 'Hello World' },
|
||||
{ id: 'house01.inf', name: 'House Tutorial #1' },
|
||||
{ id: 'house02.inf', name: 'House Tutorial #2' },
|
||||
{ id: 'house03.inf', name: 'House Tutorial #3' },
|
||||
{ id: 'house04.inf', name: 'House Tutorial #4' },
|
||||
{ id: 'house05.inf', name: 'House Tutorial #5' },
|
||||
{ id: 'house06.inf', name: 'House Tutorial #6' },
|
||||
{ id: 'house07.inf', name: 'House Tutorial #7' },
|
||||
{ id: 'alice.inf', name: 'Through the Looking-Glass' },
|
||||
{ id: 'aloneice.inf', name: 'Alone on the Ice' },
|
||||
{ id: 'adventureland.inf', name: 'Adventureland' },
|
||||
{ id: 'toyshop.inf', name: 'Toyshop' },
|
||||
{ id: 'ruins1.inf', name: 'Ruins #1' },
|
||||
{ id: 'ruins2.inf', name: 'Ruins #2' },
|
||||
{ id: 'ruins3.inf', name: 'Ruins #3' },
|
||||
{ id: 'balances.inf', name: 'Balances' },
|
||||
{ id: 'museum.inf', name: 'Museum of Inform' },
|
||||
{ id: 'advent.inf', name: 'Colossal Cave Adventure' },
|
||||
];
|
||||
|
||||
declare var ZVM;
|
||||
|
||||
// https://github.com/erkyrath/quixe/wiki/Quixe-Without-GlkOte#quixes-api
|
||||
// https://eblong.com/zarf/glk/glkote/docs.html
|
||||
// https://inform-fiction.org/zmachine/standards/z1point0/sect15.html#read_char
|
||||
// https://manpages.debian.org/testing/inform6-compiler/inform6.1.en.html
|
||||
|
||||
class GlkWindow {
|
||||
//area: HTMLElement;
|
||||
// TODO
|
||||
}
|
||||
|
||||
interface IFZVM {
|
||||
start();
|
||||
run();
|
||||
version : number;
|
||||
pc : number;
|
||||
ram : DataView;
|
||||
stack : DataView;
|
||||
read_data : {buffer?};
|
||||
handle_line_input(len:number);
|
||||
handle_char_input(charcode:number);
|
||||
}
|
||||
|
||||
class GlkImpl {
|
||||
vm : IFZVM;
|
||||
page: HTMLElement;
|
||||
input: HTMLInputElement;
|
||||
curline: HTMLElement;
|
||||
curstyle: number;
|
||||
reverse: boolean;
|
||||
windows: GlkWindow[];
|
||||
wnd: GlkWindow;
|
||||
waitingfor: "line" | "char" | null;
|
||||
focused = false;
|
||||
|
||||
constructor(page: HTMLElement, input: HTMLInputElement) {
|
||||
this.page = page;
|
||||
this.input = input;
|
||||
this.reset();
|
||||
}
|
||||
reset() {
|
||||
this.windows = [];
|
||||
this.wnd = null;
|
||||
this.clear();
|
||||
}
|
||||
clear() {
|
||||
this.curline = null;
|
||||
this.curstyle = 0;
|
||||
this.reverse = false;
|
||||
// keep from losing input handlers
|
||||
this.hideinput();
|
||||
$(this.page).empty();
|
||||
}
|
||||
init(options) {
|
||||
this.vm = options.vm;
|
||||
this.vm.start();
|
||||
}
|
||||
fatal_error(s:string) {
|
||||
throw new EmuHalt(s);
|
||||
}
|
||||
update() {
|
||||
// TODO
|
||||
}
|
||||
glk_exit() {
|
||||
this.flushline();
|
||||
this.addtext("** Game exited **", 1);
|
||||
}
|
||||
glk_window_clear(win) {
|
||||
console.log('glk_window_clear', arguments);
|
||||
this.clear();
|
||||
}
|
||||
glk_request_line_event_uni(win, buf, initlen) {
|
||||
this.waitingfor = 'line';
|
||||
this.focusinput();
|
||||
}
|
||||
glk_request_char_event_uni(win, buf, initlen) {
|
||||
this.waitingfor = 'char';
|
||||
this.focusinput();
|
||||
}
|
||||
focusinput() {
|
||||
this.ensureline();
|
||||
// don't steal focus while editing
|
||||
$(this.input).appendTo(this.curline).show()[0].scrollIntoView();
|
||||
if (this.focused) {
|
||||
$(this.input).focus();
|
||||
}
|
||||
}
|
||||
hideinput() {
|
||||
$(this.input).appendTo($(this.page).parent()).hide();
|
||||
}
|
||||
clearinput() {
|
||||
this.input.value = '';
|
||||
this.waitingfor = null;
|
||||
}
|
||||
sendkey(e: KeyboardEvent) {
|
||||
if (this.waitingfor == 'line') {
|
||||
if (e.key == "Enter") {
|
||||
this.sendinput(this.input.value.toString());
|
||||
}
|
||||
} else if (this.waitingfor == 'char') {
|
||||
this.vm.handle_char_input(e.keyCode);
|
||||
this.vm.run();
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
sendinput(s: string) {
|
||||
this.addtext(s, Const.style_Input);
|
||||
this.flushline();
|
||||
if (this.vm.read_data.buffer) {
|
||||
for (var i = 0; i < s.length; i++) {
|
||||
this.vm.read_data.buffer[i] = s.charCodeAt(i) & 0xff;
|
||||
}
|
||||
this.vm.handle_line_input(s.length);
|
||||
}
|
||||
this.clearinput();
|
||||
this.vm.run();
|
||||
}
|
||||
ensureline() {
|
||||
$(this.input).hide();
|
||||
if (this.curline == null) {
|
||||
this.curline = $('<div class="transcript-line"/>')[0];
|
||||
this.page.appendChild(this.curline);
|
||||
}
|
||||
}
|
||||
flushline() {
|
||||
this.curline = null;
|
||||
}
|
||||
addtext(line: string, style: number) {
|
||||
this.ensureline();
|
||||
if (line.length) {
|
||||
var span = $("<span/>").text(line).appendTo(this.curline);
|
||||
for (var i=0; i<8; i++) {
|
||||
if (style & (1<<i))
|
||||
span.addClass("transcript-style-" + (1<<i));
|
||||
}
|
||||
if (this.reverse) span.addClass("transcript-reverse");
|
||||
span.data('vmip', this.vm.pc);
|
||||
}
|
||||
}
|
||||
glk_put_jstring(val: string, allbytes) {
|
||||
var lines = val.split("\n");
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
if (i > 0) this.flushline();
|
||||
this.addtext(lines[i], this.curstyle);
|
||||
}
|
||||
}
|
||||
glk_put_char(ch) {
|
||||
console.log('glk_put_char', arguments);
|
||||
}
|
||||
glk_put_char_stream(str, ch) {
|
||||
console.log('glk_put_char_stream', arguments);
|
||||
}
|
||||
glk_put_string(val) {
|
||||
console.log('glk_put_string', arguments);
|
||||
}
|
||||
glk_put_string_stream(str, val) {
|
||||
console.log('glk_put_string_stream', arguments);
|
||||
}
|
||||
glk_put_buffer(arr) {
|
||||
console.log('glk_put_buffer', arguments);
|
||||
}
|
||||
glk_put_buffer_stream(str, arr) {
|
||||
console.log('glk_put_buffer_stream', arguments);
|
||||
}
|
||||
glk_set_style(val) {
|
||||
this.curstyle = val;
|
||||
}
|
||||
glk_set_style_stream(str, val) {
|
||||
console.log('glk_set_style_stream', arguments);
|
||||
}
|
||||
glk_get_char_stream(str) {
|
||||
console.log('glk_get_char_stream', arguments);
|
||||
}
|
||||
glk_get_line_stream(str, buf) {
|
||||
console.log('glk_get_line_stream', arguments);
|
||||
}
|
||||
glk_get_buffer_stream(str, buf) {
|
||||
console.log('glk_get_buffer_stream', arguments);
|
||||
}
|
||||
glk_char_to_lower(val) {
|
||||
if (val >= 0x41 && val <= 0x5A)
|
||||
return val + 0x20;
|
||||
if (val >= 0xC0 && val <= 0xDE && val != 0xD7)
|
||||
return val + 0x20;
|
||||
return val;
|
||||
}
|
||||
glk_char_to_upper(val) {
|
||||
if (val >= 0x61 && val <= 0x7A)
|
||||
return val - 0x20;
|
||||
if (val >= 0xE0 && val <= 0xFE && val != 0xF7)
|
||||
return val - 0x20;
|
||||
return val;
|
||||
}
|
||||
glk_stylehint_set(wintype, styl, hint, value) {
|
||||
console.log('glk_stylehint_set', arguments);
|
||||
}
|
||||
glk_stylehint_clear(wintype, styl, hint) {
|
||||
console.log('glk_stylehint_clear', arguments);
|
||||
}
|
||||
glk_style_distinguish(win, styl1, styl2) {
|
||||
return 0;
|
||||
}
|
||||
glk_style_measure(win, styl, hint, resultref) {
|
||||
if (resultref)
|
||||
resultref.set_value(0);
|
||||
return 0;
|
||||
}
|
||||
glk_select(eventref) {
|
||||
console.log('glk_select', arguments);
|
||||
}
|
||||
glk_window_open(splitwin, method, size, wintype, rock) {
|
||||
console.log('glk_window_open', arguments);
|
||||
if (splitwin) console.log("split windows are not supported");
|
||||
return splitwin ? 0 : 1; // 0 = no window, 1 = main window
|
||||
}
|
||||
/*
|
||||
glk_window_close(win) {
|
||||
console.log('glk_window_close', arguments);
|
||||
this.windows.pop(); // TODO
|
||||
}
|
||||
glk_window_get_parent(win) {
|
||||
console.log('glk_window_get_parent', arguments);
|
||||
}
|
||||
glk_window_set_arrangement(win) {
|
||||
console.log('glk_window_set_arrangement', arguments);
|
||||
}
|
||||
glk_window_get_stream(win) {
|
||||
console.log('glk_window_get_stream', arguments);
|
||||
}
|
||||
*/
|
||||
glk_set_window(win) {
|
||||
console.log('glk_set_window', arguments);
|
||||
//if (!win) gli_currentstr = null;
|
||||
//else gli_currentstr = win.str;
|
||||
}
|
||||
glk_window_get_size(win, widthref, heightref) {
|
||||
console.log('glk_window_get_size', arguments);
|
||||
}
|
||||
garglk_set_reversevideo(val) {
|
||||
this.reverse = !!val;
|
||||
}
|
||||
glk_gestalt(sel, val) {
|
||||
return this.glk_gestalt_ext(sel, val, null);
|
||||
}
|
||||
glk_gestalt_ext(sel, val, arr) {
|
||||
console.log('glk_gestalt_ext', arguments);
|
||||
switch (sel) {
|
||||
|
||||
case 0: // gestalt_Version
|
||||
/* This implements Glk spec version 0.7.4? */
|
||||
return 0x00000101; // 0.1.1
|
||||
|
||||
case 1: // gestalt_CharInput
|
||||
/* This is not a terrific approximation. Return false for function
|
||||
keys, control keys, and the high-bit non-printables. For
|
||||
everything else in the Unicode range, return true. */
|
||||
if (val <= Const.keycode_Left && val >= Const.keycode_End)
|
||||
return 1;
|
||||
if (val >= 0x100000000 - Const.keycode_MAXVAL)
|
||||
return 0;
|
||||
if (val > 0x10FFFF)
|
||||
return 0;
|
||||
if ((val >= 0 && val < 32) || (val >= 127 && val < 160))
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
case 2: // gestalt_LineInput
|
||||
/* Same as the above, except no special keys. */
|
||||
if (val > 0x10FFFF)
|
||||
return 0;
|
||||
if ((val >= 0 && val < 32) || (val >= 127 && val < 160))
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
case 3: // gestalt_CharOutput
|
||||
/* Same thing again. We assume that all printable characters,
|
||||
as well as the placeholders for nonprintables, are one character
|
||||
wide. */
|
||||
if ((val > 0x10FFFF)
|
||||
|| (val >= 0 && val < 32)
|
||||
|| (val >= 127 && val < 160)) {
|
||||
if (arr)
|
||||
arr[0] = 1;
|
||||
return 0; // gestalt_CharOutput_CannotPrint
|
||||
}
|
||||
if (arr)
|
||||
arr[0] = 1;
|
||||
return 2; // gestalt_CharOutput_ExactPrint
|
||||
|
||||
case 4: // gestalt_MouseInput
|
||||
if (val == Const.wintype_TextBuffer)
|
||||
return 0;
|
||||
if (val == Const.wintype_Graphics && has_canvas)
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
case 5: // gestalt_Timer
|
||||
return 0;
|
||||
|
||||
case 6: // gestalt_Graphics
|
||||
return 0;
|
||||
|
||||
case 7: // gestalt_DrawImage
|
||||
if (val == Const.wintype_TextBuffer)
|
||||
return 0;
|
||||
if (val == Const.wintype_Graphics && has_canvas)
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
case 8: // gestalt_Sound
|
||||
return 0;
|
||||
|
||||
case 9: // gestalt_SoundVolume
|
||||
return 0;
|
||||
|
||||
case 10: // gestalt_SoundNotify
|
||||
return 0;
|
||||
|
||||
case 11: // gestalt_Hyperlinks
|
||||
return 0;
|
||||
|
||||
case 12: // gestalt_HyperlinkInput
|
||||
if (val == 3 || val == 4) // TextBuffer or TextGrid
|
||||
return 0;
|
||||
else
|
||||
return 0;
|
||||
|
||||
case 13: // gestalt_SoundMusic
|
||||
return 0;
|
||||
|
||||
case 14: // gestalt_GraphicsTransparency
|
||||
return 0;
|
||||
|
||||
case 15: // gestalt_Unicode
|
||||
return 1;
|
||||
|
||||
case 16: // gestalt_UnicodeNorm
|
||||
return 1;
|
||||
|
||||
case 17: // gestalt_LineInputEcho
|
||||
return 1;
|
||||
|
||||
case 18: // gestalt_LineTerminators
|
||||
return 1;
|
||||
|
||||
case 19: // gestalt_LineTerminatorKey
|
||||
/* Really this result should be inspected from glkote.js. Since it
|
||||
isn't, be sure to keep these values in sync with
|
||||
terminator_key_names. */
|
||||
if (val == Const.keycode_Escape)
|
||||
return 0;
|
||||
if (val >= Const.keycode_Func12 && val <= Const.keycode_Func1)
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
case 20: // gestalt_DateTime
|
||||
return 0;
|
||||
|
||||
case 21: // gestalt_Sound2
|
||||
return 0;
|
||||
|
||||
case 22: // gestalt_ResourceStream
|
||||
return 0;
|
||||
|
||||
case 23: // gestalt_GraphicsCharInput
|
||||
return 0;
|
||||
|
||||
case 0x1100: // reverse video, color
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* RefBox: Simple class used for "call-by-reference" Glk arguments. The object
|
||||
is just a box containing a single value, which can be written and read.
|
||||
*/
|
||||
RefBox = function () {
|
||||
this.value = undefined;
|
||||
this.set_value = function (val) {
|
||||
this.value = val;
|
||||
}
|
||||
this.get_value = function () {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
/* RefStruct: Used for struct-type Glk arguments. After creating the
|
||||
object, you should call push_field() the appropriate number of times,
|
||||
to set the initial field values. Then set_field() can be used to
|
||||
change them, and get_fields() retrieves the list of all fields.
|
||||
|
||||
(The usage here is loose, since Javascript is forgiving about arrays.
|
||||
Really the caller could call set_field() instead of push_field() --
|
||||
or skip that step entirely, as long as the Glk function later calls
|
||||
set_field() for each field. Which it should.)
|
||||
*/
|
||||
RefStruct = function (numels) {
|
||||
this.fields = [];
|
||||
this.push_field = function (val) {
|
||||
this.fields.push(val);
|
||||
}
|
||||
this.set_field = function (pos, val) {
|
||||
this.fields[pos] = val;
|
||||
}
|
||||
this.get_field = function (pos) {
|
||||
return this.fields[pos];
|
||||
}
|
||||
this.get_fields = function () {
|
||||
return this.fields;
|
||||
}
|
||||
}
|
||||
|
||||
/* Dummy return value, which means that the Glk call is still in progress,
|
||||
or will never return at all. This is used by glk_exit(), glk_select(),
|
||||
and glk_fileref_create_by_prompt().
|
||||
*/
|
||||
DidNotReturn = { dummy: 'Glk call has not yet returned' };
|
||||
}
|
||||
|
||||
const has_canvas = typeof window === 'object';
|
||||
|
||||
const Const = {
|
||||
gestalt_Version: 0,
|
||||
gestalt_CharInput: 1,
|
||||
gestalt_LineInput: 2,
|
||||
gestalt_CharOutput: 3,
|
||||
gestalt_CharOutput_CannotPrint: 0,
|
||||
gestalt_CharOutput_ApproxPrint: 1,
|
||||
gestalt_CharOutput_ExactPrint: 2,
|
||||
gestalt_MouseInput: 4,
|
||||
gestalt_Timer: 5,
|
||||
gestalt_Graphics: 6,
|
||||
gestalt_DrawImage: 7,
|
||||
gestalt_Sound: 8,
|
||||
gestalt_SoundVolume: 9,
|
||||
gestalt_SoundNotify: 10,
|
||||
gestalt_Hyperlinks: 11,
|
||||
gestalt_HyperlinkInput: 12,
|
||||
gestalt_SoundMusic: 13,
|
||||
gestalt_GraphicsTransparency: 14,
|
||||
gestalt_Unicode: 15,
|
||||
gestalt_UnicodeNorm: 16,
|
||||
gestalt_LineInputEcho: 17,
|
||||
gestalt_LineTerminators: 18,
|
||||
gestalt_LineTerminatorKey: 19,
|
||||
gestalt_DateTime: 20,
|
||||
gestalt_Sound2: 21,
|
||||
gestalt_ResourceStream: 22,
|
||||
gestalt_GraphicsCharInput: 23,
|
||||
|
||||
keycode_Unknown: 0xffffffff,
|
||||
keycode_Left: 0xfffffffe,
|
||||
keycode_Right: 0xfffffffd,
|
||||
keycode_Up: 0xfffffffc,
|
||||
keycode_Down: 0xfffffffb,
|
||||
keycode_Return: 0xfffffffa,
|
||||
keycode_Delete: 0xfffffff9,
|
||||
keycode_Escape: 0xfffffff8,
|
||||
keycode_Tab: 0xfffffff7,
|
||||
keycode_PageUp: 0xfffffff6,
|
||||
keycode_PageDown: 0xfffffff5,
|
||||
keycode_Home: 0xfffffff4,
|
||||
keycode_End: 0xfffffff3,
|
||||
keycode_Func1: 0xffffffef,
|
||||
keycode_Func2: 0xffffffee,
|
||||
keycode_Func3: 0xffffffed,
|
||||
keycode_Func4: 0xffffffec,
|
||||
keycode_Func5: 0xffffffeb,
|
||||
keycode_Func6: 0xffffffea,
|
||||
keycode_Func7: 0xffffffe9,
|
||||
keycode_Func8: 0xffffffe8,
|
||||
keycode_Func9: 0xffffffe7,
|
||||
keycode_Func10: 0xffffffe6,
|
||||
keycode_Func11: 0xffffffe5,
|
||||
keycode_Func12: 0xffffffe4,
|
||||
/* The last keycode is always (0x100000000 - keycode_MAXVAL) */
|
||||
keycode_MAXVAL: 28,
|
||||
|
||||
evtype_None: 0,
|
||||
evtype_Timer: 1,
|
||||
evtype_CharInput: 2,
|
||||
evtype_LineInput: 3,
|
||||
evtype_MouseInput: 4,
|
||||
evtype_Arrange: 5,
|
||||
evtype_Redraw: 6,
|
||||
evtype_SoundNotify: 7,
|
||||
evtype_Hyperlink: 8,
|
||||
evtype_VolumeNotify: 9,
|
||||
|
||||
style_Normal: 0,
|
||||
style_Emphasized: 1,
|
||||
style_Preformatted: 2,
|
||||
style_Header: 3,
|
||||
style_Subheader: 4,
|
||||
style_Alert: 5,
|
||||
style_Note: 6,
|
||||
style_BlockQuote: 7,
|
||||
style_Input: 8,
|
||||
style_User1: 9,
|
||||
style_User2: 10,
|
||||
style_NUMSTYLES: 11,
|
||||
|
||||
wintype_AllTypes: 0,
|
||||
wintype_Pair: 1,
|
||||
wintype_Blank: 2,
|
||||
wintype_TextBuffer: 3,
|
||||
wintype_TextGrid: 4,
|
||||
wintype_Graphics: 5,
|
||||
|
||||
winmethod_Left: 0x00,
|
||||
winmethod_Right: 0x01,
|
||||
winmethod_Above: 0x02,
|
||||
winmethod_Below: 0x03,
|
||||
winmethod_DirMask: 0x0f,
|
||||
|
||||
winmethod_Fixed: 0x10,
|
||||
winmethod_Proportional: 0x20,
|
||||
winmethod_DivisionMask: 0xf0,
|
||||
|
||||
winmethod_Border: 0x000,
|
||||
winmethod_NoBorder: 0x100,
|
||||
winmethod_BorderMask: 0x100,
|
||||
|
||||
fileusage_Data: 0x00,
|
||||
fileusage_SavedGame: 0x01,
|
||||
fileusage_Transcript: 0x02,
|
||||
fileusage_InputRecord: 0x03,
|
||||
fileusage_TypeMask: 0x0f,
|
||||
|
||||
fileusage_TextMode: 0x100,
|
||||
fileusage_BinaryMode: 0x000,
|
||||
|
||||
filemode_Write: 0x01,
|
||||
filemode_Read: 0x02,
|
||||
filemode_ReadWrite: 0x03,
|
||||
filemode_WriteAppend: 0x05,
|
||||
|
||||
seekmode_Start: 0,
|
||||
seekmode_Current: 1,
|
||||
seekmode_End: 2,
|
||||
|
||||
stylehint_Indentation: 0,
|
||||
stylehint_ParaIndentation: 1,
|
||||
stylehint_Justification: 2,
|
||||
stylehint_Size: 3,
|
||||
stylehint_Weight: 4,
|
||||
stylehint_Oblique: 5,
|
||||
stylehint_Proportional: 6,
|
||||
stylehint_TextColor: 7,
|
||||
stylehint_BackColor: 8,
|
||||
stylehint_ReverseColor: 9,
|
||||
stylehint_NUMHINTS: 10,
|
||||
|
||||
stylehint_just_LeftFlush: 0,
|
||||
stylehint_just_LeftRight: 1,
|
||||
stylehint_just_Centered: 2,
|
||||
stylehint_just_RightFlush: 3,
|
||||
|
||||
imagealign_InlineUp: 1,
|
||||
imagealign_InlineDown: 2,
|
||||
imagealign_InlineCenter: 3,
|
||||
imagealign_MarginLeft: 4,
|
||||
imagealign_MarginRight: 5
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class ZmachinePlatform implements Platform {
|
||||
mainElement: HTMLElement;
|
||||
zfile : Uint8Array;
|
||||
zvm;
|
||||
glk;
|
||||
focused = false;
|
||||
|
||||
constructor(mainElement: HTMLElement) {
|
||||
this.mainElement = mainElement;
|
||||
$(mainElement).css('overflowY', 'auto');
|
||||
}
|
||||
|
||||
async start() {
|
||||
await loadScript('./lib/zvm/ifvms.min.js');
|
||||
//await loadScript('./lib/zvm/glkote.min.js');
|
||||
//await loadScript('./lib/zvm/glkapi.js');
|
||||
//await loadScript('./lib/zvm/parchment.debug.js');
|
||||
|
||||
// create divs
|
||||
var parent = this.mainElement;
|
||||
var gameport = $('<div id="gameport"/>').appendTo(parent);
|
||||
var windowport = $('<div id="windowport" class="transcript"/>').appendTo(gameport);
|
||||
var inputline = $('<input class="transcript-input" type="text"/>').appendTo(gameport).hide();
|
||||
this.glk = new GlkImpl(windowport[0], inputline[0] as HTMLInputElement);
|
||||
inputline.on('keypress', (e) => {
|
||||
this.glk.sendkey(e);
|
||||
});
|
||||
inputline.on('focus', (e) => {
|
||||
this.glk.focused = true;
|
||||
});
|
||||
inputline.on('blur', (e) => {
|
||||
this.glk.focused = false;
|
||||
});
|
||||
windowport.on('click', (e) => {
|
||||
inputline.focus();
|
||||
});
|
||||
}
|
||||
|
||||
loadROM(title, data) {
|
||||
this.zfile = data;
|
||||
this.reset();
|
||||
}
|
||||
|
||||
reset(): void {
|
||||
if (this.zfile == null) return;
|
||||
//this.glk = Glk;
|
||||
//this.glk = new Object();
|
||||
//Object.setPrototypeOf(this.glk, Glk);
|
||||
this.zvm = new ZVM();
|
||||
this.zvm.prepare(this.zfile.slice(0), {
|
||||
Glk: this.glk,
|
||||
});
|
||||
this.glk.reset();
|
||||
this.glk.init({
|
||||
vm: this.zvm,
|
||||
});
|
||||
console.log(this.zvm);
|
||||
}
|
||||
|
||||
pause(): void {
|
||||
}
|
||||
resume(): void {
|
||||
}
|
||||
|
||||
readAddress(a: number) {
|
||||
return this.zvm && a < this.zvm.ram.byteLength ? this.zvm.ram.getUint8(a) : this.zfile[a];
|
||||
}
|
||||
|
||||
getPC() {
|
||||
return this.zvm.pc;
|
||||
}
|
||||
/*
|
||||
loadState(state): void {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
saveState() {
|
||||
return {
|
||||
//glk: this.Glk.save_allstate(),
|
||||
io: $.extend(true, {}, this.zvm.io),
|
||||
ram: this.zvm.save_file(this.zvm.pc, 1),
|
||||
read_data: $.extend(true, {}, this.zvm.read_data),
|
||||
xorshift_seed: this.zvm.xorshift_seed,
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
isRunning(): boolean {
|
||||
return this.zvm != null;
|
||||
}
|
||||
advance(novideo?: boolean): number {
|
||||
// TODO?
|
||||
return 0;
|
||||
}
|
||||
|
||||
getToolForFilename(s: string): string {
|
||||
return "inform6";
|
||||
}
|
||||
getDefaultExtension(): string {
|
||||
return ".inf";
|
||||
}
|
||||
showHelp(tool:string, ident?:string) {
|
||||
switch (tool) {
|
||||
case 'inform6': window.open("https://www.inform-fiction.org/manual/html/"); break;
|
||||
}
|
||||
}
|
||||
getPresets(): Preset[] {
|
||||
return ZMACHINE_PRESETS;
|
||||
}
|
||||
|
||||
inspect(ident:string) {
|
||||
return inspectSymbol(this, ident);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
PLATFORMS['zmachine'] = ZmachinePlatform;
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,201 @@
|
|||
|
||||
var Module = typeof Module !== 'undefined' ? Module : {};
|
||||
|
||||
if (!Module.expectedDataFileDownloads) {
|
||||
Module.expectedDataFileDownloads = 0;
|
||||
}
|
||||
Module.expectedDataFileDownloads++;
|
||||
(function() {
|
||||
var loadPackage = function(metadata) {
|
||||
|
||||
var PACKAGE_PATH;
|
||||
if (typeof window === 'object') {
|
||||
PACKAGE_PATH = window['encodeURIComponent'](window.location.pathname.toString().substring(0, window.location.pathname.toString().lastIndexOf('/')) + '/');
|
||||
} else if (typeof location !== 'undefined') {
|
||||
// worker
|
||||
PACKAGE_PATH = encodeURIComponent(location.pathname.toString().substring(0, location.pathname.toString().lastIndexOf('/')) + '/');
|
||||
} else {
|
||||
throw 'using preloaded data can only be done on a web page or in a web worker';
|
||||
}
|
||||
var PACKAGE_NAME = 'fsinform.data';
|
||||
var REMOTE_PACKAGE_BASE = 'fsinform.data';
|
||||
if (typeof Module['locateFilePackage'] === 'function' && !Module['locateFile']) {
|
||||
Module['locateFile'] = Module['locateFilePackage'];
|
||||
err('warning: you defined Module.locateFilePackage, that has been renamed to Module.locateFile (using your locateFilePackage for now)');
|
||||
}
|
||||
var REMOTE_PACKAGE_NAME = Module['locateFile'] ? Module['locateFile'](REMOTE_PACKAGE_BASE, '') : REMOTE_PACKAGE_BASE;
|
||||
|
||||
var REMOTE_PACKAGE_SIZE = metadata['remote_package_size'];
|
||||
var PACKAGE_UUID = metadata['package_uuid'];
|
||||
|
||||
function fetchRemotePackage(packageName, packageSize, callback, errback) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', packageName, true);
|
||||
xhr.responseType = 'arraybuffer';
|
||||
xhr.onprogress = function(event) {
|
||||
var url = packageName;
|
||||
var size = packageSize;
|
||||
if (event.total) size = event.total;
|
||||
if (event.loaded) {
|
||||
if (!xhr.addedTotal) {
|
||||
xhr.addedTotal = true;
|
||||
if (!Module.dataFileDownloads) Module.dataFileDownloads = {};
|
||||
Module.dataFileDownloads[url] = {
|
||||
loaded: event.loaded,
|
||||
total: size
|
||||
};
|
||||
} else {
|
||||
Module.dataFileDownloads[url].loaded = event.loaded;
|
||||
}
|
||||
var total = 0;
|
||||
var loaded = 0;
|
||||
var num = 0;
|
||||
for (var download in Module.dataFileDownloads) {
|
||||
var data = Module.dataFileDownloads[download];
|
||||
total += data.total;
|
||||
loaded += data.loaded;
|
||||
num++;
|
||||
}
|
||||
total = Math.ceil(total * Module.expectedDataFileDownloads/num);
|
||||
if (Module['setStatus']) Module['setStatus']('Downloading data... (' + loaded + '/' + total + ')');
|
||||
} else if (!Module.dataFileDownloads) {
|
||||
if (Module['setStatus']) Module['setStatus']('Downloading data...');
|
||||
}
|
||||
};
|
||||
xhr.onerror = function(event) {
|
||||
throw new Error("NetworkError for: " + packageName);
|
||||
}
|
||||
xhr.onload = function(event) {
|
||||
if (xhr.status == 200 || xhr.status == 304 || xhr.status == 206 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0
|
||||
var packageData = xhr.response;
|
||||
callback(packageData);
|
||||
} else {
|
||||
throw new Error(xhr.statusText + " : " + xhr.responseURL);
|
||||
}
|
||||
};
|
||||
xhr.send(null);
|
||||
};
|
||||
|
||||
function handleError(error) {
|
||||
console.error('package error:', error);
|
||||
};
|
||||
|
||||
var fetchedCallback = null;
|
||||
var fetched = Module['getPreloadedPackage'] ? Module['getPreloadedPackage'](REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE) : null;
|
||||
|
||||
if (!fetched) fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE, function(data) {
|
||||
if (fetchedCallback) {
|
||||
fetchedCallback(data);
|
||||
fetchedCallback = null;
|
||||
} else {
|
||||
fetched = data;
|
||||
}
|
||||
}, handleError);
|
||||
|
||||
function runWithFS() {
|
||||
|
||||
function assert(check, msg) {
|
||||
if (!check) throw msg + new Error().stack;
|
||||
}
|
||||
Module['FS_createPath']('/', 'include', true, true);
|
||||
Module['FS_createPath']('/', 'lib', true, true);
|
||||
|
||||
/** @constructor */
|
||||
function DataRequest(start, end, audio) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.audio = audio;
|
||||
}
|
||||
DataRequest.prototype = {
|
||||
requests: {},
|
||||
open: function(mode, name) {
|
||||
this.name = name;
|
||||
this.requests[name] = this;
|
||||
Module['addRunDependency']('fp ' + this.name);
|
||||
},
|
||||
send: function() {},
|
||||
onload: function() {
|
||||
var byteArray = this.byteArray.subarray(this.start, this.end);
|
||||
this.finish(byteArray);
|
||||
},
|
||||
finish: function(byteArray) {
|
||||
var that = this;
|
||||
|
||||
Module['FS_createDataFile'](this.name, null, byteArray, true, true, true); // canOwn this data in the filesystem, it is a slide into the heap that will never change
|
||||
Module['removeRunDependency']('fp ' + that.name);
|
||||
|
||||
this.requests[this.name] = null;
|
||||
}
|
||||
};
|
||||
|
||||
var files = metadata['files'];
|
||||
for (var i = 0; i < files.length; ++i) {
|
||||
new DataRequest(files[i]['start'], files[i]['end'], files[i]['audio']).open('GET', files[i]['filename']);
|
||||
}
|
||||
|
||||
|
||||
function processPackageData(arrayBuffer) {
|
||||
assert(arrayBuffer, 'Loading data file failed.');
|
||||
assert(arrayBuffer instanceof ArrayBuffer, 'bad input to processPackageData');
|
||||
var byteArray = new Uint8Array(arrayBuffer);
|
||||
var curr;
|
||||
|
||||
// copy the entire loaded file into a spot in the heap. Files will refer to slices in that. They cannot be freed though
|
||||
// (we may be allocating before malloc is ready, during startup).
|
||||
var ptr = Module['getMemory'](byteArray.length);
|
||||
Module['HEAPU8'].set(byteArray, ptr);
|
||||
DataRequest.prototype.byteArray = Module['HEAPU8'].subarray(ptr, ptr+byteArray.length);
|
||||
|
||||
var files = metadata['files'];
|
||||
for (var i = 0; i < files.length; ++i) {
|
||||
DataRequest.prototype.requests[files[i].filename].onload();
|
||||
}
|
||||
Module['removeRunDependency']('datafile_fsinform.data');
|
||||
|
||||
};
|
||||
Module['addRunDependency']('datafile_fsinform.data');
|
||||
|
||||
if (!Module.preloadResults) Module.preloadResults = {};
|
||||
|
||||
Module.preloadResults[PACKAGE_NAME] = {fromCache: false};
|
||||
if (fetched) {
|
||||
processPackageData(fetched);
|
||||
fetched = null;
|
||||
} else {
|
||||
fetchedCallback = processPackageData;
|
||||
}
|
||||
|
||||
}
|
||||
if (Module['calledRun']) {
|
||||
runWithFS();
|
||||
} else {
|
||||
if (!Module['preRun']) Module['preRun'] = [];
|
||||
Module["preRun"].push(runWithFS); // FS is not initialized yet, wait for it
|
||||
}
|
||||
|
||||
Module['removeRunDependency']('fsinform.js.metadata');
|
||||
}
|
||||
|
||||
function runMetaWithFS() {
|
||||
Module['addRunDependency']('fsinform.js.metadata');
|
||||
var REMOTE_METADATA_NAME = Module['locateFile'] ? Module['locateFile']('fsinform.js.metadata', '') : 'fsinform.js.metadata';
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState === 4 && xhr.status === 200) {
|
||||
loadPackage(JSON.parse(xhr.responseText));
|
||||
}
|
||||
}
|
||||
xhr.open('GET', REMOTE_METADATA_NAME, true);
|
||||
xhr.overrideMimeType('application/json');
|
||||
xhr.send(null);
|
||||
}
|
||||
|
||||
if (Module['calledRun']) {
|
||||
runMetaWithFS();
|
||||
} else {
|
||||
if (!Module['preRun']) Module['preRun'] = [];
|
||||
Module["preRun"].push(runMetaWithFS);
|
||||
}
|
||||
|
||||
})();
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"files":[{"start":0,"audio":0,"end":5037,"filename":"/include/trinitystat.h"},{"start":5037,"audio":0,"end":8410,"filename":"/include/zclock.h"},{"start":8410,"audio":0,"end":13401,"filename":"/include/shuffle.h"},{"start":13401,"audio":0,"end":18697,"filename":"/include/smartcantgo.h"},{"start":18697,"audio":0,"end":21791,"filename":"/include/seeno.h"},{"start":21791,"audio":0,"end":23907,"filename":"/include/yesno.h"},{"start":23907,"audio":0,"end":30683,"filename":"/include/sound.h"},{"start":30683,"audio":0,"end":34007,"filename":"/include/whowhat.h"},{"start":34007,"audio":0,"end":39493,"filename":"/include/torch.h"},{"start":39493,"audio":0,"end":54451,"filename":"/include/tmenus.h"},{"start":54451,"audio":0,"end":58829,"filename":"/include/doors.h"},{"start":58829,"audio":0,"end":63925,"filename":"/include/footnote.h"},{"start":63925,"audio":0,"end":66819,"filename":"/include/doors2.h"},{"start":66819,"audio":0,"end":85989,"filename":"/include/newbiegrammar.h"},{"start":85989,"audio":0,"end":111330,"filename":"/include/dmenus.h"},{"start":111330,"audio":0,"end":140985,"filename":"/include/mistype.h"},{"start":140985,"audio":0,"end":155615,"filename":"/include/moveclass.h"},{"start":155615,"audio":0,"end":168639,"filename":"/include/howtoplay.h"},{"start":168639,"audio":0,"end":195354,"filename":"/include/helproutines.h"},{"start":195354,"audio":0,"end":449098,"filename":"/lib/parser.h"},{"start":449098,"audio":0,"end":504806,"filename":"/lib/english.h"},{"start":504806,"audio":0,"end":525313,"filename":"/lib/Grammar.h"},{"start":525313,"audio":0,"end":533851,"filename":"/lib/voices_and_tenses.txt"},{"start":533851,"audio":0,"end":628247,"filename":"/lib/Verblib.h"},{"start":628247,"audio":0,"end":629547,"filename":"/lib/COPYING"},{"start":629547,"audio":0,"end":633148,"filename":"/lib/linklpa.h"},{"start":633148,"audio":0,"end":886892,"filename":"/lib/Parser.h"},{"start":886892,"audio":0,"end":914466,"filename":"/lib/ChangeLog"},{"start":914466,"audio":0,"end":1008862,"filename":"/lib/verblib.h"},{"start":1008862,"audio":0,"end":1030185,"filename":"/lib/infglk.h"},{"start":1030185,"audio":0,"end":1050692,"filename":"/lib/grammar.h"},{"start":1050692,"audio":0,"end":1059586,"filename":"/lib/ARTISTIC"},{"start":1059586,"audio":0,"end":1153982,"filename":"/lib/VerbLib.h"},{"start":1153982,"audio":0,"end":1200623,"filename":"/lib/infix.h"},{"start":1200623,"audio":0,"end":1201343,"filename":"/lib/README.txt"},{"start":1201343,"audio":0,"end":1257051,"filename":"/lib/English.h"}],"remote_package_size":1257051,"package_uuid":"24847113-2ab7-492b-ad8a-665bc1ff1021"}
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -1,6 +1,6 @@
|
|||
"use strict";
|
||||
|
||||
import { WorkerResult, WorkerFileUpdate, WorkerBuildStep, WorkerMessage, WorkerError, Dependency, SourceLine, CodeListing, CodeListingMap } from "../common/workertypes";
|
||||
import { WorkerResult, WorkerFileUpdate, WorkerBuildStep, WorkerMessage, WorkerError, Dependency, SourceLine, CodeListing, CodeListingMap, Segment } from "../common/workertypes";
|
||||
|
||||
declare var WebAssembly;
|
||||
declare function importScripts(path:string);
|
||||
|
@ -617,10 +617,10 @@ var re_crlf = /\r?\n/;
|
|||
|
||||
function parseListing(code:string, lineMatch, iline:number, ioffset:number, iinsns:number, icycles?:number) : SourceLine[] {
|
||||
var lines : SourceLine[] = [];
|
||||
for (var line of code.split(re_crlf)) {
|
||||
code.split(re_crlf).forEach((line, lineindex) => {
|
||||
var linem = lineMatch.exec(line);
|
||||
if (linem && linem[1]) {
|
||||
var linenum = parseInt(linem[iline]);
|
||||
var linenum = iline < 0 ? lineindex : parseInt(linem[iline]);
|
||||
var offset = parseInt(linem[ioffset], 16);
|
||||
var insns = linem[iinsns];
|
||||
var cycles : number = icycles ? parseInt(linem[icycles]) : null;
|
||||
|
@ -635,7 +635,7 @@ function parseListing(code:string, lineMatch, iline:number, ioffset:number, iins
|
|||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return lines;
|
||||
}
|
||||
|
||||
|
@ -2389,6 +2389,125 @@ function assembleYASM(step:BuildStep) {
|
|||
}
|
||||
}
|
||||
|
||||
interface XMLNode {
|
||||
type: string;
|
||||
text: string | null;
|
||||
children: XMLNode[];
|
||||
}
|
||||
|
||||
function parseXMLPoorly(s: string) : XMLNode {
|
||||
var re = /[<]([/]?)([?a-z_-]+)([^>]*)[>]+|(\s*[^<]+)/gi;
|
||||
var m;
|
||||
var i=0;
|
||||
var stack = [];
|
||||
while (m = re.exec(s)) {
|
||||
var [_m0,close,ident,attrs,content] = m;
|
||||
//if (i++<100) console.log(close,ident,attrs,content);
|
||||
if (close) {
|
||||
var top = stack.pop();
|
||||
if (top.type != ident) throw "mismatch close tag: " + ident;
|
||||
stack[stack.length-1].children.push(top);
|
||||
} else if (ident) {
|
||||
stack.push({type:ident, text:null, children:[]});
|
||||
} else if (content != null) {
|
||||
stack[stack.length-1].text = (content as string).trim();
|
||||
}
|
||||
}
|
||||
return top;
|
||||
}
|
||||
|
||||
function compileInform6(step:BuildStep) {
|
||||
loadNative("inform");
|
||||
var errors = [];
|
||||
gatherFiles(step, {mainFilePath:"main.inf"});
|
||||
var objpath = step.prefix+".z5";
|
||||
if (staleFiles(step, [objpath])) {
|
||||
var errorMatcher = msvcErrorMatcher(errors);
|
||||
var lstout = "";
|
||||
var match_fn = (s: string) => {
|
||||
if (s.indexOf("Error:") >= 0) {
|
||||
errorMatcher(s);
|
||||
} else {
|
||||
lstout += s;
|
||||
lstout += "\n";
|
||||
}
|
||||
}
|
||||
var args = [ '-afnops', '-v5', '-Cu', '-E1', '-k', '+/share/lib', step.path ];
|
||||
var inform = emglobal.inform({
|
||||
instantiateWasm: moduleInstFn('inform'),
|
||||
noInitialRun:true,
|
||||
//logReadFiles:true,
|
||||
print:match_fn,
|
||||
printErr:match_fn,
|
||||
});
|
||||
var FS = inform['FS'];
|
||||
setupFS(FS, 'inform');
|
||||
populateFiles(step, FS);
|
||||
//fixParamsWithDefines(step.path, step.params);
|
||||
execMain(step, inform, args);
|
||||
if (errors.length)
|
||||
return {errors:errors};
|
||||
var objout = FS.readFile(objpath, {encoding:'binary'});
|
||||
putWorkFile(objpath, objout);
|
||||
if (!anyTargetChanged(step, [objpath]))
|
||||
return;
|
||||
|
||||
// parse debug XML
|
||||
var symbolmap = {};
|
||||
var entitymap = {'object':{}, 'property':{}, 'constant':{}};
|
||||
var dbgout = FS.readFile("gameinfo.dbg", {encoding:'utf8'});
|
||||
var xmlroot = parseXMLPoorly(dbgout);
|
||||
//console.log(xmlroot);
|
||||
xmlroot.children.forEach((node) => {
|
||||
switch (node.type) {
|
||||
case 'global-variable':
|
||||
case 'routine':
|
||||
var ident = node.children.find((c,v) => c.type=='identifier').text;
|
||||
var address = parseInt(node.children.find((c,v) => c.type=='address').text);
|
||||
symbolmap[ident] = address;
|
||||
break;
|
||||
case 'object':
|
||||
case 'property':
|
||||
var ident = node.children.find((c,v) => c.type=='identifier').text;
|
||||
var value = parseInt(node.children.find((c,v) => c.type=='value').text);
|
||||
entitymap[node.type][ident] = value;
|
||||
//symbolmap[ident] = address | 0x1000000;
|
||||
break;
|
||||
}
|
||||
});
|
||||
// parse segments
|
||||
var segments : Segment[] = [];
|
||||
var seglst = lstout.split("Offsets in story file:")[1];
|
||||
if (seglst) {
|
||||
let curseg : Segment = {name:'Header',start:0x0,size:0x42,type:'rom'};
|
||||
segments.push(curseg);
|
||||
let curtype = 'ram';
|
||||
let re_seg = /([0-9a-f]{5}) (\w+)/g;
|
||||
let m;
|
||||
while (m = re_seg.exec(seglst)) {
|
||||
var start = parseInt(m[1], 16);
|
||||
var name = m[2];
|
||||
if (name == 'Parse') curtype = 'rom';
|
||||
curseg.size = start - curseg.start;
|
||||
curseg = {name:name, start:start, size:0, type:curtype};
|
||||
segments.push(curseg);
|
||||
}
|
||||
}
|
||||
var listings : CodeListingMap = {};
|
||||
// 35 +00015 <*> call_vs long_19 location long_424 -> sp
|
||||
var lines = parseListing(lstout, /\s*(\d+)\s+[+]([0-9a-f]+)\s+([<*>]*)\s*(\w+)\s+(.+)/i, -1, 2, 4);
|
||||
var lstpath = step.prefix + '.lst';
|
||||
listings[lstpath] = {lines:[], asmlines:lines, text:lstout};
|
||||
return {
|
||||
output:objout, //.slice(0),
|
||||
listings:listings,
|
||||
errors:errors,
|
||||
symbolmap:symbolmap,
|
||||
segments:segments,
|
||||
//debuginfo:entitymap,
|
||||
};
|
||||
}
|
||||
}
|
||||
////////////////////////////
|
||||
|
||||
var TOOLS = {
|
||||
|
@ -2419,6 +2538,7 @@ var TOOLS = {
|
|||
'bataribasic': compileBatariBasic,
|
||||
'markdown': translateShowdown,
|
||||
'js': runJavascript,
|
||||
'inform6': compileInform6,
|
||||
}
|
||||
|
||||
var TOOL_PRELOADFS = {
|
||||
|
@ -2438,6 +2558,7 @@ var TOOL_PRELOADFS = {
|
|||
'sdcc': 'sdcc',
|
||||
'sccz80': 'sccz80',
|
||||
'bataribasic': '2600basic',
|
||||
'inform6': 'inform',
|
||||
}
|
||||
|
||||
function applyDefaultErrorPath(errors:WorkerError[], path:string) {
|
||||
|
|
Loading…
Reference in New Issue