Programmatically Drop an Item

I have defined a wearable object that is attached by a cord, so if the player tries to move to another location I want to programmatically cause them to drop the item before navigating away. So far I haven’t found a way to do this. Is such a thing possible in TADS3?

Thank you in advance!

You can create a PreCondition and apply it to every connector from the room. Lower is an example of PreCondition enforcing that some object is not held and as a bonus second PreCondition enforcing the player to wear some other object. I’m using these to enforce the player to doff and drop spacesuit and wear shoes before proceeding to other rooms. The usage is shown at the end of example in connectorTravelPreCond():

[code]objNotHeld: PreCondition
checkPreCondition(obj, allowImplicit)
{
/* if the object isn’t being worn, we have nothing to do */
if (obj == nil || !obj.isIn(gActor))
return nil;

    /* try an implicit 'doff' command */
    if (allowImplicit && tryImplicitAction(Drop, obj))
    {
        /*
         *   we executed the command - make sure it worked, and abort
         *   if it didn't
         */
        if (obj.isIn(gActor))
            exit;

        /* tell the caller we executed an implicit command */
        return true;
    }

    /* report the problem and terminate the command */
    reportFailure('Tohle {nemůž[eš]|[jsi] nemohl[a]} udělat, dokud
        {kohoco obj} {drž[íš]|[jsi] držel[a]}. ');

    /* make it the pronoun */
    gActor.setPronounObj(obj);

    /* abort the command */
    exit;
}

/* lower the likelihood rating for anything being worn */
verifyPreCondition(obj)
{
    /* if the object is being worn, reduce its likelihood rating */
    if (obj != nil && obj.isIn(gActor))
        logicalRankOrd(80, 'implied drop', 150);
}

;

objWorn: PreCondition
checkPreCondition(obj, allowImplicit)
{
/* if the object is already held, there’s nothing we need to do */
if (gActor != me || obj == nil || obj.isWornBy(gActor))
return nil;

    /* the object isn't being held - try an implicit 'take' command */
    if (obj.isIn(gActor.getOutermostRoom()) && allowImplicit
        && obj.tryWearing())
    {
        /*
         *   we successfully executed the command; check to make sure
         *   it worked, and if not, abort the command without further
         *   comment (if the command failed, presumably the command
         *   showed an explanation as to why)
         */
        if (!obj.isWornBy(gActor))
            exit;

        /* tell the caller we executed an implicit command */
        return true;
    }

    /* it's not held and we can't take it - fail */
    reportFailure('Měl by sis obout boty, gravitace je tu nepatrná, ale mohl
        by sis při odrážení něco vrazit do chodidla. ', obj);

    /* make it the pronoun */
    gActor.setPronounObj(obj);

    /* abort the command */
    exit;
}

/* lower the likelihood rating for anything not being held */
verifyPreCondition(obj)
{
    /* if the object isn't being held, reduce its likelihood rating */
    if (obj != nil && !obj.isWornBy(gActor))
        logicalRankOrd(80, 'implied wear', 150);
}

;

/************************************/

Room
down = ladderDown
;

  • ladderDown: StairwayDown -> ladderUp ‘žebřík’ ‘žebřík’ *2
    "Lehký kovový žebřík zavěšený v průlezu v podlaze kupole, vede dolů do dolní
    chodby. "

    connectorTravelPreCond()
    {
    return inherited
    + new ObjectPreCondition(spaceSuit, objNotHeld)
    + new ObjectPreCondition(shoes, objWorn);
    }
    ;[/code]

Perfect! The isIn, and isWornBy are what I needed. Thank you so much for the example!