Problems with removing

I have a problem with trying to change the default handling for removing items.

I originally tried using Instead rules, removing various rules from the rulebooks but pretty much whatever I tried, the (first taking the huge crystal) always triggered first.

Finally I found out a way to make it work - except when you ask a third person to do it for you.

Minimal version demonstrating the problem:

[code]“Removaltest” by Zalminen

Chamber is a room.

Golem is a person. Golem is in Chamber. Sidekick is a person. Sidekick is in Chamber. Golem is wearing a huge crystal.

Special_removing is an action applying to one thing.

Carry out an actor special_removing something:
say “TESTING”;

Before an actor taking off something (this is the redirect crystal removal rule):
if the noun is a huge crystal, convert to the special_removing action on the noun;

Persuasion rule for asking Golem to try taking off something:
rule succeeds;
Persuasion rule for asking Sidekick to try taking off something:
rule succeeds;
[/code]

[code]Removaltest
An Interactive Fiction by Zalminen
Release 1 / Serial number 120603 / Inform 7 build 6G60 (I6/v6.32 lib 6/12N) SD

Chamber
You can see Golem and Sidekick here.

rules
Rules tracing now switched on. Type “rules off” to switch it off again, or “rules all” to include even rules which do not apply.

Sidekick, remove crystal
(Sidekick first taking the huge crystal)
Sidekick has better things to do.

Golem, remove crystal
[Rule “Persuasion rule for asking Golem to try taking off something” applies.]
[Rule “redirect crystal removal rule” applies.]
[Rule “Carry out an actor special_removing something” applies.]
TESTING
remove crystal
[Rule “redirect crystal removal rule” applies.]
[Rule “Carry out an actor special_removing something” applies.]
TESTING
[/code]

For some strange reason it works fine when the player removes the crystal or tells the golem to remove it but fails when asking the sidekick to remove it.

Why does the (Sidekick first taking the huge crystal) show up in the first case but the conversion works fine in the others?

I’m no expert, but it seems that there’s a rule applying to third parties trying to remove something worn by someone else that isn’t being caught by your new action. I’ll take a closer look later to see if I can help at all.

Edit: In the meantime, try an experiment for me: give the crystal to the sidekick instead and see if the same thing happens or if the error happens with the golem instead.

Yeah, if the sidekick has the crystal, then it works for him but not the Golem.

I thought about trying to replace the rule that causes the game to try grabbing the crystal first but I can’t seem to locate it in the standard rules…

What effect are you trying to have? I’m not sure what you’re trying to do.

Normally “remove X” includes checks that the item must be something the actor is wearing and the removed item ends up in the actor’s inventory.
I’m trying to write rules for a special case where neither of these rules apply. And I don’t want the game to print the “(first taking the huge crystal)” either.

Anyway, looks like I got it to work the way I want once I added

Understand the command "remove" as something new;

and just rewrote the rules for both the normal operation and the special case.

You will need to account for all the other commands as well. Check the Actions index for Taking off something.

However as the standard rules say:
Taking off is an action applying to one carried thing.

I think you’re still going to have trouble… before the Before rules are even considered the parser will try to implicitly take item to satisfy the carried condition.

But why are you wanting the taking off action? I’m guessing that you’re setting up some sort of puzzle where taking the crystal off the golem statue produces some bad effect? Can you just use the taking action instead? It will be much easier to add instead rules to that.

The standard behavior of the taking off action is somewhat wonky anyway. If there’s a jacket lying around on the floor and you type “shed jacket,” you will pick up the jacket before attempting to take it off; and then of course you will fail at taking it off, because you’re holding it instead of wearing it. So the implicit take doesn’t actually help prepare for the action.

I really don’t see why this action should generate implicit takes. Perhaps it’s to enable automatic disambiguation, but on a very crude test, even if you define an action that doesn’t apply to carried things the parser seems to prefer something worn to something lying on the floor – and of course it doesn’t help at all with something worn versus something carried. So in general, I think it might be a good idea to edit the Standard Rules so they say

Taking off is an action applying to one thing.

and use a DTPM rule to make sure the parser tries to choose worn things to take off:

Does the player mean taking off something worn: it is very likely.

I’ve just posted a Uservoice suggestion that this change should be made in the Standard Rules.

I’m not sure this would solve your case, though, because it sounds like you want “remove crystal” to effectively dislodge the crystal, so it winds up on the floor. (Is that right?) In that case, I might try defining a new action:

[code]“Removaltest” by Zalminen

Chamber is a room.

Golem is a person. Golem is in Chamber. Sidekick is a person. Sidekick is in Chamber. Golem is wearing a huge crystal.

Persuasion rule for asking Golem to try doing something:
rule succeeds;
Persuasion rule for asking Sidekick to try doing something:
rule succeeds;

A blue jacket is in chamber. The player wears a red jacket.

Dislodging is an action applying to one thing.
Understand “remove [crystal]” as dislodging when the golem encloses the crystal.
Understand “dislodge [something]” as dislodging.
Check an actor dislodging:
if the noun is enclosed by the actor:
try the actor dropping the noun instead;
otherwise if the noun is not enclosed by a person:
say “[The noun] doesn’t need to be dislodged.” instead.

Check dislodging:
if the noun is not the crystal:
say “That can’t be dislodged.” instead.

Carry out an actor dislodging:
now the noun is in the location.

Report an actor dislodging:
if the actor is the player:
say “You poke [the noun] free.”;
otherwise:
say “[The actor] pokes [the noun] free.”

Test me with “remove crystal/l/golem, wear crystal/dislodge jacket/dislodge blue jacket/golem, remove crystal/golem, wear crystal/sidekick, remove crystal/sidekick, dislodge crystal/wear crystal/remove crystal”.[/code]

I’m not particularly fond of special-casing “remove [crystal]” but maybe this can help you get started, if this is indeed what you want.

Yeah, that’s the idea.

Understand "remove [crystal]" as dislodging when the golem encloses the crystal.
Ah, didn’t think of trying it this way. Thanks!

One thing to be wary of here is that players probably won’t think of typing “remove crystal” unless they get a very strong hint that they need to use that verb, and maybe not even then. “Pull crystal,” “hit crystal,” and the like are more likely. You might even want to redirect “take crystal” to dislodging the crystal, which would solve some of the problems with removing (since the implicit take would wind up dislodging the crystal).

True.

My code was actually just a made-up example of the problem I was running into. No need to analyze it too much :slight_smile:

But thanks for the help everyone!