Asking an NPC to do something with "my" thing

I’m trying to make it possible for the player to ask an NPC to do something with something the player is holding, like taking it, but for the player to be able to type this in with more natural language that could also be more specific… instead of:

Bob, take sword

do:

Bob, take my sword

I had no idea how to even begin, but I found a post by Shadow Wolf here: https://intfiction.org/t/small-i7-extension-possession-and-ownership/5465/1

However, I don’t seem to be able to get it to work with the word “my”… if:

Bob, take yourself’s sword

then it works, but that is awkward.

I have a bunch of other code, it’s all a great big mess because I just keep piling things into my “learning” project, so I guess it could be something else, but I’m not going to paste hundreds of lines of disorganized code into here… for the sake of argument, let’s assume it’s not my other code, what can be done here? And failing that, any ideas about what kind of thing I might have done that could cause this?

Edit: I think I see some of what is going on here… both the player and Bob have a sword… so bob is always obsessed with his own sword, it seems. Once there is only on sword in play, Bob takes the player’s sword. Even though the word “my” is in the command, the parser isn’t identifying that the noun in question should be the player’s… hm.

Do you have something like this already?

Understand “my” as a thing when the item described is carried by the player.
Understand “your” as a thing when the item described is carried by a person and the item described is not carried by the player.

Yeah, the code I found in that link already had that in it.

I just seems like “my” is being totally ignored, and the parser is just trying to decide which noun is best without clarification, and always going with the one the person being asked already has.

Hm. Does this only affect taking? There might be a “does the player mean” rule discouraging actors from trying to take something that’s carried.

I didn’t, but after you mentioned that I tried adding the opposite, to try to encourage the behavior, but no change:

Does the player mean asking someone to try taking a thing carried by the person asked: it is very unlikely.
Does the player mean asking someone to try taking a thing carried by the player when the player's command includes "take my": it is very likely.

I don’t know if what I wrote above is correct for anything though, but it doesn’t give an error at least. Again, the above doesn’t seem to fix anything. Using “yourself’s” instead of my works perfectly fine still, regardless of use case, but getting “my” in there doesn’t seem to work.

I tried substituting the player’s command, but it won’t let me because an “ask” command includes a “,”… how would I go about trying to replace the player’s command like “Bob, take my sword” with “Bob, take yourself’s sword” and rerun the action with that new command? Maybe that’s the way to hit it with a big stick…

This would be a bad idea in any case, because it doesn’t cover when the player says “get my.”

Some of what’s said in this thread seems to suggest that it’ll be very hard to override the behavior of “my.”

Wacky Idea: Use an after reading a command rule to replace “my” with “myy” wherever it appears (as a standalone word). Then write the rules you want to deal with “myy.”

With the extension code I’m using, I think replacing “my” with “yourself’s” should work… but if not for some reason, I can try “my” to “myy” and understanding “myy”…

I tried replacing my to yourself’s with the below, modified from an example document, but I don’t know if it is just not working because I’m doing it wrong, or if it did replace it properly but this didn’t fix it (because it just doesn’t fix it):

The last command is an indexed text that varies. 

The parser error flag is a truth state that varies. The parser error flag is false. 

Rule for printing a parser error when the latest parser error is the only understood as far as error and the player's command matches the text "my":
	now the last command is the player's command;
	now the parser error flag is true;
	let n be indexed text;
	let n be the player's command;
	replace the regular expression ".* my (.*)" in n with "my \1";
	say "(ignoring the unnecessary words '[n]')[line break]";
	replace the regular expression "my .*" in the last command with "yourself's ". 

Rule for reading a command when the parser error flag is true:
	now the parser error flag is false;
	change the text of the player's command to the last command. 

My hope is that the player’s command will just have “my” replaced by “yourself’s”, because a command directly entered as “Bob, take yourself’s sword” works just fine… I would assume a properly replaced command that is identical to that should produce the same behavior? Is the above right?

Printing a parser error happens way after reading a command. The parser error will be printed after the command has been read and the parser has given up on it. It looks to me as though what your code ought to do is print the parser error and then change the next command to the corrected text. If it doesn’t do that, it’s probalby because you’ve written a rule for reading a command as opposed to one after reading a command; I have no idea what happens if you try to put new rules in there. (See section 17.31.)

Unless you’re going to do some very very serious messing with the parser, I don’t think you’re going to be able to replace text in the command only when the parser failed to parse it. If you want to replace text, you have to do it before the parsing happens, which means you’ll have to do it every time.

So you could try this:

[code]Understand “myy” as a thing when the item described is carried by the player.
Understand “your” as a thing when the item described is carried by a person and the item described is not carried by the player.

After reading a command:
if the player’s command includes " my " begin;
replace the matched text with “myy”;
say “The player’s command is [the player’s command].”;
end if.

