Thursday, March 21, 2013

fairly fuse-ful

One of my dissatisfactions with the current state of Roodylib is that things like redrawing the screen after a screen size change or after leaving a menu does not include relevant event code if something happens to be going on. Luckily, this doesn't come up very often, and it's probably pretty easy to shrug off but it still annoys me.

You could just call runevents again, but since most fuses and daemons are timer-based, many would progress an extra turn where you do not want them to. When I used to think about how I could conceivably fix this, I thought about a complicated write-event-messages-to-string-arrays system that'd print messages again. Today, it occurred to me to change the fuse code to redefine how they work. In my new code, the timer now is a calculation between the game counter and fuse length.

While not necessary for the code to work, I added a new property to fuse objects so existing fuse code out there will still work with the new stuff. Since daemon code (I mean that in the non-fuse sense) usage is so open-ended, I took a gamble and coded it to assume the opposite-of-fuse, a timer that increases with every turn instead of decreases.

Of course, depending on what your fuse/daemon code does, you'd still have to code them strategically so they can be smartly run several times per turn.

This is another thing where I'm not sure how quickly I'll add it to RoodyLib, as it may make some assumptions that might not be good for all games.

Anyhow, the code:

property fuse_length alias e_to

replace fuse
{
    type fuse
    size 0
    timer
    {
        if self.fuse_length
            return (self.fuse_length - counter)
        else
            return 0
    }
    fuse_length 0
    in_scope 0
    tick
    {
            if self.timer <= 0
                self.fuse_length = 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
    }
}

property timer_start alias fuse_length

replace daemon  ! replaced just the daemon is near the fuse in the object tree
{
    type daemon
    size 0
    in_scope 0
    timer
    {
        if self.timer_start
        {
            return (counter - self.timer_start)
        }
        else
            return 0
    }
}


!\
Activate - added a warning for when it is called before the player global has been set.
\!
replace Activate(a, set)                ! <set> is for fuses only
{
    local err
    if not player
        {
        Font(BOLD_ON)
        print "[WARNING:  The player global must be set before
        daemon (object "; number a;") can be activated.]"
        err = true
        }
    a.in_scope = player
    a is active
    if a.type = fuse and not err
    {
        if set
            a.fuse_length = (counter + set)

        run a.activate_event
    }
    elseif a.type = daemon and not err
    {
        if set and not a.#timer_start
        {
            Font(BOLD_ON)
            print "[WARNING:  Attempt to set nonexistent timer
                property on daemon (object "; number a; ")]"
            err = true
        }
        else
            a.timer_start = (counter - set)

        run a.activate_event
    }
    elseif not err
    {
        Font(BOLD_ON)
        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
    if err
        {
        Font(BOLD_OFF)
        "\npress a key to continue..."
        HiddenPause
        }
    return (not err)
}

replace 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

    return (not err)
}
#endif ! ifclear NO_FUSES

No comments:

Post a Comment