Removing Cloned Objects

lordpalandus

Hi,

So currently in my combat system, I've found that the only way to "kill" an object is to check when the object has reached 0 or less health and then actually move the object from the current room back to some limbo room, so that I can reuse the object, and then I run a script that resets its health back to full. The issues I have with this is that:

  1. For the combat script, I can handle 99% of the script with just object.name, but when I want to move the object out, I have to name the creature specifically. Thus, I can use object.name to attack an orc, but once the orc's health drops below 0, I have to name the orc as the creature to be moved out of the room.

  2. As I have to name the creature, I've found that I have to create a large, and thoroughly confusing switch statement (object.name) with each creature being a "key", to handle the whole moving it out of the room process. However, this only works in such a way for single target battles, as I can only have 1 orc in the room.

  3. I've tried cloning an object, and most of the script works against it, but when it comes to moving the orc out of the room, it has no effect. As the orc is called orc as the object.name, and the cloned orc is called orc1, and thus any scripts affecting orc doesn't affect orc1.

So... my questions are thus:

  1. Is there a custom expression that I could write up such as : move object.name to limbo (limbo being the place where I store the creatures not in use)? Thus by doing so anytime any creature drops below 0 health, it would be moved out of the room.

  2. Would that above expression work on cloned objects?

  3. If not, is there a custom expression I could write up that could remove cloned objects when they reach 0 or less health?

I've tried looking up the documentation on cloned objects and it is very bare bones... it tells you how to create a clone, but doesn't tell you how to move the clone once it is some place, or remove the clone or have the clone work precisely like the original object, if it is an inventory item.

Any help would be appreciated!


hegemonkhan

the 'name' String Attribute is the ID for quest (so it must be unique, just as my DNA is uniquely mine/me and yours is unique yours), so while your original Object is named 'orc', Cloned Objects have to be given a different name, which is achieved by adding contigious numbers to it (I've yet never worked with clones, so I don't know whether it starts at 0, 1, or 2, and whether there's an underscore used before the number or not), for example (again, I don't know exactly how it names the Clones):

original Object's 'name' (ID) String Attribute: orc
cloned Objects' 'name' (ID) String Attribute: orc_2, orc_3, orc_4, etc

thus, you (as of right now) got no way to identify the Clones vs the original Objects. So, you need a way to do so!

we can have a system for names that we can use as one way to identify them and/or simply have an Attribute for identifying them:

  1. by naming convention/system:

we use the 'String Manipulation' Functions:

http://docs.textadventures.co.uk/quest/functions/ (scroll down to the very bottom, to the 'String Function' last section/category)

http://docs.textadventures.co.uk/quest/functions/string/startswith.html
http://docs.textadventures.co.uk/quest/functions/string/endswith.html

http://docs.textadventures.co.uk/quest/functions/string/lengthof.html

so, for example (using my own naming/labeling convention/system):

original Objects:

orc_1_object, orc_2_object, etc
ogre_1_object, ogre_2_object, etc
troll_1_object, troll_2_object, etc
goblin_1_object, goblin_2_object, etc
gremlin_1_object, gremlin_2_object, etc

