| #charset "Latin1" | |
| /* | |
| * Real NC Debug Actions Module, version 1.1 | |
| * Copyright (C) 2002, Nikos Chantziaras. | |
| * Comments and bug reports should be sent to: | |
| * realnc@lycos.de | |
| * | |
| * The copyright holder hereby grants the rights of usage, distribution | |
| * and modification of this software to everyone and for any purpose, as | |
| * long as this license and the copyright notice above are preserved and | |
| * not modified. There is no warranty for this software. By using, | |
| * distributing or modifying this software, you indicate that you accept | |
| * the terms and conditions of this license. | |
| */ | |
| /* | |
| * The documentation of this module is based on the documentation for | |
| * Neil K. Guy's and Neil deMause's "wizard.t" module for Tads 2. | |
| * Although this module is inspired by "wizard.t", no code from it is | |
| * used here, which is natural, since this is Tads 3 code. | |
| */ | |
| /* | |
| * Sometimes, when debugging an adventure, it's useful to have a small | |
| * set of special verbs that let you do things the player can't | |
| * ordinarily do. These shortcuts can be extremely useful in cutting | |
| * down test time, as they help you skip sections of a game that you | |
| * know are fine. Here are a few verbs that I've found quite helpful | |
| * for testing games. | |
| * | |
| * "Snarf" lets you pick up any takeable object, regardless of whether | |
| * it's visible and in scope or not. "Zarvo" reports on the location | |
| * of any specified object. "Pow" transports the player directly to | |
| * any location in the game. And "Mega" and "Unmega" turn the player | |
| * into a glowing superhuman, or revert the player to normal. | |
| * | |
| * To use this module, just compile it together with your game's source | |
| * file(s). Don't forget to compile for debugging (by using the | |
| * compiler's -d option). When you compile for release, the module | |
| * won't be included in your game. | |
| * | |
| * Implemented and tested with Tads v3.0.5 using a GNU/Linux system. | |
| */ | |
| /* | |
| Version history | |
| =============== | |
| 1.1 | |
| --- | |
| - None of the actions can now be directed to actors other than the | |
| player character. This is especially important for the pow action; | |
| pow would result in a run-time error if directed to an NPC. | |
| - Fixed the pow action. | |
| Powing to a location now calls the travelerLeaving() method of the | |
| current location and the travelerArriving() method of the | |
| destination. Also, the powing is done with moveIntoForTravel(), not | |
| with moveInto(). | |
| - Fixed the snarf action. | |
| The snarf action wasn't able to remove an object from a closed | |
| container if the player character and the container were both in the | |
| same location. | |
| - Intangible and Distant items are now allowed with pow and zarvo. | |
| - Fixed som stoopid end very embarasing dokumentation typoes and | |
| speling mistacles, althu meny ar steel thear. ;-) | |
| - Added version history. | |
| 1.0 | |
| --- | |
| - ??? | |
| */ | |
| #ifdef __DEBUG | |
| #include <adv3.h> | |
| #include <en_us.h> | |
| /* -------------------------------------------------------------------- | |
| * Snarf | |
| * | |
| * This verb lets you pick up any takeable item, even if it's not | |
| * accessible to you - say it's in a different room or inside a closed | |
| * container or whatever. | |
| * | |
| * I gave it the silly name "snarf" as "snarf" is not a verb I'm likely | |
| * to use in the actual game for anything. You can, of course, change | |
| * this to something more serious. | |
| * | |
| * Essentially, all this verb does is call the dobjFor(Take) handler. | |
| * The reason I have it do that instead of, say, moving the object | |
| * directly into the player's inventory, is because this way I can rely | |
| * on the standard Take checks to ensure that the player isn't trying | |
| * to pick up a fixed or decoration object or whatever. Also, the | |
| * player can't pick up more items than he or she normally can (unless | |
| * the "mega" verb has been used; see below.) | |
| * | |
| * However, "snarf" differs from the normal take verb in that instead | |
| * of checking to see if the object in question is in scope or not, it | |
| * simply lets you take any object that's anywhere in the game. It | |
| * does this by overriding the objInScope() method of TAction. Snarf | |
| * also doesn't care if the object is in a closed container. This is | |
| * done by modifying the checkMoveViaPath() method of Container. | |
| * Furthermore, the only preconditions for snarf are objNotWorn (the | |
| * object must not currently being worn) and roomToHoldObj (there must | |
| * be enough room for the object in the PC's inventory). | |
| */ | |
| DefineTAction(Snarf) | |
| // We want all objects to be in scope, so we always return true | |
| // here. | |
| objInScope( obj ) { return true; } | |
| execAction() | |
| { | |
| if (!gActor.isPlayerChar) { | |
| libMessages.systemActionToNPC(); | |
| exit; | |
| } | |
| inherited; | |
| } | |
| ; | |
| VerbRule(Snarf) | |
| 'snarf' dobjList | |
| : SnarfAction | |
| verbPhrase = 'snarf/snarfing (what)' | |
| ; | |
| modify Thing { | |
| dobjFor(Snarf) | |
| { | |
| // We do not require the object to be touchable to snarf it. | |
| // But we still require that it's not being worn, and that the | |
| // PC has enough room in his inventory to hold it. | |
| preCond = [objNotWorn, roomToHoldObj]; | |
| // Everything else works the same as with the Take action. | |
| verify() { verifyDobjTake(); } | |
| remap() { return remapDobjTake(); } | |
| check() { checkDobjTake(); } | |
| action() { actionDobjTake(); } | |
| } | |
| } | |
| modify Container { | |
| // checkMoveViaPath() is defined in the Thing class, but the | |
| // Container class overrides this method to check if the container | |
| // is closed and, if it is, disallows the action. Since snarf must | |
| // be able to take objects even from closed containers, we need to | |
| // modify this method. | |
| checkMoveViaPath( obj, dest, op ) | |
| { | |
| // Allow the operation if the current action is snarf. | |
| if (gActionIs(Snarf)) return checkStatusSuccess; | |
| // Otherwise, do whatever was the default. | |
| return inherited(obj, dest, op); | |
| } | |
| } | |
| /* -------------------------------------------------------------------- | |
| * Zarvo | |
| * | |
| * Another useful verb with a silly name. Zarvo lets you find an | |
| * object anywhere in the game without touching it. Zarvoing an object | |
| * simply prints that object's current location's `name' property. | |
| */ | |
| DefineTAction(Zarvo) | |
| objInScope( obj ) { return true; } | |
| execAction() | |
| { | |
| if (!gActor.isPlayerChar) { | |
| libMessages.systemActionToNPC(); | |
| exit; | |
| } | |
| inherited; | |
| } | |
| ; | |
| VerbRule(Zarvo) | |
| ('zarvo' | 'v') dobjList | |
| : ZarvoAction | |
| verbPhrase = 'zarvo/zarvoing (what)' | |
| ; | |
| modify Thing { | |
| dobjFor(Zarvo) | |
| { | |
| preCond = []; | |
| verify() {} | |
| check() {} | |
| action() | |
| { | |
| "\^<<self.theName>> <<self.verbToBe>> "; | |
| if (!self.location) { | |
| "floating around in the nil outer space. "; | |
| } else { | |
| "in the location called <q><<self.location.name>></q>. "; | |
| } | |
| } | |
| } | |
| } | |
| /* We want Decoration, Intangible and Distant items to work with zarvo, | |
| * so we also define dobjFor(Zarvo) handlers for them. | |
| */ | |
| modify Decoration { | |
| dobjFor(Zarvo) | |
| { | |
| // Just do what we defined in Thing. | |
| preCond() { return inherited; } | |
| verify() { inherited; } | |
| check() { inherited; } | |
| action() { inherited; } | |
| } | |
| } | |
| modify Intangible { | |
| dobjFor(Zarvo) | |
| { | |
| preCond() { return inherited; } | |
| verify() { inherited; } | |
| check() { inherited; } | |
| action() { inherited; } | |
| } | |
| } | |
| modify Distant { | |
| dobjFor(Zarvo) | |
| { | |
| preCond() { return inherited; } | |
| verify() { inherited; } | |
| check() { inherited; } | |
| action() { inherited; } | |
| } | |
| } | |
| /* -------------------------------------------------------------------- | |
| * Pow | |
| * | |
| * This is a particularly useful verb when testing that zaps you | |
| * directly to a specific location as though you'd teleported there. | |
| * Saves a lot of walking around. To use it, simply type "pow" | |
| * followed by the location to which you wish to pow, or by an object | |
| * that is contained either directly or indirectly in this location, so | |
| * that typing "pow item" for non-room objects will take you to that | |
| * object's location. This means that you can "pow" to any room with | |
| * at least one object in it, even if you haven't taken the step of | |
| * assigning nouns to your rooms. If the specified object is nested | |
| * inside multiple containers, we simply traverse the locations | |
| * upwards, until we find one that can contain actors. Only | |
| * BasicLocation objects can do that, so we simply pow the PC to the | |
| * first BasicLocation we found. | |
| * | |
| * We require that the player isn't seated (by specifying the | |
| * actorStanding precondition) to avoid problems. This means that the | |
| * PC will attempt to stand up before we pow him to the new location. | |
| * Then we transport them directly to the chosen location by using the | |
| * actor's moveInto() method. In homage to the classic "Adventure", we | |
| * surround the player with a nice orange cloud of smoke. | |
| * | |
| * There's one more time-consuming thing that you, as implementor, have | |
| * to do to be able to use this verb directly with rooms. And that is | |
| * you have to assign appropriate nouns and adjectives to each room you | |
| * want to be powable. If you don't, then the only way to pow to a | |
| * location is by using an item in that location as the direct object | |
| * of the verb. This can be a bit awkward, since interactive | |
| * disambiguation is sometimes impossible with some objects, most | |
| * probably with decoration and fixed objects ("Which door do you mean, | |
| * the door, the door, the door, or the door?"). | |
| * | |
| * So, how should you assign vocabulary words to your rooms? They | |
| * shouldn't be available in the release version of your game, only in | |
| * the debug version. Tads 3 defines the preprocessor symbol "__DEBUG" | |
| * when it compiles a game with debug information. You could simply | |
| * define a macro like this: | |
| * | |
| * #ifdef __DEBUG | |
| * #define dbgNoun(x) vocabWords_ = x | |
| * | |
| * #define dbgNoun(x) | |
| * #endif | |
| * | |
| * And assign nouns to your rooms like this: | |
| * | |
| * kitchen: Room { | |
| * 'Kitchen' 'the kitchen' | |
| * "You are not in front of a white house, but in the kitchen of a | |
| * yellow one. " | |
| * dbgNoun('kitchen-room'); | |
| * } | |
| * | |
| * Now you can pow to the kitchen like this: | |
| * | |
| * >POW KITCHEN-ROOM | |
| */ | |
| DefineTAction(Pow) | |
| objInScope( obj ) { return true; } | |
| execAction() | |
| { | |
| if (!gActor.isPlayerChar) { | |
| libMessages.systemActionToNPC(); | |
| exit; | |
| } | |
| inherited; | |
| } | |
| ; | |
| VerbRule(Pow) | |
| 'pow' singleDobj | 'pow' 'to' singleDobj | |
| : PowAction | |
| verbPhrase = 'pow/powing to (where)' | |
| ; | |
| modify Thing { | |
| dobjFor(Pow) | |
| { | |
| // We must be standing to be able to pow. | |
| preCond = [actorStanding]; | |
| verify() {} | |
| check() {} | |
| action() | |
| { | |
| // Destination. | |
| local dest = gDobj.ofKind(BasicLocation) ? gDobj : gDobj.location; | |
| // We do a "location rewind" until we find a location that | |
| // can contain actors. | |
| while (dest) { | |
| if (dest == gPlayerChar.location) { | |
| // The location we found is the same as the PC's | |
| // current location. No need to pow. | |
| "You are already there. "; | |
| return; | |
| } | |
| if (dest.ofKind(BasicLocation)) { | |
| // We found a BasicLocation. Let's pow there. | |
| "You are engulfed in a cloud of orange smoke. Coughing and gasping, you | |
| emerge from the smoke and find that your surroundings have changed... "; | |
| // Remember my original location - this is the | |
| // location where the PC was before he powed. | |
| local origin = gPlayerChar.location; | |
| // Tell the old room we're leaving. | |
| if (origin) origin.travelerLeaving(gPlayerChar, dest, nil); | |
| // Move to the destination. | |
| gPlayerChar.moveIntoForTravel(dest); | |
| // Tell the new room we're arriving, if we changed | |
| // locations. | |
| if (gPlayerChar.location) | |
| gPlayerChar.location.travelerArriving(gPlayerChar, origin, nil, nil); | |
| // We're done. | |
| return; | |
| } | |
| // One level up. | |
| dest = dest.location; | |
| } | |
| // We didn't find a BasicLocation. We can't pow. | |
| "I can't pow you there. "; | |
| } | |
| } | |
| } | |
| /* We want Decoration, Intangible and Distant items to work with pow, | |
| * so we also define dobjFor(Pow) handlers for them. | |
| */ | |
| modify Decoration { | |
| dobjFor(Pow) | |
| { | |
| preCond() { return inherited; } | |
| verify() { inherited; } | |
| check() { inherited; } | |
| action() { inherited; } | |
| } | |
| } | |
| modify Intangible { | |
| dobjFor(Pow) | |
| { | |
| preCond() { return inherited; } | |
| verify() { inherited; } | |
| check() { inherited; } | |
| action() { inherited; } | |
| } | |
| } | |
| modify Distant { | |
| dobjFor(Pow) | |
| { | |
| preCond() { return inherited; } | |
| verify() { inherited; } | |
| check() { inherited; } | |
| action() { inherited; } | |
| } | |
| } | |
| /* -------------------------------------------------------------------- | |
| * Mega | |
| * | |
| * Sometimes, in a game, you need to pick up and carry a whole plethora | |
| * of items, as the standard definition for the player character object | |
| * has set limits as to the number of objects (bulkCapacity), the | |
| * maximum bulk of any one object (maxSingleBulk) and the total weight | |
| * of objects (weightCapacity) the player can carry. This is obviously | |
| * important from both a realism standpoint and also a puzzle-making | |
| * one. However, it can be a total pain in the neck when testing. | |
| * | |
| * One of the features of the mega verb is that it increases the | |
| * strength and carrying ability of the player to superhuman levels. | |
| * Use the unmega command to restore the player to his or her normal | |
| * abilities. | |
| * | |
| * The other feature of the verb involves dark rooms. Sometimes, when | |
| * playing, it's a hassle to have to carry a torch or other light | |
| * source all the time. However, through the miracle of the mega verb, | |
| * the player can set him or herself literally glowing, thereby | |
| * obviating the light source problem. People who've played any of the | |
| * Infocom fantasies will recognize this as a kind of "frotz me" | |
| * command. Again, unmega makes the player normal once more. | |
| */ | |
| class MegaAction: IAction { | |
| // Is the PC currently in Mega mode? (Class property) | |
| playerIsMega = nil; | |
| // We save the old values so that we can restore them later with | |
| // the Unmega action. (Class properties) | |
| oldBulkCapacity = gPlayerChar.bulkCapacity; | |
| oldMaxSingleBulk = gPlayerChar.maxSingleBulk; | |
| oldWeightCapacity = gPlayerChar.weightCapacity; | |
| oldBrightness = gPlayerChar.brightness; | |
| execAction() | |
| { | |
| if (!gActor.isPlayerChar) { | |
| libMessages.systemActionToNPC(); | |
| exit; | |
| } | |
| if (MegaAction.playerIsMega) { | |
| "You are already imbued with superhuman abilities. "; | |
| } else { | |
| MegaAction.oldBulkCapacity = gPlayerChar.bulkCapacity; | |
| MegaAction.oldMaxSingleBulk = gPlayerChar.maxSingleBulk; | |
| MegaAction.oldWeightCapacity = gPlayerChar.weightCapacity; | |
| MegaAction.oldBrightness = gPlayerChar.brightness; | |
| gPlayerChar.bulkCapacity = 65535; | |
| gPlayerChar.maxSingleBulk = 65535; | |
| gPlayerChar.weightCapacity = 65535; | |
| gPlayerChar.brightness = 4; | |
| MegaAction.playerIsMega = true; | |
| "Phreeeow! You suddenly have superhuman strength, and you\'re surrounded by a | |
| strange ethereal glow which permits you to enter darkened places with impunity! "; | |
| } | |
| } | |
| } | |
| VerbRule(Mega) | |
| 'mega' | |
| : MegaAction | |
| verbPhrase = 'mega/transforming you to a glowing superhuman' | |
| ; | |
| /* -------------------------------------------------------------------- | |
| * Unmega | |
| * | |
| * Reverses the effects of Mega. | |
| */ | |
| class UnmegaAction: IAction { | |
| execAction() | |
| { | |
| if (!gActor.isPlayerChar) { | |
| libMessages.systemActionToNPC(); | |
| exit; | |
| } | |
| if (!MegaAction.playerIsMega) { | |
| "You\'re already a mere mortal! "; | |
| } else { | |
| gPlayerChar.bulkCapacity = MegaAction.oldBulkCapacity; | |
| gPlayerChar.maxSingleBulk = MegaAction.oldMaxSingleBulk; | |
| gPlayerChar.weightCapacity = MegaAction.oldWeightCapacity; | |
| gPlayerChar.brightness = MegaAction.oldBrightness; | |
| MegaAction.playerIsMega = nil; | |
| "Phreeeow! You\'re a puny human once more! You\'re also no longer doing that human | |
| lightbulb thing. "; | |
| } | |
| } | |
| } | |
| VerbRule(Unmega) | |
| 'unmega' | |
| : UnmegaAction | |
| VerbPhrase = 'unmega/transforming you to a puny human' | |
| ; | |
| #endif // __DEBUG | |
Xet Storage Details
- Size:
- 15.7 kB
- Xet hash:
- 44bbf5b959c53c6caadb445b87cd07d95553d75fd0f797445201c09f89726e8a
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.