Skip to content

Module Dissection

Jasdac edited this page Mar 10, 2021 · 4 revisions

Let's go through the Attachment module as an example:

Header file Attachment.lsh

#ifndef __Attachment
#define __Attachment


#define AttachmentMethod$reqPerm 1			// void - Sent from LevelRepo to let the attachment know that it can now request permissions
#define AttachmentMethod$detach 2			// (str)name/"*" - Detaches one or all objects for the user

#define AttachmentEvt$onAttach 1			// (key)id - Raised when the object is attached. Saves some memory vs using #define ON_ATTACH

#define Attachment$reqPerm( target ) \
	runMethod(target, "Attachment", AttachmentMethod$reqPerm, [])
#define Attachment$detachAll( target ) \
	runMethod(target, "Attachment", AttachmentMethod$detach, "*")
#define Attachment$detach( name ) \
	runMethod(llGetOwner(), "Attachment", AttachmentMethod$detach, name)
#define Attachment$detachOmni( name ) \
	runOmniMethod("Attachment", AttachmentMethod$detach, name)

#define onAttachmentAttached( id ) \
	if( SENDER_SCRIPT IS "Attachment" AND EVENT_TYPE IS AttachmentEvt$onAttach ){ \
		key id = argKey(0);

#endif

Breakdown

#ifndef __Attachment
#define __Attachment

The first part is needed so you don't run into issues when including the file multiple times.

#define AttachmentMethod$reqPerm 1			// void - Sent from LevelRepo to let the attachment know that it can now request permissions
#define AttachmentMethod$detach 2			// (str)name/"*" - Detaches one or all objects for the user

Next we define methods for this module, and we write down what arguments they expect, and what they do. If a method doesn't expect an argument, you can just enter "void".

The definition should be structured as <ScriptName>Method$<methodName> <uniqueID>. ID should be a unique positive integer for this module. Usually you just increment the number as you add methods.

#define AttachmentEvt$onAttach 1			// (key)id - Raised when the object is attached. Saves some memory vs using #define ON_ATTACH

Next we define an event that this module can raise. It's similar to method definitions. The naming convention is: <ScriptName>Evt$<evtName> <uniqueID>. ID should be a positive integer for this module.

#define Attachment$reqPerm( target ) \
	runMethod(target, "Attachment", AttachmentMethod$reqPerm, [])
#define Attachment$detachAll( target ) \
	runMethod(target, "Attachment", AttachmentMethod$detach, "*")
#define Attachment$detach( name ) \
	runMethod(llGetOwner(), "Attachment", AttachmentMethod$detach, name)
#define Attachment$detachOmni( name ) \
	runOmniMethod("Attachment", AttachmentMethod$detach, name)

Next we make macro definitions for the methods. The backslash just means to continue the definition on the next line. But you could just as well ignore it and put the whole definition on one line.

The naming convention is <ScriptName>$<methodName>( <arg1>, <arg2...> ). This is just a quick way of allowing you to call for an example Attachment$detach( name ) instead of having to manually type out runMethod(llGetOwner(), "Attachment", AttachmentMethod$detach, name).

#define onAttachmentAttached( id ) \
	if( SENDER_SCRIPT IS "Attachment" AND EVENT_TYPE IS AttachmentEvt$onAttach ){ \
		key id = argKey(0);

Finally we create macros for the events. This allows us to use onAttachmentAttached( id ) ...code... end instead of typing out a long if statement in every script that should capture the event.

Package file Attachment.lsl

#define USE_STATE_ENTRY
#define USE_RUN_TIME_PERMISSIONS
#define USE_ATTACH
#define USE_TIMER
#include "ObstacleScript/index.lsl"

bool DETACH;

reqAttach(){
    LevelRepo$canAttach();
}


detach(){

	DETACH = TRUE;
	if( !llGetAttached() )
		llDie();
	else if( llGetPermissions()&PERMISSION_ATTACH )
		llDetachFromAvatar();
	else
		llRequestPermissions(llGetOwner(), PERMISSION_ATTACH);
		
}


#include "ObstacleScript/begin.lsl"



onStateEntry()
    
    Portal$scriptOnline();
    LevelRepo$attSpawned();
    if( !llGetAttached() && llGetStartParameter() ){
        
        reqAttach();
        setInterval("chk", 3);
		setInterval("och", 1);
        
    } 
    
end

onAttach( id )
	
	raiseEvent(AttachmentEvt$onAttach, id);

end

onRunTimePermissions( perm )
    
    if( perm & PERMISSION_ATTACH ){
        
		if( DETACH )
			llDetachFromAvatar();
		else{
			llAttachToAvatarTemp(0);
			unsetTimer("chk");
        }
    }

end

handleOwnerMethod( AttachmentMethod$reqPerm )

    llOwnerSay("@acceptpermission=add");
    llSleep(.2);
    llRequestPermissions(llGetOwner(), PERMISSION_ATTACH);

end

handleOwnerMethod( AttachmentMethod$detach )

	str targ = argStr(0);
	if( targ != llGetObjectName() && targ != "*" )
		return;
		
	detach();
		

end


handleTimer( "chk" )
    
    reqAttach();
    
end

// Checks that the object that rezzed us is still present
handleTimer( "och" )

	if( llKey2Name(mySpawner()) == "" )
		detach();
		
end

#include "ObstacleScript/end.lsl"

Breakdown

Clone this wiki locally