Bound and gagged! Immobilizing PC and NPCs

Just went through a clumsy, drawn out exercise to implement immobilizing a character. Since it was a verb-by-verb slog, figured I’d ask if anyone else found a more elegant way than brute force. Or if not, offer it up to posterity to save time for someone later. The scenario is being tied up, and maybe gagged. Here is my code:

modify Actor
    gagged = nil
    immobilized = nil
    reachableWhileBound = []  // can override on instantiation or set programmatically
    cantMoveMsg = '{You/he} {are} unable to move and cannot.  '
    cantTalkMsg = '{You/he} {are} unable to speak and cannot.  '

    beforeAction() {
        if ((gActor == self) && immobilized) failCheckImmobilized();  
        if ((gActor == self) && gagged) failCheckGagged();
        inherited;
    }

    failCheckImmobilized() {
        //  these actions are ok, especially system actions
        //  see below for >EXAMINE
        //
        if ((!gActionIn(Again, Inventory, ListenTo, Look, Sleep, Smell, Wait, System, SenseImplicit))

        // conversation ok if only bound
        //
            && (!gActionIn(AskVague, TalkTo, TellVague, Yell, ConvTopicT, ConvI))

       // uncomment if want to be able to feel bindings or whatever
       // could add 'Untie' or other actions here also
       //
       //     && (!gActionIn(Feel) || (reachableWhileBound.indexOf(gDobj) == nil))

       // assuming inventory still on actor, and restraints prevent self examine
       // would need to make more elaborate if environment is complex
       //
            && (!gActionIs(Examine) || gDobj.isIn(self)))
                 failCheck(cantMoveMsg);
    }

    // prevent conversation if gagged
    //
    failCheckGagged() {
        if (gActionIn(AskVague, TalkTo, TellVague, Yell, ConvTopicT, ConvI))
             failCheck(cantTalkMsg);
    }

Obviously, would need to inventory game-specific verbs to add to lists as appropriate. This has been tested let’s say a medium amount, so hoping I’ve wrung out the corner cases.

6 Likes

Mine is minimal, but it’s the same idea teaming up beforeAction with gActionIn
My only thought about streamlining would be, if you were starting a game from scratch and planning on making lots of new verbs, you could tag those new Actions with a property failIfBound = true or something, so that the beforeAction routine can also check || gAction.failifBound, etc. rather than having to have a comprehensive list of verbs. But it’s probably not saving any coding, just maybe a little clearer to manage on a larger scale.
2¢ tossed…

2 Likes

Just what the doctor asks after the IFComp work…

my major WIP involves also, let’s call those “the sweetest of bounds and/or gagging”, and the full implementation of one of those sweet scene is at the top of the TODO list. JJ’s idea of catch-all routine filtering all action implying movement or talking during those sweet moments coupled with Zieg’s idea of a new action property (and modifies to library actions…) seems the right answer to my unusual coding problem.

Because I use a3Lite, the sweet moments are scenes, things can be even easier…

congrats to both:

[You have gained a place in the CREDITS]

Best regards from Italy,
dott. Piergiorgio.

4 Likes

I am delighted that within 12hrs of posting some work I did, SOMEONE MADE PORN OF IT. Right on pace, internet!

Lol, happy it was useful. It was verb-by-verb drudgery, glad my pain helped someone else save the time!

3 Likes

Tomorrow I’ll reply to you.

2 Likes

As promised, my reply.

I don’t like the caps part of the comment, but I recognise that the wording I have used can be construed as reference to a genre of erotica I’m absolutely not interested in it, hence the oversight in choice of words.

to put in explicit terms, what I refer is the bounds of a deep hug and the gag of a french kiss: Nothing porn, I think even in US perspective, IMVHO.

I’m still thinking how to explain the scene w/o spoilers, but for now let’s point that the entire narration is from an intimistic perspective in a context of a very unique situation whose require gradual knowledge and understanding of said situation. A situation in where, trust me, the lock in deep hugging & kissing makes sense, and IS a major puzzle.

Best regards from Italy,
dott. Piergiorgio.

4 Likes

Will reiterate my apology publicly. No offense intended. My wisecracks are SO much faster than my common sense. Your work is probably ALREADY more mature than me. :grimacing:

4 Likes

