Daemons and Fuses... no arguments?

It’s fairly simple, I want to call a function with a daemon but you can’t call a function normally, you use a pointer, I can’t find a way to use fuse/daemons with arguments, which is strange to me, am I missing something?

gist of it is, I have one major death method to handle an actor dying, it takes a ‘cause’ argument, so if a certain action needs to trigger a delayed death, (for flavor’s sake, of course) I seem out of luck. Here’s the extremely simplified, not direct code

death(cause)
if(cause == 'plague')
do x
elif(cause == 'stabbing')
do x

Same for an affliction system, this is where the real issue lies, there’s a blood boil spell, a gruesome spell that kills someone over three turns, the only issue is well, I’d like to have a master affliction function that handles the affliction based on an argument.

again, simplified

afflict(affliction)
if(affliction == 'bboil')
stage = 0
Switch statement progressing stage once per turn, with text to describe it

So take an action where we afflict this condition on the NPC while delayed, and the problem becomes clear

action()

new Daemon(self, &afflict, 1)
new Fuse (self, &death, 3)

I simply can’t find a way to pass my arguments. The daemon progresses for three turns, and at the end of the daemon the set fuse goes off, killing the actor, that’s the goal at least. I can just make separate methods for each type if I must, but I’d like to hear other possibilities.

1 Like

You’re right that you can’t call a Fuse or Daemon with an argument to the method it invokes.

One workaround might be to pass the value of the argument through an object property, for example:

    startDeathDaemon(afflict_type)
    {
        affliction = afflict_type;
        new Daemon(self, &afflict, 1);
    }
    
    afflict()
    {
         switch(affliction)
        {
        }
     }

Where affliction is a property of the self object,

An alternative approach, if you need something more complicated or sophisticated, is to define a custom Affliction class with its own afflict() method and whatever properties it needs and then call:

   new Daemon(affliction, &afflict, 1);

Where affliction is whatever object of the Affliction class you want to afflct.

4 Likes

that class approach is perfect for what I want to do, so simple in hindsight, thank you!

1 Like

There was another recent question about the use of Daemons where I suggested the use of my ResettableEvent class. You might find it a useful tool even if you’ve got your current daemon situation under control.
The class takes care of a lot of busy work for you, so the main thing that you do is define an RDaemon somewhere, and write code in its events method. The class keeps a counter for you, so in your code you can just query the ct property, for instance in a switch block. You don’t need to create a separate Fuse, you can just end the game when the daemon reaches the ct that you want.
Vis-á-vis calling the daemon with “arguments”, yes, you’d still do something similar to Eric’s suggestion and probably store that argument in a property. The code would look something like this:

   // can be defined top level or as a nested object
   // somewhere
delayedDeathDmn : RDaemon    
   cause_ = nil
   die(cause) { 
      cause_ = cause;
      start;
   }
   events { 
      switch (cause_) {
          case 'plague':   plagueEvents();  break;
          case 'snakebite': snakebiteEvents();  break;
          case 'poison': poisonEvents();  break;
      }
   }
  plagueEvents() {
      switch (ct) {
          case 2: "(boils are developing)"; break;
          case 4: "(you can barely walk)"; break;
          case 6: [end game with death message]; break;
      }
  }  
  snakebiteEvents() { ... }
;  

With this definition, you only need to call delayedDeathDmn.die('plague') at the appropriate point in your code. The way ResettableEvents work, you can also get an antidote and call delayedDeathDmn.reset before the counter hits death count, and all the underlying cancellations will be taken care of, and the daemon is ready to start from 0 again if you get another exposure to the plague.
Of course, depending on how much you want to do with it, you might just want to skip the “arguments” and make

plagueDmn : RDaemon
...
;
snakebiteDmn: RDaemon
...
;

where then you would simply call plagueDmn.start or snakebiteDmn.start as appropriate, and your definitions can dispense with the cause_, die(), and xxxEvents members, just defining events directly.

2 Likes

That actually looks rather useful, thank you! I’ll give it a try!

1 Like