Developing a money extension

I’ve been working on a money extension (zorkmids/zorkmids.materials/Extensions/Philip Riley/Zorkmids.i7x at main · rileypb/zorkmids · GitHub) which works well as far as it goes, but has three (I think) gaping holes that need to be filled at the I6 level.

The mechanics of the extension are that each thing/room has a “zorkmid content” which represents an amount of money contained in it or on it (in the case of the player, this is the player’s money in inventory). The zorkmid content of a non-container/supporter/person/room is meaningless. This scheme allows any integer amount of money to exist anywhere, and for amounts to be divided or combined at will.

The extension surfaces the money content of a container using a special object called quantity of zorkmids, which it inserts into containers, etc., before their contents are listed. For instance, the you-can-also-see rule has been modified to put the quantity of zorkmids in the room, print the contents, and then remove it.

So this all works well up to a point, where I run into a wall. The three things I know aren’t working are:

  • take all,
  • take all from container,
  • listing contents in inventory.

The first two I surmise require intervention in the parser, which so far I’ve been unable to pull off. The third needs intervention in the list writer code, specifically, it needs to inject the quantity of zorkmids into each container as it is listed.

This all has gone above my head at this point. Anyone with a good knowledge of either of these parts of the code want to take a crack at it? Even just a FollowRulebook in the right place(s) might be able to accomplish what I want.

The i7x is linked above, and there’s some test code at zorkmids/zorkmids.inform/Source/ at main · rileypb/zorkmids · GitHub. I think the extension would be very cool if we could get around these issues.

Apparently, posting here was the inspiration I needed to solve one of the problems, namely the ListWriter problem. Now if I can just figure out how to intervene in the parser before it decides All = None…

Never mind. Works for a single object, but not a list.

Update: I finally found the right place in ListWriter to insert a rulebook call, so that works. Still need help finding the right place in Parser to catch Take Alls.

Got part of TAKE ALL working, but it’s not quite right, since it doesn’t recurse up containers/supporters. Only the money in the holder of the player gets taken.

A similar problem happens when you take an explicit amount of money. The take command cannot see money in holder of the holder of the player.

TAKE ALL FROM doesn’t work at all.

How are you handling deciding whether all includes?

Also, the command >TAKE ALL FROM… normally results in the removing it from action. (See Standard Rules.) Are you handling that?

The problem is that TAKE ALL (FROM) are both handled entirely in the parser if there is nothing to take. So deciding whether all includes never gets called. The problem is I’m trying to insert an object into a container/supporter/room. And it gets worse, because TAKE ALL considers all scopes all the way up the container hierarchy, which means my extension would have to insert a separate quantity of zorkmids at every level at which there is money.

I suspect the only way to implement this extension is to allocate a large number of quantity of zorkmids objects and insert one in each container/supporter/room in scope at the beginning of the parser code, removing them at the end of the turn. Or something like that.

Can you aggregate all of the quantities for nested containers/supporters into a single “top” quantity?

That could work, and it would give more satifying feedback:

 $15: Taken.


 $7: Taken.
 $5: Taken.
 $3: Taken.

I’ll have to think on this a little longer.

A problematic case is one I didn’t consider earlier: saying TAKE $100 when inside an open container, when the container holds $75 and the room contains $75. I guess the most sensible way is to take money first from the most proximal containers going up the hierarchy.

I’m using Dynamic Objects now to create a supply of “quantity of zorkmids” objects. Then I can insert them into every container/supporter/location/person before the command is entered. This works for everything as far as I can tell, with no messing around in I6. The only thing I haven’t figured out (I think) is how to take a specific amount of money when the money is distributed among multiple visible objects. I need a reasonable way to traverse the visible objects, taking from each until we’ve taken all the requested money.

This is all very indirect, but something like this might help:

To decide which number is the object tree distance between (T1 - object) and (T2 - object):
	let C be the common ancestor of T1 with T2;
	if C is nothing, decide on -1;
	let D be a number;
	let P be T1;
	while P is not C:
		increment D;
		now P is holder of P;
	let P be T2;
	while P is not C:
		increment D;
		now P is holder of P;
	decide on D.

An object has a number called tree distance.		

Every turn (this is the update tree distances rule):
	repeat with T running through things:
		let N be the object tree distance between the player and T;
		now the tree distance of T is N.

Definition: An object is close if its tree distance is 3 or less.
Definition: An object is far if its tree distance is 5 or more.
Definition: A thing is nearby if its tree distance is at least 1.

I think that would do it. I saw it after I wrote a different bit of code which recurses downwards until it reaches the leaves, and then goes up a level and repeats (marking what’s already been explored, of course, so it won’t traverse nodes multiple times).

Anyway, I feel like this is complete except for testing and fixing some ugly spacing issues. Thanks for your suggestions!