Last active
December 7, 2016 08:38
-
-
Save realnc/9bdaeb6b1fbc0aaa50b065ef64942dbc to your computer and use it in GitHub Desktop.
TADS 3 module for yes/no answers to the narrator.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#charset "UTF-8" | |
/* | |
* Module for yes/no answers to the narrator. | |
* 2003/06/17, by Nikos Chantziaras <[email protected]> | |
* This file is in the Public Domain. There is no copyright. | |
* | |
* To use this module, simply compile it together with the rest of your | |
* game's source files. | |
*/ | |
#include <adv3.h> | |
#include <en_us.h> | |
/* | |
* To enable the player to answer a question asked by the narrator (NPC | |
* questions are handled by the Tads 3 library), call one of the "set" | |
* methods of the ncYesNo object. The methods are: | |
* | |
* set( STRING_OR_FUNCTION, STRING_OR_FUNCTION ) | |
* | |
* The arguments must be either strings or functions that take no | |
* arguments. The first argument is called/displayed when the player | |
* types YES, the second when the answer is NO. Example: | |
* | |
* dobjFor(Attack) | |
* { | |
* action() | |
* { | |
* "Attacking the troll is pretty dangerous. Are you sure? "; | |
* ncYesNo.set( | |
* // This anonymous function will be called if the player | |
* // anwers with YES. | |
* {: | |
* "You get ready for battle, but the troll kills you | |
* before you can even blink!\b*** You have died ***\b"; | |
* finishGame(finishOptionUndo); | |
* }, | |
* // This string will be displayed if the player anwers NO. | |
* 'Wise decision. ' | |
* ); | |
* } | |
* } | |
* | |
* setAll( STRING_OR_FUNCTION ) | |
* | |
* Same as set(), but the argument is used for both YES and NO. | |
* | |
* setRhetorical() | |
* | |
* This calls setAll() like this: | |
* | |
* self.setAll(self.rhetoricalAnswer); | |
* | |
* The property 'rhetoricalAnswer' contains the string to be displayed | |
* with setRhetorical(). The default is: 'That was a rhetorical | |
* question. ' If you want to display something else, you can simply | |
* set it to something different: | |
* | |
* modify ncYesNo { | |
* rhetoricalAnswer = 'The question was rhetorical. '; | |
* } | |
* | |
* The property 'defaultYesAnswer' contains the string to be displayed | |
* when the player types YES while no question has been asked and the | |
* PC has no current interlocutor. The default is: 'You sound rather | |
* positive. ' | |
* | |
* Similarly, the 'defaultNoAnswer' property defaults to: 'You sound | |
* rather negative. ' | |
* | |
* The player has only one turn to answer to a question. After that, | |
* the reset() method is called, which resets any effects caused by one | |
* of the "set" methods. | |
* | |
* The situation where the PC has a current interlocutor is handled | |
* automaticly. Example: | |
* | |
* >no | |
* I'm glad you disagree. | |
* | |
* >bob, no | |
* Bob does not respond. | |
* [The PC's current interlocutor is now Bob.] | |
* | |
* >no | |
* Bob does not respond. | |
* | |
* >knock on my door | |
* Don't you think knocking on your own door is a bit strange? | |
* | |
* >no | |
* That was a rhetorical question. | |
* [Although the current interlocutor is Bob, we treat NO as the | |
* answer to the narrator's question.] | |
* | |
* >no | |
* Bob does not respond. | |
* [Since the player already answered the narrator's question, NO is | |
* now redirected to Bob.] | |
*/ | |
ncYesNo: object { | |
rhetoricalAnswer = 'That was a rhetorical question. '; | |
defaultYesAnswer = 'You sound rather positive. '; | |
defaultNoAnswer = 'You sound rather negative. '; | |
reset() | |
{ | |
if (self._active) { | |
self._onYes = nil; | |
self._onNo = nil; | |
self._active = nil; | |
self._myFuse.removeEvent(); | |
self._myFuse = nil; | |
if (self._lastIssuer.isPlayerChar()) { | |
self._lastIssuer.lastInterlocutor = self._lastInterlocutor; | |
} | |
} | |
} | |
set( yes, no ) | |
{ | |
if (self._active) self.reset(); | |
self._onYes = yes; | |
self._onNo = no; | |
self._active = true; | |
self._myFuse = new Fuse(self, &reset, 1); | |
self._lastIssuer = gIssuingActor; | |
self._lastInterlocutor = self._lastIssuer.getCurrentInterlocutor(); | |
} | |
setAll( yesOrNo ) | |
{ | |
self.set(yesOrNo, yesOrNo); | |
} | |
setRhetorical() | |
{ | |
self.setAll(self.rhetoricalAnswer); | |
} | |
// Private members; do not modify or evaluate. | |
_onYes = nil; | |
_onNo = nil; | |
_active = nil; | |
_myFuse = nil; | |
_lastIssuer = nil; | |
_lastInterlocutor = nil; | |
} | |
/* -------------------------------------------------------------------- | |
* Modify YesAction and NoAction to use the ncYesNo system. | |
*/ | |
modify YesAction { | |
execAction() | |
{ | |
if (gActor.isPlayerChar()) { | |
if (ncYesNo._active) { | |
if (dataType(ncYesNo._onYes) == TypeSString) { | |
say(ncYesNo._onYes); | |
} else { | |
(ncYesNo._onYes)(); | |
} | |
} else { | |
if (gIssuingActor.getCurrentInterlocutor()) { | |
inherited(); | |
} else { | |
say(ncYesNo.defaultYesAnswer); | |
} | |
} | |
} else { | |
inherited(); | |
} | |
} | |
} | |
modify NoAction { | |
execAction() | |
{ | |
if (gActor.isPlayerChar()) { | |
if (ncYesNo._active) { | |
if (dataType(ncYesNo._onNo) == TypeSString) { | |
say(ncYesNo._onNo); | |
} else { | |
(ncYesNo._onNo)(); | |
} | |
} else { | |
if (gIssuingActor.getCurrentInterlocutor()) { | |
inherited(); | |
} else { | |
say(ncYesNo.defaultNoAnswer); | |
} | |
} | |
} else { | |
inherited(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment