Simple code problem

I'm trying to create a function to give a score based purely on which treasures a player is either carrying or has in a case (whether or not the player is holding the case). The code for the function at present is:

x = 0
foreach (o, AllObjects()) {
  if (o.parent = player or o.parent = case) {
    x = x + o.treasure
  }
}
return (x)

I've given each treasure an integer attribute, value 10, but the problem is that if I am carrying an object which is not a treasure there is an error. I presume this is because, if the code refers to an attribute for an object which doesn't have that attribute assigned, it is returned as an empty thing of type object. One method of dealing with this is to assign the treasure attribute as 0 to every carryable object, but is there a more efficient way to do this?


This is probably what you want:

x = 0
foreach (o, AllObjects()) {
  if (o.parent = player or o.parent = case) {
    if GetInt (o, "treasure") {                  // Checks if o has "treasure" integer attribute
      x = x + o.treasure
    }
  }
}
return (x)

I think you meant:

x = 0
foreach (o, AllObjects()) {
  if (o.parent = player or o.parent = case) {
    if (HasInt (o, "treasure")) {
      x = x + o.treasure
    }
  }
}
return (x)

However, it shouldn't be necessary to do this for every object. You can use GetDirectChildren to get the list of objects in the player and in the case. so you'd have:

x = 0
objects = ListCombine (GetDirectChildren (player), GetDirectChildren (case))
foreach (o, objects) {
  if (HasInt (o, "treasure")) {
    x = x + o.treasure
  }
}
return (x)

or to support the player putting other containers inside the inventory or the case:

x = 0
objects = GetAllChildObjects (player)
if (not ListContains (objects, case)) {
  objects = ListCombine (objects, GetAllChildObjects (case))
}
foreach (o, objects) {
  if (HasInt (o, "treasure")) {
    x = x + o.treasure
  }
}
return (x)

(if the player is carrying the case, objects in the case don't need to be checked again)


Thanks, that's very helpful.


if the code refers to an attribute for an object which doesn't have that attribute assigned, it is returned as an empty thing of type object.

Yep; empty attributes have the value null. This means that you can delete an attribute by setting it to null, and also you can do things like this:

objects = FilterByNotAttribute (AllObjects(), "treasure", null)

That filters a list of objects, returning only the ones for which the treasure attribute is not null. It looks a bit weird using FilterByNotAttribute like this, but it's the simplest way to get a list of all objects that have a specific attribute.

(looping over all objects yourself and using HasInt is slightly more efficient; but the difference is so small it's not usually worth thinking about. In this case, I'd use whichever makes your code easier for you to understand)


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

Support

Forums