lsl scripts

73
Stefano Cacciaguerra Ph.D in Computer Science 1 Linden Script Language - LSL by Stefano Cacciaguerra

Upload: giovanna-sardo

Post on 26-May-2015

415 views

Category:

Technology


28 download

TRANSCRIPT

Page 1: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 1

Linden Script Language - LSL

by

Stefano Cacciaguerra

Page 2: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 2

Outline

I. Basic Script Concept

II. Constants, Variables and Data Type

III. Flow-Control Statement

IV. States

V. Functions

VI. Events Handler

VII. Tutorial

Page 3: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 3

I. What is LSL?

LSL is language used to attach behaviors to the objects

It has syntax similar to Java, with an implicit state machine

for every script.

Multiple scripts may also be attached to the same object,

allowing a style of small, single-function scripts to evolve.

This leads to scripts that perform specific functions and

allows them to be combined to form new behaviors.

Page 4: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 4

What is LSL?

The script is compiled into an executable byte code.

This byte code is then run within a virtual machine on the

simulator.

Each script receives a time slice of the total simulator time

allocated to scripts in order to guarantee fairness.

Each script executes within its own chunk of memory,

preventing scripts from writing into other protected memory.

Page 5: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 5

Creating the Hello ScriptCreating the Hello ScriptCreating the Hello ScriptCreating the Hello Script

default

{

state_entry()

{

llSay(0, "Hello, Avatar!");

}

touch_start(integer total_number)

{

llSay(0, "Touched.");

}

}

This script says “Hello, Avatar!” when it enters

some state, and it says

“Touched.” when it is touched.

Page 6: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 6

Default StateDefault StateDefault StateDefault State

default

{

...

}

All scripts have a simple implicit state machine with one

or more states.

They must have a default state. When a script is first

started or reset, it will start out in the default state.

Page 7: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 7

Default StateDefault StateDefault StateDefault State

Every time you enter a state, the script engine calls the

state_entry() event and execute the code found there.

On state exit, the script engine calls the state_exit() event.

In our example, we call the llSay() function in state_entry().

The state entry and exit handlers are a convenient place to

initialize state data and clean up state specific data.

Page 8: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 8

FunctionsFunctionsFunctionsFunctions

The language has over 200 built in functions which allow

scripts and objects to interact with their environment.

All of the built in functions start with 'll'.

The example calls the llSay() function twice, which is used

to emit text on the specified channel.

llSay( integer channel, string text );

Page 9: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 9

FunctionsFunctionsFunctionsFunctions

llSay( integer channel, string text );

Say text on channel.

Channel 0 is the public chat channel that all avatars see as

chat text.

Channels 1 to 2,147,483,648 are private channels that

are not sent to avatars but other scripts can listen for.

Page 10: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 10

Touch EventTouch EventTouch EventTouch Event

touch_start(integer total_number)

{

llSay(0, "Touched.");

}

There are many events that can be detected in your scripts

by declaring a handler.

The touch_start() event is raised when a user touches the

object through the user interface.

Page 11: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 11

SaveSaveSaveSave

Save the script by clicking on Save.

During the saving process, the editor will

• save the text of the script

• compile the script into bytecode

• and then save that.

When you see message “Compile successful!” in the

preview window, you know the compile and save is done.

Page 12: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 12

Test the scriptTest the scriptTest the scriptTest the script

Apply it to an object in the world.

Create a new object in the world by context clicking in the

main world view and selecting Create.

Create a simple primitive by clicking in the world.

Once the object appears, you can drag your newly created

script onto the object to start the script.

Soon, you will see the message Object: Hello Avatar!

Page 13: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 13

II. CommentsII. CommentsII. CommentsII. Comments

Comment your scripts:

• at the start of the script to explain the purpose of the script

• before every global variable to describe what it holds

• before every global function to describe what it does

• wherever the code solves a specific problem.

LSL uses Java/C++ style single line comments.

// This script toggles a the rotation of an object

Page 14: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 14

ExampleExampleExampleExample

// g_is_rotating stores the current state of rotation. TRUE is rotating else FALSE.

integer g_is_rotating = FALSE;

default

{ // toggle state during the touch handler

touch(integer num)

{

if(g_is_rotating)

{ // turn off rotation

llTargetOmega(<0,0,1>, 0, 0);

g_is_rotating = FALSE;

}

else

{ // rotate around the positive z axis - up.

llTargetOmega(<0,0,1>, 4, 1);

g_is_rotating = TRUE;

}

}

}

