Hint System (adv3Lite) -- solved

Apparently the hint system in adv3Lite is somewhat different from the same system in adv3, so adv3 techniques may or may not work with this question.

The deal is this: It occurred to me that it would be useful or entertaining to do with the hint and scoring systems what I did using Inform 6 in my very first game (Not Just an Ordinary Ballerina, 1999) – namely, to reduce the score for an Achievement depending on how many hints the player has asked for. Conceivably, if the author is feeling naughty, you might even score a value of -1 if you read ALL of the hints. But a zero would be more likely. If the points of an Achievement start out at 5, I’d like either to decrement it as hints are read, or simply set it to a certain value when a certain hint appears on the screen for the first time.

This turns out to be quite difficult.

The texts in a Goal object are stored as single-quoted strings – as data. Calling a method called <<someAchievement.reducePoints()>> from within the string is, of course, easy. The difficulty is, the string will be read several times while the Goal’s hints are being displayed. So decrementing simply won’t work. Not only that, but the order in which the hint texts are evaluated is from the bottom of the list to the top (that is, in reverse order), and all of the hints are evaluated EACH time a hint is to be displayed. As a result, the point value of the very first hint (which would presumably be close to the maximum value for that Achievement) will always be the one that the Achievement ends up with when the hints are displayed.

It appears (poking around in the LRM) that the method displaying the text is displaySubItem() in the MenuTopicItem class. Here’s the relevant code from the library, including the comment:

/* * show the item: if it's a simple string, just display it; * otherwise, assume it's an object, and call its getItemText * method to get its text (and possibly trigger any needed * side-effects) */ say(dataType(item) == TypeSString ? item : item.getItemText());
This seems to suggest that I can put an object into the item list – an object with a getItemText() method. But what type of object? That’s what I don’t know. An anonymous function? Probably not.

And in any case, getItemText() will probably get called in exactly the same way as my <<>> call from within the text string, meaning I’ll get the same result I’m getting now.

It occurs to me to try this:

modify MenuTopicItem displaySubItem(idx, lastBeforeInput, eol) { adjustScore(idx); inherited (idx, lastBeforeInput, eol); } adjustScore(idx) {} ;
At first I thought that would create the same problem as before – but miraculously, it works. Yay! When all else fails, modify the library objects!