Removing a clone (based on name) from play

I get why this isn't working but I can't for the life of me figure out how to change it. I suspect the only error is that 4th line?

The scenario:
A grenade is thrown into game.pov.parent and for every grenade in the room a script should run
and then the grenade should disappear from the room. Because... you know.. it exploded.
I've been at this before and received a ton of help from various forum peeps but I never quite managed to get it work. Thought I'd give another try today.
This here (below) seems to work fine except the fact that it won't remove the grenade (and throws an error because of it)
Thoughts, anyone?

foreach (o, GetAllChildObjects(player.parent)) {
  if (StartsWith(o.name, "grenade")) {
    SetTimeout (1) {
      RemoveObject (o)                 //This is not working
      // Script here
    }
  }
}

Error running script: Error compiling expression 'o': Unknown object or variable 'o'


The SetTimeout is probably the culprit.

After 1 second, that script is already done, and the o variable is nonexistent.


Yeah, SetTimeout creates a script attribute which will be called after a second. It doesn't have access to the variables from outside it.

This function might help you:

  <function name="SetTimeoutForObject" parameters="interval, obj, script">
    timername = GetUniqueElementName("timeout")
    if (not timername = "") {
      create timer (timername)
      timer = GetTimer(timername)
      SetTimerInterval(timer, interval)
      if (EndsWith (TypeOf (obj), "dictionary")) {
        timer.params = obj
      }
      else {
        timer.params = QuickParams (TypeOf(obj), obj)
      }
      timer.timeoutscript = script
      SetTimerScript(timer) {
        this.enabled = false
        invoke (this.timeoutscript, this.params)
        destroy (this.name)
      }
      EnableTimer(timer)
    }
  </function>

Then you could make your code:

foreach (o, GetAllChildObjects(player.parent)) {
  if (StartsWith(o.name, "grenade")) {
    SetTimeoutForObject (1, o) {
      RemoveObject (object)
      // Script here
    }
  }
}

(in this case, the second parameter to SetTimeoutForObject can either be an object, in which case you can access it as object within the timeout script, or it can be a dictionary in which case all its values are accessible to the timeout script.

I would also note that if there are a lot of grenades, this may result in slowdown after the game has been played for a long time, because of thousands of exploded grenades floating around in space outside any room.

It might be beneficial to use destroy (object.name) for dealing with clones - this actually destroys the exploded grenade, but you need to be careful to do this after any other code that tries to do anything with the grenade.


Thanks for taking the time MrA!
Looking good. However I get this:

Error running script: Error compiling expression 'QuickParams (TypeOf(obj), obj)': FunctionCallElement: Could find not function 'QuickParams(String; Element)'

QuickParamsis nothing I've ever heard of so I'm completely in the dark here.


Oops, sorry.

QuickParams is a new function added to the core in 5.8

To use it with earlier versions you'd need to add it yourself:

  <function name="QuickParams" parameters="key1, value1, key2, value2, key3, value3" type="dictionary">
    d = NewDictionary()
    dictionary add (d, key1, value1)
    if (IsDefined("key2")) {
      dictionary add (d, key2, value2)
    }
    if (IsDefined("key3")) {
      dictionary add (d, key3, value3)
    }
    return (d)
  </function>

It's just a quick way to create dictionaries.


@MrA

I can't tell you how good it feels to finally have this function set up!
Thank you so very much!

Everything is working super smoothly!


Log in to post a reply.

Support

Forums