Page 15: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 15

Arithmetic OperationsArithmetic OperationsArithmetic OperationsArithmetic Operations

Assignment '='

equality '=='

inequality '!=‘

// variables to hold a information about the target

key g_target;

vector g_target_postion;

float g_target_distance;

// function that demonstrates assignment

set_globals(key target, vector pos)

{

g_target = target;

g_target_position = pos;

// assignment from the return value of a function

vector my_pos = llGetPos();

g_target_distance = llVecDist(g_target_position, my_pos);

}

Page 16: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 16

Hexadecimal EntryHexadecimal EntryHexadecimal EntryHexadecimal Entry

Integers may be entered in hex form (e.g. 0xffff) starting it

with “0x”:

integer Mask = 0xff; // Equivalent to integer Mask = 255

integer Bit = 0x0100; // Equivalent to integer Mask = 256

Page 17: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 17

Binary Arithmetic OperatorsBinary Arithmetic OperatorsBinary Arithmetic OperatorsBinary Arithmetic Operators

Increment and Decrement++ and --

Shift Right>>

Division/

Modulo (remainder)%

Exclusive OR^

Multiplication*

Shift Left<<

Subtraction-

Addition+

MeaningOperator

Page 18: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 18

Boolean OperatorsBoolean OperatorsBoolean OperatorsBoolean Operators

True if the LX is greater than or equal to the DX>=

True if the LX and DX hand side are both true&&

Operator returns True if either the LX or DX are True||

True if the LX is less than or equal to the DX<=

Unary operator returns the logical negation of the

expression to the DX!

True if the LX is greater than the DX>

True if the LX is less than the DX<

Operator returnsOperator

Page 19: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 19

Bitwise OperatorsBitwise OperatorsBitwise OperatorsBitwise Operators

Unary operator returns the bitwise complement ofthe expression to the DX.~

Returns the bitwise or of the LX and DX.|

Returns the bitwise and of the LX and DX.&

Operator returnsOperator

A bitwise operation operates on one or two bit patterns or

binary numerals at the level of their individual bits

integer mask = AGENT | SCRIPTED | ACTIVE;

Page 20: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 20

LSL TypesLSL TypesLSL TypesLSL Types

LSL provides a small set of basic types simple:

integer: A signed, 32-bit integer value with valid range from

-2147483648 to 2147483647.

float: An IEEE 32-bit floating point value with values ranging

from 1.175494351E-38 to 3.402823466E+38.

Page 21: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 21

Simple: KeySimple: KeySimple: KeySimple: Key

key: A unique identifier can be used to reference objects and

avatars in SL. Known as UUID (Universal Unique IDentifier).

The special constant NULL_KEY can be used to represent no

key, which is to say there is no object.

It is impossible for a script to change an item’s key

key nokey = NULL_KEY;

key owner = llGetOwner();

Page 22: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 22

Composite: VectorComposite: VectorComposite: VectorComposite: Vector

Vector cross product (vector product)%

Vector dot product (scalar product)*

Subtract one vector from another-

Add two vectors together+

Operator returnsOperator

vector: 3 floats that are used together as a single item. Each

component can be accessed via '.x', '.y', and '.z'.

ZERO_VECTOR is equal to <0.0, 0.0, 0.0>

Page 23: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 23

ExampleExampleExampleExample

vector p = llGetPos(); // Get the object’s position in the sim

v1= < x1, y1, z1> and v2= < x2, y2, z2>

v3 = v1 + v2 = <x1+x2, y1+y2, z1+z2> similarly for “–”

a1 = v1 * v2 = x1*x2 + y1*y2 + z1*z2

is the angle between v1 and v2

v5 = v1 % v2 = <y1z2 - z1y2, z1x2 - x1z2, x1y2 - y1x2>

is the vector perpendicular to both v1 and v2

v6 = a * v1 = <a*x1, a*y1, a*z1>

Page 24: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 24

Composite: RotationComposite: RotationComposite: RotationComposite: Rotation

Rotate the first rotation by the inverse of the second/

Rotate the first rotation by the second*

Subtract one rotation from another-

Add two rotations together+

MeaningOperator

rotation: A quaternion, 4 floats that are used together as a

single item to represent a rotation. Each component can be

accessed via '.x', '.y', and '.z' and '.s'.

Page 25: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 25

ExampleExampleExampleExample

Rotation zero = ZERO_ROTATION

zero= <0.0, 0.0, 0.0, 1.0> // to represent no rotation

