-
Notifications
You must be signed in to change notification settings - Fork 2
Obstacle Header File
There are multiple Asset (Obstacle) headers for different types of Assets. These reside in /headers/Obstacles. These are basically template files on how to interface with Assets, since they usually do so on their own channel for performance and flexibility reasons. If none of these standard headers fit your type of Asset, feel free to roll your own!
Let's take a look at how they're usually built. These are just best practice guidelines and you don't HAVE to use them. But I suggest doing so if you want other people to use your Assets in their own levels!
First off, let's look at the full header file:
#ifndef __Trap
#define __Trap
#define TrapConst$CHAN (OBSTACLE_CHAN+0x7) // Listener
#define TrapTask$seat 1 // (key)player
#define TrapTask$attack 2 //
#define TrapTask$unSeat 3 //
#define Trap$seat( targ, label, player ) \
llRegionSayTo(targ, TrapConst$CHAN, mkarr(label + TrapTask$seat + (player)))
#define Trap$attack( targ, label, args ) \
llRegionSayTo(targ, TrapConst$CHAN, mkarr(label + TrapTask$attack + args))
#define Trap$attackAll( label, args ) \
llRegionSay(TrapConst$CHAN, mkarr(label + TrapTask$attack + args))
// Level event bindings
#define LevelCustomType$TRAP "oTrap" // Generic type for traps like the lasher
#define LevelCustomEvt$TRAP$hit 1 // (key)player1, (key)player2... - Trap has hit a player
#define LevelCustomEvt$TRAP$seated 2 // (key)player1, (key)player2... - Trap has been sat on by one or more players
#define LevelCustomEvt$TRAP$unseated 3 // (key)player1, (key)player2... - Trap has been unsat by one or more players
#define onTrapHit( trap, players ) \
if( isEventLevelCustom() AND argStr(1) == LevelCustomType$TRAP AND argInt(2) == LevelCustomEvt$TRAP$hit ){ \
key trap = argKey(0); \
list players = llDeleteSubList(METHOD_ARGS, 0, 2);
#define onTrapSeated( trap, players ) \
if( isEventLevelCustom() AND argStr(1) == LevelCustomType$TRAP AND argInt(2) == LevelCustomEvt$TRAP$seated ){ \
key trap = argKey(0); \
list players = llDeleteSubList(METHOD_ARGS, 0, 2);
#define onTrapUnseated( trap, players ) \
if( isEventLevelCustom() AND argStr(1) == LevelCustomType$TRAP AND argInt(2) == LevelCustomEvt$TRAP$unseated ){ \
key trap = argKey(0); \
list players = llDeleteSubList(METHOD_ARGS, 0, 2);
// Useful templates
// Put this into onTrapHit to auto seat a viable player when a trap is triggered
// Auto seats with a filter function, the filter function is passed the arguments key trap, key player
#define _TRAPS_autoSeat(filterFunction){ \
\
players = llListRandomize(players, 1); \
integer i; \
for(; i < count(players); ++i ){ \
\
key p = l2k(players, i); \
if( ~llListFindList(PLAYERS, [(str)p]) ){ \
\
if( filterFunction(trap, p) ){ \
\
Trap$seat(trap, "*", p); \
i = count(players); \
\
} \
\
} \
\
} \
}
#endif
#ifndef __Trap
#define __Trap
Each header file should start with this, defining __ if not already defined. This is to prevent trying to include the script multiple times. C++ programmers will recognize this pattern.
#define TrapConst$CHAN (OBSTACLE_CHAN+0x7) // Listener
Defines the channel this obstacle type listens on. Usually OBSTACLE_CHAN plus some random number. Defined as <Script>Const$CHAN
#define TrapTask$seat 1 // (key)player
#define TrapTask$attack 2 //
#define TrapTask$unSeat 3 //
Defines tasks we can run on this Asset. Defined as <Script>Task$ and is usually an integer. These look similar to ObstacleScript methods, but are their own thing, since usually when you communicate with an Asset you just sent a JSON array on that type's channel with [id, task, arg1, arg2...] for performance reasons.
#define Trap$seat( targ, label, player ) \
llRegionSayTo(targ, TrapConst$CHAN, mkarr(label + TrapTask$seat + (player)))
...
Creates some macros. As stated before, these actions are usually sent as simple JSON arrays.
// Level event bindings
#define LevelCustomType$TRAP "oTrap" // Generic type for traps like the lasher
#define LevelCustomEvt$TRAP$hit 1 // (key)player1, (key)player2... - Trap has hit a player
#define LevelCustomEvt$TRAP$seated 2 // (key)player1, (key)player2... - Trap has been sat on by one or more players
#define LevelCustomEvt$TRAP$unseated 3 // (key)player1, (key)player2... - Trap has been unsat by one or more players
Next we define event bindings if this Asset should raise events on the Game Controller.
- LevelCustomType$TRAP - This is the custom event type that's raised, so we know what Asset type raised the event. It should be defined as
LevelCustomType$<SCRIPT> "o<Script>". The o stands for Obstacle, since there are other custom level events that aren't tied to obstacles. Such as water balloons. - LevelCustomEvt$TRAP$hit - This is the event id for our Asset type. Defined as
LevelCustomEvt$<SCRIPT>$<event> <index>. This way when we raise the event, the Game Controller can tell that the event was raised from a Trap, and the trap event was hit. You can define as many of these events as you want. Just make sure to use a unique index for each, and adding comments showing what data is passed alongside the event.