Testing for presence of noun/second noun in I6 inclusion

I have the following inclusion:

Include (-
	[ CheckDPMR result sinp1 sinp2 rv adjustment return_value;
		adjustment = 0;
		if ((noun) && noun hasnt (+ familiar +) ) adjustment = adjustment - 1;
		if ((second) && second hasnt (+ familiar +) ) adjustment = adjustment - 1;
		sinp1 = inp1; sinp2 = inp2; inp1 = noun; inp2 = second;
		rv = FollowRulebook( (+does the player mean rules+) );
		inp1 = sinp1; inp2 = sinp2;
		if ((rv) && RulebookSucceeded()) {
			result = ResultOfRule();
			if (result == (+ it is very likely outcome +) ) return_value = 4;
			if (result == (+ it is likely outcome +) ) return_value =  3;
			if (result == (+ it is possible outcome +) ) return_value =  2;
			if (result == (+ it is unlikely outcome +) ) return_value =  1;
			if (result == (+ it is very unlikely outcome +) ) return_value =  0;
			return_value = return_value + adjustment;
			if (return_value < 0) return_value = 0;
			return return_value;
		}
		return 2;
	];
-).

When, however, I type something with a missing second noun, I get:

[** Programming error: tried to test “has” or “hasnt” of <illegal object
number 1> **]

I’m not sure how to test for this. I thought testing for the presence of second would solve the problem. I’m assuming that I6 has shortcircuiting logic?

You’re testing exactly right—Inform stores 0 (“nothing”) in the noun and second noun variables if there’s nothing supplied—but it looks like it’s also using 1 as a special value, which is also not a valid object in Glulx.

I’m unfortunately not sure what setting noun or second to 1 means. inp1 and inp2 can be set to 1 to mean “there’s a value that’s not an object here” (e.g. a number), but noun and second should always be objects or 0, shouldn’t they?

1 Like

hmm… it seems it only happens with actions applying to one number and one thing, and the command is like “type 4” without specifying the indirect object.

Oh, right! I was misremembering.

When you supply a number (or anything else that’s not an object), it stores 1 in inp1 or inp2, and the number itself in noun or second.

So check to make sure that (noun), and also that (inp1 ~= 1). Then that (second), and also that (inp2 ~= 1). (Or be fancy and say inp1 ~= 0 or 1.)

1 Like

[Note: I’m using 6M62 (long story)]

Not quite right, I don’t think. I see:

CheckDPMR: inp1 = 1176662
CheckDPMR: inp2 = 0
CheckDPMR: sinp1 = 0
CheckDPMR: sinp2 = 0
[** Programming error: tried to test “has” or “hasnt” of <illegal object
number 1> **]
CheckDPMR: noun = <illegal object number 1>
CheckDPMR: second = keypad

the first time through and then after the next invocation of the command:

CheckDPMR: inp1 = 1
CheckDPMR: inp2 = 1176758
CheckDPMR: sinp1 = 0
CheckDPMR: sinp2 = 0
CheckDPMR: noun = <illegal object number 1>
CheckDPMR: second = keypad

without error.

That’s with:

		print "CheckDPMR: inp1 = ", inp1, "^";
		print "CheckDPMR: inp2 = ", inp2, "^";
		print "CheckDPMR: sinp1 = ", sinp1, "^";
		print "CheckDPMR: sinp2 = ", sinp2, "^";
		if ((noun) && inp1 ~= 0 or 1 && noun hasnt (+ familiar +) ) adjustment = adjustment - 1;
		print "CheckDPMR: noun = ", (name) noun, "^";
		print "CheckDPMR: second = ", (name) second, "^";

So I’m still not clear what’s going on with inp1 and inp2.

aha! It seems I need:

	if ((noun) && inp1 == 0 && noun hasnt (+ familiar +) ) adjustment = adjustment - 1;
	if ((second) && inp2 == 0 && second hasnt (+ familiar +) ) adjustment = adjustment - 1;

Seems to work.