vector r = llGetRot(); // Get the object’s rotation

Page 26: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 26

Composite: ListComposite: ListComposite: ListComposite: List

list: A heterogeneous list of the other data types. Lists are

created via comma separated values of the other data types

enclosed by '[' and ']'. The empty list is represente by []

string StringVar = "Hello, Carbon Unit";

rotation ZERO_ROTATION = <0,0,0,1>;

list MyList = [ 1234, ZERO_ROTATION, StringVar ];

=> [ 1234, <0,0,0,1>, "Hello, Carbon Unit" ]

Page 27: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 27

ExamplesExamplesExamplesExamples

MyList = 3.14159 + MyList;

=> [ 3.14159, 1234, <0,0,0,1>, "Hello, Carbon Unit" ]

MyList = MyList + MyList;

=> [ 3.14159, 1234, <0,0,0,1>, "Hello, Carbon Unit", 3.14159, 1234, <0,0,0,1>, "Hello, Carbon Unit" ]

Page 28: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 28

Accessing Item Inside a ListAccessing Item Inside a ListAccessing Item Inside a ListAccessing Item Inside a List

Items are accessed by llList2Integer, llList2String, llList2Float

and so on.

Items in the lists are indexed starting at 0

list clothes = [“shirt”, “hat”, “coat”, “pants”, “socks”]

string s;

s = llList2String(clothes, 0) // s is the shirt

s = llList2String(clothes, 4) // s is the coat

Page 29: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 29

Accessing Item Inside a ListAccessing Item Inside a ListAccessing Item Inside a ListAccessing Item Inside a List

Lists are immutables, once created the value in the list is not

possible to change it.

It is possible to build a new list with llList2List. It takes three

arguments the list, a start index and an end index

list clothes = [“shirt”, “hat”, “coat”, “pants”, “socks”]

clothes = llList2List(clothes, 0, 0) + [“belt”] + llList2List(clothes, 2, 4)

clothes = [“shirt”, “belt”, “coat”, “pants”, “socks”]

Page 30: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 30

Composite: StringComposite: StringComposite: StringComposite: String

Inequality!=

Equality==

Concatenation+

Operator returnsOperator

A string could hold text enclosed by '“' and '”'.

Page 31: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 31

Type ConversionType ConversionType ConversionType Conversion

implicit type casts:

• integer to float

• string to key.

explicit type casts:

• integer to string

• float to Integer

• float to string

• vector to string

• rotation to string

• Integer to List

• float to List

• Key to List

• string to List

• vector to List

• rotation to List

• string to Integer

• string to float

• string to vector

• string to rotation

Page 32: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 32

Global FunctionsGlobal FunctionsGlobal FunctionsGlobal Functions

Global functions are also declared much like Java/C, with the

exception that no 'void' return value exists:

make_physical_and_spin(vector torque)

{

// double the torque

vector double_torque = 2.0*torque;

llSetStatus(STATUS_PHYSICS, TRUE);

llApplyTorque(double_torque);

}

Page 33: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 33

Global VariablesGlobal VariablesGlobal VariablesGlobal Variables

Global variables and functions are accessible from anywhere

in the file. Only one declaration may be made per line:

vector gStartPosition;

Global variables may also be initialized if desired, although

uninitialized global and local variables are initialized to legal

zero values:

vector gStartPosition = <10.0,10.0,10.0>

Page 34: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 34

Local VariablesLocal VariablesLocal VariablesLocal Variables

Local variables are scoped below their declaration within

the block of code they are declared in

Local variables may be declared within any block of code.

Page 35: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 35

Local VariablesLocal VariablesLocal VariablesLocal Variables

integer test_function()