The way I’ve been approaching this general class of problem (situationally making large-scale changes to the allowed actions) is via a general “scene” system. Short version:

  • Create a global singleton as the scene controller, let’s call it sceneController
  • Modify the constructor for Action via something like:
     modify Action
             construct() {
                     inherited();
                     addBeforeAfterObj(sceneController);
             }
     ;
  • The scene controller gets a method for letting objects subscribe to notifications. When the controller’s beforeAction() and afterAction() methods are called, the controller goes through the subscriber list, calling a method (I use globalBeforeAction() and globalAfterAction) on the subscriber
  • I provide a class (BeforeAfterThing) whose instances get auto-subscribed at pre-init
  • I also have a scene class, with BeforeAfterThing as a mixin, whose globalBeforeAction() and globalAfterAction() methods first call a isActive() on the scene object, immediately returning if it’s not true. If it is true, then it calls sceneBeforeAction() or sceneAfterAction() as appropriate.

The individual scene instances can then implement whatever action-preempting behavior you need. For convenience I use two base classes: one that allows all actions except for those defined in a list, and one that blocks all actions except for those defined in a list. I’ve also got some generic action “classes” that can be checked for (sense actions, movement actions, and that kind of thing).

4 Likes

after the little divagation, jbg’s idea is somewhat similar to my ideas for a “dungeon master” discreetly steering the PC (and player) toward the “right spot”. That is, a concept similar to bounding and gagging the PC, but allowing more freedom of action along the path toward the right spot, somewhat replacing the GuidedTour NPC mechanism, missing in a3Lite.

Let’s say that the PC accrues knowledge until he realise a major, shocking, realisation and needs the classical “fresh air on a balcony”, where the real turning point start. Problem, the threshold can be fired in multiple locations, so using barriers is not only clumsy to code, but can lead to serious issues, up to and including the dreaded “unwinnable state”.

So the interesting problem is that not only that the PC is bound on a path with multiple entry points, also the player should be encouraged to follow it, not forced into it. (hence my calling “Dungeon Master”), tentatively an invisible NPC follower, with its appropriate reactBefore/reactAfter along the path.

of course, the “dungeon master” can handle bounding & gagging, but honestly, in the “sweet case” of hugging & kissing, I feel that I’m coding an interloper, not precisely an happy coding…

BTW, if bounding & gagging, whatever type, is a work tailored for ALAN 3 and library 220ß, whose not only has this:



EVENT tied_up
  "Suddenly you're interrupted. A couple of crooks enter the room,
   grab hold of you, push you into a chair, gag you and tie you
   into it tightly. You cannot move your arms or legs."
  MAKE my_game NOT attack.
  MAKE my_game NOT attack_with.
  MAKE my_game NOT bite.
  MAKE my_game NOT break.
  MAKE my_game NOT burn.
  MAKE my_game NOT burn_with.
  ...
END EVENT.

and has also even a very nifty “restricted level”, by far the best restricting actions of all IF language, bounding and gagging are implemented with exactly
one instruction:



EVENT tied_up
  "Suddenly your investigations are interrupted.
   A couple of crooks enter the room, grab hold of you, push
   you sitting on a chair and tie you into it tightly.
   You cannot move your arms or legs."
  SET restricted_level OF my_game TO 2. -- all action verbs will be disabled
  MAKE my_game rub.                     -- but 'rub' will work
END EVENT.

(cfr. Alan Standard Library v2.2.0 User’s Manual, ch. 18.3)

so, the ideal should be a contrib library implementing this restricted_level, or better, adding this to the optionals of adv3Lite…

Now, and JJ is allowed to wisecrack :wink: , if someone want really badly to code a BDSM AIF, s/he now know what IF language to use :smiley:

Best regrds from Italy,
dott. Piergiorgio.

2 Likes

I don’t know how relevant it is to everything that contributors to this thread might want to achieve, but it may be worth pointing out that adv3Lite defines an actorAction() method on the actor (normally the Player Character) which could be used to veto certain actions, for example:

actorAction()
{
        if(gActionIs(Jump))
        {
            "You are rooted to the spot." ;
            exit;
        }
 }
3 Likes

Adv3 also defines actorAction, which is in fact where I put my version of the code, rather than beforeAction… Off the top of my head I can’t think of a strong reason why they differ, other than that actorAction isn’t called till all scope objects run their beforeAction, in case that matters.

In my case I ended up using a beforeAction() and afterAction() approach because Action provides the addBeforeAfterObj() mechanism for adding objects to the action’s notification list independent of scope. And I use it to add a singleton (instead of adding individual actors directly) beause Action doesn’t provide a way of removing objects after they’ve been added via addBeforeAfterObj().

I considered just adding an Action.removeBeforeAfterObj() method (internally Action just keeps track of them in a Vector and there’s no fancy bookeeping). But I think I prefer breaking the elaborate situational logic out into its own thing. Mostly because most of the scene-like things I have are triggerable by either the player or NPCs. So baking it all into a method on Actor (or on a subclass) feels like something that would get out of hand.

2 Likes