Your fix appears to fix the problem because it’s a programming error that will almost certainly cause problems elsewhere. You’ve forgotten to add the parameters to showSuggestions when you call inherited. In other words, this:
modify Actor
showSuggestions(explicit = true, tag = (pendingKeys == [] ? suggestionKey
: pendingKeys))
{
inherited;
}
;
Should have been this:
modify Actor
showSuggestions(explicit = true, tag = (pendingKeys == [] ? suggestionKey
: pendingKeys))
{
inherited(explicit, tag); // DON'T FORGET TO PASS THE ARGUMENTS ON!
}
;
Normally this error would have caused a run-time error. It doesn’t here because the showSuggestions() method defines default values for both its arguments. So what you’ve done is to override showSuggestions so that it always uses its default arguments whatever its caller wanted. It’s as if you had written:
modify Actor
showSuggestions(explicit = true, tag = (pendingKeys == [] ? suggestionKey
: pendingKeys))
{
inherited(true, pendingKeys == [] ? suggestionKey : pendingKeys));
}
;
Thus, what you have done is to tell showSuggestions() to ignore the arguments that are passed to it. This is a bad idea; it will almost certainly cause problems elsewhere in your game (for example, you may not get the right list of suggested topics in a ConvNode).
The command TALK TO X is meant to be used to start a conversation with X. The command TOPICS is the command that explicitly asks for a list of topics. So when the player types TOPICS the showSuggestions() method is called with the explicit argument as true. If there are no topic suggestions to be displayed you then get the “You have nothing in mind…” message because the player explicitly asked for a list of topics. The command TALK TO X is not, however, an explicit request for a list of topics; it’s an explicit request to talk to x (i.e. to start a conversation with x). As a courtesy to the player it also displays a list of topic suggestions if there are any, enclosing them in parentheses. Since the player has not explicitly asked for a list of topics, he or she is not told that there aren’t any if indeed there are not. In this case showSuggestions() is called with the explicit argument set to nil.
This solution is safer than the ‘fix’ applied by the OP, but do be aware that it will prevent TALK TO from doing what it’s actually meant to do. In particular this not only prevents TALK TO X from ever displaying a list of suggested topics (which is what the OP wants), it also prevents TALK TO X from displaying any HelloTopic responses at the start of the conversation. If this is what you actually want in your game, then well and good, but it’s inadvisable as a general solution, since it breaks what TALK TO is meant to do. TALK TO X is meant to be equivalent to X, HELLO.
Indeed, what TALK TO X does in the library is simply to call X.sayHello(). The sayHello() method is defined as follows:
sayHello()
{
/*
* Only carry out the full greeting if we're not already the player
* character's current interlocutor.
*/
if(gPlayerChar.currentInterlocutor != self)
{
/*
* Note that we are now the player character's current
* interlocutor
*/
gPlayerChar.currentInterlocutor = self;
/* Look for an appropriate HelloTopic to handle the greeting. */
handleTopic(&miscTopics, [helloTopicObj], &noResponseMsg);
}
/* Add a paragraph break */
"<.p>";
/* Display a list of not-explicitly-asked-for topic suggestions */
showSuggestions(nil, suggestionKey);
}
What this does is to show a greeting message (i.e. the response to any HelloTopic that’s been defined) if the player character isn’t already talking to the addressee, and then to go on and display an implicitly asked for list of topic suggestions. The bug is that it doesn’t do anything else when a TALK TO message is issued to an actor with whom the player character is already in conversation. The fix thus needs to be applied to the sayHello() method, something along the lines of:
sayHello()
{
/*
* Only carry out the full greeting if we're not already the player
* character's current interlocutor.
*/
if(gPlayerChar.currentInterlocutor != self)
{
/*
* Note that we are now the player character's current
* interlocutor
*/
gPlayerChar.currentInterlocutor = self;
/* Look for an appropriate HelloTopic to handle the greeting. */
handleTopic(&miscTopics, [helloTopicObj], &noResponseMsg);
}
/* Otherwise say we're already talking to this actor */
else
say(alreadyTalkingMsg);
/* Add a paragraph break */
"<.p>";
/* Display a list of not-explicitly-asked-for topic suggestions */
showSuggestions(nil, suggestionKey);
}
alreadyTalkingMsg = BMsg(already talking, '{I} {am} already talking to {1}. ', theName)
This response can readily be changed on a per-actor basis, e.g. to Jerry’s preferred:
lucy: Actor 'Lucy;;;her'
alreadyTalkingMsg = '<q>What is it you want to say, sweetie?</q> '
;
I’ll take a look at making this change in the library (and checking that it works as expected) when I get a chance.