Accumulated removed clones

I've been working on a combat system that makes enemies as it needs, then removes them. But the engine still keeps them. Is there a way to remove these clones from the stored objects so it doesn't end up with Enemy2985553?


Hello.

What code are you using to remove the clones?


DeleteObject (this)


Oh, there is a DeleteObject function, cool. That should be part of the script items menu rather then the remove one.


I don't think there is a DeleteObject, it doesn't appear in my copy of the core libraries.

The usual way to delete objects is:

destroy ("monster25")

Note that like its counterpart create, the parameter here is a string containing the name of the object to destroy. Which means that if you're working with clones, you would most likely be doing:

destroy (this.name)

You also need to be careful with other variables. When you destroy an object, any attributes and variables which point to it become null, and it is removed from any objectlists that contain it. This wouldn't be a problem in most cases; but if you're using parallel lists or similar (generally bad practice, but a lot of people do) this can lead to some very confusing bugs. Also, the foreach statement will cause an error if you modify the list it is looping over. So you can't destroy an object inside a foreach loop whose list initially contains the object.

So some people might write code like this:

foreach (monster, SomeFunctionThatReturnsAListOfMonsters()) {
  ApplyStatusEffects (monster)
  if (monster.hp > 0) {
    TakeMonsterTurn (monster)
  }
  else {
    // if it's been poisoned or something
    destroy (monster.name)
  }
}

That breaks because the 'destroy' modifies the internal list that is being used by the foreach loop, causing it to end immediately. It would also cause an error if the ApplyStatusEffects function destroyed the monster,

To make that work, you'd have to do something like:

monsters_to_destroy = NewStringList()
foreach (monster, SomeFunctionThatReturnsAListOfMonsters()) {
  ApplyStatusEffects (monster)
  if (monster.hp > 0) {
    TakeMonsterTurn (monster)
  }
  else {
    list add (monsters_to_destroy, monster.name)
  }
}
foreach (name, monsters_to_destroy) {
  destroy (name)
}

(which works because in the second loop the list contains the name of the monster, rather than the monster itself)

Hope that all makes sense :)


You were right about DeleteObject, it was destroy, but as of your script examples, I don't know what they are doing. Mine is

<function name="Enemy combat"><![CDATA[
Enemies = Listcount (GetDirectChildren(Arena))
msg ("There are " + Enemies + " enemies to fight.")
Foreach (Enemy, GetDirectChildren(Arena)) {
   msg ("It is " Enemy.name + "'s turn.")
   do (Enemy,  "CombatPref")
}
Enemies = Listcount (GetDirectChildren(Arena))
if (Enemies = 0) {
   msg ("Enemy combat complete.")
   wait {
      PlayerCombat
   }
}
]]></function>

And the do (Enemy, "CombatPref")

<CombatPref type="script"><![CDATA[
   action = GetRandomInt(1,10)
   if (action > 1) {
      msg ("Enemy attacks.")
   }
   else {
      msg ("Enemy flees.")
      destroy (this.name)
   }
]]></CombatPref>

It's not quite a combat system yet... But it functions fine.


This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums