Fuses and Daemons
Description
Fuses and daemons are object-attached events that
are moved in and out of scope (and therefore, starting or stopping them)
with Activate
and Deactivate
routines. They are described here together mainly because most things
done in one can also be done in the other (this author almost always
uses fuses but knows at least one other author who always uses daemons).
Daemons
The simpler of the two is daemons as they are nothing more than events that can be started and stopped.
daemon <name>
{}
event in <name> ! the "in" is optional
{
! Event/daemon code
}
NOTE: In the source code for Kent Tessman’s Spur (available on the IF Archive), in a couple of places, the daemons’ in_scope properties are changed to a location in an attempt to limit them to one room. Assumedly, this code worked properly with the standard Hugo library or compiler back in 1999, but these daemons do not trigger properly with the current standard library or compiler. Luckily, there are plenty of other ways to limit events like that to a single room. Just be aware of this issue when compiling available Hugo code from that era.
Fuses
Fuses are event objects with the addition of timer
and tick
properties.
fuse property | description |
---|---|
timer | the number of turns before the fuse event runs (can be set “by hand” or by Activate(<fuse name>, <timer turns>) |
tick | a routine that decrements timer by one and returns the number of turns remaining (i.e., the value of timer) |
fuse <name>
{}
event in <name> ! the "in" is optional
{
! any code that executes each turn the fuse is running
if not self.tick
{
! code that executes when the fuse runs out
}
}
Vault of Hugo example
The bombfuse
fuse object in “Vault of Hugo” does this:
if not self.tick
{
if Contains(location, bomb) ! if in player's location
{
"\nKABOOM!\n\n\
(Right next to the bomb was not, as they say, such
a great place to be as it went off. You're dead now.)"
endflag = 2 ! when endflag is non-false, it
! immediately triggers the end of the
! game
}
else
{
... ! what happens if the player is NOT in the same room as the bomb
Activating/Deactivating
Both daemons and fuses are started and stopped by Activate
and
Deactivate
, respectively.
Usage |
---|
Activate(<daemon_object>) |
Starting daemons
Usage |
---|
Activate(<daemon_object>,<number_of_turns_in_timer>) |
Starting fuses
Usage |
---|
Deactivate(<daemon_object>) |
Stopping either
The code for everything listed above
For reference, here is the code from hugolib.h that defines all of this:
!\
*****************************************************************************
FUSE AND DAEMON CLASSES AND ROUTINES
*****************************************************************************
\!
#ifclear NO_FUSES
property timer alias n_to ! for fuses only
property tick alias ne_to !
property activate_event alias when_open
property deactivate_event alias when_closed
class fuse
{
type fuse
size 0
timer 0
in_scope 0
tick
{
if --self.timer < 0
self.timer = 0
#ifset DEBUG
if debug_flags & D_FUSES
{
print "[Running fuse "; number self; ": timer = ";
print number self.timer; "]"
}
#endif
if self.timer = 0
Deactivate(self)
return self.timer
}
}
class daemon
{
type daemon
size 0
in_scope 0
}
routine Activate(a, set) ! <set> is for fuses only
{
local err
a.in_scope = player
a is active
if a.type = fuse
{
if set
a.timer = set
run a.activate_event
}
elseif a.type = daemon
{
if set and not a.#timer
{
print "[WARNING: Attempt to set nonexistent timer
property on daemon (object "; number a; ")]"
err = true
}
else
a.timer = set
run a.activate_event
}
else
{
print "[WARNING: Attempt to activate non-fuse/\
daemon (object "; number a; ")]"
err = true
}
#ifset DEBUG
if debug_flags & D_FUSES and not err
{
print "[Activating "; a.name; " "; number a;
if a.type = fuse
print " (timer = "; number a.timer; ")";
print "]"
}
#endif
}
routine Deactivate(a)
{
local err
remove a
a.in_scope = 0
a is not active
if a.type ~= fuse and a.type ~= daemon
{
print "[WARNING: Attempt to deactivate non-fuse/\
daemon (object "; number a; ")]"
err = true
}
else
{
run a.deactivate_event
}
#ifset DEBUG
if debug_flags & D_FUSES and not err
{
print "[Deactivating "; a.name; " "; number a; "]"
}
#endif
}
#endif ! ifclear NO_FUSES
!\