postures.t | documentation |
#charset "us-ascii" #include <tads.h> #include "advlite.h" /* * postures.t * * The POSTURES extension is intended for use with the adv3Lite library. It * adds handling to keep track of actor posture (standing, sitting or lying) * and for the enforcement of postures in relation to various kinsds of nested * room. * * VERSION 2 *. 16-Feb-25 * * Usage: include this extension after the adv3Lite library but before your * own game-specific files. This makes it possible to sit, stand and lie in * and on various things, with the posture being tracked. */ posturesID: ModuleID name = 'Postures' byline = 'by Eric Eve' htmlByline = 'by Eric Eve' version = '1' ; /* * The Posture class is used to define the various postures used in the * POSTURES EXTENSION. */ class Posture: object /* The participle (e.g. 'standing') relating to the posture. [POSTURES EXTENSION] */ participle = nil /* * The property of a potential container that must be true if the actor is * to be allowed to adopt this posture in that container (e.g. * &canStandInMe). [POSTURES EXTENSION] */ allowedInProp = nil /* * The property of a potential container that must be true if the actor is * to be allowed to adopt this posture on that container (e.g. * &canStandOnMe). [POSTURES EXTENSION] */ allowedOnProp = nil /* * The property of a potential container that contains the message to * display if we can't adopt this posture in it. [POSTURES EXTENSION] */ cannotInMsgProp = nil /* * The property of a potential container that contains the message to * display if we can't adopt this posture on it. [POSTURES EXTENSION] */ cannotOnMsgProp = nil /* * A method that returns true or nil according to whether an actor can * adopt this posture in/on obj, which depends on the contType of obj. * [POSTURES EXTENSION] */ canAdoptIn(obj) { local prop = obj.contType == In ? allowedInProp : allowedOnProp; return obj.(prop); } /* * The verb phrase (subject and verb) corresponding an action that * involves taking this posture. [POSTURES EXTENSION] */ verbPhrase = nil /* The action needed to bring an actor into this posture. */ action = nil ; /* The standing posture. [POSTURES EXTENSION] */ standing: Posture participle = BMsg(standing, 'standing') allowedOnProp = &canStandOnMe allowedInProp = &canStandInMe cannotInMsgProp = &cannotStandInMsg cannotOnMsgProp = &cannotStandOnMsg verbPhrase = BMsg(i stand, '{I} {stand}') action = Stand ; /* The sitting posture [POSTURES EXTENSION] */ sitting: Posture participle = BMsg(sitting, 'sitting') allowedOnProp = &canSitOnMe allowedInProp = &canSitInMe cannotInMsgProp = &cannotSitInMsg cannotOnMsgProp = &cannotSitOnMsg verbPhrase = BMsg(i sit, '{I} {sit}') action = Sit ; /* The lying posture {POSTURES EXTENSION] */ lying: Posture participle = BMsg(lying, 'lying') allowedOnProp = &canLieOnMe allowedInProp = &canLieInMe cannotInMsgProp = &cannotLieInMsg cannotOnMsgProp = &cannotLieOnMsg verbPhrase = BMsg(i lie, '{I} {lie}') action = Lie ; /* Modifications to Thing needed for the POSTURES EXTENSION. */ modify Thing /* * The posture currently adopted by this Thing. We define this on Thing * rather than Actor mainly because the player character can be a Thing, * but it could also use to describe the metaphorical posture of inanimate * objects (A rug lies on the floor, the jug sits on the rug, the tall * grandfather clock stands by the door). * [DEFINED IN POSTURES EXTENSION] */ posture = standing /* A description of our posture as a participle, e.g. 'standing' or 'sitting'. */ postureDesc = posture.participle /* * The posture that's adopted by default by an actor entering or boarding * this this. [DEFINED IN POSTURES EXTENSION] */ defaultPosture = standing /* By default we can't stand, sit or lie in anything. [POSTURES EXTENSION] */ canStandInMe = nil canSitInMe = nil canLieInMe = nil /* * Attempt to make this Thing adopt the posture pos (without changing * location). [DEFINED IN POSTURES EXTENSION] */ tryMakingPosture(pos) { /* * If my posture is already pos then there's nothing to do, except * display a message explaining the fact. */ if(posture == pos) DMsg(posture already adopted, '{I} {am} already {1}. ', pos.participle); /* * Otherwise, if I can adopt the posture pos in my location, do so and * report than I've done so. */ else if(pos.canAdoptIn(location)) { posture = pos; DMsg(okay adopt posture, 'Okay, {i} {am} {now} {1}. ', pos.participle); } /* * Otherwise display a message saying I can't adopt the posture pos in * my current location. */ else { local dobj = location; gMessageParams(dobj); local prop = contType == In ? &cannotInMsgProp : &cannotOnMsgProp; prop = pos.(prop); say(self.(prop)); } } /* The postures module changes the handling for a number of verbs */ /* * Modification for StandOn handling [DEFINED IN POSTURES EXTENSION] * If the actor is already on the dobj, we just try to change the actor's posture * to standing. Otherwise we first move the actor to the dobj and then change the * actor's posture to standing. */ dobjFor(StandOn) { remap = remapOn preCond = [touchObj, actorInStagingLocation] action() { /* * If the actor is already on the dobj, just try to change the * actor's posture to standing. */ if(gActor.location == self) gActor.tryMakingPosture(standing); else { /* Otherwise, move the actor into the dobj */ gActor.actionMoveInto(self); /* Then change the actor's posture to standing. */ gActor.posture = standing; } } report() { say(okayStandOnMsg); } } /* [DEFINED IN POSTURES EXTENSION] */ okayStandOnMsg = BMsg(okay stand on, '{I} {stand} on {1}. ', gActionListStr) /* * Modification for SitOn handling [DEFINED IN POSTURES EXTENSION] If the actor is already on * the dobj, we just try to change the actor's posture to sitting. Otherwise we first move the * actor to the dobj and then change the actor's posture to sitting. */ dobjFor(SitOn) { remap = remapOn preCond = [touchObj, actorInStagingLocation] action() { if(gActor.location == self) gActor.tryMakingPosture(sitting); else { gActor.actionMoveInto(self); gActor.posture = sitting; } } report() { say(okaySitOnMsg); } } /* [DEFINED IN POSTURES EXTENSION] */ okaySitOnMsg = BMsg(okay sit on, '{I} {sit} on {1}. ', gActionListStr) /* * Modification for LieOn handling [DEFINED IN POSTURES EXTENSION] * If the actor is already on the dobj, we just try to change the actor's posture * to lying. Otherwise we first move the actor to the dobj and then change the * actor's posture to lying. */ dobjFor(LieOn) { remap = remapOn preCond = [touchObj, actorInStagingLocation] action() { if(gActor.location == self) gActor.tryMakingPosture(lying); else { gActor.actionMoveInto(self); gActor.posture = lying; } } report() { say(okayLieOnMsg); } } /* [DEFINED IN POSTURES EXTENSION] */ okayLieOnMsg = BMsg(okay lie on, '{I} {lie} on {1}. ', gActionListStr) /* * If an actor Boards something, we need to know what posture the actor * ends up in; we use the new location's default posture. * [MODIFIED FOR POSTURES EXTENSION] */ dobjFor(Board) { action() { /* Carry out the inherited action */ inherited; /* * Change the actor's posture to the default posture for the * actor's new location. */ gActor.posture = gActor.location.defaultPosture; } report() { DMsg(okay get on posture, '{1} on {2}. ', gActor.posture.verbPhrase, gActionListStr); } } /* * If an actor gets off something, we need to know what posture the actor * ends up in. We use the new location's defaultPosture. [MODIFIED FOR POSTURES EXTENSION] */ dobjFor(GetOff) { action() { /* Carry out the inherited action. */ inherited; /* * Change the actor's posture to the default posture for the * actor's new location. */ gActor.posture = gActor.location.defaultPosture; } } /* * Common verify routine for standing, sitting or lying IN something, * where pos is the posture to be adopted. * [DEFINED IN POSTURES EXTENSION] */ verifyEnterPosture(pos) { /* First verify that the actor can enter me */ verifyDobjEnter(); /* * Get the property (e.g. &canStandInMe) that determines whether the * actor can adopt the posture pos in me */ local postureProp = pos.allowedInProp; /* * Get the property (e.g. &cannotStandInMsg) containing the message to * display is the actor can't adopt the posture pos in me. */ local failureProp = pos.cannotInMsgProp; /* * If the actor can't adopt the posture pos in me then rule out the * action as illogical. */ if(!self.(postureProp)) illogical(self.(failureProp)); } /* [MODIFIED FOR POSTURES EXTENSION] */ dobjFor(StandIn) { /* If I have a remapIn object, then remap this action to it. */ remap = remapIn /* * Before standing in something, the actor must be able to touch it, * and the actor must be in the appropriate staging location. */ preCond = [touchObj, actorInStagingLocation] verify() { /* Verify that the actor can enter me and stand in me */ verifyEnterPosture(standing); } action() { /* If the actor is already in me, try making the actor stand. */ if(gActor.location == self) gActor.tryMakingPosture(standing); /* Otherwise change location and posture */ else { /* Move the actor into me */ gActor.actionMoveInto(self); /* Change the actor's posture to standing. */ gActor.posture = standing; } } report() { say(okayStandInMsg); } } /* [MODIFIED FOR POSTURES EXTENSION] */ cannotStandInMsg = BMsg(cannot stand in, '{I} {can\'t} stand in {the dobj}. ') /* [MODIFIED FOR POSTURES EXTENSION] */ okayStandInMsg = BMsg(okay stand in, '{I} {stand} in {1}. ', gActionListStr) /* * SitIn is handled much like StandIn * [MODIFIED FOR POSTURES EXTENSION] */ dobjFor(SitIn) { remap = remapIn preCond = [touchObj, actorInStagingLocation] action() { if(gActor.location == self) gActor.tryMakingPosture(sitting); else { gActor.actionMoveInto(self); gActor.posture = sitting; } } report() { say(okaySitInMsg); } } /* [MODIFIED FOR POSTURES EXTENSION] */ okaySitInMsg = BMsg(okay sit in, '{I} {sit} in {1}. ', gActionListStr) /* [MODIFIED FOR POSTURES EXTENSION] */ cannotSitInMsg = BMsg(cannot sit in, '{I} {can\'t} sit in {the dobj}. ') /* * LieIn is handled much like StandIn * [MODIFIED FOR POSTURES EXTENSION] */ dobjFor(LieIn) { remap = remapOn preCond = [touchObj, actorInStagingLocation] action() { if(gActor.location == self) gActor.tryMakingPosture(lying); else { gActor.actionMoveInto(self); gActor.posture = lying; } } report() { say(okayLieInMsg); } } /* [MODIFIED FOR POSTURES EXTENSION] */ okayLieInMsg = BMsg(okay lie in, '{I} {lie} in {1}. ', gActionListStr) /* [MODIFIED FOR POSTURES EXTENSION] */ cannotLieInMsg = BMsg(cannot lie in, '{I} {can\'t} lie in {the dobj}. ') /* * When an actor enters something we need to determine what posture the * actor ends up in. * [MODIFIED FOR POSTURES EXTENSION] */ dobjFor(Enter) { action() { /* Carry out the inherited handling */ inherited; /* * Change the actor's posture to the default posture for the * actor's new location. */ gActor.posture = gActor.location.defaultPosture; } } /* * When an actor gets out of something we need to determine what posture * the actor ends up in. We use the new location's default posture. * [MODIFIED FOR POSTURES EXTENSION] */ dobjFor(GetOutOf) { action() { /* Carry out the inherited handling */ inherited; /* * Change the actor's posture to the default posture for the * actor's new location. */ gActor.posture = gActor.location.defaultPosture; } } /* * Include the actor's posture in the subheading (e.g. '(sitting on the * chair)') * [MODIFIED FOR POSTURES EXTENSION] */ roomSubhead(pov) { say(nestedLoc(pov)); } /* MODIFIED FOR POSTURES EXTENSION to include the actor's posture */ nestedLoc(actor) { return BMsg(actor nested location posture name, ' (<<actor.posture.participle>> <<actor.location.objInPrep>> <<actor.location.theName>>)'); } ; /* * Modifications to Room class for use with POSTURES EXTENSION. */ modify Room /* * By default we assume that an actor can sit, stand or lie in a room * [DEFINED IN POSTURES EXTENSION] */ canStandInMe = true canSitInMe = true canLieInMe = true /* * The name of the room as it appears in the status line. * [MODIFIED FOR POSTURES EXTENSION to include the actor's posture] */ statusName(actor) { local nestedLocDesc = ''; /* * If the actor is not directly in the room we add the actor's * immediate container in parentheses after the room name. */ if(!actor.location.ofKind(Room)) nestedLocDesc = nestedLoc(actor); /* * If the Room is illuminated, display its ordinary room title, * followed by the actor's immediate location if it's not the Room. If * the Room is in darkness, use the darkName instead of the roomTitle. */ if(isIlluminated) "<<roomTitle>><<nestedLocDesc>>"; else "<<darkName>><<nestedLocDesc>>"; } ; modify TravelConnector /* * The posture an actor needs to be in before travelling via this connector. This will * normally be standing, but this could be changed if, for example, the actor needs to crawl * through this connector. */ posture = standing /* Ensure the actor is in the posture needed to travel via this connector. */ setTravelPosture() { /* * If the actor is not in the correct posture, try executing the appropriate action to put * them in that posture. */ if(gActor.posture != posture) { tryImplicitAction(posture.action); // "<<buildImplicitActionAnnouncement(gActor.posture == posture, true)>>"; } /* Return true or nil according to whether the actor is now in the correct posture. */ return gActor.posture == posture; } ; /* * A Bed is something an actor can sit, stand or lie on, but is most likely to * lie on and least likely to stand on. [DEFINED IN POSTURES EXTENSION] */ class Bed: Platform lieOnScore = 120 standOnScore = 80 defaultPosture = lying ; /* * Chair is something an actor would normally sit on, but could also stand on, * but not lie on. [DEFINED IN POSTURES EXTENSION] */ class Chair: Platform canLieOnMe = nil sitOnScore = 120 standOnScore = 80 defaultPosture = sitting ; /* * By default we assume that an actor can stand, sit or lie in a Booth. This * can, of course, be overridden in particular instances. * [DEFINED IN POSTURES EXTENSION] */ modify Booth canStandInMe = true canSitInMe = true canLieInMe = true ; /* * We modify the Stand, Sit and Lie actions so that they now result in the * actor changing posture without changing location. * [MODIFIED IN POSTURES EXTENSION] */ modify Stand execAction(c) { gActor.tryMakingPosture(standing); } ; /* [MODIFIED IN POSTURES EXTENSION] */ modify Sit execAction(c) { gActor.tryMakingPosture(sitting); } ; /* [MODIFIED IN POSTURES EXTENSION] */ modify Lie execAction(c) { gActor.tryMakingPosture(lying); } ; actorInTravelPosture: PreCondition checkPreCondition(obj, allowImplicit) { if(obj.posture == requiredPosture) return true; if(allowImplicit && tryImplicitAction(requiredPosture.action)) return true; DMsg(not in posture to travel, '{I} need{s/ed} to be {1} first. ', requiredPosture.participle); return nil; } requiredPosture = standing preCondOrder = 80 ; modify TravelAction preCond = valToList(inherited) + actorInTravelPosture ; modify GoThrough // preCond = valToList(inherited) + actorInTravelPosture ; modify ClimbDown preCond = valToList(inherited) + actorInTravelPosture ; modify ClimbUp preCond = valToList(inherited) + actorInTravelPosture ; modify Door checkTravelBarriers(traveler) { if(traveler.ofKind(Actor) && !actorInTravelPosture.checkPreCondition(traveler, true)) return nil; return inherited(traveler); } ;
Adv3Lite Library Reference Manual
Generated on 26/02/2025 from adv3Lite version 2.2
Generated on 26/02/2025 from adv3Lite version 2.2