Can someone tell me how to finish this script? Assigning the script to the local clone is extremely difficult.

if (ListContains(ScopeReachable(), Boar)) {
  if (Got(Bow)) {
    if (Bow.arrows > 0) {
      if (RandomChance(Kill.chance)) {
      }
      else {
        msg ("You missed, and the boar ran away.")
      }
      Bow.arrows = Bow.arrows - 1
    }
    else {
      msg ("You don't have any arrows.")
    }
  }
  else {
    msg ("You need a bow to shoot the boar, it is too fast to kill otherwise.")
  }
}

My issue is removing the this 'boar' clone if the player has missed it, or giving it a 'dead' variable if the player has hit it. The problem with both is referring specifically to the local clone, not the prototype or all clones.

Once the player enters any room, there is a 10% chance of a boar spawning, using this script:

if (RandomChance(10)) {
  CloneObjectAndMove (Boar, player.parent)

I need to tell Quest that when the player types "kill boar", the command is referring to the local clone. How do I do that in the most simplest way? Would "boar.player.parent" even make sense as a means of referring to that clone? If I use ScopeReachable (which i hardly know how to use), how do I get it to scan the list of reachable boars, select the local boar, and assign the command to it?


if (RandomChance(10)) {
  game.stored_clone_object_attribute = CloneObject (Boar)
  game.stored_clone_object_attribute.parent = player.parent // moves the cloned object to the same room as you're in (as we changed the line above to just 'CloneObject', instead of what it was 'CloneObjectAndMove', so we needed to manually do it with this line here
}

the 'game.stored_clone_object_attribute' (you can replace it with whatever Object and your own-named Attribute that you want, this is just a quick example) is storing (a reference/pointer to/of) your local/temporary clone Object, meaning you can use it for whatever/where-ever you want/need to use that local/temporary clone object

like so:

if (ListContains(ScopeReachable(), game.stored_clone_object_attribute)) {
  if (Got(Bow)) {
    if (Bow.arrows > 0) {
      if (RandomChance(Kill.chance)) {
        game.stored_clone_object_attribute.dead = true // setting the (boar) clone to being 'dead'
        msg ("You killed the boar!")
      }
      else {
        msg ("You missed, and the boar ran away.")
        destroy (game.stored_clone_object_attribute.name) // destroying the clone object
      }
      Bow.arrows = Bow.arrows - 1
    }
    else {
      msg ("You don't have any arrows.")
    }
  }
  else {
    msg ("You need a bow to shoot the boar, it is too fast to kill otherwise.")
  }
}

if you want to store multiple cloned objects, then we'd just use an Object List Attribute instead of an Object (reference/pointer) Attribute:

<game name="example">
  <attr name="start" type="script">
    game.stored_clone_objectlist_attribute = NewObjectList ()
  </attr>
</game>

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

if (RandomChance(10)) {
  clone_object_variable = CloneObject (Boar)
  list add (game.stored_clone_objectlist_attribute, clone_object_variable)
  clone_object_variable.parent = player.parent
}

If you set the pattern of the kill command to (regular expression) ^kill (?<object>boar)$ then the command script will have access to a variable object which is in the same room as the player and has an alias starting with "boar". If there is no boar present, the player will get the default "I can't see that" message.


Genius, now let's see if I understand this enough to make it function properly.


Okay so I think it works perfectly, but I have encountered an odd problem arising for a reason i I cannot find. After crafting a bow and arrows, and typing "kill boar", I get "You need a bow to shoot the boar, it is too fast to kill otherwise".

This is my script for crafting a bow so far:

CloneObjectAndMove (Bow, player)
msg ("You have crafted a bow.")

I am even told after crafting a bow, "You have crafted a bow" - as I intended, yet despite apparently having a bow, I cannot kill the boar.


):


oops... you actually got the same problem with the 'bow' as you do/did with the 'boar', see below:

