Placing Children of Surfaces in Scope During TAKE ALL (How can we do this?)

K.V.

Hello.

I have a table, which is a surface.

There are items on the table, and they are not initially hidden.

Is there something simple I can put in the scope field of the 'take' command to make it check surfaces' children during TAKE ALL?


I previously suggested making a separate "take all" command that could do this. But now I've looked at how "all" is implemented, I'm thinking that it could be done so much better.

Suggested pseudocode for the 'all' case (either in a "take all" command, or modifying CoreParser to allow this for all commands):

scope = GetScope (command, whatever the arguments are)
tried = NewObjectList()
while (ListCount(scope) > 0) {
  do (command, "script", {variable = scope[0]} )
  list add (tried, scope[0])
  scope = ListExclude (GetScope(blah blah), tried)
}

Basically, keep picking an object that's still in scope but hasn't been tried yet, and running the command on it. As long as the scope list contains the surface before its children, it should work. (and that seems to be the case for scope functions that are based around GetAllChildObjects)

This can't be done using the current "multiple" and "multipleobjects" structure; but that seems inelegant, redundant, and inefficient in any case. Which is why I'm suggesting either a dedicated "take all" command, or changing the way CoreParser deals with "all".
(A command could also have a couple of boolean attributes to control whether new objects added to scope are handled. For example, if you type "open all", and a box turns out to contain a smaller box, should the inner box be opened?)


Is there something simple I can put in the scope field of the 'take' command to make it check surfaces' children during TAKE ALL?

I should have responded to this first :p
Not in the "scope" field, because that's ignored by the parser when using "ALL". Instead, we have the multiple script and/or multipleobjects delegate, which do almost the same thing as 'scope' but in a less efficient way, and are only used when the player enters "ALL".


The scope field is not used with ALL; it uses the "multipleobjects" script on the command instead. Just tested it (which has prompted a minor update), but for me it does indeed check surfaces (and open conainers).


I previously suggested making a separate "take all" command that could do this. But now I've looked at how "all" is implemented, I'm thinking that it could be done so much better.

Agreed, but I think for a later release. This would potentially break any game that modified TAKE, etc.


This would potentially break any game that modified TAKE, etc.

I was thinking that if a command has multiple/multipleobjects, they are treated as they are now. If not, object-lookups for "ALL" are deferred until the command is actually run.

That way, modified 'take' commands that include those attributes will continue to work as they do now; while the newer version of the command can omit them and trust the parser to handle 'all' sanely.


K.V.

I previously suggested making a separate "take all" command that could do this

I thought I remember that, but couldn't find it for the life of me.


But now I've looked at how "all" is implemented, I'm thinking that it could be done so much better.

Maybe it's good that I couldn't find it.


Not in the "scope" field, because that's ignored by the parser when using "ALL". Instead, we have the multiple script and/or multipleobjects delegate, which do almost the same thing as 'scope' but in a less efficient way, and are only used when the player enters "ALL".

I just learned something! (Woot, woot!!!)


for me it does indeed check surfaces (and open conainers)

I tried in 5.7 and 5.8. It tries to take the surfaces and the containers in the room, but it doesn't try to take the things on the surfaces or the things in the containers.

Now, I don't think it should try to take the things in containers, but I do think it should try to take the stuff on surfaces.

You are in a room.
You can see a table (on which there is a bowl (containing an orange), a lazy susan and a hat) and a Man Purse.

> take all
table: It's too big to take.
Man Purse: You pick it up.

> x table
An oak dining table.

On it, you see a bowl (containing an orange), a lazy susan and a hat.

> take all
table: It's too big to take.

This would potentially break any game that modified TAKE, etc.

I've already been through this twice. I decided it's my fault for procrastinating. I shouldn't have a work-in-progress that's still in progress through 3 versions of Quest, anyway...

Plus, no one in their right mind would update their creation software until they finished up any incomplete projects, unless they were fully prepared to revise their code accordingly; right?


Plus, no one in their right mind would update their creation software until they finished up any incomplete projects, unless they were fully prepared to revise their code accordingly; right?

I am sure people do just that - and in fairness Quest tells them to update, with no warning.


K.V.

I am sure people do just that - and in fairness Quest tells them to update, with no warning.

That was an attempt at self-deprecating humor.

I am one of those people. ...or I was. I learned after the second time.

...but I would have had no issues at all if I hadn't modified default commands, either.

Well, that's not true. The wearables addition messed me up a little bit, and there were no mods involved that time. But the wearables stuff is super-awesome and definitely needs to be built in, so I don't view this one as a big deal.


But now I've looked at how "all" is implemented, I'm thinking that it could be done so much better.

Maybe it's good that I couldn't find it.

I think the "take all" command is a decent stopgap measure. But a lot of the code in it is general enough that it could be incorporated into the core parser, to work with all commands that don't already have "special" handling of it.

For "take all", off the top of my head I think I had something like:

