| /* | |
| marry.t -- Inter-character marriage for TADS games. | |
| Copyright (c) 1997 by Christopher Nebel | |
| This code may be freely included in any TADS game, commercial | |
| or otherwise, but is not in the Public Domain. Please send | |
| bugs and comments to <c.nebel@apple.com>. | |
| INTRODUCTION: | |
| Ever wanted to write a more mannerly interactive fiction game? | |
| An adaptation of "Pride and Prejudice," perhaps? Well, here's | |
| a small library to help. Using it, you can allow the player | |
| to marry other NPCs and even arrange marriages between NPCs. | |
| INSTRUCTIONS: | |
| This code was written to work with TADS 2.2 using adv.t, though | |
| with minor modifications it could work with WorldClass as well. | |
| Write your actors as usual, include "marry.t", then start | |
| overriding these two methods: | |
| - verMarry(d) : A marriage has been proposed between <self> | |
| and <d>. Speak now, or forever hold your piece. | |
| - saywillmarry(d) : Performs the actual marriage. | |
| There's also one useful property, "betrothed". If a character has | |
| agreed to marry someone, this property points to the character they're | |
| married (or at least engaged) to. If they're single, it will be nil. | |
| There are several other methods that are defined for internal use: | |
| verDoMarry(actor), doMarry(actor), marry(d), and saybetrothed. In | |
| general, you shouldn't override these, though you might use them | |
| for special effects. | |
| MORE DETAILED INSTRUCTIONS: | |
| - verMarry(d): This is where you determine who will agree to marry whom. | |
| It covers not only cases where the player is proposing (e.g., "marry Jane" | |
| or "Jane, marry me"), but also NPCs that you're ordering to marry to each | |
| other (e.g., "Wickham, marry Lydia.") | |
| verMarry works like a normal verXoVerb handler (though it isn't really one). | |
| If there is any output, the proposal is considered to be rejected. If | |
| there is no output, program flow continues on to check the other partner | |
| and then to the "saywillmarry" method. | |
| By default, no one will agree to marry anyone, the anti-social wretches. | |
| To change this, override verMarry. Here's a simple example: | |
| Jane: Actor | |
| verMarry(d) = { | |
| if (d != Bingley) | |
| "\"But I love Mr.\ Bingley!\" "; | |
| } | |
| ; | |
| Now Jane will agree to marry Bingley, but no one else. However, Bingley | |
| has his own say in the matter, so for the marriage to work, we have to | |
| override his verMarry as well: | |
| Bingley: Actor | |
| verMarry(d) = { | |
| if (d != Jane) | |
| "Mr.\ Bingley seems uninterested in marrying <<d.thedesc>>. "; | |
| } | |
| ; | |
| Of course, you are free to represent much more complicated relationships. | |
| The one caveat is that you should not alter the game state in verMarry, | |
| since like a verXoVerb method, you will be called invisibly at times. | |
| Here's a more complex example: | |
| Elizabeth: Actor | |
| verMarry(d) = { | |
| if (d == Darcy) { | |
| if (not darcyletter.isknownto(self)) | |
| "\"I think not -- a more conceited, arrogant man I've never met.\" "; | |
| else | |
| ; // Thinks he's ok, don't object. | |
| } | |
| else if (d == Wickham) { | |
| if (Wickham.betrothed) | |
| "\"But Mr. Wickham is already married!\" "; | |
| else { | |
| if (darcyletter.isknownto(self)) | |
| "\"What an idea!\" she replies in a scathing tone. "; | |
| else | |
| "\"What an idea!\" she smiles. "; | |
| } | |
| } | |
| else if (d == Collins) { | |
| "Elizabeth rolls her eyes slightly. "; | |
| } | |
| } | |
| ; | |
| - saywillmarry(d): Performs the actual marriage. Standard behavior is | |
| provided by an internal method "marry", so there's no need to call the | |
| inherited "saywillmarry." The default version simply prints "<<self>> | |
| consents to marry <<d>>"; you'll probably want to override this with | |
| something more elaborate. | |
| If you order two NPCs to marry, the system calls "saywillmarry" such that | |
| "self" is the proposing actor and "d" is the proposee; e.g., the command | |
| "Collins, marry Charlotte", would call "Collins.saywillmarry(Charlotte)." | |
| If you propose (successfully) to an NPC, either by saying "marry Jane" or | |
| "Jane, marry me," it will call Jane.saywillmarry(Me). This is admittedly | |
| backwards from the other case, but helps keep the code associated with an | |
| actor all in one place. | |
| WHO GETS CALLED WHEN: | |
| This gets a little complicated, so pay attention. Marriage commands come | |
| in three possible forms: | |
| 1. "marry X." | |
| 2. "X, marry me." | |
| 3. "X, marry Y." | |
| Cases 1 and 2 are handled identically, though they're different to the | |
| parser. First it calls X.verMarry(Me) to give the proposee a chance to | |
| protest, then it calls Me.verMarry(X) to give the player the same chance. | |
| For Me.verMarry(X), it's actually more that the player might not be | |
| allowed to marry -- presumably they want to, or they wouldn't have | |
| proposed in the first place. Finally, if no one complains, it calls | |
| X.saywillmarry(Me). | |
| In case 3, the player is ordering two NPCs to marry. First the system | |
| calls X.verMarry(Y) -- X might not want to be pushed around by the player, | |
| in addition to not wanting to marry Y. Then it calls Y.verMarry(X) to | |
| see if Y will accept X's proposal. | |
| To sum up: | |
| "marry Kitty" or "Kitty, marry me." | |
| 1. Kitty.verMarry(Me) -- does Kitty want to marry you? | |
| 2. Me.verMarry(Kitty) -- can you marry Kitty? | |
| If no output results, | |
| 3. Kitty.saywillmarry(Me) | |
| "Wickham, marry Lydia." | |
| 1. Wickham.verMarry(Lydia) -- will Wickham propose to Lydia in the first place? | |
| 2. Lydia.verMarry(Wickham) -- will Lydia accept? | |
| If no output results, | |
| 3. Wickham.saywillmarry(Lydia) | |
| */ | |
| #pragma C+ | |
| marryVersion: versionTag | |
| id="$Id: marry.t 1997/12/25 03:48:00 cdn Exp cdn $\n" | |
| author='Christopher Nebel' | |
| func='support for inter-character marriage' | |
| ; | |
| marryVerb: deepverb | |
| verb = 'marry' 'wed' | |
| sdesc = "marry" | |
| doAction = 'Marry' | |
| validDoList(actor, prep, iobj) = | |
| (inherited.validDoList(actor, prep, iobj) + visibleList(Me)) | |
| validDo(actor, obj, seqno) = | |
| (obj.isVisible(actor)) | |
| ; | |
| modify thing | |
| verMarry(obj) = | |
| "You have a very fertile imagination. " | |
| saybetrothed = { | |
| /* Necessary because adv.t doesn't have a sufficiently | |
| detailed grasp of grammatical cases. This could be | |
| simplified under WorldClass. */ | |
| if (self == Me) | |
| "You are already spoken for. "; | |
| else | |
| "\^<<self.thedesc>> is already spoken for. "; | |
| } | |
| verDoMarry(actor) = { | |
| /* Make sure they're not trying to marry themselves and | |
| that both parties are unmarried. */ | |
| if (actor == self) | |
| "That would be awfully narcissistic. "; | |
| else if (self.betrothed) | |
| self.saybetrothed; | |
| else if (actor.betrothed) | |
| actor.saybetrothed; | |
| } | |
| doMarry(actor) = { | |
| /* | |
| - "marry X" or "X, marry me." | |
| X gets to object first, then Me, then call X.marry(Me). | |
| - "X, marry Y." | |
| X gets to object first, then Y, then call X.marry(Y). | |
| */ | |
| local h, A, B; | |
| if (actor == Me) | |
| A = self, B = actor; | |
| else | |
| A = actor, B = self; | |
| h = outhide(true); | |
| A.verMarry(B); | |
| if (outhide(h)) { | |
| /* Output resulted, which means there's an objection; | |
| call it again and do no more. */ | |
| A.verMarry(B); | |
| } | |
| else { | |
| h = outhide(true); | |
| B.verMarry(A); | |
| if (outhide(h)) { | |
| /* Same drill as before. */ | |
| B.verMarry(A); | |
| } | |
| else | |
| A.marry(B); | |
| } | |
| } | |
| marry(d) = { | |
| self.betrothed = d; | |
| d.betrothed = self; | |
| self.saywillmarry(d); | |
| } | |
| saywillmarry(d) = { | |
| /* Again, could be simplified under WorldClass. */ | |
| if (d == Me) | |
| "\^<<self.thedesc>> consents to marry you. "; | |
| else { | |
| "\^<<self.thedesc>> consents to "; | |
| if ((d.isHim and self.isHim) or (d.isHer and self.isHer)) | |
| "enter into a domestic partnership with "; | |
| else "marry "; | |
| "<<d.thedesc>>. "; | |
| } | |
| } | |
| ; | |
| modify movableActor | |
| verMarry(d) = { | |
| "\^<<self.thedesc>> shows no interest in marriage. "; | |
| } | |
| actorAction(v, d, p, i) = { | |
| if (v == marryVerb) | |
| /* Let 'em try... */; | |
| else | |
| pass actorAction; | |
| } | |
| ; | |
Xet Storage Details
- Size:
- 7.83 kB
- Xet hash:
- 8e640c7430e846e312abd3618d444fa3b8b647691f974f660db65957ea844ece
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.