mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-11-29 14:51:17 +00:00
1933 lines
74 KiB
INI
1933 lines
74 KiB
INI
|
! ----------------------------------------------------------------------------
|
||
|
! Balances 160701 One of the standard Inform 6 example games
|
||
|
!
|
||
|
! created: 25.09.1994
|
||
|
! updated: 06.10.1994
|
||
|
! modernised: 11.12.1995
|
||
|
! translated to Inform 6: 08.05.1996
|
||
|
! minor bugs fixed: 16.12.1996
|
||
|
! modernised again by Vince Laviano: 01.07.2016
|
||
|
!
|
||
|
! This short story was written to demonstrate large-scale programming of
|
||
|
! the parser, and features multiple objects, complicated plurals, variable
|
||
|
! verbs, objects named by the player and questions. The spell-casting
|
||
|
! system is written in a "safe" way so that it could easily be transplanted.
|
||
|
!
|
||
|
! Needs Inform 6, library 6/5 or later to compile.
|
||
|
! ----------------------------------------------------------------------------
|
||
|
|
||
|
Release 6;
|
||
|
Serial "160701";
|
||
|
Switches d;
|
||
|
|
||
|
Constant Story "BALANCES";
|
||
|
Constant Headline "^An Interactive Short Story
|
||
|
^Copyright (c) 1994, 1995, 1996, 2016 by Graham Nelson.^";
|
||
|
|
||
|
Constant OBJECT_SCORE 5;
|
||
|
Constant MAX_SCORE 51;
|
||
|
|
||
|
Include "Parser";
|
||
|
Include "VerbLib";
|
||
|
|
||
|
! ----------------------------------------------------------------------------
|
||
|
! The white featureless cubes from "Spellbreaker", which can be identified
|
||
|
! by being written on with the magic burin, so that their names are given
|
||
|
! by the player in the course of play
|
||
|
!
|
||
|
! A particularly witty thing to do is to give several of them the same name,
|
||
|
! or to frotz some of them to distinguish them from the others...
|
||
|
! And the game will have no problem with this.
|
||
|
! ----------------------------------------------------------------------------
|
||
|
|
||
|
Array cube_text_buffer -> 8;
|
||
|
Global the_named_word = 0;
|
||
|
Global from_char; Global to_char;
|
||
|
|
||
|
Class FeaturelessCube
|
||
|
with number 0 0 0 0, ! There's room for 8 bytes of text in these 4 entries
|
||
|
description "A perfect white cube, four inches on a side.",
|
||
|
parse_name
|
||
|
[ i j flag;
|
||
|
if (parser_action==##TheSame)
|
||
|
{ for (i=0:i<8:i++)
|
||
|
if ((parser_one.&number)->i
|
||
|
~= (parser_two.&number)->i) return -2;
|
||
|
return -1;
|
||
|
}
|
||
|
for (::i++)
|
||
|
{ j=NextWord(); flag=0;
|
||
|
if (j=='cube' or 'white' ||
|
||
|
(j=='featureless' or 'blank' &&
|
||
|
((self.&number)->0) == 0)) flag=1;
|
||
|
if (j=='cubes')
|
||
|
{ flag=1; parser_action=##PluralFound; }
|
||
|
if (flag==0 && ((self.&number)->0) ~= 0)
|
||
|
{ wn--;
|
||
|
if (TextReader(0)==0) return i;
|
||
|
for (j=0: j<8: j++)
|
||
|
if ((self.&number)->j ~= cube_text_buffer->j)
|
||
|
return i;
|
||
|
flag=1;
|
||
|
}
|
||
|
if (flag==0) return i;
|
||
|
}
|
||
|
],
|
||
|
article "a",
|
||
|
short_name
|
||
|
[ i; if (((self.&number)->0) == 0) print "featureless white cube";
|
||
|
else
|
||
|
{ print "~";
|
||
|
while (((self.&number)->i) ~= 0)
|
||
|
print (char) (self.&number)->i++;
|
||
|
print "~ cube";
|
||
|
}
|
||
|
rtrue;
|
||
|
],
|
||
|
plural
|
||
|
[; self.short_name(); print "s";
|
||
|
],
|
||
|
baptise
|
||
|
[ i; wn = the_named_word;
|
||
|
if (TextReader(1)==0) return i;
|
||
|
for (i=0: i<8: i++)
|
||
|
(self.&number)->i = cube_text_buffer->i;
|
||
|
self.article="the";
|
||
|
print_ret "It is now called ", (the) self, ".";
|
||
|
],
|
||
|
has scored;
|
||
|
|
||
|
! Copies word "wn" from what the player most recently typed, putting it as
|
||
|
! plain text into cube_text_buffer, returning false if no such word is there
|
||
|
|
||
|
[ TextReader flag point i j len;
|
||
|
|
||
|
if (flag==1 && from_char~=to_char)
|
||
|
{ for (i=from_char, j=0:i<=to_char && j<7:i++)
|
||
|
{ cube_text_buffer->j = buffer->i;
|
||
|
if (buffer->i ~= ' ' or ',' or '.') j++;
|
||
|
}
|
||
|
for (:j<8:j++) cube_text_buffer->j = 0;
|
||
|
from_char=0; to_char=0;
|
||
|
rtrue;
|
||
|
}
|
||
|
|
||
|
for (i=0:i<8:i++) cube_text_buffer->i = 0;
|
||
|
if (wn > parse->1) { wn++; rfalse; }
|
||
|
i=wn*4+1; j=parse->i; point=j+buffer; len=parse->(i-1);
|
||
|
|
||
|
for (i=0:i<len && i<7:i++) cube_text_buffer->i = point->i;
|
||
|
|
||
|
wn++; rtrue;
|
||
|
];
|
||
|
|
||
|
Object burin "magic burin"
|
||
|
with name "magic" "magical" "burin" "pen",
|
||
|
description
|
||
|
"This is a magical burin, used for inscribing objects with words
|
||
|
or runes of magical import. Such a burin also gives you the
|
||
|
ability to write spell scrolls.",
|
||
|
before
|
||
|
[; WriteOn:
|
||
|
if (second ofclass FeaturelessCube)
|
||
|
{ if (second notin player)
|
||
|
"Writing on a cube is such a fiddly process that you
|
||
|
need to be holding it in your hand first.";
|
||
|
if (burin notin player)
|
||
|
"You would need some powerful implement for that.";
|
||
|
second.baptise();
|
||
|
rtrue;
|
||
|
}
|
||
|
if (second ofclass SpellBook)
|
||
|
"If a burin could write in a spell book, you wouldn't need
|
||
|
the gnusto spell!";
|
||
|
if (second ofclass Scroll)
|
||
|
"You cannot write just anything on the magic parchment of
|
||
|
a scroll: you can only ~copy~ a spell to it.";
|
||
|
];
|
||
|
|
||
|
[ WriteOnSub; "Graffiti is banned."; ];
|
||
|
|
||
|
[ CopyToSub;
|
||
|
if (burin notin player) "You need to be holding the burin to copy a spell.";
|
||
|
if (second ofclass SpellBook)
|
||
|
"If a burin could write in a spell book, you wouldn't need
|
||
|
the gnusto spell!";
|
||
|
if (~~(second ofclass Scroll)) "You can only copy spells to scrolls.";
|
||
|
if (child(second)~=0)
|
||
|
"The scroll is already full of incantation.";
|
||
|
"The scroll is not blank, only illegible.";
|
||
|
];
|
||
|
|
||
|
! ----------------------------------------------------------------------------
|
||
|
! Now the whole spell-casting system
|
||
|
! ----------------------------------------------------------------------------
|
||
|
|
||
|
Attribute known_about; ! Player has seen this spell somewhere
|
||
|
Attribute reversed; ! Effect of this known spell reversed
|
||
|
|
||
|
Attribute is_spell;
|
||
|
Class Spell
|
||
|
with name "spell" "spells", article "the",
|
||
|
number 0,
|
||
|
word_name
|
||
|
[; print (address) (self.&name)-->0;
|
||
|
],
|
||
|
short_name
|
||
|
[; self.word_name(); print " spell"; give self known_about; rtrue;
|
||
|
],
|
||
|
specification
|
||
|
[; self.short_name();
|
||
|
print ": ", (string) self.purpose;
|
||
|
],
|
||
|
before
|
||
|
[; Examine: self.specification(); ".";
|
||
|
],
|
||
|
has is_spell;
|
||
|
|
||
|
Object memory
|
||
|
with capacity 5,
|
||
|
number_known 1,
|
||
|
describe_contents
|
||
|
[ i j k;
|
||
|
objectloop (i in self) if (i.number==100) j++;
|
||
|
if (j>0)
|
||
|
{ print "The ";
|
||
|
objectloop (i in self)
|
||
|
if (i.number==100)
|
||
|
{ k++; i.word_name();
|
||
|
if (k==j-1) print " and ";
|
||
|
if (k<j-1) print ", ";
|
||
|
}
|
||
|
if (j==1) print " spell is"; else print " spells are";
|
||
|
print " yours forever. Other than that, y";
|
||
|
}
|
||
|
else print "Y";
|
||
|
print "ou have ";
|
||
|
j=0; k=0;
|
||
|
objectloop (i in self) if (i.number<100) j++;
|
||
|
if (j>0)
|
||
|
{ print "the ";
|
||
|
objectloop (i in self)
|
||
|
if (i.number<100)
|
||
|
{ k++;
|
||
|
print (name) i;
|
||
|
if (i.number==2) print " (twice)";
|
||
|
if (i.number==3) print " (thrice)";
|
||
|
if (i.number==4) print " (four times)";
|
||
|
if (i.number>=5) print " (many times)";
|
||
|
if (k==j-1) print " and ";
|
||
|
if (k<j-1) print ", ";
|
||
|
}
|
||
|
}
|
||
|
else print "no spells";
|
||
|
" memorised.";
|
||
|
],
|
||
|
learn_spell
|
||
|
[ sp;
|
||
|
if (sp.number==100) "You always know that spell.";
|
||
|
print "Using your best study habits, you commit the ";
|
||
|
sp.word_name();
|
||
|
print " spell to memory";
|
||
|
if (sp notin self) sp.number=0;
|
||
|
move sp to self;
|
||
|
self.number_known++;
|
||
|
sp.number++;
|
||
|
if (sp.number==1) print ".";
|
||
|
if (sp.number==2) print " once again.";
|
||
|
if (sp.number==3) print " a third time.";
|
||
|
if (sp.number>3) print " yet another time.";
|
||
|
if (self.number_known <= self.capacity) { new_line; rtrue; }
|
||
|
self.forget_spell(sibling(child(self)));
|
||
|
" You have so much buzzing around in your head, though,
|
||
|
that it's likely something may have been forgotten
|
||
|
in the shuffle.";
|
||
|
],
|
||
|
forget_spell
|
||
|
[ sp;
|
||
|
if (sp notin self || sp.number==100) rtrue;
|
||
|
self.number_known--;
|
||
|
sp.number--;
|
||
|
if (sp.number==0) remove sp;
|
||
|
rtrue;
|
||
|
];
|
||
|
|
||
|
Spell -> gnusto_spell
|
||
|
with name "gnusto",
|
||
|
purpose "copy a scroll into your spell book",
|
||
|
number 100,
|
||
|
magic
|
||
|
[ i a_book;
|
||
|
if (second ofclass SpellBook)
|
||
|
"Unlike scrolls, spell books are magically guarded against
|
||
|
the 'theft' of their lore.";
|
||
|
if (second==0 || ~~(second ofclass Scroll))
|
||
|
"Your spell fizzles vaguely out.";
|
||
|
if (second notin player)
|
||
|
"A gnusto spell would require close scrutiny of the scroll
|
||
|
it is to copy: which you do not seem to be holding.";
|
||
|
objectloop (i in player)
|
||
|
if (i ofclass SpellBook) a_book=i;
|
||
|
if (a_book==0)
|
||
|
"Your spell fails, as you have no spell book.";
|
||
|
i=child(second);
|
||
|
if (i==0 || ~~(i ofclass Spell))
|
||
|
{ print_ret "Your spell fails, as ", (the) second,
|
||
|
" is illegible.";
|
||
|
}
|
||
|
a_book.learn_spell(i); remove second;
|
||
|
print_ret
|
||
|
"Your spell book begins to glow softly. Slowly, ornately,
|
||
|
the words of ", (the) i, " are inscribed,
|
||
|
glowing even more brightly then the book itself.
|
||
|
The book's brightness fades, but the spell remains!
|
||
|
However, the scroll on which it was written vanishes as
|
||
|
the last word is copied.";
|
||
|
];
|
||
|
|
||
|
Class SpellBook
|
||
|
with array_of_spells 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0,
|
||
|
capacity 16,
|
||
|
learn_spell
|
||
|
[ sp p i;
|
||
|
p = self.&array_of_spells;
|
||
|
for (i=0:i<self.capacity && (p-->i)~=0:i++) ;
|
||
|
if (i==self.capacity) rtrue;
|
||
|
p-->i = sp;
|
||
|
],
|
||
|
before
|
||
|
[; Open, Close:
|
||
|
print_ret
|
||
|
(The) self, " is always open to the right place, but it
|
||
|
is also always closed. This eliminates tedious leafing and
|
||
|
hunting for spells. Many lives have been saved by this
|
||
|
magical innovation.";
|
||
|
Attack:
|
||
|
print_ret "When you are done, ", (the) self, " remains unmarred.";
|
||
|
],
|
||
|
after
|
||
|
[ p i j; Examine:
|
||
|
p = self.&array_of_spells;
|
||
|
for (i=0:i<self.capacity && (p-->i)~=0:i++)
|
||
|
{ j=p-->i; <Examine j>;
|
||
|
}
|
||
|
rtrue;
|
||
|
];
|
||
|
|
||
|
Class Scroll
|
||
|
with parse_name
|
||
|
[ i j k; j=-1;
|
||
|
if (self has general)
|
||
|
{ if (child(self)~=0 && child(self) ofclass Spell)
|
||
|
j=(child(self).&name)-->0; else j='illegible';
|
||
|
}
|
||
|
for (::)
|
||
|
{ k=NextWord();
|
||
|
if (k=='scrolls') parser_action=##PluralFound;
|
||
|
if ((k=='scrolls' or 'scroll' or j) || k==(self.&name)-->0)
|
||
|
i++;
|
||
|
else return i;
|
||
|
}
|
||
|
],
|
||
|
before
|
||
|
[ i; Examine:
|
||
|
i=child(self);
|
||
|
give self general;
|
||
|
if (i==0 || ~~(i ofclass Spell))
|
||
|
"The scroll has faded, and you cannot read it.";
|
||
|
print "The scroll reads ~"; i.specification(); "~.";
|
||
|
],
|
||
|
invent
|
||
|
[; if (inventory_stage==2 && self has general)
|
||
|
{ if (child(self)==0 || ~~(child(self) ofclass Spell))
|
||
|
print " (which is illegible)";
|
||
|
else
|
||
|
{ print " (of ", (the) child(self), ")"; }
|
||
|
}
|
||
|
];
|
||
|
|
||
|
[ ReadableSpell i j k;
|
||
|
if (scope_stage==1)
|
||
|
{ if (action_to_be==##Examine) rfalse;
|
||
|
rtrue;
|
||
|
}
|
||
|
if (scope_stage==2)
|
||
|
{ objectloop (i in player)
|
||
|
if (i ofclass SpellBook)
|
||
|
{ for (k=0:k<i.capacity && (i.&array_of_spells)-->k~=0:k++)
|
||
|
{ j=(i.&array_of_spells)-->k; PlaceInScope(j);
|
||
|
}
|
||
|
}
|
||
|
rtrue;
|
||
|
}
|
||
|
! No need for scope_stage 3 (the error stage), because our
|
||
|
! ParserError routine handles that case instead
|
||
|
];
|
||
|
|
||
|
[ CopyableSpell i j k;
|
||
|
if (scope_stage==1) return 1;
|
||
|
if (scope_stage==2)
|
||
|
{ objectloop (i in player)
|
||
|
if (i ofclass SpellBook)
|
||
|
{ for (k=0:k<i.capacity && (i.&array_of_spells)-->k~=0:k++)
|
||
|
{ j=(i.&array_of_spells)-->k; PlaceInScope(j);
|
||
|
}
|
||
|
}
|
||
|
rfalse;
|
||
|
}
|
||
|
! No need for scope_stage 3 (the error stage), because our
|
||
|
! ParserError routine handles that case instead
|
||
|
];
|
||
|
|
||
|
[ LearnedSpell i;
|
||
|
if (scope_stage==1) rfalse;
|
||
|
if (scope_stage==2)
|
||
|
{ objectloop (i in memory)
|
||
|
if (i has is_spell) PlaceInScope(i);
|
||
|
rfalse;
|
||
|
}
|
||
|
! No need for scope_stage 3 (the error stage), because our
|
||
|
! ParserError routine handles that case instead
|
||
|
];
|
||
|
|
||
|
[ SpellsSub; memory.describe_contents(); ];
|
||
|
|
||
|
[ LearnSub; if (location==thedark)
|
||
|
print "(The magic writing of the spells casts enough light
|
||
|
that you can read them.)^";
|
||
|
memory.learn_spell(noun);
|
||
|
];
|
||
|
|
||
|
Global the_spell_was = gnusto_spell;
|
||
|
|
||
|
[ CastOneSub; <Cast the_spell_was noun>; ];
|
||
|
|
||
|
[ CastSub;
|
||
|
the_spell_was = noun; memory.forget_spell(noun);
|
||
|
|
||
|
if (noun has reversed)
|
||
|
{ give noun ~reversed;
|
||
|
if (noun.unmagic() ~= 0) return;
|
||
|
"Nothing happens.";
|
||
|
}
|
||
|
|
||
|
if (second ~= 0)
|
||
|
{ ResetVagueWords(second); ! Set "it", "him", "her"
|
||
|
if (second provides before
|
||
|
&& second.before() ~= 0) return; ! Run before routine(s)
|
||
|
}
|
||
|
if (noun.magic() ~= 0) return;
|
||
|
"Nothing happens.";
|
||
|
];
|
||
|
|
||
|
[ InScope i;
|
||
|
if (verb_word=='c,cast' or 'cast')
|
||
|
objectloop (i in memory) PlaceInScope(i);
|
||
|
rfalse;
|
||
|
];
|
||
|
|
||
|
[ ParserError i flag vb;
|
||
|
if (etype==VERB_PE or ASKSCOPE_PE)
|
||
|
{ if (etype==ASKSCOPE_PE)
|
||
|
{ if (verb_word=='cast') vb=1;
|
||
|
if (verb_word=='learn' or 'memorise' or 'memorize') vb=2;
|
||
|
if (verb_word=='copy') vb=3;
|
||
|
if (vb==0) { etype=CANTSEE_PE; rfalse; }
|
||
|
}
|
||
|
wn=verb_wordnum; if (vb~=0) wn++;
|
||
|
for (i=player+1:i<=top_object:i++)
|
||
|
if (i ofclass Spell && Refers(i,wn)==1
|
||
|
&& i has known_about) flag=1;
|
||
|
if (flag==1)
|
||
|
{ if (vb==0 or 1)
|
||
|
"You haven't got that spell committed to memory. [Type ~spells~
|
||
|
to see what you do remember.]";
|
||
|
if (vb==2)
|
||
|
"Your training is such that you can only memorise such a spell
|
||
|
with the aid of a spell book containing it.";
|
||
|
if (vb==3)
|
||
|
"You have no text of that spell to copy.";
|
||
|
}
|
||
|
if (vb==1)
|
||
|
"You haven't learned that spell, if indeed it is a spell.";
|
||
|
if (vb==2 or 3)
|
||
|
"You haven't access to that spell, if indeed it is a spell.";
|
||
|
}
|
||
|
rfalse;
|
||
|
];
|
||
|
|
||
|
[ ChooseObjects obj code;
|
||
|
if (code<2) rfalse;
|
||
|
if (action_to_be==##WriteOn && obj in player) return 9;
|
||
|
return 0;
|
||
|
];
|
||
|
|
||
|
[ UnknownVerb word i;
|
||
|
objectloop (i in memory)
|
||
|
if (word==(i.&name)-->0) { the_spell_was = i; return 'c,cast'; }
|
||
|
rfalse;
|
||
|
];
|
||
|
|
||
|
[ PrintVerb v;
|
||
|
if (v=='c,cast') { print "cast a spell at"; rtrue; }
|
||
|
rfalse;
|
||
|
];
|
||
|
|
||
|
! ----------------------------------------------------------------------------
|
||
|
! And now, on with the story. First, some global variables:
|
||
|
! ----------------------------------------------------------------------------
|
||
|
|
||
|
Global prepared_flag = false; ! Prepared for resurrection?
|
||
|
Global hearing_good = false; ! Sharp hearing?
|
||
|
Global number_filled = 0; ! Sockets in the temple filled
|
||
|
|
||
|
! ----------------------------------------------------------------------------
|
||
|
! A "questions" verb. Thus,
|
||
|
! "who is my friend helistar"
|
||
|
! "what was the great change"
|
||
|
! and so on are recognised.
|
||
|
! ----------------------------------------------------------------------------
|
||
|
|
||
|
[ QuerySub;
|
||
|
noun.description();
|
||
|
];
|
||
|
[ Topic i;
|
||
|
if (scope_stage==1) return 0;
|
||
|
if (scope_stage==2)
|
||
|
{ objectloop (i ofclass Question) PlaceInScope(i);
|
||
|
rtrue;
|
||
|
}
|
||
|
"At the moment, even the simplest questions confuse you.";
|
||
|
];
|
||
|
|
||
|
Class Question;
|
||
|
Question
|
||
|
with name "helistar" "my" "friend" "colleague",
|
||
|
description
|
||
|
"Helistar is your colleague, an Enchanter like you who has been much
|
||
|
on your mind lately. She has been investigating some very dark
|
||
|
magic indeed, and seems not to be around any more. You feel rather
|
||
|
vague about the details.";
|
||
|
Question
|
||
|
with name "magical" "magic" "burin",
|
||
|
description "A burin is an engraving and writing tool.";
|
||
|
Question
|
||
|
with name "change" "great",
|
||
|
description
|
||
|
"Something you had a lot to do with, but what exactly? No, it's gone.";
|
||
|
Question
|
||
|
with name "cyclops",
|
||
|
description
|
||
|
"A one-eyed giant, usually hostile. (Don't they teach anything at
|
||
|
adventurer school these days?)";
|
||
|
Question
|
||
|
with name "grue",
|
||
|
description
|
||
|
"The grue is a sinister, lurking presence in the dark places of the
|
||
|
earth. Its favorite diet is adventurers, but its insatiable appetite
|
||
|
is tempered by its fear of light. No grue has ever been seen by the
|
||
|
light of day, and few have survived its fearsome jaws to
|
||
|
tell the tale.";
|
||
|
Question
|
||
|
with name "grimoire",
|
||
|
description
|
||
|
"According to Chambers English Dictionary, a grimoire is ~a magician's
|
||
|
book for calling up spirits~.";
|
||
|
Question
|
||
|
with name "spells" "work",
|
||
|
description
|
||
|
"Your memory is still dream-hazed, but it's coming back. As a trained
|
||
|
Enchanter, you have the ability to cast spells like ~frotz~, provided
|
||
|
you have learned them in advance. Some of these spells can be cast
|
||
|
at something; others can be cast alone.
|
||
|
^^Spells are very complicated. Each time you cast one, you forget it
|
||
|
(though you can get around this by learning it several times, so as
|
||
|
to have several uses up your sleeve). The only way to hang on to
|
||
|
a spell is to have it written down, on a scroll or in a spell book.
|
||
|
Scrolls are not ideal for this, and you can only learn a spell from
|
||
|
your spell book. (But you can add spells to your book.)
|
||
|
^^[Type ~learn frotz~ and then ~frotz coin~ for an example. You can
|
||
|
also type ~spells~ to see what you currently have memorised.]";
|
||
|
|
||
|
! ----------------------------------------------------------------------------
|
||
|
! Some multiple objects, coins in fact, coded in deluxe fashion:
|
||
|
! ----------------------------------------------------------------------------
|
||
|
|
||
|
Attribute is_coin;
|
||
|
Class Coin
|
||
|
with name "coin",
|
||
|
description "A round unstamped disc, presumably part of the local
|
||
|
currency.",
|
||
|
parse_name
|
||
|
[ i j w;
|
||
|
if (parser_action==##TheSame)
|
||
|
{ if ((parser_one.&name)-->0 == (parser_two.&name)-->0) return -1;
|
||
|
return -2;
|
||
|
}
|
||
|
w=(self.&name)-->0;
|
||
|
for (::i++)
|
||
|
{ j=NextWord();
|
||
|
if (j=='coins') parser_action=##PluralFound;
|
||
|
else if (j~='coin' or w) return i;
|
||
|
}
|
||
|
],
|
||
|
has is_coin;
|
||
|
|
||
|
Class GoldCoin
|
||
|
class Coin,
|
||
|
with name "gold",
|
||
|
short_name "gold coin",
|
||
|
plural "gold coins";
|
||
|
Class SilverCoin
|
||
|
class Coin,
|
||
|
with name "silver",
|
||
|
short_name "silver coin",
|
||
|
plural "silver coins";
|
||
|
Class BronzeCoin
|
||
|
class Coin,
|
||
|
with name "bronze",
|
||
|
short_name "bronze coin",
|
||
|
plural "bronze coins";
|
||
|
|
||
|
SilverCoin players_coin;
|
||
|
|
||
|
[ TossCoinSub; if (noun notin player) "You need to be holding the coin first.";
|
||
|
move noun to parent(player);
|
||
|
if (location==thedark) "You throw it away into the darkness.";
|
||
|
if (random(20)==1)
|
||
|
"You toss the coin, and it lands... on its edge, amazingly.";
|
||
|
"You toss the coin, and it comes up... blank, since neither side is
|
||
|
marked.";
|
||
|
];
|
||
|
|
||
|
! ----------------------------------------------------------------------------
|
||
|
! The player's spell book, and three initial spells (to go with gnusto):
|
||
|
! ----------------------------------------------------------------------------
|
||
|
|
||
|
SpellBook players_book "spell book"
|
||
|
with name "spell" "book" "my" "spellbook",
|
||
|
description "My Spell Book^";
|
||
|
|
||
|
Spell frotz_spell
|
||
|
with name "frotz",
|
||
|
purpose "cause an object to give off light",
|
||
|
magic
|
||
|
[; if (second==0) "There is a brief, blinding flash of light.";
|
||
|
if (second has animate)
|
||
|
"The spell, not designed for living creatures, goes sour.";
|
||
|
if (second in compass)
|
||
|
"The spell dissipates vaguely.";
|
||
|
give second light;
|
||
|
print_ret
|
||
|
"There is an almost blinding flash of light as ", (the) second,
|
||
|
" begins to glow! It slowly fades to a less painful level, but ",
|
||
|
(the) second, " is now quite usable as a light source.";
|
||
|
],
|
||
|
unmagic
|
||
|
[; if (second==0) "There is a brief moment of deep darkness.";
|
||
|
if (second has animate)
|
||
|
"The spell, not designed for living creatures, goes sour.";
|
||
|
if (second in compass)
|
||
|
"The spell dissipates vaguely.";
|
||
|
if (second hasnt light)
|
||
|
print_ret (The) second, " isn't producing light as it is.";
|
||
|
give second ~light;
|
||
|
print_ret "A pool of darkness coagulates around ", (the) second,
|
||
|
" but slowly fades back to normality. Still, ",
|
||
|
(the) second, " is no longer any kind of light source.";
|
||
|
];
|
||
|
|
||
|
Spell rezrov_spell
|
||
|
with name "rezrov",
|
||
|
purpose "open even locked or enchanted objects",
|
||
|
magic
|
||
|
[; if (second==0) "The world is open already.";
|
||
|
if (second has animate)
|
||
|
"It might be a boon to surgeons if it worked, but it doesn't.";
|
||
|
if (second has open || second hasnt openable)
|
||
|
"It doesn't need opening.";
|
||
|
if (second hasnt locked)
|
||
|
{ give second open;
|
||
|
print_ret (The) second, " opens obediently.
|
||
|
Like swatting a fly with a sledge hammer, if you ask me.";
|
||
|
}
|
||
|
give second open ~locked;
|
||
|
print "Silently, ", (the) second, " swings open. ";
|
||
|
if (second has container) <<Search second>>; new_line; rtrue;
|
||
|
],
|
||
|
unmagic
|
||
|
[; if (second==0) "The world is closed already.";
|
||
|
if (second has animate)
|
||
|
"Happily, that is unnecessary.";
|
||
|
if (second has locked || second hasnt lockable)
|
||
|
"It doesn't need locking.";
|
||
|
give second ~open locked;
|
||
|
"Silently, ", (the) second, " swings shut and locks.";
|
||
|
];
|
||
|
|
||
|
Spell yomin_spell
|
||
|
with name "yomin",
|
||
|
purpose "mind probe",
|
||
|
magic
|
||
|
[; if (second==0 || second hasnt animate)
|
||
|
"That must be either vegetable or mineral.";
|
||
|
if (second==player) "You give yourself a mild headache.";
|
||
|
print_ret "You look into the rather ordinary thoughts of ",
|
||
|
(the) second, ".";
|
||
|
],
|
||
|
unmagic
|
||
|
[; if (second==0 || second hasnt animate)
|
||
|
"That must be either vegetable or mineral.";
|
||
|
if (second==player) "You give yourself a mild headache.";
|
||
|
print_ret (The) second, " is rather shocked, for some reason.";
|
||
|
];
|
||
|
|
||
|
! ----------------------------------------------------------------------------
|
||
|
! The first scene: the Hut and its (rather easy) secret
|
||
|
! ----------------------------------------------------------------------------
|
||
|
|
||
|
Class Place
|
||
|
has light;
|
||
|
|
||
|
Place Hut "Ramshackle Hut"
|
||
|
with description
|
||
|
"Until quite recently, someone lived here, you feel sure.
|
||
|
Now the furniture is matchwood and
|
||
|
the windows are glassless. Outside, it is a warm, sunny day,
|
||
|
and grasslands extend to the low hills on the horizon.",
|
||
|
out_to Grasslands, w_to Grasslands,
|
||
|
cant_go "There's only the one room: better go ~out~.",
|
||
|
name "windows" "grasslands" "grass" "hills";
|
||
|
|
||
|
Object -> furniture "wooden furniture"
|
||
|
with name "furniture" "broken" "wood" "wooden",
|
||
|
before
|
||
|
[; Examine, Search, LookUnder:
|
||
|
self.before=0; score=score+5;
|
||
|
move h_box to player;
|
||
|
"Searching through the furniture, which is good for nothing
|
||
|
but firewood now, you come across an old cedarwood box,
|
||
|
which you pick up for a closer look.";
|
||
|
],
|
||
|
has scenery;
|
||
|
|
||
|
Object h_box "cedarwood box"
|
||
|
with name "cedar" "cedarwood" "wooden" "box",
|
||
|
description "The box bears the calligraphed initial H."
|
||
|
has container openable lockable locked;
|
||
|
|
||
|
SpellBook -> helistars_book "Helistar's grimoire"
|
||
|
with name "grimoire" "helistar" "helistars",
|
||
|
description "This must be the grimoire of dangerous spells kept by
|
||
|
your irresponsible friend Helistar. Many pages are
|
||
|
missing, but a few spells remain:^",
|
||
|
has proper;
|
||
|
|
||
|
! ----------------------------------------------------------------------------
|
||
|
! Grasslands and the valley
|
||
|
! ----------------------------------------------------------------------------
|
||
|
|
||
|
Place Grasslands "Grasslands, near Hut"
|
||
|
with name "grasslands" "grass" "hut" "path",
|
||
|
description
|
||
|
"The grasslands sway over low hills in all directions: it is a
|
||
|
peaceful wilderness, broken only by this hut and a faint path
|
||
|
to the north.",
|
||
|
in_to Hut, e_to Hut,
|
||
|
n_to Valley,
|
||
|
cant_go "You wander around for a while but end up back at the hut.";
|
||
|
|
||
|
Place Valley "Pocket Valley"
|
||
|
with name "valley" "trail",
|
||
|
description
|
||
|
"A pleasant pocket valley in the grassy hills, through which a
|
||
|
trail runs north-to-south.",
|
||
|
n_to "The trail runs out to nothing, and you retreat for fear of
|
||
|
getting so lost you couldn't find the hut again by nightfall.",
|
||
|
cant_go "You wander around the pleasant valley, but are afraid to
|
||
|
lose sight of the trail.",
|
||
|
s_to Grasslands;
|
||
|
|
||
|
[ RideSub; print_ret "You can hardly ride ", (a) noun, "."; ];
|
||
|
|
||
|
Object -> horse "horse"
|
||
|
with short_name
|
||
|
[; if (self has general) print "winged horse";
|
||
|
else print "chestnut horse";
|
||
|
rtrue;
|
||
|
],
|
||
|
parse_name
|
||
|
[ i j; if (self has general) j='winged'; else j=-1;
|
||
|
while (NextWord()==j or 'horse' or 'chestnut') i++;
|
||
|
return i;
|
||
|
],
|
||
|
describe
|
||
|
[; print_ret
|
||
|
"There is ", (a) self, " here, munching on a pile of oats.";
|
||
|
],
|
||
|
before
|
||
|
[; Cast: if (the_spell_was == bozbar_spell)
|
||
|
{ give self general;
|
||
|
"A pair of handsome brown wings suddenly appears on
|
||
|
the horse's powerful shoulders. The horse turns in a
|
||
|
complete circle, a look of puzzlement on his face.";
|
||
|
}
|
||
|
if (the_spell_was == yomin_spell)
|
||
|
"He is mainly thinking about oats. Partly who you are
|
||
|
and what you're up to, but mainly oats.";
|
||
|
Enter: <<Ride self>>;
|
||
|
Ride: if (horse hasnt general)
|
||
|
"You ride around for a while, exercising the horse, but
|
||
|
soon enough he tires of this and pointedly brings you
|
||
|
back to the oats. Obligingly you dismount and he
|
||
|
begins grazing again.";
|
||
|
|
||
|
print "You begin to ride north. Then, slowly at first but with
|
||
|
increasing sureness, the horse begins beating its powerful
|
||
|
wings. You rise majestically through the air, sailing
|
||
|
gracefully across a chasm where the hills fall away.
|
||
|
The horse lands gently on the far side and deposits you,
|
||
|
taking to the skies again.^";
|
||
|
PlayerTo(Edge); rtrue;
|
||
|
],
|
||
|
has animate;
|
||
|
|
||
|
Object -> oats "pile of oats"
|
||
|
with name "oats" "pile" "of",
|
||
|
before
|
||
|
[; Examine, Search, LookUnder:
|
||
|
self.before=NULL;
|
||
|
move shiny_scroll to player; score=score+5;
|
||
|
itobj=shiny_scroll;
|
||
|
"Sifting through the oats, you find a shiny scroll! Lucky
|
||
|
you got to it before the horse did. As you turn it over
|
||
|
in your hands, it seems undamaged.";
|
||
|
Take: "What would you want with all those oats?";
|
||
|
],
|
||
|
has scenery;
|
||
|
|
||
|
Scroll shiny_scroll "shiny scroll"
|
||
|
with name "shiny";
|
||
|
|
||
|
Spell -> bozbar_spell
|
||
|
with name "bozbar",
|
||
|
purpose "cause an animal to sprout wings",
|
||
|
magic
|
||
|
[; if (second==0 || second hasnt animate)
|
||
|
"The spell dies away in vain.";
|
||
|
if (second==player)
|
||
|
"Your elbows twitch, but there is no other effect.";
|
||
|
print_ret "For a moment, ", (the) second,
|
||
|
" looks highly discomforted, but the moment passes.";
|
||
|
],
|
||
|
unmagic
|
||
|
[; if (second==0 || second hasnt animate)
|
||
|
"The spell dies away in vain.";
|
||
|
if (second==player) "What wings?";
|
||
|
if (second==horse && horse has general)
|
||
|
{ give horse ~general;
|
||
|
"The Enchanter giveth, and the Enchanter taketh away.
|
||
|
The horse looks disconsolate but returns to the oats.";
|
||
|
}
|
||
|
print_ret (The) second, " has no wings to lose.";
|
||
|
];
|
||
|
|
||
|
! ----------------------------------------------------------------------------
|
||
|
! The Chasm and the snake
|
||
|
! ----------------------------------------------------------------------------
|
||
|
|
||
|
Place Edge "Edge of Chasm"
|
||
|
with name "wide" "chasm" "road" "daffodils" "clump",
|
||
|
description
|
||
|
"The road ends suddenly at a wide chasm. The road leads upward
|
||
|
to the north, and you can see it continuing on the southern side
|
||
|
of the chasm.",
|
||
|
u_to Up_Road, n_to Up_Road,
|
||
|
cant_go "The chasm is too perilous to approach. The only safe way is
|
||
|
up and to the north.",
|
||
|
before
|
||
|
[; Jump: deadflag = true;
|
||
|
"You jump bravely into the chasm, and plunge...
|
||
|
gracefully through the air. (It gets a bit less noble and
|
||
|
airy after that.)";
|
||
|
];
|
||
|
|
||
|
Object -> snake "hissing snake"
|
||
|
with name "hissing" "snake",
|
||
|
initial
|
||
|
"Lying in a tight coil at the edge of the chasm is a hissing snake.",
|
||
|
description
|
||
|
"It has some V-markings, some scaly parts, colours from grey to
|
||
|
reddish-brown. Is that any help?",
|
||
|
life
|
||
|
[; "The snake hisses angrily!"; ],
|
||
|
before
|
||
|
[; Cast:
|
||
|
switch(the_spell_was)
|
||
|
{ urbzig_spell:
|
||
|
remove self;
|
||
|
snakes_cube.initial =
|
||
|
"Beside a clump of daffodils is a featureless white cube.";
|
||
|
"The snake is replaced by a clump of daffodils.";
|
||
|
bozbar_spell:
|
||
|
deadflag = true; remove self;
|
||
|
snakes_cube.initial =
|
||
|
"A featureless cube rests where the snake took off from.";
|
||
|
"The snake is transformed into a huge, winged serpent,
|
||
|
a dragon which bellows and leaps out into the chasm,
|
||
|
backwinging furiously... and knocking you over the
|
||
|
edge quite by accident.";
|
||
|
yomin_spell:
|
||
|
"Horrid reptilian thoughts insinuate their way into you.";
|
||
|
}
|
||
|
Take, Remove:
|
||
|
"The slipperiness of its skin is only one of many reasons
|
||
|
why this is ill-advised.";
|
||
|
],
|
||
|
has animate;
|
||
|
|
||
|
FeaturelessCube -> snakes_cube "cube"
|
||
|
with initial
|
||
|
"The snake appears to be curled around a featureless white cube.",
|
||
|
before
|
||
|
[; if (snake notin nothing) "The snake won't let you near that cube!";
|
||
|
];
|
||
|
|
||
|
! ----------------------------------------------------------------------------
|
||
|
! The crest of the hill; Icarus the tortoise; the chewed scroll
|
||
|
! ----------------------------------------------------------------------------
|
||
|
|
||
|
Place Up_Road "Crest of Hill"
|
||
|
with description
|
||
|
"The road crosses the top of a ridge here, sloping downwards to
|
||
|
the south and the northwest. A track diverges to east.",
|
||
|
nw_to Cave_Mouth, s_to Edge, d_to Edge, e_to Track;
|
||
|
|
||
|
Object -> tortoise "tortoise"
|
||
|
with name "tortoise" "turtle",
|
||
|
initial "A tortoise ambles along the road, extremely slowly.",
|
||
|
life
|
||
|
[; "The tortoise (slowly) turns its neck to look at you (stupidly).";
|
||
|
],
|
||
|
before
|
||
|
[; Cast: switch(the_spell_was)
|
||
|
{ urbzig_spell:
|
||
|
"Just how safe do you want your surroundings to be?";
|
||
|
bozbar_spell:
|
||
|
move chewed_scroll to parent(self); remove self;
|
||
|
StartDaemon(self); score=score+5;
|
||
|
"The tortoise seems to be incapable of expressing
|
||
|
surprise, but is now soaring away high in the sky.
|
||
|
Something rather grubby is left behind.";
|
||
|
yomin_spell:
|
||
|
"For a moment you think there is nothing there, as you
|
||
|
chew absentmindedly on a leaf. But somewhere inside
|
||
|
the tortoise is a sense of wonder at the amazing blue
|
||
|
canopy of the sky.";
|
||
|
}
|
||
|
Take, Remove:
|
||
|
"Your parents always warned you not to pick up casual
|
||
|
acquaintances met on the road.";
|
||
|
],
|
||
|
daemon
|
||
|
[ i; if (location ~= Up_Road or Track || random(6)~=1) rfalse;
|
||
|
if (random(4)==1 && self hasnt general)
|
||
|
{ move feather to location; give self general;
|
||
|
"^A tortoise-feather flutters to the ground before you!";
|
||
|
}
|
||
|
i=random(3);
|
||
|
switch(i)
|
||
|
{ 1: print "^High in the sky,";
|
||
|
2: print "^Far above you,";
|
||
|
3: print "^Tiny in the blue sky,";
|
||
|
}
|
||
|
" a tortoise flaps across the sun.";
|
||
|
],
|
||
|
has animate;
|
||
|
|
||
|
Scroll torn_scroll "torn scroll"
|
||
|
with name "torn";
|
||
|
|
||
|
Spell -> lobal_spell
|
||
|
with name "lobal",
|
||
|
purpose "sharpen hearing",
|
||
|
magic
|
||
|
[; if (second==0 || second hasnt animate)
|
||
|
"There is a loud bang in your ear, but no other effect.";
|
||
|
if (second==player)
|
||
|
{ if (hearing_good) "There is no further effect.";
|
||
|
hearing_good=1; StartTimer(self, 5);
|
||
|
"Nothing happens, possibly because those butterflies on the
|
||
|
other side of the hill keep distracting you.";
|
||
|
}
|
||
|
print_ret (The) second,
|
||
|
" is no doubt grateful for the gift of sharper hearing.";
|
||
|
],
|
||
|
unmagic
|
||
|
[; if (second==0 || second hasnt animate)
|
||
|
"There is a brief silence, but no other effect.";
|
||
|
if (second==player) { StopTimer(self); hearing_good=0; "Pardon?"; }
|
||
|
print_ret (The) second,
|
||
|
" is no doubt grateful not to have to listen to you.";
|
||
|
],
|
||
|
time_left 0,
|
||
|
time_out
|
||
|
[; if (hearing_good)
|
||
|
{ hearing_good = false;
|
||
|
"^Those wretched butterflies finally shut up.";
|
||
|
}
|
||
|
];
|
||
|
|
||
|
Scroll chewed_scroll "chewed scroll"
|
||
|
with initial "It looks as if the tortoise was eating something - once
|
||
|
it might have been a scroll, but now it lies there,
|
||
|
chewed up like a lettuce leaf.",
|
||
|
before
|
||
|
[; Cast: if (the_spell_was == caskly_spell)
|
||
|
{ move torn_scroll to parent(self);
|
||
|
remove self; score=score+5;
|
||
|
"Before your eyes, the scroll begins to repair itself,
|
||
|
failing only at the very last tear. Not quite perfect
|
||
|
perhaps, but certainly a readable, if torn scroll.";
|
||
|
}
|
||
|
Eat: "~Eating your words~ is notoriously dangerous for a wizard.
|
||
|
Rearranged in the stomach, a spell might do anything!";
|
||
|
],
|
||
|
with name "chewed";
|
||
|
|
||
|
Object feather "tortoise feather"
|
||
|
with name "tortoise" "feather",
|
||
|
description
|
||
|
"Possibly your rarest, and also least valuable, possession.";
|
||
|
|
||
|
! ----------------------------------------------------------------------------
|
||
|
! The cave mouth and the perfect sapphire
|
||
|
! ----------------------------------------------------------------------------
|
||
|
|
||
|
Place Cave_Mouth "Cave Mouth"
|
||
|
with name "gorse" "footpath" "cave" "mouth",
|
||
|
description
|
||
|
"This is a cave mouth, at one end of a road which winds southeast
|
||
|
over rising ground. The entrance west to the caves is a dark
|
||
|
tunnel, and only a footpath runs further north, into gorse.",
|
||
|
u_to Up_Road, se_to Up_Road, in_to Iron_Door, w_to Iron_Door,
|
||
|
n_to Footpath;
|
||
|
|
||
|
Object -> Iron_Door "iron door"
|
||
|
with name "iron" "door" "heavy",
|
||
|
description "It just looks like an ordinary heavy iron door.",
|
||
|
door_dir
|
||
|
[; if (location==Cave_Mouth) return w_to; return e_to;
|
||
|
],
|
||
|
door_to
|
||
|
[; if (location==Cave_Mouth) return In_Cave;
|
||
|
return Cave_Mouth;
|
||
|
],
|
||
|
describe
|
||
|
[; if (self has open) "^The iron door stands open.";
|
||
|
if (self hasnt locked) "^The iron door is unlocked but shut.";
|
||
|
"A heavy iron door bars the cave mouth.";
|
||
|
],
|
||
|
found_in In_Cave Cave_Mouth
|
||
|
has static door openable locked lockable;
|
||
|
|
||
|
! Cf. T. S. Eliot, "Burnt Norton" II:
|
||
|
! (but see also Mallarme's sonnet from which Eliot borrowed the image)
|
||
|
|
||
|
Object -> sapphire "perfect sapphire"
|
||
|
with name "perfect" "sapphire" "gemstone" "gem",
|
||
|
initial "Clotted in the mud beside the door is a perfect sapphire.",
|
||
|
before
|
||
|
[; Examine: remove self; move caskly_spell to memory;
|
||
|
players_book.learn_spell(caskly_spell);
|
||
|
caskly_spell.number=100;
|
||
|
"As you gaze into the perfect blue of the sapphire,
|
||
|
you feel your mind begin to reel. Unable to bear
|
||
|
the naked sight of perfection, you look away, ashamed.
|
||
|
As you do so, the sapphire cracks and wastes away to
|
||
|
thin hot dust. But something remains, something in your
|
||
|
mind...";
|
||
|
];
|
||
|
|
||
|
Spell caskly_spell
|
||
|
with name "caskly",
|
||
|
purpose "cause perfection",
|
||
|
magic
|
||
|
[; if (second==0) "Trying to make everything perfect was a little
|
||
|
too ambitious.";
|
||
|
if (second==player) "Oh, don't be too hard on yourself.";
|
||
|
if (second==helistars_book)
|
||
|
"Your spell is not powerful enough to restore the lost pages.";
|
||
|
print_ret (The) second, " looks pretty perfect as is.";
|
||
|
];
|
||
|
|
||
|
! ----------------------------------------------------------------------------
|
||
|
! Inside the Cave, the powerful urbzig spell and its consequences
|
||
|
! ----------------------------------------------------------------------------
|
||
|
|
||
|
Place In_Cave "Inside Cave"
|
||
|
with description
|
||
|
"A wide but shallow cave not far inside the hill. There is no
|
||
|
obvious exit, except for the way you came in.",
|
||
|
out_to
|
||
|
[; if (CoinsIn(left_pan)+CoinsIn(right_pan) < 6)
|
||
|
"Something bars your way, and you hear
|
||
|
the scales jangling militantly. You were trying to
|
||
|
steal its coins!";
|
||
|
if (scales.number~=0) "Something bars your way, and you hear
|
||
|
the scales jangle slightly with energy.";
|
||
|
return Iron_Door;
|
||
|
],
|
||
|
e_to
|
||
|
[; return self.out_to();
|
||
|
],
|
||
|
cant_go "The only way is back ~out~ through the iron door.",
|
||
|
after
|
||
|
[; Take: if (parent(noun)==left_pan or right_pan)
|
||
|
print_ret "Taken from ", (the) parent(noun), ".";
|
||
|
],
|
||
|
has ~light;
|
||
|
|
||
|
FeaturelessCube -> cave_cube "cube"
|
||
|
with initial "Balanced on a rock formation is a featureless white cube.";
|
||
|
|
||
|
Object -> scales "pair of scales"
|
||
|
with name "pair" "of" "scales" "pans", number 0,
|
||
|
describe
|
||
|
[; print "^A fair-sized pair of scales hangs from a bracket in the
|
||
|
cave wall. ";
|
||
|
if (self.number==0) "The scales are balanced.";
|
||
|
if (self.number==1) "The left-hand side is higher.";
|
||
|
"The right-hand side is higher.";
|
||
|
],
|
||
|
before
|
||
|
[; "There are left and right hand pans, which you should refer to
|
||
|
individually.";
|
||
|
],
|
||
|
has static supporter;
|
||
|
|
||
|
Class ScalePan
|
||
|
with name "pan" "side" "tray",
|
||
|
before
|
||
|
[; Receive:
|
||
|
if (noun ofclass Scroll or Coin) rfalse;
|
||
|
if (noun==feather) rfalse;
|
||
|
"The pans gleam with what almost seems greed, and somehow they
|
||
|
contrive to nudge your hand past them with your worthless and
|
||
|
boring item.";
|
||
|
],
|
||
|
after
|
||
|
[ i j d w1 w2; Receive, LetGo: i=scales.number;
|
||
|
objectloop (j in left_pan) w1=w1 + WeightOf(j);
|
||
|
objectloop (j in right_pan) w2=w2 + WeightOf(j);
|
||
|
if (w1==w2) scales.number=0;
|
||
|
if (w1 > w2) scales.number=-1;
|
||
|
if (w1 < w2) scales.number=1;
|
||
|
j=scales.number; d=(w2-w1)*(scales.number);
|
||
|
if (j==i) rfalse;
|
||
|
if (j==0) "The scales come into balance.";
|
||
|
if (j==1) print "The left pan "; else print "The right pan ";
|
||
|
if (d==1) "very slowly rises up.";
|
||
|
"rises up.";
|
||
|
],
|
||
|
has supporter scenery;
|
||
|
|
||
|
[ WeightOf obj;
|
||
|
if (obj==bronze_coin) return 2;
|
||
|
if (obj ofclass Scroll || obj==feather) return 1;
|
||
|
return 3;
|
||
|
];
|
||
|
|
||
|
[ CoinsIn obj i c;
|
||
|
objectloop (i in obj) if (i ofclass Coin) c++;
|
||
|
return c;
|
||
|
];
|
||
|
|
||
|
ScalePan -> right_pan "right pan" with name "right";
|
||
|
GoldCoin -> ->;
|
||
|
GoldCoin -> ->;
|
||
|
GoldCoin -> ->;
|
||
|
|
||
|
ScalePan -> left_pan "left pan" with name "left";
|
||
|
BronzeCoin -> -> bronze_coin;
|
||
|
GoldCoin -> ->;
|
||
|
GoldCoin -> ->;
|
||
|
|
||
|
Scroll -> -> crumpled_scroll "crumpled scroll"
|
||
|
with name "crumpled";
|
||
|
Spell -> -> -> urbzig_spell
|
||
|
with name "urbzig",
|
||
|
purpose "turn a dangerous object into a harmless one",
|
||
|
magic
|
||
|
[; if (second==0) "The spell fizzles away.";
|
||
|
if (second==player) "It's a matter of opinion, isn't it?";
|
||
|
if (second==helistars_book or mace || second ofclass FeaturelessCube)
|
||
|
{ CDefArt(second); remove second;
|
||
|
if (second==mace && cyclops in location)
|
||
|
{ remove cyclops; move eye_cube to location;
|
||
|
" turns into a featureless white cube just as the cyclops
|
||
|
was about to hit you with it. Mightily embarrassed
|
||
|
by this, he drops the cube and runs off!";
|
||
|
}
|
||
|
print " turns into a moth and flutters away.^";
|
||
|
rtrue;
|
||
|
}
|
||
|
print_ret "Nothing obvious happens. Perhaps ", (the) second,
|
||
|
" isn't so very dangerous after all.";
|
||
|
],
|
||
|
unmagic
|
||
|
[; if (second==0) "The spell fizzles away.";
|
||
|
if (second==player) "It's a matter of opinion, isn't it?";
|
||
|
if (second has static || second has scenery)
|
||
|
{ print_ret "Your spell is too weak for something quite as
|
||
|
monumentally harmless as ", (the) second, ".";
|
||
|
}
|
||
|
if (second==helistars_book or snake or cyclops or mace
|
||
|
|| second ofclass FeaturelessCube)
|
||
|
"Nothing obvious happens.";
|
||
|
if (second in player)
|
||
|
{ remove second; deadflag = true;
|
||
|
"Suddenly, a tarantula races up your arm to your throat!
|
||
|
Perhaps it was unwise to gizbru something you were
|
||
|
actually holding.";
|
||
|
}
|
||
|
if (cyclops has general)
|
||
|
"Nothing happens. Perhaps that's just as well,
|
||
|
after the last time.";
|
||
|
move cyclops to location;
|
||
|
remove second; give cyclops general; StartTimer(cyclops, 5);
|
||
|
print_ret (The) second, " is replaced by a buck-toothed cyclops
|
||
|
wielding a mace!";
|
||
|
];
|
||
|
|
||
|
Object cyclops "buck-toothed cyclops"
|
||
|
with name "buck" "toothed" "buck-toothed" "cyclops",
|
||
|
initial "A huge buck-toothed cyclops menaces you, armed with a
|
||
|
heavy mace!",
|
||
|
before
|
||
|
[; Cast: if (the_spell_was == bozbar_spell)
|
||
|
"Does the term ~death wish~ mean anything to you?";
|
||
|
if (the_spell_was == urbzig_spell)
|
||
|
"The cyclops bellows with glee as your spell has
|
||
|
no effect. (After all, he wouldn't be ~dangerous~ if
|
||
|
an urbzig spell worked on him, would he?)";
|
||
|
],
|
||
|
life [; "He roars incoherently, swinging the mace!"; ],
|
||
|
time_left 0,
|
||
|
time_out
|
||
|
[; if (self notin location)
|
||
|
{ remove self; rtrue;
|
||
|
}
|
||
|
deadflag = true; remove mace; remove cyclops;
|
||
|
"Feeling that he's given you quite long enough to explain why
|
||
|
you made such a mess of his life, he swings the great mace
|
||
|
maniacally down on you!";
|
||
|
],
|
||
|
each_turn
|
||
|
[ i; i=random(4); if (i==1) "^The cyclops leaps and bellows!";
|
||
|
if (i==2)
|
||
|
"^Whirling the mace, the cyclops jabbers at you incoherently.";
|
||
|
if (i==3)
|
||
|
"^The cyclops is losing patience (the appropriate cyclops
|
||
|
word is untranslatable into English, but approximately means
|
||
|
~forbearance in not smashing all nearby skulls~).";
|
||
|
"^The cyclops jabs you with the mace, almost breaking your rib.";
|
||
|
],
|
||
|
has animate transparent;
|
||
|
|
||
|
Object -> mace "mace"
|
||
|
with name "heavy" "mace" "axe",
|
||
|
description "It looks much too heavy for you to even lift.";
|
||
|
|
||
|
FeaturelessCube -> eye_cube "cube"
|
||
|
with initial
|
||
|
"A featureless white cube lies where the cyclops dropped it.";
|
||
|
|
||
|
! ----------------------------------------------------------------------------
|
||
|
! The Footpath and the carpet
|
||
|
! ----------------------------------------------------------------------------
|
||
|
|
||
|
Place Footpath "Gorse Bushes"
|
||
|
with description
|
||
|
"The footpath from the cave mouth runs into dense, impenetrable
|
||
|
gorse bushes. Perhaps it wasn't so much a footpath as a rill
|
||
|
in the earth where roots wouldn't take; anyway, there's no way
|
||
|
but back south.",
|
||
|
s_to Cave_Mouth;
|
||
|
|
||
|
Object -> carpet "beautiful red carpet"
|
||
|
with name "beautiful" "magic" "red" "carpet",
|
||
|
initial
|
||
|
"Slung over one of the gorse bushes is a beautiful red carpet.",
|
||
|
description
|
||
|
"This is a carpet of unusual design. It is red, beautifully woven
|
||
|
and bears a pattern of cubes.",
|
||
|
before
|
||
|
[ i; Receive:
|
||
|
if (self notin location || self hasnt moved)
|
||
|
"Not until the carpet's on the ground, you can't.";
|
||
|
Ride: <<Enter self>>;
|
||
|
Enter:
|
||
|
if (self notin location || self hasnt moved)
|
||
|
"Not until the carpet's on the ground, you can't.";
|
||
|
if (location==Balance_Room)
|
||
|
"Mysteriously, the carpet rucks and pulls until you're
|
||
|
thrown off. It settles back on the white floor with a
|
||
|
contented sigh.";
|
||
|
if (location==In_Cave)
|
||
|
"The carpet rises suddenly, crashing into the roof of
|
||
|
the cave and throwing you back off again. Painfully.";
|
||
|
if (location==Bazaar) i=Up_Road; else i=Bazaar;
|
||
|
print "The carpet rises suddenly into the fluffy white
|
||
|
clouds, and after a headlong journey deposits you...^";
|
||
|
move self to i;
|
||
|
PlayerTo(i,1); move player to self; <<Look>>;
|
||
|
Take: if (player in self) "Not while you're on it!";
|
||
|
for (i=child(self):i~=0:i=child(self))
|
||
|
{ move i to location;
|
||
|
print "(Dislodging ", (the) i, ")^";
|
||
|
}
|
||
|
],
|
||
|
has supporter enterable;
|
||
|
|
||
|
! ----------------------------------------------------------------------------
|
||
|
! A Bazaar Lottery
|
||
|
! ----------------------------------------------------------------------------
|
||
|
|
||
|
Global last_called = 1;
|
||
|
Global explicit_flag = 0;
|
||
|
Global tickets_taken = 0;
|
||
|
|
||
|
Class Ticket(6)
|
||
|
with number -1, name "ticket",
|
||
|
description
|
||
|
[; if (self.number==2306) "It is labelled ~First Prize~!";
|
||
|
if (self.number==5802) "It is labelled ~Nineteenth Prize~.";
|
||
|
"~You lose,~ says the ticket, with a smily face. ~Try again!~";
|
||
|
],
|
||
|
short_name
|
||
|
[; if (self.number==-1) rfalse;
|
||
|
print "lottery ticket ", self.number; rtrue;
|
||
|
],
|
||
|
parse_name
|
||
|
[ i j w;
|
||
|
i=0;
|
||
|
if (NextWord()=='lottery') i++; else wn--;
|
||
|
if (NextWord()=='tickets')
|
||
|
{ parser_action=##PluralFound; return i+1; } else wn--;
|
||
|
if (NextWord()~='ticket') return 0;
|
||
|
i++;
|
||
|
w=TryNumber(wn);
|
||
|
if (w==-1000) { explicit_flag = false; return i; }
|
||
|
if (w==0) return 0;
|
||
|
if (self.number==-1)
|
||
|
{ objectloop(j ofclass Ticket)
|
||
|
if (w == j.number) return 0;
|
||
|
}
|
||
|
else
|
||
|
{ if (self.number~=w) return 0;
|
||
|
}
|
||
|
i++; last_called = w; explicit_flag = true; return i;
|
||
|
],
|
||
|
before
|
||
|
[; Examine:
|
||
|
if (self in board)
|
||
|
"It would be cheating to see what's written on the curled up
|
||
|
tickets still in the board.";
|
||
|
Cast: "~Get outta here, bub!~, the barker says, disgusted.";
|
||
|
];
|
||
|
|
||
|
Place Bazaar "Crowded Bazaar"
|
||
|
with description
|
||
|
"This is a crowded, noisy bazaar. Directly in front of you is
|
||
|
a lottery! But the contemptuous-looking barker is doing a
|
||
|
very poor trade: hardly anyone wants his first prize, the
|
||
|
big cuddly toy elephant, or even his nineteenth prize, a
|
||
|
featureless white cube.",
|
||
|
each_turn
|
||
|
[; switch(random(4))
|
||
|
{ 1: "^~Roll up! Roll up! One silver piece for three goes!~";
|
||
|
2: "^~Come on, then! Just a silver coin gets you three!~";
|
||
|
3: "^~Think what you could win, all for one silver coin!~";
|
||
|
4: "^~This could be your lucky day!~";
|
||
|
}
|
||
|
],
|
||
|
before
|
||
|
[; Learn:
|
||
|
"~None of that!~ snaps the barker angrily, putting you off
|
||
|
your study habits. He mutters about ~Enchanter cheats~,
|
||
|
but under the circumstances you decide to let the insult
|
||
|
pass.";
|
||
|
],
|
||
|
cant_go "Everywhere, the crowds of jabbering natives block your way
|
||
|
to all the good stalls. In fact, the only one you can get at is
|
||
|
this dismal lottery.";
|
||
|
|
||
|
Object -> board "lottery board"
|
||
|
with credit 0,
|
||
|
name "board" "lottery" "holes",
|
||
|
description
|
||
|
"There are a hundred holes each way, making, um, let's see, yes,
|
||
|
ten thousand tickets in all. Still, there are nineteen prizes,
|
||
|
so your odds must be, oh, well, not too awful anyway.",
|
||
|
before
|
||
|
[ i; LetGo:
|
||
|
if (self.credit == 0)
|
||
|
"The barker stabs you in the chest with
|
||
|
his finger. ~That's a silver coin to you, bub!~";
|
||
|
|
||
|
if (explicit_flag)
|
||
|
{ objectloop (i ofclass Ticket)
|
||
|
if (last_called == i.number)
|
||
|
"That ticket's already taken.";
|
||
|
}
|
||
|
else
|
||
|
{ .RandomChoice;
|
||
|
last_called = random(10000);
|
||
|
objectloop (i ofclass Ticket)
|
||
|
if (last_called == i.number)
|
||
|
jump RandomChoice;
|
||
|
}
|
||
|
|
||
|
tickets_taken++;
|
||
|
self.credit--;
|
||
|
|
||
|
i = Ticket.create();
|
||
|
if (i == 0)
|
||
|
"The barker looks metaphysically embarrassed. ~Um,
|
||
|
Inform's object creation system seems not to have worked.~";
|
||
|
|
||
|
i.number = last_called; itobj = i;
|
||
|
|
||
|
move i to player; give i moved proper;
|
||
|
if (explicit_flag==0)
|
||
|
print "Randomly picking from the ", 10001-tickets_taken,
|
||
|
" numbered holes with tickets in, you ";
|
||
|
else print "You ";
|
||
|
print_ret "take ", (the) i, " out of the board.";
|
||
|
|
||
|
Examine: ;
|
||
|
Receive:
|
||
|
if (noun ofclass Ticket)
|
||
|
"~No changes of mind, that's your ticket now! Give it to
|
||
|
me if you want to play it.~";
|
||
|
<<Push self>>;
|
||
|
default:
|
||
|
"The barker is burly, and won't let you
|
||
|
tamper with the board.";
|
||
|
],
|
||
|
initial
|
||
|
"Behind the barker is a huge drilled board, and inside each little
|
||
|
numbered hole is a rolled-up lottery ticket."
|
||
|
has static container open;
|
||
|
|
||
|
Ticket -> -> ticket_in_board "rolled-up ticket from the board"
|
||
|
with article "a";
|
||
|
|
||
|
Object -> barker "barker"
|
||
|
with name "barker" "burly" "man",
|
||
|
number 0,
|
||
|
description
|
||
|
"A boxer gone to seed who failed as a magician all down the
|
||
|
coast, that'd be your guess.",
|
||
|
life
|
||
|
[; Attack, Kiss: "No way. He must weigh twice what you do.";
|
||
|
Ask: switch(noun)
|
||
|
{ 'prize', 'prizes':
|
||
|
"~Just one silver coin and a prize could be yours!~";
|
||
|
'white', 'featureless', 'cube':
|
||
|
"He blows the dust off it. ~Genuine antique, that.~";
|
||
|
'elephant', 'toy', 'cuddly':
|
||
|
"~Good quality merchandise,~ he says, in a way that
|
||
|
suggests he can only spell one of those three words.";
|
||
|
'ticket', 'tickets', 'lottery':
|
||
|
"~Three tickets for one silver coin!~";
|
||
|
default: "~Just play the game, bub.~";
|
||
|
}
|
||
|
Order, Answer: "The barker glowers at you.";
|
||
|
Give: if (noun ofclass Ticket)
|
||
|
{ remove noun;
|
||
|
if (noun.number==2306)
|
||
|
{ move elephant to player; give elephant moved;
|
||
|
remove pelephant;
|
||
|
Bazaar.description =
|
||
|
"This is a crowded, noisy bazaar. Directly in front of you is
|
||
|
the lottery!";
|
||
|
"With very bad grace, the barker shoves the
|
||
|
cuddly toy elephant into your arms.";
|
||
|
}
|
||
|
if (noun.number==5802)
|
||
|
{ move barker_cube to player; give barker_cube moved;
|
||
|
remove pcube;
|
||
|
Bazaar.description =
|
||
|
"This is a crowded, noisy bazaar. Directly in front of you is
|
||
|
the lottery!";
|
||
|
score=score+5;
|
||
|
"With concealed relief, the barker shoves the
|
||
|
featureless white cube into your hands.";
|
||
|
}
|
||
|
"~Bad luck! You lose!~";
|
||
|
}
|
||
|
if (self.number==2) "~You've had enough goes already!~ he
|
||
|
growls. No wonder trade is bad.";
|
||
|
if (~~(noun ofclass Coin))
|
||
|
"~What do you call that? One silver coin to play!~";
|
||
|
if ((noun.&name)-->0 == 'bronze')
|
||
|
"~Bronze! Not a chance, sunshine.~";
|
||
|
remove noun;
|
||
|
board.credit = board.credit + 3;
|
||
|
self.number++;
|
||
|
if ((noun.&name)-->0 == 'gold')
|
||
|
"Gleefully the barker snatches the gold coin. ~Sorry
|
||
|
bub, no change. Business is slack today!~";
|
||
|
"Grudgingly the barker takes the silver coin and stands
|
||
|
back to let you at the board, arms folded.";
|
||
|
],
|
||
|
before
|
||
|
[; Cast: switch(the_spell_was)
|
||
|
{ bozbar_spell:
|
||
|
"He's not that much of an animal.";
|
||
|
lobal_spell:
|
||
|
"His problem is listening, not hearing.";
|
||
|
caskly_spell:
|
||
|
"For a moment his hair seems to comb itself.
|
||
|
Irritated, he ruffles it again, and the spell dies
|
||
|
an ignominious death.";
|
||
|
yomin_spell:
|
||
|
if (elephant has moved || barker_cube has moved)
|
||
|
"The barker's mind is a heap of grumbles about lost
|
||
|
prizes and scrawny Enchanters.";
|
||
|
if (self hasnt general)
|
||
|
{ give self general;
|
||
|
"~Hope that scrawny Enchanter doesn't pick 2306!~
|
||
|
thinks the barker (slowly).";
|
||
|
}
|
||
|
"~If that mark does win, hope it's only worthless
|
||
|
old 5802,~ ponders the barker.";
|
||
|
}
|
||
|
],
|
||
|
has animate scenery;
|
||
|
|
||
|
Object -> prizes "prizes"
|
||
|
with name "prize" "prizes",
|
||
|
before [; "~Hands off those prizes!~"; ],
|
||
|
has scenery;
|
||
|
|
||
|
Object -> pelephant "prize elephant"
|
||
|
with name "prize" "elephant" "cuddly" "toy",
|
||
|
description "Pink, cuddly, toy, elephant. Says it all, really.",
|
||
|
before [; Examine: ; default: "~Hands off those prizes!~"; ],
|
||
|
has scenery;
|
||
|
|
||
|
Object -> pcube "prize cube"
|
||
|
with name "prize" "featureless" "white" "cube",
|
||
|
description "Wouldn't you like to win it?",
|
||
|
before [; Examine: ; default: "~Hands off those prizes!~"; ],
|
||
|
has scenery;
|
||
|
|
||
|
Object elephant "cuddly toy elephant"
|
||
|
with name "cuddly" "toy" "elephant",
|
||
|
description "Pink, cuddly, toy, elephant. Says it all, really.",
|
||
|
before
|
||
|
[; Cast: if (the_spell_was == bozbar_spell)
|
||
|
"Let me get this straight. You, the enchanter who
|
||
|
defeated Krill, the head of the Borphee Guild
|
||
|
himself... are attempting to grow wings on a pink
|
||
|
cuddly elephant?";
|
||
|
if (the_spell_was == yomin_spell) "Woolly.";
|
||
|
];
|
||
|
|
||
|
FeaturelessCube barker_cube "cube";
|
||
|
|
||
|
! ----------------------------------------------------------------------------
|
||
|
! The spells in Helistar's grimoire
|
||
|
! ----------------------------------------------------------------------------
|
||
|
|
||
|
Spell lleps_spell
|
||
|
with name "lleps",
|
||
|
purpose "reverse effect of memorised spell",
|
||
|
magic
|
||
|
[; if (second==0 || second notin memory)
|
||
|
"The spell backfires, painfully.";
|
||
|
if (second.number==100)
|
||
|
"You know that spell too well for your mind to be able
|
||
|
to accept the change.";
|
||
|
if (second has reversed) give second ~reversed;
|
||
|
else give second reversed;
|
||
|
if (second==lleps_spell)
|
||
|
{ memory.forget_spell(second);
|
||
|
"Your mind wrenches as the two lleps spells
|
||
|
cancel each other out, leaving only a sensation
|
||
|
quite like a hangover.";
|
||
|
}
|
||
|
print_ret "Your mind wrenches as ", (the) second,
|
||
|
" reverses itself.";
|
||
|
],
|
||
|
unmagic
|
||
|
[; return self.magic(); ! The reverse of "lleps" is "lleps"
|
||
|
];
|
||
|
|
||
|
Spell mortin_spell
|
||
|
with name "mortin",
|
||
|
purpose "cause immediate death of caster",
|
||
|
magic
|
||
|
[; deadflag = true;
|
||
|
"You really can't fault Helistar on this one. Death is
|
||
|
absolutely immediate, like a sudden blackout curtain...";
|
||
|
],
|
||
|
unmagic
|
||
|
[; prepared_flag = true;
|
||
|
"Nothing quite happens... and yet you feel enormously more
|
||
|
confident as you go about this dangerous world.";
|
||
|
];
|
||
|
|
||
|
! ----------------------------------------------------------------------------
|
||
|
! Death and the Boneyard
|
||
|
! ----------------------------------------------------------------------------
|
||
|
|
||
|
[ AfterLife;
|
||
|
if (~~prepared_flag) rfalse;
|
||
|
|
||
|
if (player in Balance_Room)
|
||
|
"^^Your foresight in preparing a resurrection was wasted. The
|
||
|
tangled magic of the Balance Room coiled around your puny
|
||
|
enchantment like a constricting serpent.";
|
||
|
|
||
|
prepared_flag = false; deadflag = false; hearing_good = false;
|
||
|
|
||
|
if (memory.capacity >= 2) memory.capacity--;
|
||
|
|
||
|
while (child(player)~=0) move child(player) to parent(player);
|
||
|
move players_book to player;
|
||
|
|
||
|
print "^^With great foresight you prepared yourself for resurrection...
|
||
|
Your mind feels a little weaker, but at least you're alive.^";
|
||
|
PlayerTo(Boneyard);
|
||
|
];
|
||
|
|
||
|
Place Boneyard "Boneyard"
|
||
|
with name "bones" "blades" "shoulder" "skulls",
|
||
|
description
|
||
|
"This is a room of bones. Shoulder blades make up the floor,
|
||
|
skulls the walls and leg-bones the door frames. The west exit
|
||
|
leads into darkness, but the doorway to the north opens onto a
|
||
|
seemingly normal scene.",
|
||
|
n_to
|
||
|
[; if (scales.number ~= 0) return In_Cave;
|
||
|
return Grasslands;
|
||
|
],
|
||
|
w_to "Some magical force blocks your way, as though that doorway
|
||
|
led into adventures from your past which you cannot rejoin now.",
|
||
|
before
|
||
|
[; Examine, Search:
|
||
|
if (noun==w_obj) "You can make out nothing to the west.";
|
||
|
];
|
||
|
|
||
|
Scroll -> worthless_scroll "worthless scroll"
|
||
|
with initial "You are almost treading on a worthless scroll.",
|
||
|
name "worthless";
|
||
|
|
||
|
Spell -> -> filfre_spell
|
||
|
with name "filfre",
|
||
|
purpose "produce gratuitous fireworks",
|
||
|
magic
|
||
|
[; if (self hasnt scored) { score++; give self scored; }
|
||
|
"A brief shower of gratuitous fireworks spells out:
|
||
|
^^The masterly Enchanter trilogy was written by Marc Blank,
|
||
|
Dave Lebling and Steve Meretzky.";
|
||
|
],
|
||
|
unmagic
|
||
|
[; "A lengthy shower of artistically justified fireworks spells out:
|
||
|
^^The masterly Enchanter trilogy was written by Jane Austen,
|
||
|
Emily Bronte and Edgar Allen Poe.";
|
||
|
];
|
||
|
|
||
|
! ----------------------------------------------------------------------------
|
||
|
! The Cubical Temple
|
||
|
! ----------------------------------------------------------------------------
|
||
|
|
||
|
Place Track "Track, outside Temple"
|
||
|
with description
|
||
|
"This is the end of a long track winding through desolate hills,
|
||
|
which runs back west up to the ridge.",
|
||
|
before
|
||
|
[; Listen:
|
||
|
if (~~hearing_good) "The chanting is too quiet to make out.";
|
||
|
"The endlessly repeating threnody of the monks tells of
|
||
|
the legend of one who will some day enlighten their order,
|
||
|
and so be taken up to a higher plane. He (or she,
|
||
|
presumably) is known as The Four-Cubed One.";
|
||
|
],
|
||
|
w_to Up_Road, u_to Up_Road;
|
||
|
|
||
|
Object -> Temple "cubical Temple"
|
||
|
with name "temple" "cubical" "cube" "enormous",
|
||
|
before
|
||
|
[ i j;
|
||
|
Enter: "The Temple is featureless and unbroken. Perhaps the top
|
||
|
is open, because the sound must come from somewhere...
|
||
|
but you wouldn't bet on it.";
|
||
|
Cast: switch(the_spell_was)
|
||
|
{ rezrov_spell:
|
||
|
"The huge temple remains impassive at your relatively
|
||
|
puny enchantment.";
|
||
|
frotz_spell:
|
||
|
objectloop (i in player)
|
||
|
if (i ofclass FeaturelessCube) j++;
|
||
|
if (j==0)
|
||
|
"The temple shakes, but then is still again.";
|
||
|
if (j<4) "The temple shakes! White light plays
|
||
|
over your hands and possessions, but then all is
|
||
|
still again.";
|
||
|
print "The temple shakes and white light bathes you.
|
||
|
Smoothly it unfolds itself in a four-dimensional
|
||
|
way your senses can barely comprehend. All you
|
||
|
know is that when it is over,
|
||
|
you find yourself in...^";
|
||
|
hearing_good = false; score=score+5;
|
||
|
PlayerTo(Balance_Room); rtrue;
|
||
|
}
|
||
|
],
|
||
|
describe
|
||
|
[; print "^You stand outside an enormous temple in the shape of a
|
||
|
perfect, featureless white cube, four hundred feet on a
|
||
|
side. From somewhere within you hear the ";
|
||
|
if (hearing_good) print "bellowing noise";
|
||
|
else print "tiny sound";
|
||
|
" of the monks chanting.";
|
||
|
],
|
||
|
description
|
||
|
"It's much like every other gigantic temple in the shape of a
|
||
|
featureless white cube you've ever seen. No obvious way in.",
|
||
|
has static;
|
||
|
|
||
|
! ----------------------------------------------------------------------------
|
||
|
! Inside the Temple
|
||
|
! ----------------------------------------------------------------------------
|
||
|
|
||
|
Place Balance_Room "Balance Room"
|
||
|
with description
|
||
|
"This seems to be the inside of a featureless white cube, forty
|
||
|
feet on a side. The air is stale and there is no exit.";
|
||
|
|
||
|
Object -> balance_meter "image of the scales"
|
||
|
with name "image" "scales" "of" "pair", article "the",
|
||
|
initial "The image of a pair of scales hangs high in the air. One
|
||
|
pan is much lower than the other.",
|
||
|
before
|
||
|
[; "It's only an image.";
|
||
|
],
|
||
|
has static;
|
||
|
|
||
|
Object -> dusty_podium "dusty podium"
|
||
|
with name "podium" "dusty" "cobwebs" "cobwebbed",
|
||
|
initial "Far below the scales, in the centre of the ~floor~, is a
|
||
|
predictably-shaped podium, but it is so dusty and
|
||
|
cobwebbed that you can't see what it once was.",
|
||
|
before
|
||
|
[; Cast: if (the_spell_was == caskly_spell)
|
||
|
"Nice try, but it is protected from enchantment.";
|
||
|
"However dusty it is, the podium is still protected from
|
||
|
casual enchantment.";
|
||
|
Rub: remove self; move balance_key to Balance_Room;
|
||
|
itobj = balance_key;
|
||
|
"No substitute for old-fashioned hard work, sometimes,
|
||
|
and after much patient (sneezy) scrubbing, the podium
|
||
|
appears in its true white glory. Set into it are four
|
||
|
sockets, arranged in a two by two square.";
|
||
|
],
|
||
|
has static;
|
||
|
|
||
|
Object balance_key "podium"
|
||
|
with name "podium" "pedestal" "platform" "cubical",
|
||
|
description "As predicted, it is cubical.",
|
||
|
initial "Far below the scales, in the centre of the ~floor~, is a
|
||
|
predictably-shaped podium. Set into it are four sockets,
|
||
|
arranged in a two by two square.",
|
||
|
has static supporter;
|
||
|
|
||
|
Object -> sockets "two by two square"
|
||
|
with name "square" "two" "by" "two",
|
||
|
before
|
||
|
[ i; if (action~=##Examine || number_filled==0)
|
||
|
"You'll have to say which socket you mean.
|
||
|
(Let's call them ~top left~, ~bottom right~ and so on.)";
|
||
|
objectloop (i in self)
|
||
|
{ print (The) i;
|
||
|
if (child(i)==0) print " is empty.^";
|
||
|
else { print " contains ", (a) child(i), ".^"; }
|
||
|
}
|
||
|
rtrue;
|
||
|
],
|
||
|
has static;
|
||
|
|
||
|
Class Socket
|
||
|
with name "socket", article "the",
|
||
|
before
|
||
|
[; Cast: "The sockets are proof against magic.";
|
||
|
Examine: print (The) self, ", cubical and slightly more
|
||
|
than four inches on a side, is decorated with ",
|
||
|
(string) self.description;
|
||
|
if (child(self) == nothing) ".";
|
||
|
print_ret ", and contains ", (a) child(self), ".";
|
||
|
Receive: if (~~(noun ofclass FeaturelessCube))
|
||
|
"The socket rejects that.";
|
||
|
if (child(self) ~= nothing)
|
||
|
"There is already a cube in that socket.";
|
||
|
],
|
||
|
after
|
||
|
[; LetGo: number_filled--;
|
||
|
"With much struggle, you manage to pull the cube away.";
|
||
|
Receive: number_filled++;
|
||
|
if (number_filled==4)
|
||
|
{ if (snakes_cube in bl_socket
|
||
|
&& barker_cube in ul_socket
|
||
|
&& cave_cube in br_socket
|
||
|
&& eye_cube in ur_socket)
|
||
|
{ deadflag=2; score=score+5;
|
||
|
"As you place the final cube into the sockets, you feel
|
||
|
imbued with celestial wisdom (more so than usually).
|
||
|
You find yourself growing to the height of the cube, so
|
||
|
that you pull the balances back level by hand, and then
|
||
|
you grow still further, out of the temple until it is but
|
||
|
a cube in your hand, and you are a giant towering over
|
||
|
the land.
|
||
|
^^Then, of course, you wake up, glumly realising it's time
|
||
|
to go to your job at the new Borphee Laboratories and
|
||
|
all those Wheatstone bridge experiments. But at least
|
||
|
you can dream about the old days.";
|
||
|
}
|
||
|
"The sockets are all full now, but that doesn't mean
|
||
|
anything's happened.";
|
||
|
}
|
||
|
"The cube is a predictably perfect fit in the socket.";
|
||
|
],
|
||
|
has static container open;
|
||
|
|
||
|
Socket -> bl_socket "bottom left socket"
|
||
|
with name "bottom" "left" "serpent",
|
||
|
description "a serpent";
|
||
|
|
||
|
Socket -> ul_socket "top left socket"
|
||
|
with name "top" "left" "bazaar",
|
||
|
description "a scene in a bazaar";
|
||
|
|
||
|
Socket -> br_socket "bottom right socket"
|
||
|
with name "bottom" "right" "cave",
|
||
|
description "an engraving of a rocky cave";
|
||
|
|
||
|
Socket -> ur_socket "top right socket"
|
||
|
with name "top" "right" "eye",
|
||
|
description "an eye";
|
||
|
|
||
|
! ----------------------------------------------------------------------------
|
||
|
! That's all of the object definitions: just a little code and grammar left
|
||
|
! ----------------------------------------------------------------------------
|
||
|
|
||
|
[ Initialise;
|
||
|
|
||
|
location = Hut;
|
||
|
move burin to player;
|
||
|
move players_coin to player;
|
||
|
move players_book to player;
|
||
|
|
||
|
thedark.description =
|
||
|
"It is pitch black. You are likely to be eaten by a grue.";
|
||
|
! (In fact you are stone-cold certain not to be, but never mind.)
|
||
|
|
||
|
players_book.learn_spell(gnusto_spell);
|
||
|
players_book.learn_spell(frotz_spell);
|
||
|
players_book.learn_spell(yomin_spell);
|
||
|
players_book.learn_spell(rezrov_spell);
|
||
|
|
||
|
helistars_book.learn_spell(frotz_spell);
|
||
|
helistars_book.learn_spell(lleps_spell);
|
||
|
helistars_book.learn_spell(mortin_spell);
|
||
|
|
||
|
give gnusto_spell known_about;
|
||
|
|
||
|
"^^^^^[Welcome to a short story called ~Balances~, one of the example
|
||
|
games for the Inform design system. Some people may recognise the
|
||
|
setting, but others might like to type ~how do spells work~ -
|
||
|
the game responds to a few such questions.]
|
||
|
^^You feel a little confused as to how you got here. Something
|
||
|
to do with Helistar! That's right, and how the world is so far
|
||
|
off balance nowadays, after the Great Change.^^";
|
||
|
];
|
||
|
|
||
|
[ PrintRank;
|
||
|
print ", earning you the rank of ";
|
||
|
if (score >= 50) "Scientist.";
|
||
|
if (score >= 40) "Spellbreaker.";
|
||
|
if (score >= 30) "Sorcerer.";
|
||
|
if (score >= 20) "Enchanter.";
|
||
|
if (score >= 10) "novice Enchanter.";
|
||
|
"lost dreamer.";
|
||
|
];
|
||
|
|
||
|
[ DiagnoseSub;
|
||
|
switch(memory.capacity)
|
||
|
{ 5: "You feel fine, and your memory is unimpaired.";
|
||
|
4: "You feel shaky after your brush with death, but your mental
|
||
|
faculties seem sound.";
|
||
|
3: "For someone who has died twice, you're in reasonable shape.";
|
||
|
}
|
||
|
"How many times have you died now? Your memory isn't what it was.";
|
||
|
];
|
||
|
|
||
|
! ----------------------------------------------------------------------------
|
||
|
! Grammar extensions needed by the spell-casting and cube-writing rules:
|
||
|
! ----------------------------------------------------------------------------
|
||
|
|
||
|
Include "Grammar";
|
||
|
|
||
|
[ AnyWord; from_char=0; to_char=0; the_named_word=wn++; return burin; ];
|
||
|
|
||
|
[ 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 burin;
|
||
|
}
|
||
|
return -1;
|
||
|
];
|
||
|
|
||
|
Verb "write" "scribe"
|
||
|
* AnyWord "on" held -> WriteOn
|
||
|
* QuotedText "on" held -> WriteOn;
|
||
|
Verb "copy" * scope=CopyableSpell "to" noun -> CopyTo;
|
||
|
Verb "who" "what" "how"
|
||
|
* "do" scope=Topic -> Query
|
||
|
* "is" scope=Topic -> Query
|
||
|
* "was" scope=Topic -> Query;
|
||
|
Verb "spells" "memory"
|
||
|
* -> Spells;
|
||
|
Verb "learn" "memorise" "memorize"
|
||
|
* scope=ReadableSpell -> Learn;
|
||
|
Extend "examine" first
|
||
|
* scope=ReadableSpell -> Examine;
|
||
|
Verb "c,cast"
|
||
|
* -> CastOne
|
||
|
* noun -> CastOne;
|
||
|
Verb "cast"
|
||
|
* scope=LearnedSpell -> Cast
|
||
|
* scope=LearnedSpell "at" noun -> Cast
|
||
|
* scope=LearnedSpell "on" noun -> Cast;
|
||
|
Verb "diagnose" "health"
|
||
|
* -> Diagnose;
|
||
|
|
||
|
! ----------------------------------------------------------------------------
|
||
|
! And one for the game itself.
|
||
|
! ----------------------------------------------------------------------------
|
||
|
|
||
|
Verb "ride" "mount" "straddle"
|
||
|
* creature -> Ride
|
||
|
* noun -> Enter;
|
||
|
Verb "flip" "toss" * is_coin -> TossCoin;
|
||
|
! ----------------------------------------------------------------------------
|