FANDOM


Four lever door puzzle

What it does

The PC may only open a door by activating 4 levers in correct sequence. If they get the sequence wrong then they receive a small punishment in the form of a lightning bolt (or effect of your choice) from each of the levers. Damage is applied dependant on the players level. For any lever in the sequence the player may activate or deactivate it safely.


Notes

In this example each of the scripts should be placed in the OnUsed slot of the levers. The lever tags should all be the same differentiated by a final integer - lever_01, lever_02 etc. Compile the INCLUDE file first, and I've found that if you change the INCLUDE file then you need to re-compile all of it's calling scripts for the change to take effect. The scripts for the levers are all basically the same, just the LocalInt on the PC changing for the position in the sequence. Thus the scripts are scalable for any number of levers.


The Script, part 1

#INCLUDE script

///////////////////////////
// reset_chst_lever 
///////////////////////////
void ResetChestLevers(object oPC)
{
    string sLeverTag = "ChestLever_0";
    string sLTag;
    object oChest, oLever;
    int i;
    int iLevel = 0;
    oChest = GetObjectByTag("KeyChest"); // chest or door to open
    // Calculate oPC's total level
    for(i=1; i<4; i++)
    {
         iLevel += GetLevelByPosition(i, oPC);
    }
    
    // Set the level of Damage dependent on oPC's total level
    effect oOuch = EffectDamage(2 * iLevel);
    
    // loop to set all levers to off and fire a beam at oPC - Also resets the levers on/off LocalInt
    for(i=1; i < 5; i++)
    {
        sLTag = sLeverTag + IntToString(i);
        oLever = GetObjectByTag(sLTag);
        
        AssignCommand(oLever, ActionPlayAnimation( ANIMATION_PLACEABLE_DEACTIVATE ));
        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_LIGHTNING, oLever, BODY_NODE_CHEST), oPC, 2.0);
        SetLocalInt(oLever, "Tripped", 0);
    }
    // set oPC LocalInt - so they have to restart - Apply dammage for getting it wrong
    SetLocalInt(oPC, "ChestLever", 0);
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, oOuch, oPC);
    // Area LocalInt to indicate state of chest/door
    SetLocalInt(GetArea(oPC), "ChestOpen", 0);
    // Finally - close the chest/door if its open
    if(GetIsOpen(oChest))
    {
        AssignCommand(oChest, ActionPlayAnimation(ANIMATION_PLACEABLE_CLOSE));
        SetLocked(oChest, TRUE);
    }
}


The Script, Part 2

Lever 1

///////////////////////////
//  use_chestlever1
///////////////////////////
#include "reset_chst_lever"
void main()
{
    object oPC = GetLastUsedBy();

        if (GetLocalInt(OBJECT_SELF,"Tripped") != 1)
        {
            AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_GET_MID, 1.0, 1.0));
            AssignCommand(OBJECT_SELF, ActionPlayAnimation(ANIMATION_PLACEABLE_ACTIVATE));
            if (GetLocalInt(oPC, "ChestLever") > 0)
            {
                ResetChestLevers(oPC);
                return;
            }
            SetLocalInt(OBJECT_SELF, "Tripped", 1);
            SetLocalInt(oPC, "ChestLever", 1);
        }
        else
        {
            AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_GET_MID, 1.0, 1.0));
            AssignCommand(OBJECT_SELF, ActionPlayAnimation( ANIMATION_PLACEABLE_DEACTIVATE ));
            if (GetLocalInt(oPC, "ChestLever") != 1)
            {
                ResetChestLevers(oPC);
                return;
            }
            SetLocalInt(OBJECT_SELF, "Tripped", 0);
            SetLocalInt(oPC, "ChestLever", 0);
        }
}

Lever 2

/////////////////////////////
// use_chestlever2
/////////////////////////////

