TADS Programming - Ask/Tell - Part 2 asktell.t: ASK/TELL-based conversation system for TADS V1.0 Suzanne Skinner, 1999, Public Domain tril@igs.net @~Concluded from last issue ioTopicVerb: a verb which uses topics as indirect objects. Non- topics will never show up in disambiguation questions. validIo and validIoList are not used for scoping, nor are verIoAskAbout and the like used. Instead, all disambiguation is done within disambigIobj. If no topics match the player's input, that method will return the special catchall topic catchallNonTopic. Since no NPCs or infoSources know about this topic, it will simply cause a "disavow" to be printed. Similarly, if topics match but no known topics match, catchallUnknownTopic will be returned, which will cause a reply of "you don't know about that" to any type of query (ask, tell, consult, look up). Important properties: none class ioTopicVerb: deepverb validIoList(actor, prep, dobj) = (nil) validIo(actor, obj, seqno) = true ioDefault(actor, prep) = (nil) disambigIobj(actor, prep, dobj, verprop, wordlist, objlist, flaglist, numberWanted, isAmbiguous, silent) = { local i, len; local newlist = []; local unknownTopicsFound = nil; len = length(objlist); for (i=1; i <= len; i++) { if (isclass(objlist[i], topic)) { if (objlist[i].known) newlist += objlist[i]; else unknownTopicsFound = true; } } if (length(newlist) < 1) { if (unknownTopicsFound) newlist += catchallUnknownTopic; else newlist += catchallNonTopic; } return newlist; } ; doTopicVerb: a verb which uses topics as direct objects. disambigDobj simply calls disambigIobj on ioTopicVerb. See ioTopicVerb for more details. Important properties: none class doTopicVerb: deepverb validDoList(actor, prep, io) = (nil) validDo(actor, obj, seqno) = true doDefault(actor, prep, io) = (nil) Allowing multiple objects can cause erroneous sdescs (e.g. catchallNonTopic.sdesc) to get printed. rejectMultiDobj(prep) = { "You can't use multiple objects with that verb."; return true; } disambigDobj(actor, prep, io, verprop, wordlist, objlist, flaglist, numberWanted, isAmbiguous, silent) = { return ioTopicVerb.disambigIobj(actor, prep, io, verprop, wordlist, objlist, flaglist, numberWanted, isAmbiguous, silent); } ; ********** adv.t Modifications *********** Modifications to thing for default responses to ask, tell, consult, look up, and redirections of ioConsultOn to doConsultOn, ioAskFor to doAskFor. Important properties: none, unless you want to change default responses. modify thing replace verDoAskAbout(actor, io) = {"There is no response.";} verIoAskFor(actor) = {} verDoAskFor(actor, io) = {"There is no response.";} ioAskFor(actor, dobj) = {dobj.doAskFor(actor, self);} replace verDoTellAbout(actor, io)= {"There is no response.";} verIoConsultOn(actor) = {} verDoConsultOn(actor, io) = {"That's not an information source.";} ioConsultOn(actor, dobj) = {dobj.doConsultOn(actor, self);} verIoLookupIn(actor) = {"That's not an information source.";} verDoLookupIn(actor, io) = {} ; Modifications to movableActor (parent class for all actors) Important properties: + askTopics(topic, words): This method should output text and return true for a valid topic, otherwise return nil, in which case disavow will be printed by doAskAbout. The specific vocabulary words used to refer to the topic are passed in the "words" parameter. + tellTopics(topic, words): works almost identically to askTopics. + doAskFor(actor, io): You should override this method if you want to allow the player to ask this NPC *for* something. Like "ask about", it takes topics only. By default, it simply outputs self.disavow. + disavow: default changed to "There is no response.". This method will be called if askTopics returns nil. + tellDisavow: calls disavow by default. This method will be called if tellTopics returns nil. modify movableActor askTopics(topic, words) = {return nil;} tellTopics(topic, words) = {return nil;} doAskFor(actor, io) = {self.disavow;} replace disavow = "There is no response." tellDisavow = {self.disavow;} replace doAskAbout(actor, io) = { if (!self.askTopics(io, objwords(2))) self.disavow; } verDoTellAbout(actor, io) = {} doTellAbout(actor, io) = { if (!self.tellTopics(io, objwords(2))) self.tellDisavow; } verDoAskFor(actor, io) = {} ; ************** Special Objects ************* catchallNonTopic: If the game is expecting a topic, and the player enters vocabulary that does not match any objects of the topic class (known or unknown), then the disambiguation function on ioTopicVerb or doTopicVerb will return a single-item list consisting of catchallNonTopic. Since no NPC or infoSource will have a response/entry for this topic, it will simply cause a "disavow" statement to be printed. Important properties: none catchallNonTopic: knownTopic sdesc = "non-topic (you should never see this)" ; catchallUnknownTopic: Similar to catchallNonTopic, this topic will be returned by disambiguation functions if the player's vocabulary matches no *known* topics, but at least one unknowntopic. Default messages are set here so that ask, tell, and consult will all output topic.unknownMsg in response. The default message for "look up" must be handled in infoSource itself, in ioLookupIn. Important properties: none catchallUnknownTopic: knownTopic sdesc = "unknown topic (you should never see this)" ioAskAbout(actor, dobj) = {topic.unknownMsg;} ioAskFor(actor, dobj) = {topic.unknownMsg;} ioTellAbout(actor, dobj) = {topic.unknownMsg;} ioConsultOn(actor, dobj) = {topic.unknownMsg;} ; ********* New and Replaced Verbs ******* replace askVerb: ioTopicVerb, darkVerb verb = 'ask' sdesc = "ask" prepDefault = aboutPrep ioAction(aboutPrep) = 'AskAbout' ioAction(forPrep) = 'AskFor' ; replace tellVerb: ioTopicVerb, darkVerb verb = 'tell' sdesc = "tell" prepDefault = aboutPrep ioAction(aboutPrep) = 'TellAbout' ; consultVerb: ioTopicVerb verb = 'consult' sdesc = "consult" prepDefault = onPrep ioAction(onPrep) = 'ConsultOn' ioAction(aboutPrep) = 'ConsultOn' ; lookupVerb: doTopicVerb verb = 'look up' 'read about' sdesc = "look up" prepDefault = inPrep ioAction(inPrep) = 'LookupIn' ; ************ New Prepositions ************* forPrep: Prep preposition = 'for' sdesc = "for" ; #pragma C- - o -