I've had this running through my head for a while; mostly just testing it out to see how it works. This could be an alternate implementation for some of the scope functions.
Basically, I've got a function RecursiveScope
which uses a set of objects according to some expressions passed to it.
Its parameters are:
true
, all visible objects will be returned; if it's an objectlist, objects in the objectlist will be returnedtrue
if the root object should be included in the returned listNot sure if this is interesting to anyone else; or if it's more efficient than the way Quest core currently does it (I suspect it could be in some circumstances), but I think it would be interesting because it means you can quickly and easily write a function to find objects that match any arbitrary criteria.
Here's the script, as well as some examples of how it could be used to implement some of the other scope functions.
<function name="ScopeInventory" type="objectlist">
return (ScopeVisibleInventory())
</function>
<function name="ScopeVisibleInventory" type="objectlist">
return (RecursiveScope (game.pov, true, "GetBoolean (this, \"visible\") and (GetBoolean (this, \"isopen\") or GetBoolean (this, \"transparent\"))"))
</function>
<function name="ScopeReachableInventory" type="objectlist">
return (RecursiveScope (game.pov, true, "GetBoolean (this, \"visible\") and GetBoolean (this, \"isopen\")"))
</function>
<function name="ChildrenOfType" parameters="parent, type, direct_children_only" type="objectlist">
return (RecursiveScope (parent, "DoesInherit (this, \"" + type + "\")", not direct_children_only)
</function>
<function name="RecursiveScope" parameters="root, include, recurse, all, exclude" type="objectlist">
if (not IsDefined ("include")) {
include = true
}
if (not IsDefined ("exclude")) {
exclude = null
}
if (not IsDefined ("recurse")) {
recurse = null
}
if (not IsDefined ("all")) {
include = false
}
result = NewObjectList()
if (EndsWith (TypeOf (root), "list")) {
todo = ListCompact (root)
}
else {
todo = NewObjectList()
if (TypeOf (root) = "object" and not Equals (root, null)) {
list add (todo, root)
}
}
skiproot = 0
if (not Equals (all, true)) {
skiproot = ListCount (todo)
}
params = QuickParams ("root", root, "remainder", todo, "results", result, "isroot", true)
while (ListCount (todo) > 0) {
obj = ObjectListItem (todo, 0)
list remove (todo, obj)
dictionary add (params, "this", obj)
if (skiproot = 0 and IsDefined ("exclude")) {
if (TypeOf (exclude) = "list") {
if (ListContains (exclude, obj)) {
skiproot = 1
}
}
else if (TypeOf (exclude) = "string") {
if (eval (exclude, params)) {
skiproot = 1
}
}
}
if (skiproot > 0) {
skiproot = skiproot - 1
if (skiproot = 0) {
list remove (params, "isroot")
list add (params, "isroot", false)
}
}
else {
if (TypeOf (include) = "list") {
if (ListContains (include, obj)) {
list add (result, obj)
}
}
else if (TypeOf (include) = "boolean") {
if (include and GetBoolean (obj, "visible")) {
list add (result, obj)
}
}
else if (TypeOf (include) = "string") {
if (eval (include, params)) {
list add (result, obj)
}
}
else if (TypeOf (include) = "script") {
invoke (include, params)
}
}
if (IsDefined ("recurse")) {
if (TypeOf (recurse) = "list") {
if (ListContains (recurse, obj)) {
foreach (child, GetDirectChildren (obj)) {
list add (todo, child)
}
}
}
else if (TypeOf (recurse) = "boolean") {
if (recurse and GetBoolean (obj, "visible")) {
foreach (child, GetDirectChildren (obj)) {
list add (todo, child)
}
}
}
else if (TypeOf (recurse) = "string") {
if (eval (recurse, params)) {
foreach (child, GetDirectChildren (obj)) {
list add (todo, child)
}
}
}
}
dictionary remove (params, "this")
}
return (result)
</function>