Tut | Interaction - JasXSL/GoThongs GitHub Wiki

There are two ways of handling interactivity. I find the first one to be the easiest as it offloads most of the code to the _Main script. This makes it easier if you need to go in and change code later on. A good example of a direct scripted event is used in potions. So check out that tutorial as well.

Adding a key

Let's create a key. We name it "Key" and set the description to:

D$Take Key$$LVIN$KEY1

D$Take Key means the HUD popup description is "Take Key". LVIN$KEY1 means that when a player interacts with the object, an event will be raised in the _MAIN script.

We'll drop the got Portal script into the object since it's a spawnable asset. Then a generic got LocalConf.

/*

    The asset description should contain LVIN$ set
    Sub-prims can use description "ROOT" to automatically redirect interact to the root prim
    
*/
#define USE_EVENTS
#include "got/_core.lsl"

integer BFL;
#define BFL_INTERACTED 1

// Put code that should be run on interact success here
interactSuccess(){
    // If we've already ben interacted with, return just to make sure it doesn't interact multiple times
    if(BFL&BFL_INTERACTED)return;
    BFL = BFL|BFL_INTERACTED;
    
    // Trigger a key pickup sound    
    llTriggerSound("efd1d995-f589-0182-fc19-4d543886761d", 1);
    
    // Kill off the key
    llDie();
}

// Put code that should be run on interact failure here
interactFail(){
    
}


default
{
    // Just in case
    on_rez(integer mew){llResetScript();}
    
    // Limit memory use
    state_entry(){memLim(1.5);}
    
    // STDIN
    #include "xobj_core/_LM.lsl"
    
    // If we received an interaction method
    if(METHOD == LocalConfMethod$stdInteract){
        // Argument 1 is (bool)success
        if((integer)method_arg(1)){
            interactSuccess();
        }else{
            interactFail();
        }
    }
    #define LM_BOTTOM  
    #include "xobj_core/_LM.lsl"  
}

Let's pick up the key and drop it into the object's inventory.

Then let's say Spawn Key to spawn the key and position it, then add it as usual.

I'm going to add a flag to the top of the script called BFL_KEY_TAKEN which will be used later on when we add a door.

In the _MAIN script we go and look in the LevelEvt$interact event and check if the task was "KEY1" (remember from the description). We'll set the BFL_KEY_TAKEN flag and set success to TRUE. Success set to TRUE will cause the key localconf to run interactSuccess() which will play a sound and delete the key.

Adding the door

Let's make a door that can only be opened after we get the key. I'm going to use the double doors from the first stage. This is the script:

// Simple door script

#define USE_EVENTS
#include "got/_core.lsl"

// Prim for door A
integer A;
float A_WIDTH;
rotation A_ROT;
vector A_POS;

// Prim for door B
integer B;
float B_WIDTH;
rotation B_ROT;
vector B_POS;

// Flags
integer BFL;
#define BFL_OPENED 1
// Opens the door
open(){
    if(BFL&BFL_OPENED)return;
    BFL = BFL|BFL_OPENED;
    llTriggerSound("bf15bedf-2ed1-37d1-b73c-869f367f680b", 1);
    rotation r = A_ROT*llEuler2Rot(<0,0,PI_BY_TWO>);
    rotation r2 = B_ROT/llEuler2Rot(<0,0,PI_BY_TWO>);
    llSetLinkPrimitiveParams(A, [
        PRIM_POS_LOCAL, A_POS-llRot2Fwd(A_ROT)*(A_WIDTH/2)+llRot2Fwd(r)*(A_WIDTH/2),
        PRIM_ROT_LOCAL, r,
        PRIM_LINK_TARGET, B,
        PRIM_POS_LOCAL, B_POS+llRot2Fwd(B_ROT)*(B_WIDTH/2)-llRot2Fwd(r2)*(B_WIDTH/2),
        PRIM_ROT_LOCAL, r2
    ]);
}

default
{
    on_rez(integer mew){llResetScript();}
    state_entry()
    {
        // Get door parameters. You can write your own door script here. It's just standard rotations and stuff.
        memLim(1.5);
        
        links_each(nr, name, 
            if(name == "A")A = nr;
            else if(name == "B")B = nr;
        )
        list pp = llGetLinkPrimitiveParams(A, [PRIM_POS_LOCAL, PRIM_ROT_LOCAL, PRIM_SIZE]);
        vector v = llList2Vector(pp, 2);
        A_WIDTH = v.x;
        A_ROT = llList2Rot(pp, 1);
        A_POS = llList2Vector(pp, 0);
        
        pp = llGetLinkPrimitiveParams(B, [PRIM_POS_LOCAL, PRIM_ROT_LOCAL, PRIM_SIZE]);
        v = llList2Vector(pp, 2);
        B_WIDTH = v.x;
        B_ROT = llList2Rot(pp, 1);
        B_POS = llList2Vector(pp, 0);
    }
    
    #include "xobj_core/_LM.lsl"
    
    // This method is sent from _MAIN
    if(METHOD == LocalConfMethod$stdInteract){
        // If the interact was successful, open the door
        if((integer)method_arg(1)){
            open();
        }
        // Otherwise play a door is locked sound
        else{
            llTriggerSound("e7d96215-60e2-584d-f526-0d783850425a", 1);
        }
    }
    #define LM_BOTTOM  
    #include "xobj_core/_LM.lsl"  
}

I name the door "Double Door". Make sure the door has a description like:

D$Door$$LVIN$DOOR1

After making your door script, just add it to the inventory of the level. Say "spawn Double Door", position it and add it as per usual.

Let's add the door to the _MAIN script:

Finally let's test play by live-spawning both assets.

⚠️ **GitHub.com Fallback** ⚠️