Conditional locale descs with multiple player characters

I’m having some trouble with objects appearing in room descriptions under certain conditions. What I want is for items with the incorporeal property to only be visible - and therefore listed in a room description - if the player is also incorporeal. I plan for the player to be able to switch between two people: one corporeal, the other not.

I thought about moving all incorporeal objects to a secret room whenever the player becomes the corporeal character, but decided it might be overly complicated with multiple rooms and multiple locations to which to return them. My solution was to have these incorporeal objects in their usual positions, but to make them privately-named (with a conditional ‘Understand’ phrase so the incorporeal character can interact with them) and to give them a locale priority of 0 when the player is incorporeal, preventing them being listed at all.

It works perfectly with the test command (I appropriated the ‘sing’ verb to try out switching between incorporeal and corporeal) but when I use the possess verb to switch between other people, the item (here, the pen) is still listed in the room description. The privately-named part worked fine, suggesting that the player has successfully become corporeal.

Beginning as the incorporeal character, singing to change to corporeal and then possessing the corporeal character results in the correct behaviour, so I assume I’ve made a mistake in the possessing action. Trouble is, I can’t see it for looking.

Here’s my code and the resulting transcript. Any pointers would be very much appreciated.

[code]“Test” by Rhian

A thing can be corporeal or incorporeal. A thing is usually corporeal.
A thing can be revealed or hidden. A thing is usually revealed.

Definition: a thing is hidden:
if it is incorporeal and the player is corporeal, yes;
no.

After choosing notable locale objects:
if something (called the object) is hidden:
set locale priority of the object to 0.

Instead of singing:
if the player is corporeal:
now the player is incorporeal;
say “You are now incorporeal.”;
rule succeeds;
if the player is incorporeal:
now the player is corporeal;
say “You are now corporeal.”;
rule succeeds.
[For testing only.]

Possessing is an action applying to one visible thing. Understand “possess [something]” as possessing.

Check possessing:
if the noun is not a person, say “You can’t possess inanimate objects.” instead.

Carry out possessing Sarah:
now the player is Sarah;
now the player is corporeal;
move Diana to the Repository;
say “You claim Sarah’s corporeal form.”

Instead of possessing the player:
if the player is Diana:
say “You can’t possess yourself.”;
otherwise:
say “You’re already possessing this form.”

Departing is an action applying to nothing. Understand “depart” as departing.

Check departing:
if the player is Diana, say “You can’t depart from yourself.” instead.

Carry out departing:
if the player is Sarah:
move Diana to the location of the player;
now the player is Diana;
now the player is incorporeal;
say “You return to your incorporeal form.”

The player is a woman called Diana. Diana is incorporeal.

The Hall is a room.

The pen is in the Hall. The pen is incorporeal and privately-named. Understand “pen” as the pen when the player is incorporeal.

Sarah is a woman in the Hall.

The Repository is a room.

Test me with “x pen / possess sarah / l / x pen / depart / sing / l / possess sarah / l”[/code]

Your code is redundant, and I think that’s causing the problem. You’ve created a property that has the values hidden or revealed, and then you’ve created an adjective that shares the same name as one of the values. Try this instead:

[code]A thing can be corporeal or incorporeal. A thing is usually corporeal.
Definition: a thing is hidden:
if it is incorporeal and the player is corporeal, yes;
no.
Definition: a thing is revealed if it is not hidden.

[not tested]
[/code]

This rule doesn’t work as it should:

After choosing notable locale objects: if something (called the object) is hidden: set locale priority of the object to 0.
It’s basically looking for just one hidden thing and setting its locale priority. You need to loop through all hidden things in the location.

After choosing notable locale objects: repeat with X running through hidden things in the location: set locale priority of X to 0.

(Capmikee also has a good point, but the adjective isn’t causing this particular problem.)

Thanks guys, this is really helpful. Juhana’s code sorted it for me, and I see where I was going wrong. Much obliged!

Chopping that down further yields Definition: a thing is hidden rather than revealed if it is incorporeal and the player is corporeal.

I feel like the OP ought to be able to do a lot of what was wanted with a statement like this:

After deciding the scope of the player when the player is corporeal: repeat with item running through all incorporeal things enclosed by the location: remove item from scope.

I’ve wanted to do something like this myself on occasion, but it isn’t possible—objects can only be added to scope in this way, not removed. Does anyone who’s familiar with the internals know whether this is a fundamental limitation of the library, or just a design oversight?

–Erik

It’s fundamental to the way scope is handled. (Going back to I6.) “deciding the scope” iterates through all objects in scope. The “add X to scope” line actually iterates through X as well, before the activity completes. The earlier objects have already been touched.

Thanks. Too bad.

–Erik