if (Got(Bow)) {

you're checking if you got the original 'Bow' Object within your inventory (contained within your Player Object)

but you're moving the clone of the 'bow' into your inventory

CloneObjectAndMove (Bow, player)

so, you got to have it reference the 'bow' clone:

if (Got(CLONE_OF_THE_BOW)) {

see, if you can figure out how to do the same, that you did with the 'boar clone' and the 'boar', with the 'bow clone' and the 'bow'


Ohhh I see. I was under the impression that it worked before because it printed "You have crafted a bow" - but that was purely print. Clones are pesky, but I can leash them if I try :)


To check if you're carrying a clone of the Bow, you'd want to use:

if (ListCount (FilterByAttribute (ScopeInventory(), "prototype", Bow)) > 0) {

Okay, still not working. This is what I have thus far:

("Kill Boar" command)

if (ListContains(ScopeReachable(), game.stored_clone_object_attribute)) {
  if (Got(game.bow_clone)) {
    if (Bow.arrows > 0) {
      if (RandomChance(Kill.chance)) {
        game.stored_clone_object_attribute.dead = true
        msg ("You killed the boar!")
      }
      else {
        msg ("You missed, and the boar ran away.")
        destroy (game.stored_clone_object_attribute.name)
      }
      Bow.arrows = Bow.arrows - 1
    }
    else {
      msg ("You don't have any arrows.")
    }
  }
  else {
    msg ("You need a bow to shoot the boar, it is too fast to kill otherwise.")
  }
}

("Craft Bow" command)

game.bow_clone = CloneObject (Bow)
CloneObjectAndMove (game.bow_clone, player)
msg ("You have crafted a bow.")

It's worth noting that HK's code only allows you to kill the last boar that was created. If you leave the room that contained it and encounter another boar, you can't go back and kill the previous one later.


(filler for getting my edited post, updated/posted)


you almost got it...

game.bow_clone = CloneObject (Bow)
CloneObjectAndMove (game.bow_clone, player) // <---- this is doing the double cloning (you're cloning the clone), we need to change this problem code line
msg ("You have crafted a bow.")

you're cloning the clone of the bow... you accidentally are doing double cloning..

here's the change/fix:

game.bow_clone = CloneObject (Bow)
game.bow_clone.parent = player // or: MoveObject (game.bow_clone, player)
msg ("You have crafted a bow.")

and to clean up my code a bit further (making sure the clones are destroyed -- I over-looked this issue with my previous post's code):

if (ListContains(ScopeReachable(), game.stored_clone_object_attribute)) {
  if (Got(game.bow_clone)) {
    if (Bow.arrows > 0) {
      if (RandomChance(Kill.chance)) {
        game.stored_clone_object_attribute.dead = true
        msg ("You killed the boar!")
      }
      else {
        msg ("You missed, and the boar ran away.")
      }
      Bow.arrows = Bow.arrows - 1
    }
    else {
      msg ("You don't have any arrows.")
    }
  }
  else {
    msg ("You need a bow to shoot the boar, it is too fast to kill otherwise.")
  }
}
on ready {
  destroy (game.stored_clone_object_attribute.name)
  destroy (game.bow_clone.name)
  game.stored_clone_object_attribute = null
  game.bow_clone = null 
}

mrangel is right that my code only handles the current clone Object, use his method using the built-in stuff for how Commands work, via his use of the 'regex' and of the built-in 'object' Object Variable for the Command handling's internal usage.

you can use my code, but you'd need to use Object List Attributes instead (if you want to handle multiple/previous clones), see my first post... but there's a little extra code work... involved... ask fi you need help with it.. if you're going to use this method of mine... but it's better to just use mrangel's method, as he's using the built-in code, making it easier, as it already does internally what my code does.


Woo! It works just fine and dandy.

As for all this "regex" and Object List Attributes... I say to you, whaaaaat? I'm not certain what you guys mean, or how your suggestions work. Also, what is this code and what does it do?

on ready {
  destroy (game.stored_clone_object_attribute.name)
  destroy (game.bow_clone.name)
  game.stored_clone_object_attribute = null
  game.bow_clone = null 
}

the two 'destroy' code lines destroy/delete your cloned objects, so you don't have a ton of 'boar' and 'bow' clone objects taking up memory: slowing down your game possibly...

the other two code lines, is to just stop the Attributes from still pointing to those cloned objects (which don't exist anymore, due to the two 'destroy' code lines above

it's just some coding safe guards to prevent coding/memory/space/performance issues for you and your game


@HK:

You're destroying the bow and the boar outside the 'if' block; so whether or not they exist.
If the player doesn't have a bow, it will display the message that they don't have a bow, then destroy the boar clone, then generate an error.

You don't need to do this:

  game.stored_clone_object_attribute = null
  game.bow_clone = null 

The C# method ElementFactory.RemoveReferences (which is called from ElementFactory.DestroyElement) already iterates over all attributes of all objects, and removes any that point to a destroyed object.

Also, given that there's a number of arrows, I suspect that a bow isn't intended to be a single use item.

The description of the problem implies that there are multiple boars in different locations. Your code only works if there is only ever one boar clone and one bow clone in the game at a time.


Mrangel you are correct in all of your assumptions about my game, so should I incorporate everything else mentioned to me or am I okay with how my game is now?


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

Support

Forums