I want to implement spellcasting in a Inform IF game I'm trying to write.
In previous games, written in BASIC/QBASIC I've done this using a verb
"cast" and a noun "<spell>", where <spell> would be fireball/lightning/death
Basically it worked very well, since I didn't check scope for every noun.
Since I had to write my own parser, I only checked whether the noun was "in
scope" when it mattered for the verb (take/drop/examine etc). It didn't
matter for "cast", since the only thing that had to be checked was whether
that spell was castable.
I want to make spells objects that are "owned" by the player and other
characters in the game. The player must be able to "examine" them:
"Fireball: this spell will send a ball of flame towards your opponent. It
will do 20 points of damage...."
and "cast" them
> CAST FIREBALL AT DWARF
This last one I reckon I can do when I write the cast verb routine.
The problem is with the inventory. The spell must not appear in the
inventory, except perhaps to say:
"You are carrying: x,y,z. You can cast: fireball"
In order to allow the player and other characters to cast the spell, the
easiest implementation I can think of is to make the spell an object with
the actor as the parent. Of course it shouldn't be able to be dropped,
given, etc etc.
One other way is to only make the spells in scope for "examine" and "cast".
This is easy enough for the player, but not for other characters. I suppose
I could make only one person able to cast that spell at any one time (say if
they hold a certain item) but it'd be nicer if the player, the enchanter and
the elf could all cast the same spell. This would be most easily achieved
with multiple spell objects I think (same as having many swords in the game,
owned by several characters).
Is there any way for an object to be a child of something (even the player)
and yet only selectively in scope? Initially I made the object the child of
a dummy room, and then tried writing an InScope routine that PlaceInScope'd
the object if it was of the spell class and was part of an examine action,
but that failed miserably. I just got "You can't see that here" errors.
That would do for starters, but it still leaves me with the problem of
multiple users of the spell.
[ inscope noun;
if (action_to_be == ##examine && noun.class == spell) PlaceInScope (noun);
Using this I can examine everything else I own and can see (if I omit the
rfalse I can't) but I can't see the spell. A simpler routine does work, but
it's not generic.
if (action_to_be == ##examine ) PlaceInScope (fireball);
Any help would be MUCH appreciated. This is bugging me ;-)
University of Cambridge Dept of Medicine
Opinions expressed are mine - I'll take the rap for my own mistakes.
(swap cam for spam to reply via email)
Big fish, little fish, put it in a box. Stacking boxes, stacking boxes...
Take a look at Balances (source code on GMD in inform5.5/examples, I think).
It has a complete Enchanter-style spell system.
I think the way it works is to create a "memory" object, which exists just to
hold the spells. You give your player object "add_to_scope memory", and then
give memory 'transparent' so that the player can still refer to the spells
that are inside it. Since memory isn't actually a child of the player, it
doesn't show up in inventory.
Then you'd also have to worry about players typing "drop fireball" and stuff
like that. Better to keep the spells in scope in another way, and if you do
want them to be listed in the inventory, hack the routine to go through the
spell list after going through the normal inventory.
Actually, here's another thought: you may want to actually NOT keep them in
scope. Instead, keep them in an unconnected object or something, and use
"scope=" tokens for the grammar of the Cast verb (and any other verbs you want
to allow with spells) to put them in scope for those verbs only. That way you
can be positive that "drop fireball" will never accidently work.
(Although "throw fireball at hellbeast" would be a cool synonym for "cast"...)