{

// Test vector that we can use anywhere in the function

vector test = <1,2,3>;

integer j;

for (j = 0; j < 10; j++)

{

// This vector is a different variable than the one declared above

// This IS NOT good coding practice

vector test = <j, j, j>;

}

// this test fails

if (test == <9,9,9>)

{ // never reached}

}

Page 36: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 36

III. Conditional StatementsIII. Conditional StatementsIII. Conditional StatementsIII. Conditional Statements

The 'if' statement as the Java/C version.

check_message(string message)

{

if(message == "open")

{ open(); }

else if(message == "close")

{ close(); }

else

{ llSay(0, "Unknown command: " + message); }

}

Page 37: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 37

Conditional StatementsConditional StatementsConditional StatementsConditional Statements

The NULL_KEY constant counts as FALSE.

There can be zero or more 'else if' statements, and an

optional final 'else'.

The usual set of integer arithmetic and comparison operators .

// a function that accepts some information about its environment and

// determines the 'best' next step. This kind of code might be

// part of a simple box meant to move close to an agent and attach to

// them once near. This code sample relies on the standard linden

// library functions as well as two other methods not defined here.

Page 38: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 38

Conditional StatementsConditional StatementsConditional StatementsConditional Statements

assess_next_step(integer perm, integer attached, integer balance, float dist)

{

string msg;

if(!attached)

{

if((perm & PERMISSION_ATTACH) && (dist < 10.0))

{ attach(); }

else if((dist > 10.0) || ((dist > 20.0) && (balance > 1000)))

{ move_closer(); }

else

{ llRequestPermissions(llGetOwner(), PERMISSION_ATTACH); }

}

}

Page 39: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 39

for loopfor loopfor loopfor loop

A for loop is most useful for when you know how many times

you need to iterate over an operation.

Just like a Java or C for loop, the parentheses have three parts:

• the initializer,

• the continuation condition,

• and the increment.

The loop continues while the middle term evaluates to true, and

the increment step is performed at the end of every loop.

Page 40: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 40

for loopfor loopfor loopfor loop

// move a non-physical block smoothly upward (positive z) the total

// distance specified divided into steps discrete moves.

move_up(float distance, integer steps)

{

float step_distance = distance / (float)steps;

vector offset = <0.0, 0.0, step_distance>;

vector base_pos = llGetPos();

integer i;

for(i = 0; i <= steps; ++i)

{

llSetPos(base_pos + i * offset);

llSleep(0.1);

}

}

Page 41: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 41

dodododo----while loopwhile loopwhile loopwhile loop

The do-while loop construct is most useful when you are sure

that you want to perform an operation at least once, but you are

not sure how many times you want to loop.

The syntax is the same as Java and C program.

A simple English translation would be 'do the code inside the

curly braces and continue doing it if the statement after the

while is true.

// output the name of all inventory items attached to this object

Page 42: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 42

dodododo----while loopwhile loopwhile loopwhile loop

talk_about_inventory(integer type)

{

string name;

integer i = 0;

integer continue = TRUE;

do

{

name = llGetInventoryName(type, i);

if (llStringLength(name) > 0)

{ llSay(0, "Inventory " + (string)i + ": " + name); }

else

{ llSay(0, "No more inventory items");

continue = FALSE; }

i++;

} while(continue);

}

Page 43: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 43

while loopwhile loopwhile loopwhile loop

The while loop allows you to exit the loop without doing a single

iteration inside.

mention_inventory_type(integer type)

{

integer i = llGetInventoryNumber(type);

while(i--)

{

llSay(0, "item: " + llGetInventory(i));

}

}

Page 44: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 44

State ChangeState ChangeState ChangeState Change

State change allow you to move through the LSL virtual

machine's flexible state machine by transitioning your script

to and from user defined states and the default state.

You can define your own script state by placing the

keyword 'state' before its name and enclosing the event

handlers with open and close curly braces ('{' and '}'.)

Invoke the transition to a new state by calling it with the

syntax: 'state <statename>'.

Page 45: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 45

State ChangeState ChangeState ChangeState Change

default

{

state_entry()

{

llSay(0, "I am in the default state");

llSetTimer(1.0);

}

timer()

{

state SpinState;

}

}

Page 46: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 46

State ChangeState ChangeState ChangeState Change

state SpinState

{

state_entry()

{

llSay(0, "I am in SpinState!");

llTargetOmega(<0,0,1>, 4, 1.0);

llSetTimer(2.0);

}

timer()

{ state default; }

state_exit()

{ llTargetOmega(<0,0,1>, 0, 0.0); }

}

Page 47: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 47

IV. StatesIV. StatesIV. StatesIV. States

All scripts must have a 'default' state, which is the first state

entered when the script starts.

States contain event handlers that are triggered by the LSL

virtual machine.

All states must supply at least one event handler!

When state changes:

• all callback settings are retained

• and all pending events are cleared.

Page 48: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 48

state_entry()state_entry()state_entry()state_entry()

The state_entry event occurs whenever a new state is entered:

• including program start,

• and is always the first event handled.

No data is passed to this event handler.

Page 49: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 49

Warning: state_entry()Warning: state_entry()Warning: state_entry()Warning: state_entry()

It is a mistake to assume that the state_entry() callback is

called when you rez an object out of your inventory.

When you derez an object into your inventory the current

state of the script is saved, so there will not be a call to

state_entry() during the rez.

If you need to provide startup code every time an object is

created, you should create a global function and call it from

both state_entry() and the on_rez() callbacks.

Page 50: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 50

ExampleExampleExampleExample

// global initialization function.

init()

{

// Set up a listen callback for whoever owns this object.

key owner = llGetOwner();

llListen(0, "", owner, "");

}

Page 51: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 51

ExampleExampleExampleExample

default

{

state_entry()

{ init(); }

on_rez(integer start_param)

{ init(); }

listen(integer channel, string name, key id, string message)

{

llSay(0, "Hi " + name + "! You own me.");

}

}

Page 52: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 52

state_exitstate_exitstate_exitstate_exit()()()()

Provide a state_exit() if you need to clean up any events

requested in the current state, but do not expect in the next state

default

{

state_entry()

{ state TimerState;}

}

The state_exit() handler is not called when an object is being

deleted - all callbacks, handlers, sounds, etc, will be cleaned up

automatically for you.

Page 53: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 53

state_exitstate_exitstate_exitstate_exit()()()()

state TimerState

{

state_entry()

{ // set a timer event for 5 seconds in the future.

llSetTimerEvent(5.0); }

timer()

{ llSay(0, "timer");

state ListenState; }

state_exit()

{ // turn off future timer events.

llSetTimerEvent(0.0); }

}

Page 54: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 54

state_exitstate_exitstate_exitstate_exit()()()()

integer g_listen_control;

state ListenState

{

state_entry()

{ // listen for anything on the public channel

g_listen_control = llListen(0, "", NULL_KEY, ""); }

listen(integer channel, string name, key id, string message)

{ llSay(0, "listen");

state TimerState; }

state_exit()

{ // turn off the listener

llListenRemove(g_listen_control); }

}

Page 55: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 55

V. Math FunctionsV. Math FunctionsV. Math FunctionsV. Math Functions

llAtan2

llCeil

llCos

llAsin

llFabs

llFloor

llAcos

llAbs

Trigonometry

llSin

llSqrt

llTan

llRound

llPow

llFrand

Trigonometry

llVecNorm

llVecMag

llVecDist

Vector

llRot2Up

llRot2Left

llRot2Fwd

llEuler2Rot

llRot2Angle

llRot2Axis

llAxisAngle2Rot

llRot2Euler

llRotBetween

llAxes2Rot

llAngleBetween

Rotation

Page 56: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 56

String and List FunctionsString and List FunctionsString and List FunctionsString and List Functions

llStringToBase64

llToLower

llToUpper

llInsertString

llMD5String

llStringLength

llGetSubString

llSubStringIndex

llXorBase64Strings

llDeleteSubString

llBase64ToString

String

llList2Key

llList2List

llList2ListStrided

llGetListLength

llList2CSV

llList2Float

llGetListEntryType

llList2Integer

llList2Rot

llDeleteSubList

llCSV2List

List

llListInsertList

llListRandomize

llListSort

llListFindList

llParseString2List

llList2Vector

llList2String

List

Page 57: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 57

CommunicationCommunicationCommunicationCommunication

llSay

llShout

llWhisper

llListenRemove

llListenControl

llListen

In World

llInstantMessage

llGetNextEmail

llEmail

Messaging

Page 58: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 58

InventoryInventoryInventoryInventory FunctionsFunctionsFunctionsFunctions

llGetInventoryName

llGetInventoryType

llGetInventoryNumber

llGetInventoryKey

llGetInventoryPermMask

llGetInventoryCreator

llAllowInventoryDrop

Inventory

llRemoveInventory

llRequestInventoryData

llRezObject

llGiveInventoryList

llRezAtRoot

llGiveInventory

llGetNotecardLine

Inventory

Page 59: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 59

VI. Tutorial: The FortuneVI. Tutorial: The FortuneVI. Tutorial: The FortuneVI. Tutorial: The Fortune----

Telling Magic Answer BallTelling Magic Answer BallTelling Magic Answer BallTelling Magic Answer Ball

How about a bell that responds to yes or no questions

spoken on the public chat channel?

Versions:

I Picking a Random Answer

II Listening to Residents

III Cleaning up and Polishing

Page 60: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 60

Picking a Random Answer

It contains the bare minimum functionality: generating answer.

It has a global list of answers and a function that picks a

random entry from the list and returns it, on touched event

generation

Page 61: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 61

Provide a Random

Answer When Touched

// The global variable holding all the answers

list answers = [

// positive answers

"Yes.",

"It is certain.",

"All signs point to yes.",

"You may rely on it",

"Without a doubt.",

// negative answers

"No.",

"Absolutely not.",

"Doubtful.",

"Most assuredly not.",

"My sources say no.",

//non commital answers

"Outlook hazy.",

"Uncertain.",

"The answer is unknowable.",

"I'd better not tell you now.",

"Cannot predict that at this time."

];

Page 62: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 62

Provide a Random

Answer When Touched

// pick a random answer from the list of answers and return it

string generateAnswer()

{

// generate a random number between 0 and the length of the

// list (but not exactly the length of the list), then cast it

// to an integer. This will give us a random number betwen 0

// and the length of the list - 1.

integer answerIndex = (integer)llFrand(llGetListLength(answers));

// return the answerIndex'th item of the list answers

return llList2String(answers, answerIndex);

}

Page 63: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 63

Provide a Random

Answer When Touched

default

{

touch_start(integer total_number)

{

llOwnerSay(generateAnswer());

}

}

Page 64: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 64

Listening to Residents

It listens for messages on the public channel and generates

answers in response.

In the state_entry event, the script calls the built-in function

llListen and asks for a listen event to be raised whenever

there is a message spoken on channel 0.

In the listen event, the script uses the name parameter to

personalize its response.

Page 65: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 65

Provide a Random Personalized

Answer on the Public Channel

default

{

state_entry()

{

// listen on the public chat channel for any text from

// anyone or anything.

llListen(0, "", NULL_KEY, "");

}

listen(integer channel, string name, key id, string message)

{

// script heard something, answer

llSay(0, generateAnswer() + name);

}

}

Page 66: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 66

Cleaning up and Polishing

It adds two new global variables, a question prefix, and some

helpful instructions.

Two new functions:

• isQuestion � which will return true if it’s argument is a question directed at the script

• startsWith � a utility function that takes two arguments and return true if the first argument starts with the second.

• In this code we add a new touch_start event handler that displays the help text when the object is touched.

Page 67: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 67

Provide a Random Personalized

Answer on the Public Channel

// Script will only answer qestions prefixed by this string

string questionPrefix = "Magic Ball, ";

// provide these instructions with touched

// script will add the questionPrefix string to this string

string instructions = "Ask me a yes or no question starting with ";

// The global variable holding all the answers

list answers = [

];

Page 68: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 68

Provide a Random Personalized

Answer on the Public Channel

// return TRUE if str starts with prefix.

integer startsWith(string str, string prefix)

{

// get the substring of the string, from 0 to the length

// of the prefix, and compare this substring to prefix

return llGetSubString(str, 0, llStringLength(prefix) - 1) == prefix;

}

Page 69: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 69

Provide a Random Personalized

Answer on the Public Channel

// Return TRUE if candidate is a question, which is to say, if

// the candidate begins with the question prefix. This function

// is case-insensitive (it ignores differences between upper and

// lower case in the candidate and prefix)

integer isAQuestion(string candidate)

{

return startsWith(llToUpper(candidate), llToUpper(questionPrefix));

}

Page 70: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 70

Provide a Random Personalized

Answer on the Public Channel

default

{

state_entry()

{

// listen on the public chat channel for any text

// from anyone or anything.

llListen(0, "", NULL_KEY, "");

}

touch_start(integer total_number)

{

// provide instructions

llSay(0, instructions + "\"" + questionPrefix + "\"");

}

Page 71: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 71

Provide a Random Personalized

Answer on the Public Channel

listen(integer channel, string name, key id, string message)

{

// script heard something, if it's a question for

// this script, answer it.

if (isAQuestion(message))

{

llSay(0, generateAnswer() + name);

}

}

}

Page 72: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 72

Webgrafia

Linden Script Language Tutorial (2007).

http://xahlee.org/sl/ls.html

The Second Life LSL Portal (2008).http://wiki.secondlife.com/wiki/LSL_Portal

Kan-ed – Using the Linden Script language (2005)

http://www.kan-ed.org/second-life/using-LSL.html

Linden Scripting Language Guide (2008)

Help Dialog in SL Client: Scripting Language

Page 73: Lsl scripts

Stefano Cacciaguerra Ph.D in Computer Science 73

Bibliografia

“Creating your world:

the official guide to advanced content creation for Second Life”

By A. Weber, K. Rufer-Bach and R. Platel, Wiley editor