Identify Objects by Common Attribute
MattFinucane
07 Aug 2019, 21:04Hi!
I'd like to have the player searched at one point in my game, and if any objects in the player's inventory have the attribute "forbidden" for there to be consequences.
Ideally in this instance, I'd like to then be able to list all the objects in the player's inventory that meet this condition, a kind of "this is where you fucked up", but that's less important.
Any help in achieving this would be much appreciated!
mrangel
07 Aug 2019, 23:23If the attribute is a boolean one, then you'd want something like:
forbiddenobjects = FilterByAttribute (ScopeInventory(), "forbidden", true)
If the 'forbidden' attribute has different values, but you want to find all objects that have that attribute, then you'd do:
forbiddenobjects = FilterByNotAttribute (ScopeInventory(), "forbidden", null)
(an attribute that doesn't exist is the same as an attribute whose value is null
, so you search for the ones whose value is not null)
Your logic probably ends up looking like:
forbiddenobjects = FilterByNotAttribute (ScopeInventory(), "forbidden", null)
if (ListCount (forbiddenobjects) = 0) {
msg ("Okay, you can pass.")
}
else {
msg ("You aren't allowed to come in here carrying "+FormatList (forbiddenobjects, ",", ", and", "")+"!")
// insert consequences here
}
hegemonkhan
08 Aug 2019, 07:33you can also do this (but the newer 'FilterByAttribute' and 'FilterByNotAttribute' helper Functions do it for you):
game.count = 0
foreach (object_variable, ScopeInventory()) {
if (HasAttribute (object_variable, "forbidden")) {
game.count = game.count + 1
}
}
if (game.count = 0) {
// WHATEVER
} else {
// WHATEVER
}
or
game.count = 0
foreach (object_variable, ScopeInventory()) {
if (GetAttribute (object_variable, "forbidden") = WHATEVER_VALUE) {
game.count = game.count + 1
}
}
if (game.count = 0) {
// WHATEVER
} else {
// WHATEVER
}

MattFinucane
08 Aug 2019, 08:22Thanks both for the quick responses - I don't generally use the code editor view except to check things, but will give this a shot (doesn't look too complicated).
A quick follow-up question - I'd like to improve on the in-built 'if object contains' such that if an object the player contains (i.e. a backpack) contains the requisite item, the function would still work. Basically how can I make that IF go down multiple levels without resorting to an if statement for every conceivable sub-container?
Thanks again!
mrangel
08 Aug 2019, 10:04I'd like to improve on the in-built 'if object contains' such that if an object the player contains (i.e. a backpack) contains the requisite item, the function would still work.
There are a few different ways to check if the player contains an object. The expression in the if statement could be any of the following (I'm testing if the player object game.pov
contains an object called gem
as an example, but the same will work for any objects)
gem.parent = game.pov
- tests if the gem is directly held by a player, not in a containerContainsReachable (game.pov, gem)
- also finds the gem if it is in an open container the player is holdingContainsVisible (game.pov, gem)
- as above, but also finds objects inside transparent containers that the player can see but can't use.Contains (game.pov, gem)
- Finds all objects inside the player, including invisible objects and those inside containers, regardless of whether the player can see or reach them. This is the code that is generated by "if object contains" in the GUI editor.
It's worth noting that ContainsVisible
and ContainsReachable
are both false if the gem is invisible; the other two don't care, they only test the location of the gem.
If you want to get a list of objects in a particular function, you've got a similar set of functions (these each return a list of objects):
GetDirectChildren (game.pov)
- returns all objects directly inside a container, not in subcontainers. In this case, it finds objects the player is carrying. This will include invisible items.ScopeReachableInventory ()
- returns all inventory objects the player can use from their inventory; this is all objects inside the player that aren't invisible, in an invisible container, or inside a closed containerScopeInventory()
- as above, but objects in a closed container will be included if the container is transparent.GetAllChildObjects (game.pov)
- gets a list of all objects inside the player. This only checks the location, and doesn't care if an object is invisible or inside a container.

MattFinucane
08 Aug 2019, 13:12Very helpful, thanks again - will try these both out this evening and report back!

MattFinucane
08 Aug 2019, 22:10Thanks both! Everything you provided worked, especially when I tweaked the first code with GetAllChildObjects, so the sentries would search the player's bags as well.