Does Quest ever try to implicitly (or silently) take something?

I'm wondering if there are any commands which require an object to be held where Quest will try to take the object automatically before continuing the action.

I can't find any code that looks like it does this, and I can't recall it ever happening. Just checking.

I think Quest always tells you "You're not holding that." I don't think it ever tries to pick anything up for you.


I don't think that happens,. There are some codes you can create where within another action an object is added to your inventory without picking it up. Other than that I doubt quest will auto add something to your inventory.


Hello.

I doubt quest will auto add something to your inventory.

You are correct.

...but sometimes (in old, awesome text adventures; as well as in games created with Inform, which does its best to behave just like those old, awesome text adventures) things are implicitly taken because they must be held to perform an action.

The only instance I've found in Quest is when you are holding a container (or surface) and the object is in (or on) said container (or surface).

...but Quest just considers that "holding" the object (which I can't argue against). Plus, Quest doesn't try to take it first; so, that also (sort of, technically) excludes the action.


A Z-machine game will try to implicitly take things you need to be holding before attempting to carry out the command.

For instance, SHOW STEAK TO DRAGON

You need to be holding something to show it to someone in a Z-machine game (for some reason), you see, and in Quest. . .

Wait. Bad example. Quest's show command just confused me.

Quest:

> show steak to dragon
I can't see that. (steak to dragon)

Inform 7:

>show steak to dragon
(first taking the steak)
The dragon is unimpressed.

Restarting. . .


PUT STEAK IN PIT

In this scenario, there is a steak in the room, and there is also a pit (which is an open container).

You are not holding the steak.

By default, if using Inform to author the game, this will happen:

Dragon's Lair
You can see a dragon, a steak and a Pit of Nowhere (empty) here.

>put steak in pit
(first taking the steak)
You put the steak into the Pit of Nowhere.


In Quest:

You are in a Dragon's Lair.
You can see a dragon, a steak and a Pit of Nowhere.

> put steak in pit
You are not carrying it.

Let's do that again, but this time the player is holding a plate and the steak is on the plate.

Inform 7:

Dragon's Lair
You can see a dragon and a Pit of Nowhere (empty) here.

>i
You are carrying:
  a plate
    a steak

>put steak in pit
(first taking the steak)
You put the steak into the Pit of Nowhere.

>

Quest

You are in a Dragon's Lair.
You can see a dragon and a Pit of Nowhere.

> i
You are carrying a plate (on which there is a steak).

> put steak in pit
Done.

One more time, except this time the steak's take response is set to say "It's too hot to handle!" rather than allowing it to be taken. (This might not make sense to you, having not played the game up until this scene, but, well, I'll tell you: the steak was cooked to perfection just before this scene. Therefore, it is too hot to handle.)

Inform 7

Dragon's Lair
You can see a dragon and a Pit of Nowhere (empty) here.

>i
You are carrying:
  a plate
    a steak

>put steak in pit
(first taking the steak)
It's too hot to handle!

>

Quest

You are in a Dragon's Lair.
You can see a dragon and a Pit of Nowhere.

> put steak in pit
Done.

But what happens if you try to take the steak yourself first, you ask?

Inform 7:

Dragon's Lair
You can see a dragon and a Pit of Nowhere (empty) here.

>i
You are carrying:
  a plate
    a steak

>take steak
It's too hot to handle!

>put steak in pit
(first taking the steak)
It's too hot to handle!

>

Quest:

You are in a Dragon's Lair.
You can see a dragon and a Pit of Nowhere.

> i
You are carrying a plate (on which there is a steak).

> take steak
It's too hot to handle!

> put steak in pit
Done.

So, I guess Quest sort of does implicitly take that steak, but Quest is not aware that it is doing it.


What if we try to drop the steak?

Inform 7:

Dragon's Lair
You can see a dragon and a Pit of Nowhere (empty) here.

>i
You are carrying:
  a plate
    a steak

>drop steak
You haven't got that.

Quest

You are in a Dragon's Lair.
You can see a dragon and a Pit of Nowhere.

> i
You are carrying a plate (on which there is a steak).

> drop steak
You drop it.

I think Inform handles it better up until that last command, and I don't think Quest or Inform handle dropping the steak which is on the plate the player is holding correctly.

Inform just sees that it isn't directly held and says you don't have it.

Quest doesn't try to take it from the container/surface before trying to drop it. (I'm assuming Quest is not turning the plate upside down to drop it. If so, how does Quest know it isn't a slice of Ooey-Gooey Caramel Pie (which is pretty much stuck to the plate)?)


Anyway, I was only asking because I am porting an old game to Quest, and the old game has an object attribute which is checked whenever trying to implicitly take something. I couldn't think of a time Quest ever "tried taking something first", but I thought it wise to check before deciding the attribute would never be used in Quest.

I'd honestly forgotten about this until your post, but now I realize there are bugs in my port. dum-Dum-DUM!!!

Quick, somebody call the Verminator!

On second thought, just call Kelly Bundy!

Wait. . .

You know what? If someone could just call Christina Applegate for me, that would be great; mm-kay? Tell her I am her age, and I've always admired her for her mind and her looks.


Sorry; I get totally distracted whenever I think about Christina Applegate. . .

I do very much appreciate your response, Bumper2016!

Your answer is correct. I'm just a crazy guy doing crazy things, and I completely failed to explain what I meant in my initial post, if you can dig that. :)


Hmm…

(edited; silly mistake)

  <function name="AddToResolvedNames" parameters="var, result">
    scope = Split (GetScoping(game.pov.currentcommandpattern.scope, variable))
    success = false
    if (TypeOf(result) = "object") {
      if (result.type = "object") {
        if (ListContains (scope, "inventory") and not Contains (game.pov, result)) {
          msg ("(first taking the {object:" + result.name + "})")
          DoTake (result, false)
          success = Contains (game.pov, result)
        }
        else {
          success = true
        }
        list add (game.pov.currentcommandresolvedobjects, result)
      }
    }
    else if (TypeOf(result) = "objectlist") {
      if (ListContains (scope, "inventory")) {
        needs_to_take = NewObjectList()
        foreach (obj, result) {
          if (not Contains (game.pov, obj)) {
            list add (needs_to_take, obj)
          }
          else {
            success = true
          }
        }
        if (ListCount (needs_to_take) > 0) {
          msg ("(First taking the " + FormatList (needs_to_take, ", ", " and ", "") + ")")
          multiple = ListCount (needs_to_take) > 1
          location = game.pov.parent
          foreach (obj, needs_to_take) {
            DoTake (obj, multiple)
            if (Contains (game.pov, obj)) {
              success = true
            }
            else {
              list remove (result, obj)
            }
          }
          if (not location = game.pov.parent) {
            // If taking an object made us teleport, cancel the command
            // Is there a way to check for game over too?
            success = false
          }
        }
      }
      else {
        success = true
      }
      foreach (obj, result) {
        if (obj.type = "object") {
          list add (game.pov.currentcommandresolvedobjects, obj)
        }
      }
    }
    dictionary add(game.pov.currentcommandresolvedelements, var, result)

    // If we tried and failed to automatically pick up objects, abort the command
    // So that we don't get both "It's too heavy" and "I'm not holding it" errors
    //    (if the player specified a list of objects, we carry on with any that actually succeeded)
    if (success) {
      ResolveNextName
    }
    else {
      FinishTurn
      HandleNextCommandQueueItem()
    }
  </function>

Hehehe.

At first, I thought you were just copying and pasting the existing code. I was like, 'word?!?' Ha ha!

I never would have thought about modifying AddToResolvedNames to handle this. I was too busy wondering how many functions would be involved, when I should have been wondering which function they all use.


It was more complicated than I expected, because of the multiple commands. But I think this is probably the best place to handle it; after all the names have been parsed, but before the command is run.

It will come up with some oddness if picking up an object triggers a game over; but otherwise I think it's fairly good.


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

Support

Forums