Asking NPC for something

When the player asks a particular NPC something, I want it to say something about the object that has been asked for.

So the code I’ve got at the moment (that isn’t working) is:

Instead of asking John for [anything]: say "John gives you [the noun]"

When the player enters ‘Ask John for a hat’ it says “You can’t see any such thing.”
But when the player enters ‘Ask John for’ it says John gives you John

Does anyone know of a way I can refer to the thing that has just been asked for?

Thanks in advance

Sounds like the object asked for isn’t in scope. Where is this hat in question? Is it in the room with you & John?

Also, don’t you want “second noun” there? I think John is the noun and the hat is the second noun.

Also, that use of the bracketed token [anything] is incorrect. You need to use “anything” (or “something”) w/o brackets:

Instead of asking John for something: say "John gives you [the second noun]."

–Erik

The bracketed [anything] happens to work in that example, because it’s a comment and the compiler ignores it!

Instead of asking John for:
   say "John gives you [the second noun]."

Just as “taking” is a valid shorthand for “taking anything”, “asking John for” is shorthand for “asking John for anything”.

Unless I missed something, the larger problem with this code is that, since it’s an Instead rule, John doesn’t actually give you the hat–it just says that he does.

If you want the object to actually be given, a Before rule might work better.

Well I was really trying to understand it more generally, so for example if John is a genie, he gives the player whatever is asked for (although the question of what to do if the player wants to do something with it is something else altogether). Another use would be if the player asks for something (for example, a banana) and have the response "John says ‘A banana? I don’t have one of those, but I can give you one of these…’. But I suppose it’s probably a better idea just to get it working in the current context I’m working with for now - which is that John has multiple hats, and will give the player one if they ask for it. I have

John carries 4 hats

And my code for asking John for anything executes when the player types “Ask John for 4 quarters”, but not when typing “Ask John for a quarter” or anything else.

Ah, makes sense, thanks! Doesn’t fix the problem at hand, but I’m sure it will prevent another one.

Ah, good to know!

I was going to try to implement the actual giving after I’d overcome this current issue, but one thing is that when the code is executed (eg if the player asks specifically for something I’ve said John has) if I put this stuff in a before rule it goes through the rule and still has the stock response (“John has better things to do”)

Thanks for all the help, guys.

I think I may be struggling with the idea of plurality - is there an easy way to say that 4 hats exist, John has the 4 hats, and when asked for one he gives it to the player?

Do you have:

A hat is a kind of thing

