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/floooh/chips
|
||||||
* https://github.com/DrGoldfire/Z80.js
|
* https://github.com/DrGoldfire/Z80.js
|
||||||
* http://www.twitchasylum.com/jsvecx/
|
* http://www.twitchasylum.com/jsvecx/
|
||||||
|
* https://github.com/curiousdannii/ifvms.js/
|
||||||
|
|
||||||
### Compilers
|
### 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://github.com/batari-Basic/batari-Basic
|
||||||
* https://www.veripool.org/wiki/verilator
|
* https://www.veripool.org/wiki/verilator
|
||||||
* http://mcpp.sourceforge.net/
|
* http://mcpp.sourceforge.net/
|
||||||
|
* http://www.ifarchive.org/indexes/if-archiveXinfocomXcompilersXinform6.html
|
||||||
|
|
||||||
### Assemblers/Linkers
|
### 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-family: "Andale Mono", "Menlo", "Lucida Console", monospace;
|
||||||
font-size: 10pt;
|
font-size: 10pt;
|
||||||
line-height: 1.2;
|
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=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=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=markdown">Markdown</a></li>
|
||||||
|
<li><a class="dropdown-item" href="?platform=zmachine">Z-Machine (Inform 6)</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -311,6 +312,7 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
||||||
<!-- emulator video -->
|
<!-- emulator video -->
|
||||||
<div id="emuscreen">
|
<div id="emuscreen">
|
||||||
</div>
|
</div>
|
||||||
|
<!-- for Javatari only -->
|
||||||
<div id="javatari-div" style="float:center;margin:10px;display:none">
|
<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-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>
|
<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="codemirror/mode/gas/gas.js"></script>
|
||||||
<script src="src/codemirror/6502.js"></script>
|
<script src="src/codemirror/6502.js"></script>
|
||||||
<script src="src/codemirror/bataribasic.js"></script>
|
<script src="src/codemirror/bataribasic.js"></script>
|
||||||
|
<script src="src/codemirror/inform6.js"></script>
|
||||||
<link rel="stylesheet" href="css/codemirror.css">
|
<link rel="stylesheet" href="css/codemirror.css">
|
||||||
<script src="codemirror/addon/edit/matchbrackets.js"></script>
|
<script src="codemirror/addon/edit/matchbrackets.js"></script>
|
||||||
<script src="codemirror/addon/search/search.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());
|
this.recorder.recordFrame(this.saveState());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
inspect(sym: string) : string {
|
||||||
|
return inspectSymbol((this as any) as Platform, sym);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export abstract class BaseDebugPlatform extends BasePlatform {
|
export abstract class BaseDebugPlatform extends BasePlatform {
|
||||||
|
@ -352,23 +355,23 @@ export abstract class BaseDebugPlatform extends BasePlatform {
|
||||||
return this.frameCount > frame0;
|
return this.frameCount > frame0;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inspect(sym: string) : string {
|
export function inspectSymbol(platform : Platform, sym : string) : string {
|
||||||
if (!this.debugSymbols) return;
|
if (!platform.debugSymbols) return;
|
||||||
var symmap = this.debugSymbols.symbolmap;
|
var symmap = platform.debugSymbols.symbolmap;
|
||||||
var addr2sym = this.debugSymbols.addr2symbol;
|
var addr2sym = platform.debugSymbols.addr2symbol;
|
||||||
if (!symmap || !this.readAddress) return null;
|
if (!symmap || !platform.readAddress) return null;
|
||||||
var addr = symmap["_"+sym] || symmap[sym]; // look for C or asm symbol
|
var addr = symmap["_"+sym] || symmap[sym]; // look for C or asm symbol
|
||||||
if (!(typeof addr == 'number')) return null;
|
if (!(typeof addr == 'number')) return null;
|
||||||
var b = this.readAddress(addr);
|
var b = platform.readAddress(addr);
|
||||||
// don't show 2 bytes if there's a symbol at the next address
|
// don't show 2 bytes if there's a symbol at the next address
|
||||||
if (addr2sym && addr2sym[addr+1] != null) {
|
if (addr2sym && addr2sym[addr+1] != null) {
|
||||||
return "$"+hex(addr,4) + " = "+hex(b,2);
|
return "$"+hex(addr,4) + " = $"+hex(b,2)+" ("+b+" decimal)"; // unsigned
|
||||||
} else {
|
} else {
|
||||||
var b2 = this.readAddress(addr+1);
|
let b2 = platform.readAddress(addr+1);
|
||||||
var w = b | (b2<<8);
|
let w = b | (b2<<8);
|
||||||
return "$"+hex(addr,4) + " = "+hex(b,2)+" "+hex(b2,2)+" ($"+hex(w,2)+")";
|
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',
|
'cmoc': 'text/x-csrc',
|
||||||
'yasm': 'gas',
|
'yasm': 'gas',
|
||||||
'smlrc': 'text/x-csrc',
|
'smlrc': 'text/x-csrc',
|
||||||
|
'inform6': 'inform6',
|
||||||
}
|
}
|
||||||
|
|
||||||
function gaEvent(category:string, action:string, label?:string, value?:string) {
|
function gaEvent(category:string, action:string, label?:string, value?:string) {
|
||||||
|
|
|
@ -62,6 +62,17 @@ function newDiv(parent?, cls? : string) {
|
||||||
|
|
||||||
const MAX_ERRORS = 200;
|
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 {
|
export class SourceEditor implements ProjectView {
|
||||||
constructor(path:string, mode:string) {
|
constructor(path:string, mode:string) {
|
||||||
this.path = path;
|
this.path = path;
|
||||||
|
@ -92,10 +103,12 @@ export class SourceEditor implements ProjectView {
|
||||||
}
|
}
|
||||||
|
|
||||||
newEditor(parent:HTMLElement, isAsmOverride?:boolean) {
|
newEditor(parent:HTMLElement, isAsmOverride?:boolean) {
|
||||||
var isAsm = isAsmOverride || this.mode=='6502' || this.mode =='z80' || this.mode=='jsasm' || this.mode=='gas'; // TODO
|
var modedef = MODEDEFS[this.mode] || MODEDEFS.default;
|
||||||
var lineWrap = this.mode=='markdown';
|
var isAsm = isAsmOverride || modedef.isAsm;
|
||||||
|
var lineWrap = modedef.lineWrap;
|
||||||
|
var theme = modedef.theme || MODEDEFS.default.theme;
|
||||||
this.editor = CodeMirror(parent, {
|
this.editor = CodeMirror(parent, {
|
||||||
theme: 'mbo',
|
theme: theme,
|
||||||
lineNumbers: true,
|
lineNumbers: true,
|
||||||
matchBrackets: true,
|
matchBrackets: true,
|
||||||
tabSize: 8,
|
tabSize: 8,
|
||||||
|
@ -525,12 +538,15 @@ export class ListingView extends DisassemblerView implements ProjectView {
|
||||||
|
|
||||||
refresh(moveCursor: boolean) {
|
refresh(moveCursor: boolean) {
|
||||||
this.refreshListing();
|
this.refreshListing();
|
||||||
if (!this.assemblyfile || !platform.saveState) return;
|
// load listing text into editor
|
||||||
var state = lastDebugState || platform.saveState();
|
if (!this.assemblyfile) return;
|
||||||
var pc = state.c ? (state.c.EPC || state.c.PC) : 0;
|
|
||||||
var asmtext = this.assemblyfile.text;
|
var asmtext = this.assemblyfile.text;
|
||||||
var disasmview = this.getDisasmView();
|
var disasmview = this.getDisasmView();
|
||||||
disasmview.setValue(asmtext);
|
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) {
|
if (pc >= 0 && this.assemblyfile) {
|
||||||
var res = this.assemblyfile.findLineForOffset(pc, 15);
|
var res = this.assemblyfile.findLineForOffset(pc, 15);
|
||||||
if (res) {
|
if (res) {
|
||||||
|
|
|
@ -763,7 +763,7 @@ var VerilogPlatform = function(mainElement, options) {
|
||||||
}
|
}
|
||||||
getDefaultExtension() { return ".v"; };
|
getDefaultExtension() { return ".v"; };
|
||||||
|
|
||||||
inspect(name) {
|
inspect(name:string) : string {
|
||||||
if (!gen) return;
|
if (!gen) return;
|
||||||
if (name && !name.match(/^\w+$/)) return;
|
if (name && !name.match(/^\w+$/)) return;
|
||||||
var val = gen[name];
|
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";
|
"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 var WebAssembly;
|
||||||
declare function importScripts(path:string);
|
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[] {
|
function parseListing(code:string, lineMatch, iline:number, ioffset:number, iinsns:number, icycles?:number) : SourceLine[] {
|
||||||
var lines : SourceLine[] = [];
|
var lines : SourceLine[] = [];
|
||||||
for (var line of code.split(re_crlf)) {
|
code.split(re_crlf).forEach((line, lineindex) => {
|
||||||
var linem = lineMatch.exec(line);
|
var linem = lineMatch.exec(line);
|
||||||
if (linem && linem[1]) {
|
if (linem && linem[1]) {
|
||||||
var linenum = parseInt(linem[iline]);
|
var linenum = iline < 0 ? lineindex : parseInt(linem[iline]);
|
||||||
var offset = parseInt(linem[ioffset], 16);
|
var offset = parseInt(linem[ioffset], 16);
|
||||||
var insns = linem[iinsns];
|
var insns = linem[iinsns];
|
||||||
var cycles : number = icycles ? parseInt(linem[icycles]) : null;
|
var cycles : number = icycles ? parseInt(linem[icycles]) : null;
|
||||||
|
@ -635,7 +635,7 @@ function parseListing(code:string, lineMatch, iline:number, ioffset:number, iins
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
return lines;
|
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 = {
|
var TOOLS = {
|
||||||
|
@ -2419,6 +2538,7 @@ var TOOLS = {
|
||||||
'bataribasic': compileBatariBasic,
|
'bataribasic': compileBatariBasic,
|
||||||
'markdown': translateShowdown,
|
'markdown': translateShowdown,
|
||||||
'js': runJavascript,
|
'js': runJavascript,
|
||||||
|
'inform6': compileInform6,
|
||||||
}
|
}
|
||||||
|
|
||||||
var TOOL_PRELOADFS = {
|
var TOOL_PRELOADFS = {
|
||||||
|
@ -2438,6 +2558,7 @@ var TOOL_PRELOADFS = {
|
||||||
'sdcc': 'sdcc',
|
'sdcc': 'sdcc',
|
||||||
'sccz80': 'sccz80',
|
'sccz80': 'sccz80',
|
||||||
'bataribasic': '2600basic',
|
'bataribasic': '2600basic',
|
||||||
|
'inform6': 'inform',
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyDefaultErrorPath(errors:WorkerError[], path:string) {
|
function applyDefaultErrorPath(errors:WorkerError[], path:string) {
|
||||||
|
|
Loading…
Reference in New Issue