Arena is a room. Amy is a woman in arena. Amy carries a bastard sword. The player carries a short sword.

Test me with “x my sword/x your sword/amy, x my sword/amy, x your sword”.

Persuasion rule: persuasion succeeds.[/code]

It might be better to use regular expressions so that you can capture “my” when it’s its own word but not set off by spaces. (The regexp for this is “\bmy\b” I think.) I was a bit too lazy to do that now. Note that Amy’s name does not get messed with (I would advise against doing an IF adaptation of the Moomin stories featuring Little My). The normal behavior of the word “my” may get messed with, where “my” refers to absolutely anything and not just things you’re carrying, but eh, that’s not so bad. The behavior of “your” is a bit funny as the second command reveals; you could make it more intuitive by changing the relevant Understand line to:

Understand "your" as a thing when the item described is carried by the person asked.

Oh, also note that if you’re going to do snippet matching the way I did in this example you say “the player’s command matches ‘my’” if you want the case where “my” is the entire command and “the player’s command includes ‘my’” if you want the case where “my” is a bit of the command. If you’re going to do a regular expression I guess that you want “replace the regular expression ‘\bmy\b’ in T with ‘my’” and that’s OK. But if you actually want to test a regular expression you want “if T matches the text ‘my’” for the case where “my” is part of T and “if T exactly matches the text ‘my’” for the case where “my” is the entirety of T. The two different uses of “matches” drive me crazy; I wrote “matches” instead of “includes” in my test code and I had just looked at the documentation for it.

One note with Matt W’s code: if you’re comparing against " my " rather than “\bmy\b”, you should probably include spaces on either side of whatever you’re replacing it with.

Also, one thing which might be useful (or might not). On the Z-machine, iirc the player’s command is put in all lowercase before being parsed. So if you use something with capital letters as a signal, it’s guaranteed not to clash with something the player typed.

Ok, this works. I actually tried something similar to this before trying the parser error thing…

I had tried:

After reading a command:
	if the player's command includes " my ":
		replace the matched text with " yourself's ";

But this did not succeed. I’m assuming it’s got something to do with snippets vs text and the apostrophe…

Oh well, in any case, creating a “myy” and replacing “my” with “myy” works. Thanks!

I’m guessing that “yourself’s” won’t work unless you have Shadow Wolf’s Possession and Ownership extension included; Possession and Ownership will allow “foo’s sword” to be understood whenever “foo” is a person’s name and foo carries something called “sword” [it takes care of this in part by putting a space between ‘foo’ and the 's]. Since “yourself” is the name of the default PC, “yourself’s” will be understood.

Another complicating factor is that if you have what’s called an assembly, where you write “A nose is a kind of thing. Every person incorporates a nose,” the nose that is part of Amy will get the name “Amy’s nose.” So for those kinds of thing the apostrophe-s gets understood, with some limitations (if the person is named Amy Myrdal, the nose will be “Amy Myrdal’s nose,” so “Amy Myrdal’s nose” and “Amy nose” and “Myrdal’s nose” will all be understood, but not “Amy’s nose” or “Myrdal nose”; the words have to match exactly). That doesn’t work with “yourself’s”; I think the nose belonging to the default player object gets named “your nose.”

Yeah, I have Shadow Wolf’s code installed and am using assemblies both. I figured out what was wrong, the order of events was off, so I had to insert something new into Shadow Wolf’s code here:

After reading a command (this is the mangle possessives in the players command rule):
[added these lines]
	if the player's command includes " my ":
		replace the matched text with " yourself's ";
[/end added these lines]
	let N be indexed text;
	let N be the player's command;
	replace the regular expression "(\w)[']s" in N with "\1 [']s";
	replace the regular expression "s['](\W)" in N with "s [']s\1"; [Cheat to handle possessives]
	change the text of the player's command to N;
 
Understand "[something related by reversed possession] 's" as a thing.
Understand "[something related by reversed incorporation] 's" as a thing.
Understand "my" as a thing when the player is holding the item described. Understand "your" as a thing when the person asked is holding the item described.
 
[Sometimes items are permanently associated with a person, even if they are currently held by someone else, or not held at all (a building, for example). Ownership handles this.]
					   
Ownership relates one person (called the owner)  to various things. The verb to own (he owns, they own, he owned, he is owned) implies the ownership relation.
Understand "my" as a thing when the player owns the item described. Understand "your" as a thing when the person asked owns the item described.
Understand "[something related by reversed ownership] 's" as a thing.

If that was processed separately, it was interfering with the other lines below replacing for dealing with the apostrophe. Now it all works happily.

Where is this extension located? I do not see Shadow Wolf on the I7 Extensions by Author page.

It wasn’t released officially on the extensions page I don’t think, but still code someone shared through the forum:

viewtopic.php?f=7&t=8119&hilit=possession+and+ownership