Cloned Objects (again, I don't know how they're exactly named by quest's cloning functions):

orc_1_object_2, orc_1_object_3, etc
ogre_1_object_2, ogre_1_object_3, etc
troll_1_object_2, troll_1_object_3, etc
goblin_1_object_2, goblin_1_object_3, etc
gremlin_1_object_2, goblin_1_object_3, etc

example scripting:

(the code doesn't handle if your numbers are more than 1 digit, I just realized this at the end, so I'd have to think some more and re-design the code to handle if the numbers are more than 1 digit)

<function name="example_function" parameters="object_parameter">
  <![CDATA[

    // --------------------------------------

    if (StartsWith (object_parameter.name, "orc")) {
      msg ("This is either one of your original orc Objects or one of any of your cloned orc Objects")
    } else  if (StartsWith (object_parameter.name, "ogre") {
      msg ("This is either one of your original ogre Objects or one of any of your cloned ogre Objects")
    } else  if (StartsWith (object_parameter.name, "troll") {
      msg ("This is either one of your original troll Objects or one of any of your cloned troll Objects")
    } else  if (StartsWith (object_parameter.name, "goblin") {
      msg ("This is either one of your original goblin Objects or one of any of your cloned goblin Objects")
    } else  if (StartsWith (object_parameter.name, "gremlin") {
      msg ("This is either one of your original gremlin Objects or one of any of your cloned gremlin Objects")
    }

    // -----------------------------------------------------------------

    if (StartsWith (object_parameter.name, "orc") and LengthOf (object_parameter.name) > LengthOf ("orc_x_object")) {
      msg ("This is one of any of your cloned orc Objects")
    } else if (StartsWith (object_parameter.name, "orc") and LengthOf (object_parameter.name) > LengthOf ("ogre_x_object")) {
      msg ("This is one of any of your cloned ogre Objects")
    } else  if (StartsWith (object_parameter.name, "troll") and LengthOf (object_parameter.name) > LengthOf ("troll_x_object")) {
      msg ("This is one of any of your cloned troll Objects")
    } else  if (StartsWith (object_parameter.name, "goblin") and LengthOf (object_parameter.name) > LengthOf ("goblin_x_object")) {
      msg ("This is one of any of your cloned goblin Objects")
    } else  if (StartsWith (object_parameter.name, "gremlin") and LengthOf (object_parameter.name) > LengthOf ("gremlin_x_object")) {
      msg ("This is one of any of your cloned gremlin Objects")
    }

    // ----------------------------------------------

    if (StartsWith (object_parameter.name, "orc") and LengthOf (object_parameter.name) = LengthOf ("orc_x_object")) {
      msg ("This is one of your original orc Objects")
    } else if (StartsWith (object_parameter.name, "orc") and LengthOf (object_parameter.name) = LengthOf ("ogre_x_object")) {
      msg ("This is one of your original ogre Objects")
    } else  if (StartsWith (object_parameter.name, "troll") and LengthOf (object_parameter.name) = LengthOf ("troll_x_object")) {
      msg ("This is one of your original troll Objects")
    } else  if (StartsWith (object_parameter.name, "goblin") and LengthOf (object_parameter.name) = LengthOf ("goblin_x_object")) {
      msg ("This is one of your original goblin Objects")
    } else  if (StartsWith (object_parameter.name, "gremlin") and LengthOf (object_parameter.name) = LengthOf ("gremlin_x_object")) {
      msg ("This is one of your original gremlin Objects")
    }

    // ---------------------------------------

    if (StartsWith (object_parameter.name, "orc") and LengthOf (object_parameter.name) = LengthOf ("orc_x_object")) {
      if (Mid (object_parameter.name, 5, 1) = "1") {  // it might be: 4 instead of 5
        msg ("This is your 'orc_1_object' original Object")
      } else if (Mid (object_parameter.name, 5, 1) = "2") {  // it might be: 4 instead of 5
        msg ("This is your 'orc_2_object' original Object")
      }
    } else if (StartsWith (object_parameter.name, "ogre") and LengthOf (object_parameter.name) = LengthOf ("ogre_x_object")) {
      if (Mid (object_parameter.name, 5, 1) = "1") { // it might be: 4 instead of 5
        msg ("This is your 'ogre_1_object' original Object")
      } else if (Mid (object_parameter.name, 5, 1) = "2") {  // it might be: 4 instead of 5
        msg ("This is your 'ogre_2_object' original Object")
      }
    } else  if (StartsWith (object_parameter.name, "troll") and LengthOf (object_parameter.name) = LengthOf ("troll_x_object")) {
      if (Mid (object_parameter.name, 5, 1) = "1") {  // it might be: 4 instead of 5
        msg ("This is your 'troll_1_object' original Object")
      } else if (Mid (object_parameter.name, 5, 1) = "2") {  // it might be: 4 instead of 5
        msg ("This is your 'troll_2_object' original Object")
      }
    } else  if (StartsWith (object_parameter.name, "goblin") and LengthOf (object_parameter.name) = LengthOf ("goblin_x_object")) {
      if (Mid (object_parameter.name, 5, 1) = "1") {  // it might be: 4 instead of 5
        msg ("This is your 'goblin_1_object' original Object")
      } else if (Mid (object_parameter.name, 5, 1) = "2") {  // it might be: 4 instead of 5
        msg ("This is your 'goblin_2_object' original Object")
      }
    } else  if (StartsWith (object_parameter.name, "gremlin") and LengthOf (object_parameter.name) = LengthOf ("gremlin_x_object")) {
      if (Mid (object_parameter.name, 5, 1) = "1") {  // it might be: 4 instead of 5
        msg ("This is your 'gremlin_1_object' original Object")
      } else if (Mid (object_parameter.name, 5, 1) = "2") {  // it might be: 4 instead of 5
        msg ("This is your 'gremlin_2_object' original Object")
      }
    }

    // ----------------------

    if (StartsWith (object_parameter.name, "orc") and LengthOf (object_parameter.name) > LengthOf ("orc_x_object")) {
      if (Mid (object_parameter.name, 5, 1) = "1") {  // it might be: 4 instead of 5
        if (EndsWith (object_parameter.name, "2") {
          msg ("This is your 'orc_1_object_2' cloned Object")
        } else  if (EndsWith (object_parameter.name, "3") {
          msg ("This is your 'orc_1_object_3' cloned Object")
        }
      } else if (Mid (object_parameter.name, 5, 1) = "2") {  // it might be: 4 instead of 5
         if (EndsWith (object_parameter.name, "2") {
          msg ("This is your 'orc_2_object_2' cloned Object")
        } else  if (EndsWith (object_parameter.name, "3") {
          msg ("This is your 'orc_2_object_3' cloned Object")
        }
      }
    ] else if (StartsWith (object_parameter.name, "ogre") and LengthOf (object_parameter.name) > LengthOf ("ogre_x_object")) {
      if (Mid (object_parameter.name, 5, 1) = "1") {  // it might be: 4 instead of 5
        if (EndsWith (object_parameter.name, "2") {
          msg ("This is your 'ogre_1_object_2' cloned Object")
        } else  if (EndsWith (object_parameter.name, "3") {
          msg ("This is your 'ogre_1_object_3' cloned Object")
        }
      } else if (Mid (object_parameter.name, 5, 1) = "2") {  // it might be: 4 instead of 5
         if (EndsWith (object_parameter.name, "2") {
          msg ("This is your 'ogre_2_object_2' cloned Object")
        } else  if (EndsWith (object_parameter.name, "3") {
          msg ("This is your 'ogre_2_object_3' cloned Object")
        }
      }
    ]
    // etc etc etc (troll, goblin, gremlin)

    // ------------------------------

  ]]>
</function
  1. using Attributes:

(Inherited Attributes / Object Types / Types / quest's user-level classes/groups/templates)

(not sure if you can access the nested 'monster_type', but if can't, the code can be easily fixed up)

<function name="example_function" parameters="object_parameter">
  if (DoesInherit (object_parameter, "monster_type") {
    if (DoesInherit (object_parameter, "orc_type") {
      msg ("This is either one of your original orc objects or one of your cloned orc objects")
    } else if (DoesInherit (object_parameter, "ogre_type") {
      msg ("This is either one of your original ogre objects or one of your cloned ogre objects")
    }
    // ect etc etc (troll, goblin, gremlin)
  }
</function>

<object name="orc_1_object">
  <inherit name="orc_type" />
</object>

<object name="orc_2_object">
  <inherit name="orc_type" />
</object>

<object name="ogre_1_object">
  <inherit name="ogre_type" />
</object>

<object name="ogre_2_object">
  <inherit name="ogre_type" />
</object>

<object name="troll_1_object">
  <inherit name="troll_type" />
</object>

<object name="troll_2_object">
  <inherit name="troll_type" />
</object>

<object name="goblin_1_object">
  <inherit name="goblin_type" />
</object>

<object name="goblin_2_object">
  <inherit name="goblin_type" />
</object>

<object name="gremlin_1_object">
  <inherit name="gremlin_type" />
</object>

<object name="gremlin_2_object">
  <inherit name="gremlin_type" />
</object>

<type name="orc_type">
  <inherit name="monster_type" />
</type>

<type name="ogre_type">
  <inherit name="monster_type" />
</type>

<type name="troll_type">
  <inherit name="monster_type" />
</type>

<type name="goblin_type">
  <inherit name="monster_type" />
</type>

<type name="gremlin_type">
  <inherit name="monster_type" />
</type>

<type name="monster_type">
</type>

or using normal Attributes (String Attribute for this example):

(keeping the Object Types just for this example, but we're using their String Attributes, so it doesn't matter)

<function name="example_function" parameters="object_parameter">
  if (GetString (object_parameter, "type_of_object") = "monster") {
    if (GetString (object_parameter, "type_of_monster") = "orc") {
      msg ("This is either one of your original orc objects or one of your cloned orc objects")
    } else if (GetString (object_parameter, "type_of_monster") = "ogre") {
      msg ("This is either one of your original ogre objects or one of your cloned ogre objects")
    }
    // ect etc etc (troll, goblin, gremlin)
  }
</function>

<object name="orc_1_object">
  <inherit name="orc_type" />
</object>

<object name="orc_2_object">
  <inherit name="orc_type" />
</object>

<object name="ogre_1_object">
  <inherit name="ogre_type" />
</object>

<object name="ogre_2_object">
  <inherit name="ogre_type" />
</object>

<object name="troll_1_object">
  <inherit name="troll_type" />
</object>

<object name="troll_2_object">
  <inherit name="troll_type" />
</object>

<object name="goblin_1_object">
  <inherit name="goblin_type" />
</object>

<object name="goblin_2_object">
  <inherit name="goblin_type" />
</object>

<object name="gremlin_1_object">
  <inherit name="gremlin_type" />
</object>

<object name="gremlin_2_object">
  <inherit name="gremlin_type" />
</object>

<type name="orc_type">
  <inherit name="monster_type" />
  <attr name="type_of_monster" type="string">orc</attr>
</type>

<type name="ogre_type">
  <inherit name="monster_type" />
  <attr name="type_of_monster" type="string">ogre</attr>
</type>

<type name="troll_type">
  <inherit name="monster_type" />
  <attr name="type_of_monster" type="string">troll</attr>
</type>

<type name="goblin_type">
  <inherit name="monster_type" />
  <attr name="type_of_monster" type="string">goblin</attr>
</type>

<type name="gremlin_type">
  <inherit name="monster_type" />
  <attr name="type_of_monster" type="string">gremlin</attr>
</type>

<type name="monster_type">
  <attr name="type_of_object" type="string">monster</attr>
</type>

lastly, there's also iteration and List/Dictionary Attributes, for handling many Objects/items

for example (using the example above with the normal Attributes: the String Attributes example):

(using the lazy 'AllObjects()' Function, but you can use whatever generating/using Objectlist Attribute Function, you want)

(this example design causes us to fight ALL monsters of the provided type of monster objectlist to the 'fight_function', not very practical, but it's jsut an example. As instead of using the created types of monster objectlists - which is obviously very impractical, we can use the 'GetDirectChildren()' Function to just get the monsters of that specific room you're in, to fight. If you need help with how to adjust/design the code for this, let me know. Though the concepts of the impractical part of this example, are very useful for application of much more practical stuff for a game)

<game name="example_game">
  <attr name="start" type="script">
    monster_object_creation_and_population_function
  </attr>
</game>

<function name="monster_object_creation_and_population_function">
  game.monster_objectlist_attribute = NewObjectList ()
  game.orc_objectlist_attribute = NewObjectList ()
  game.ogre_objectlist_attribute = NewObjectList ()
  game.troll_objectlist_attribute = NewObjectList ()
  game.goblin_objectlist_attribute = NewObjectList ()
  game.gremlin_objectlist_attribute = NewObjectList ()
  foreach (object_variable, AllObjects ()) {
    if (GetString (object_variable, "type_of_object") = "monster") {
      list add (game.monster_objectlist_attribute, object_variable)
      if (GetString (object_variable, "type_of_monster") = "orc") {
        list add (game.orc_objectlist_attribute, object_variable)
      } else if (GetString (object_variable, "type_of_monster") = "ogre") {
        list add (game.ogre_objectlist_attribute, object_variable)
      } else if (GetString (object_variable, "type_of_monster") = "troll") {
        list add (game.troll_objectlist_attribute, object_variable)
      } else if (GetString (object_variable, "type_of_monster") = "goblin") {
        list add (game.goblin_objectlist_attribute, object_variable)
      } else if (GetString (object_variable, "type_of_monster") = "gremlin") {
        list add (game.gremlin_objectlist_attribute, object_variable)
      }
    }
  }
</function>

<function name="fight_function" parameters="enemy_objectlist_parameter">
  <![CDATA[
    enemy_objectlist_variable = NewObjectList ()
    foreach (object_variable, enemy_objectlist_parameter) {
      list add (enemy_objectlist_variable, object_variable)
    }
    while (ListCount (enemy_objectlist_variable) > 0) {
      foreach (enemy_object_variable, enemy_objectlist_variable) {
        if (not enemy_object_variable.condition_string_attribute ="dead") {
          enemy_object_variable.current_life_integer_attribute = enemy_object_variable.current_life_integer_attribute - player.damage_integer_attribute
          if (enemy_object_variable.current_life_integer_attribute < 1) {
            enemy_object_variable.condition_string_attribute = "dead")
            list remove (enemy_objectlist_variable, enemy_object_variable)
          } else {
            player.current_life_integer_attribute = player.current_life_integer_attribute - enemy_object_variable.damage_integer_attribute
            if (player.current_life_integer_attribute < 1) {
              msg ("You were killed")
              msg ("GAME OVER")
              finish
            }
          }
        } else {
          list remove (enemy_objectlist_variable, enemy_object_variable)
        }
      }
    }
  ]]>
</function>

The Pixie

I have a tutorial here that goes through this sort of thing (it creates monsters rather than cloning, but it has the same issue.
https://github.com/ThePix/quest/wiki/The-Zombie-Apocalypse-(on-the-web-version)

If you look down at the attacking part, by doing a command as:

attack #object#

This gives you an object variable to play around with. You can reduce its hits, move it away, whatever. You do not need to know its name in the code at all.

That might be enough to get you going, but if not, paste the attack code into a post, and we can look deeper.


lordpalandus

Unfortunately, neither of these help me.

I'm not using JavaScript code at all. I'm simply using the built-in features and expression boxes. I cannot use any of the suggestions as I do not understand the coding part and just using the visual scripting that comes with the editor.

So, it looks like I'll have to find a solution elsewhere. Thanks for taking some time and trying to help.


hegemonkhan

via the GUI/Editor:


Functions:

creation:

(left side's tree of stuff) Functions -> Add -> (set it up / define it)

using it (your own custom Functions or the built-in Functions):

run as script -> add new script -> 'scripts' section/category -> 'call function' Script -> Name box: NAME_OF_FUNCTION, (if you have/use Parameters) Add Parameters box: input your Arguments (inputs) for your Parameters (Function's VARIABLES)


Object Types:

creation:

(left side's tree of stuff) Advanced -> Object Types -> Add -> (set it up / define it: think of Object Types as a basket of Attributes, so instead of individually adding each Attribute to Objects, you can give a basket of many Attributes to Objects via using Object Types/Inherited Attributes) Name: WHATEVER

(left side's tree of stuff) Advanced -> Object Types -> 'WHATEVER' Object Type -> 'Attributes' Box and/or 'Inherited types' box (layers of Object Types: nested Object Types) -> Add -> (set up your normal Attributes and/or Inherited Attributes/Types)

using it (adding it to an Object):

(left side's tree of stuff) 'WHATEVER' Object -> 'Attributes' Tab -> 'Inherited Attributes' box (NOT the 'Attributes' box and NOT the 'statusattributes' box) -> Add -> Name: NAME_OF_OBJECT_TYPE


Scripting:

the '[EXPRESSION]' Script option lets you code in stuff (which has a slightly different syntax than to code in stuff directly, as it depends on what the GUI/Editor handles for you code wise vs having to do it yourself in code).

so, for example:

run as script -> add new script -> 'scripts' section/category -> 'if' Script -> if [EXPRESSION] WRITE/TYPE/CODE_IN_YOUR_EXPRESSION(ACTION)


jmnevil54

Hi. I tried to reply earlier, but the computer wasn't working.
I actually added this onto The Pixie's code.
msg ("You stomp on it, safe at last!")
RemoveObject (this)
}
I'm not sure what the this does, but nonetheless, you set the code up like this:
obj.changedhitpoints => {
if (this.hitpoints < 1) {
msg ("It is dead!")
this.dead = true
player.exp = player.exp + 20
love
player.gold = player.gold + 20
msg ("You stomp on it, safe at last!")
RemoveObject (this)
}
}
And I suppose you need to find the name for the cloned object. Try copy-pasting my code in first. I just have a feeling.
(P.S. The forums did something to the brackets, which you will need to fix.)


hegemonkhan

'this' is a special keycommand that GETS the parent Object that is the container of the scripting that 'this' is within (there's some places that it can't be used, but otherwise it's very useful when you got to handle dynamic/many-different Objects), for example:

<object name="hat">
  <attr name="wear" type="script">
    this.parent = player // the parent Object of the 'wear' Script Attribute is the 'hat' Object, so 'this' GETS the 'hat' Object (reference)
  </attr>
</object>

----------------

what makes 'this' useful is this (sorry, pun not intended), an example:

instead of having to do this (argh, 'this' is such a common word, going to be lots of un-intended puns, lol):

<object name="hat">
  <attr name="wear" type="script">
    hat.parent = player
  </attr>
</object>

<object name="shirt">
  <attr name="wear" type="script">
    shirt.parent = player
  </attr>
</object>

<object name="pants">
  <attr name="wear" type="script">
    pants.parent = player
  </attr>
</object>

etc etc etc (pretend we have a lot of Objects)

YUCK! while I can copy and paste the line, I still have to delete the Object name and re-type in the correct/new Object name for every Object

we can instead do this (a bit better):

<object name="hat">
  <attr name="wear" type="script">
    this.parent = player
  </attr>
</object>

<object name="shirt">
  <attr name="wear" type="script">
    this.parent = player
  </attr>
</object>

<object name="pants">
  <attr name="wear" type="script">
    this.parent = player
  </attr>
</object>

This is a bit better, now I can just copy and paste the line for each Object, I don't have to re-type the new Object name each time, as we're not using it, we're using 'this' instead.

we can further do better (less work/typing/coding on our part hehe --- so much better!):

(using Object Types, to demonstrate the usefulness of 'this' keycommand)

<object name="hat">
  <inherit name="wearable_type">
</object>

<object name="shirt">
  <inherit name="wearable_type">
</object>

<object name="pants">
  <inherit name="wearable_type">
</object>

<type name="wearable_type">
  <attr name="wear" type="script">
    this.parent = player
  </attr>
</type>

and if you really want to wipe out a huge chunk of work on your part, use scripting and let the computer do all the work for you!
(however, this is slow, as you have to wait for the scripting/computer to create the code for you to have it in your game, every time you play the game)
(whereas if you put in the code, it doesn't have to take the time to create the code every time you play the game)

see this link about this issue:

ht.tp://stackoverflow.com/questions/846103/runtime-vs-compile-time

Log in to post a reply.

Support

Forums