to_take = GetDirectChildren(game.pov.parent)
found = false
while (ListCount(to_take) > 0) {
  obj = ListItem(to_take, 0)
  list remove (to_take, obj)

  // Skip scenery, NPCs, and objects that have moved out of scope
  // In the case of a magic item that teleports you when you pick it up,
  //    this also stops "all" attempting to take things you can no longer see
  if (ListContains (ScopeVisibleNotHeldNotScenery(), obj) and not (DoesInherit(obj, "npc_type") or obj = game.pov)) {

    // There could also be clauses here so that it skips over things like trees and reflections
    // I think "not_all" is a bit heavy handed in some cases; and it would be nice to have a per-command equivalent
    // Personally, I think when the player types "get all", they mean "get all things that look movable";
    //   which (if you use them) could mean skipping objects that don't have 'take' in their displayverbs
    if (not GetBoolean(obj, "not_all")) {
      found = true
      DoTake (obj, true)
    }

    // If it's got not_all or we failed to take it, try taking things off it
    if (ListContains (ScopeReachableNotHeld(), obj)) {
      to_take = ListCombine (to_take, GetDirectChildren(obj))
    }
  }
}
if (!found) {
  msg ("[NothingToTake]")
}

I tried in 5.7 and 5.8. It tries to take the surfaces and the containers in the room, but it doesn't try to take the things on the surfaces or the things in the containers.

So what happens with this example game for you? For me, I get the ornament, and the ball if the box is open.

<!--Saved by Quest 5.8.6715.16057-->
<asl version="580">
  <include ref="English.aslx" />
  <include ref="Core.aslx" />
  <game name="GET ALL test">
    <gameid>78311507-d42b-45c8-8749-2074ba0e90a1</gameid>
    <version>1.0</version>
    <firstpublished>2018</firstpublished>
  </game>
  <object name="room">
    <inherit name="editor_room" />
    <description>The room is big.</description>
    <object name="player">
      <inherit name="editor_object" />
      <inherit name="editor_player" />
    </object>
    <object name="Joanna">
      <inherit name="editor_object" />
      <inherit name="namedfemale" />
      <inherit name="container_closed" />
      <feature_container />
      <open type="boolean">false</open>
      <contentsprefix>holding</contentsprefix>
      <transparent />
      <look>Joanna is quite pretty.</look>
    </object>
    <object name="Teapot">
      <inherit name="editor_object" />
      <take />
      <look>It is blue.</look>
      <scenery />
    </object>
    <object name="box">
      <inherit name="container_open" />
      <feature_container />
      <look>A box, made of cardboard.</look>
      <take />
      <object name="ball">
        <inherit name="editor_object" />
        <take />
        <object name="nail">
          <inherit name="editor_object" />
        </object>
      </object>
    </object>
    <object name="table">
      <inherit name="editor_object" />
      <inherit name="surface" />
      <feature_container />
      <object name="ornament">
        <inherit name="editor_object" />
        <take />
      </object>
    </object>
  </object>
</asl>

K.V.

In Quest 5.8 beta 4


OFF-TOPIC (sort of)

It's not a good idea to put objects with visible set to false in the player's inventory either. (I can't remember why I did this. It seems like I was toying around with NO TEA and TEA or something.)

<!--Saved by Quest 5.8.6708.15638-->
<asl version="580">
  <include ref="English.aslx" />
  <include ref="Core.aslx" />
  <game name="Drop ALL">
    <gameid>f32db144-c83f-4c75-be3b-1d9559acf615</gameid>
    <version>1.0</version>
    <firstpublished>2018</firstpublished>
  </game>
  <object name="room">
    <inherit name="editor_room" />
    <isroom />
    <object name="player">
      <inherit name="editor_object" />
      <inherit name="editor_player" />
      <object name="thing">
        <inherit name="editor_object" />
        <visible type="boolean">false</visible>
      </object>
    </object>
  </object>
</asl>

image


What if the player was carrying something which wasn't visible AND something flagged as scenery, you ask?

<!--Saved by Quest 5.8.6708.15638-->
<asl version="580">
  <include ref="English.aslx" />
  <include ref="Core.aslx" />
  <game name="Drop ALL">
    <gameid>f32db144-c83f-4c75-be3b-1d9559acf615</gameid>
    <version>1.0</version>
    <firstpublished>2018</firstpublished>
  </game>
  <object name="room">
    <inherit name="editor_room" />
    <isroom />
    <object name="player">
      <inherit name="editor_object" />
      <inherit name="editor_player" />
      <object name="thing">
        <inherit name="editor_object" />
        <visible type="boolean">false</visible>
      </object>
      <object name="thing2">
        <inherit name="editor_object" />
        <scenery />
      </object>
    </object>
  </object>
</asl>

image


NOTE:

I'm calling SHENANIGANS!

There's spam all over the forum this morning, but I had to switch to this account because K.V. has made too many posts! "Whoa, there!!!"

I was just trying to help out as much as I could! Gee whiz!!!


... looks like someone's made an error in drop.multipleobjects.


K.V.

Yep!

I think it all goes back to the same concept: the player will only be carrying visible objects which aren't scenery. Therefore, what's the point in checking for either in the inventory pane or when dropping all?


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

Support

Forums