#charset "us-ascii"
#include <tads.h>
#include "advlite.h"
/*
* TIAACTION EXTENSION
*
* Adds the TIAAction class to adv3Lite
*
* A TIA Action is an action involving three objects: Direct Object, Indirect
* Object and Accessory Object
*/
tiaactionID: ModuleID
name = 'TIA Action'
byline = 'by Eric Eve'
htmlByline = 'by Eric Eve'
version = '1'
;
/*
* DEFINED IN TIAACTION EXTENSION. A TIAAction is one that has three objects
* (direct, indirect and indirect), such as PUT COIN IN SLOT WITH TWEEZERS.
*/
class TIAAction: TIAction
/* The current accessory object of this action. */
curAobj = nil
/* The various methods to call on the accessory object of this action. */
verAobjProp = nil
checkAobjProp = nil
actionAobjProp = nil
preCondAobjProp = nil
reportAobjProp = nil
/*
* A list of the accessory objects that this actually actually ends up
* acting on at the action stage. [TIAACTION EXTENSION]
*/
aoActionList = []
/* Reset the action variables to their initial state, including the accessory object. */
reset()
{
inherited;
curAobj = nil;
aoActionList = [];
}
/* execute this action, noting the accessory object in addition to the other two. */
execAction(cmd)
{
/*
* Note the current direct object of this command from the Command
* object.
*/
curDobj = cmd.dobj;
/*
* Note the current indirect object of this command from the Command
* object.
*/
curIobj = cmd.iobj;
/*
* Note the current accessory object of this command from the Command
* object.
*/
curAobj = cmd.acc;
/* Note all three objects as possible pronoun antecedents. [TIAACTION EXTENSION] */
notePronounAntecedent(curDobj, curIobj, curAobj);
/* execute the resolved action. */
execResolvedAction();
}
/*
* [TIAACTION EXTENSION]
* Carry out the check phase for this command on all three objects involved in the command.
*/
checkAction(cmd)
{
/*
* If we don't pass the check stage on both the iobj and the dobj's
* preconditions, then return nil to tell our caller we've failed this
* stage.
*/
if(!(checkPreCond(curIobj, preCondIobjProp)
&& checkPreCond(curDobj, preCondDobjProp)
&& checkPreCond(curAobj, preCondAobjProp)))
return nil;
/*
* Return the result of running the check phase on both the indirect
* and the direct objects.
*/
return check(curIobj, checkIobjProp) && check(curDobj, checkDobjProp)
&& check(curAobj, checkAobjProp);
}
/* Set all three resolved objects for this action. [TIAACTION EXTENSION] */
setResolvedObjects(dobj, iobj, aobj)
{
curDobj = dobj;
curIobj = iobj;
curAobj = aobj;
}
/*
* Test whether the direct, the indirect and the accessory objects for
* this action are in scope. [TIAACTION EXTENSION]
*/
resolvedObjectsInScope()
{
buildScopeList();
return scopeList.indexOf(curDobj) != nil
&& scopeList.indexOf(curIobj) != nil
&& scopeList.indexOf(curAobj) != nil;
}
/*
* Carry out the report phase for this action. If there's anything in the
* aoActionList and we're not an implicit action, call the report method
* on the indirect, then the indirect object and finally on the accessory
* object). Note that this method is called by
* the current Command object once its finished iterating over all the
* objects involved in the command. [TIAACTION EXTENSION]
*/
reportAction()
{
/*
* Carry out the inherited handling, which executes the report stage
* on the direct object.
*/
inherited;
/*
* If we're not an implicit action and there's something to report on,
* carry out the report stage on our indirect object.
*/
if(!isImplicit && aoActionList.length > 0)
curAobj.(reportAobjProp);
}
/* Get the message parameters relating to this action for all three objects. */
getMessageParam(objName)
{
switch(objName)
{
case 'aobj':
case 'acc':
/* return the current indirect object */
return curAobj;
default:
/* inherit default handling */
return inherited(objName);
}
}
/*
* Execute this action as a resolved action, that is once its direct,
* indirect and accessory objects are known. [TIAACTION EXTENSION]
*/
execResolvedAction()
{
try
{
/*
* If the indirect object was resolved first (before the direct
* object) then we run the verify stage on the indirect object
* first. If it fails, return nil to tell the caller it failed.
*/
if(resolveIobjFirst && !verifyObjRole(curIobj, IndirectObject))
return nil;
/*
* Run the verify routine on the direct object next. If it
* disallows the action, stop here and return nil.
*/
if(!verifyObjRole(curDobj, DirectObject))
return nil;
/*
* If the indirect object was resolved after the direct object,
* run the verify routines on the indirect object now, and return
* nil if they disallow the action.
*/
if(!resolveIobjFirst && !verifyObjRole(curIobj, IndirectObject))
return nil;
/*
* Run the verify routines on the accessory object and return nil if
* they disallow the action.
*/
if(!verifyObjRole(curAobj, AccessoryObject))
return nil;
/*
* If gameMain defines the option to run before notifications
* before the check stage, run the before notifications now.
*/
if(gameMain.beforeRunsBeforeCheck)
beforeAction();
/*
* Try the check stage on all three objects. If either disallows
* the action return nil to stop the action here.
*/
if(!checkAction(nil))
return nil;
/*
* If gameMain defines the option to run before notifications
* after the check stage, run the before notifications now.
*/
if(!gameMain.beforeRunsBeforeCheck)
beforeAction();
/* Carry out the action stage on one set of objects */
doActionOnce();
/* Return true to tell our caller the action was a success */
return true;
}
catch (ExitActionSignal ex)
{
actionFailed = true;
return nil;
}
}
/*
* Execute the action phase of the action on both objects. Note that
* although some TIAActions can operate on multiple direct objects, none
* defined in the library acts on multiple indirect objects, so there's
* only minimal support for the latter possibility. [TIAACTION EXTENSION]
*/
doActionOnce()
{
local msgForDobj, msgForIobj, msgForAobj;
/*
* If we're iterating over several objects and we're the kind of
* action which wants to announce objects in this context, do so.
*/
if(announceMultiAction && gCommand.dobjs.length > 1)
announceObject(curDobj);
/*
* Note that the current object we're dealing with is the direct
* object.
*/
curObj = curDobj;
/*
* If we're an implicit action add us to the list of implicit actions
* to be reported.
*/
if(isImplicit)
buildImplicitActionAnnouncement(true, nil);
try
{
/*
* Add the ImplicitActionFilter to the current output stream so
* that any pending implicit action reports are prepended to any
* action reports output at this stage.
*/
gOutStream.addOutputFilter(ImplicitActionFilter);
/*
* Run the action routine on the current direct object and capture
* the output for later use. If the output is null direct object
* can be added to the list of objects to be reported on at the
* report stage, provided the iobj action routine doesn't report
* anything either.
*
* NOTE TO SELF: Don't try making this work with captureOutput();
* it creates far more hassle than it's worth!!!!
*/
msgForDobj =
gOutStream.watchForOutput({:curDobj.(actionDobjProp)});
/* Note that we've acted on this direct object. */
actionList += curDobj;
/* Note that the current object is now the indirect object. */
curObj = curIobj;
/*
* Execute the action method on the indirect object. If it doesn't
* output anything, add the current indirect object to
* ioActionList in case the report phase wants to do anything with
* it, and add the dobj to the reportList if it's not already
* there so that a report method on the dobj can report on actions
* handled on the iobj.
*/
msgForIobj =
gOutStream.watchForOutput({:curIobj.(actionIobjProp)});
/* Note that the current object is now the indirect object. */
curObj = curAobj;
/*
* Execute the action method on the accessory object. If it
* doesn't output anything, add the current accessory object to
* aoActionList in case the report phase wants to do anything with
* it, and add the dobj to the reportList if it's not already
* there so that a report method on the dobj can report on actions
* handled on the iobj.
*/
msgForAobj =
gOutStream.watchForOutput({:curAobj.(actionAobjProp)});
}
finally
{
/* Remove any implicit action announcement from the output stream */
gOutStream.removeOutputFilter(ImplicitActionFilter);
}
/*
* If neither the action stage for the direct object nor the action
* stage for the direct object nor the action stage for the accessory
* obect produced any output then add the indirect and accessory
* objects to the list of indirect and accessory objects that could be
* reported on, and add the current direct object to the list of
* direct objects to be reported on at the report stage.
* [TIAACTION EXTENSION]
*/
if(!(msgForDobj) && !(msgForIobj) && !(msgForAobj))
{
ioActionList += curIobj;
aoActionList += curAobj;
reportList = reportList.appendUnique([curDobj]);
}
else if(!isImplicit)
{
/*
* Otherwise, if we're not an implicit action, clear out the
* implicit action reports which we should now have displayed.
*/
gCommand.implicitActionReports = [];
}
/*
* Return true to tell our caller we completed the action
* successfully.
*/
return true;
}
;
/*
* MODIFICATION TO THING FOR TIAACTION EXTENSION
*/
modify Thing
/* Defined on TIAAction extension. */
aobjFor(Default)
{
verify()
{
illogical(notImportantMsg);
}
}
;
Adv3Lite Library Reference Manual
Generated on 03/07/2024 from adv3Lite version 2.1