#include "reset_chst_lever"
void main()
{
    object oPC = GetLastUsedBy();
        if (GetLocalInt(OBJECT_SELF,"Tripped") != 1)
        {
            AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_GET_MID, 1.0, 1.0));
            AssignCommand(OBJECT_SELF, ActionPlayAnimation(ANIMATION_PLACEABLE_ACTIVATE));
            if (GetLocalInt(oPC, "ChestLever") != 1)
            {
                ResetChestLevers(oPC);
                return;
            }
            SetLocalInt(OBJECT_SELF, "Tripped", 1);
            SetLocalInt(oPC, "ChestLever", 2);
        }
        else
        {
            AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_GET_MID, 1.0, 1.0));
            AssignCommand(OBJECT_SELF, ActionPlayAnimation( ANIMATION_PLACEABLE_DEACTIVATE ));
            if (GetLocalInt(oPC, "ChestLever") != 2)
            {
                ResetChestLevers(oPC);
                return;
            }
            SetLocalInt(OBJECT_SELF, "Tripped", 0);
            SetLocalInt(oPC, "ChestLever", 1);
        }
}

Lever 3

/////////////////////////////
// use_chestlever3
/////////////////////////////
#include "reset_chst_lever"
void main()
{
    object oPC = GetLastUsedBy();

        if (GetLocalInt(OBJECT_SELF,"Tripped") != 1)
        {
            AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_GET_MID, 1.0, 1.0));
            AssignCommand(OBJECT_SELF, ActionPlayAnimation(ANIMATION_PLACEABLE_ACTIVATE));
            if (GetLocalInt(oPC, "ChestLever") != 2)
            {
                ResetChestLevers(oPC);
                return;
            }
            SetLocalInt(OBJECT_SELF, "Tripped", 1);
            SetLocalInt(oPC, "ChestLever", 3);
        }
        else
        {
            AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_GET_MID, 1.0, 1.0));
            AssignCommand(OBJECT_SELF, ActionPlayAnimation( ANIMATION_PLACEABLE_DEACTIVATE ));
            if (GetLocalInt(oPC, "ChestLever") != 3)
            {
                ResetChestLevers(oPC);
                return;
            }
            SetLocalInt(OBJECT_SELF, "Tripped", 0);
            SetLocalInt(oPC, "ChestLever", 2);
        }
}

Lever 4

//////////////////////////
// use_chestlever 4
//////////////////////////
#include "reset_chst_lever"
void main()
{
    object oPC = GetLastUsedBy();
    object oChest = GetObjectByTag("KeyChest");

        if (GetLocalInt(OBJECT_SELF,"Tripped") != 1)
        {
            AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_GET_MID, 1.0, 1.0));
            AssignCommand(OBJECT_SELF, ActionPlayAnimation(ANIMATION_PLACEABLE_ACTIVATE));
            if (GetLocalInt(oPC, "ChestLever") != 3)
            {
                ResetChestLevers(oPC);
                return;
            }
            SetLocalInt(OBJECT_SELF, "Tripped", 1);
            SetLocalInt(oPC, "ChestLever", 4);
            // OPEN The Chest/Door Here
            SetLocked(oChest, FALSE);
            AssignCommand(oChest, ActionPlayAnimation(ANIMATION_PLACEABLE_OPEN));
            // Let the Area know the chest/door state
            SetLocalInt(GetArea(OBJECT_SELF), "ChestOpen", 1);
        }
        else
        {
            AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_GET_MID, 1.0, 1.0));
            AssignCommand(OBJECT_SELF, ActionPlayAnimation( ANIMATION_PLACEABLE_DEACTIVATE ));
            if (GetLocalInt(oPC, "ChestLever") != 4)
            {
                ResetChestLevers(oPC);
                return;
            }
            SetLocalInt(OBJECT_SELF, "Tripped", 0);
            SetLocalInt(oPC, "ChestLever", 3);
            // Close The Chest Here
            if(GetIsOpen(oChest))
            {
                AssignCommand(oChest, ActionPlayAnimation(ANIMATION_PLACEABLE_CLOSE));
                SetLocked(oChest, TRUE);
                // Let the Area know the chest/door state
                SetLocalInt(GetArea(OBJECT_SELF), "ChestOpen", 0);
            }
        }
}

Foot Note

The chest or door should be set to locked & require key to open. All objects should be set to plot. Oh, and the levers should NOT use the default initial setting but should be set to 'Deactivated'.

Feel free to cut, hack, plagarise or ignore at will.

Enjoy,

Mighty Blob

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.