? Because if you just have “John has 4 hats” without declaring a hat as a kind of thing, I7 will create a single object called “4 hats.” (For some reason this reminds me of the following video: "Four candles by the Two Ronnies.) And then it’ll understand “4” and “hats” as referring to that object, but not “hat” – it doesn’t know that “hat” is the singular of “hats.”

It sounds like what you want is something like this:

[code]“Four Candles”

Lamp is a room.
A hat is a kind of thing. John is a man in Lamp. John carries four hats.
Instead of asking John for a hat:
if John carries a hat:
move a random hat that is carried by John to the player;
say “John gives you a hat.”;
otherwise:
say “John is out of hats.”[/code]

The player can’t ask John for more than one hat at a time this way – and you may not want to let em do so. You probably also want to make the hat wearable, and give it a description. Or if you want to be able to ask John for anything he has, you can do this:

[code]Lamp is a room.
A hat is a kind of thing. John is a man in Lamp. John carries four hats. John carries
Instead of asking John for something:
if John carries the second noun:
move the second noun to the player;
say “John gives you [the second noun].”;
otherwise:
say “John don’t have that.”

Does the player mean asking John for something that is carried by John:
it is likely.[/code]

which works in this case, at least, though again it doesn’t allow you to ask for multiple hats (the default parser error is at least helpful here). You need that last line so it doesn’t think you’re asking John for the hat you already have.

You’d also need to accommodate “JOHN, GIVE ME A HAT” and like that, but you probably want to “ASK JOHN FOR A HAT” working first. Also, the people who know more than me (that’s everyone else) might point out some other problems that could crop up.

[EDIT: One issue is, if the thing you ask John for isn’t in the room at all, you’ll get “You can’t see any such thing” instead of “John don’t have that.” It might require some mild I6 trickery to get a special rule for asking John for something that isn’t in the room – zarf, I think you showed me how to do that once?]

You don’t need to implement the details of the giving action again; you can take advantage of the implementation that’s built in.

Looking at the Actions Index, we see that the “asking for” action is treated like the order “NPC, give me X”. Normally, the NPCs don’t obey the player character’s orders, so we have to tell Inform that John can be “persuaded” to give the player what he wants. So one way to do it would be like this:

[code]The Foyer is a room.

John is a man in the Foyer. John carries a hat. John carries a cane.

Persuasion rule for asking John to try doing something:
Persuasion succeeds.
[/code]
Unfortunately, this is not quite enough yet. When we ask him for the hat, the game will now say “John is unable to do that” instead of “John has better things to do”. To find out why, we enter “actions” while testing the game in the IDE, and ask John for the hat again. The output tells us that the action “failed the block giving rule”. So we look again at the Actions Index under “giving it to” and find that this is usually blocked by the Standard Rules. By clicking the button labeled “unlist” next to the “block giving rule”, we insert a line into the source code that removes that rule (“The block giving rule is not listed in the check giving it to rulebook.”). Now it works.

Ah, once I’d abandoned my attempt to do something beyond what I actually need it to do, this was what was holding me back from success! Thanks very much.

I’m very grateful for all the help. This community probably has the highest helpfulness to size ratio I’ve encountered online. I will attempt to add to this! My biological and technological distinctiveness will be added to your own*

[size=50]*Just to avoid seeming creepy - this is a Star Trek joke[/size]

Hmm, this is causing continuing issues. I’m now trying to show someone the hats - they will only respond in a certain way if the player shows them four or more hats… but “show” won’t let the player show multiple items. Is there any way around this without unpicking the ‘show’ rule entirely? I’ve tried insteads and befores, neither of which work

EDIT: Something that I doubt will solve my current plight but has come up is the idea of defining a rule as applying to an unspecified number of objects (eg So and so is an action applying to some carried things). Is this possible at all?

And this whole showing thing is getting really annoying. I’ve been working on it for over an hour! I must be missing something really obvious…

EDIT: After 2 hours (shameful, shameful!) I have made some progress. Through the use of

Understand "show [things] to [someone]" as showing it to. I can show multiple hats. Still having some issues with the details of what happens next, but I’m sure I can sort them out…

You tell Inform that a command takes multiple items like this:

Understand "show [things preferably held] to [someone]" as showing it to. Understand "show [someone] [things preferably held]" as showing it to (with nouns reversed).

It’s the grammar token “[things]” instead of “[something]” that does that trick. The “[preferably held]” part is so that Inform shall interpret e.g. SHOW ALL TO JOHN as showing John everything you carry rather than everything in the location whether you carry it or not.
(And, obviously, that second line is to make sure Inform understands SHOW JOHN THE HAT AND THE MAT as well as SHOW THE HAT AND THE MAT TO JOHN, even though “JOHN” and “HAT AND MAT” are mentioned in a different order in the different cases.)

Haha, as you posted this I was editing my post to say that I had done almost this. I had missed out the ‘preferably held’ though. Thanks!

Slow but steady progress…

Not that slow, I think …

I’ve got it doing what I want it to do… except now, if I show someone 4 hats (for example), it says ‘hat:’ once for each one

So I have…

[code]Understand “show [things preferably held] to [someone]” as showing it to.
Understand “show [someone] [things preferably held]” as showing it to (with nouns reversed).

Numma is a number that varies.

Every turn:
If numma is 4:
let Respondy be “Wow, 4 hats! Woo hoo etc”;
otherwise:
let Respondy be “I am not impressed.”;
Say Respondy;
now numma is 0.

Instead of showing a hat to Robert:
increase numma by 1. [/code]

So this does a fair job of counting how many hats are shown to Robert, and responding accordingly. However, because it says ‘hat’ each time, you end up with things like this:

show Robert hats
hat: hat: hat: hat: Wow, 4 hats! Woo hoo etc

Does anyone know a way around this?

EDIT: it occurs to me that I need to put code in covering turns when he hasn’t shown the guy some hats, but that’s nothing to worry about

Those hats are printed by a standard rule called the “announce items from multiple object lists rule”, which is listed in a rulebook called the “action-processing rules”.
It goes like this:

This is the announce items from multiple object lists rule: if the current item from the multiple object list is not nothing, say "[current item from the multiple object list]: [run paragraph on]". 

You need to tamper with it somehow. The following is a first shot:

The new announce items from multiple object lists rule is listed instead of the announce items from multiple object lists rule in the action-processing rules.

This is the new announce items from multiple object lists rule:
	if the current item from the multiple object list is a hat:
		say "[run paragraph on]";
	otherwise if the current item from the multiple object list is not nothing :
		say "[current item from the multiple object list]: [run paragraph on]".

Felix, it appears that you are my saviour once more. Thanks!