Pages
LSL help: any question is fair game!
Saturday, November 27, 2010
Detecting A Name
touch_start(integer total_number)
{
llOwnerSay(llDetectedName(0));
}
In this example I put it in a touch event, but it could also go in a collision event. You can also set things to be run by the owner of the object only by using the following snippet. Anything between the brackets will be owner only:
if(llDetectedKey(0) == llGetOwner()){
}
Sunday, September 19, 2010
The Sigil Stone
I have been asked a few times about how this is done so I thought I'd do a blog post (I need more stuff to blog about anyway, merp). I'm sure you've probably seen this kind of effect before, it's mostly used with cartoon avatars, to give them that black drawn outline look. Here's how it's done.
First take the prim you want to use for the inside, then copy it and make it slightly larger than the inside prim. Make it as hollow as it can get, then texture the outside invisible, so you can see the inside, and retexture the inside of the hollow prim.
You can do this with sculptie prims too but it's done slightly differently since you can't make them hollow. Create the two prims in the same way, so that one is slightly larger than the other. This time, on the larger prim, go to the "object" tab in the build menu, and under the sculptie texture input, select "inside out".
Monday, August 16, 2010
Setting up your own Open Sim
Well, a few months ago I had tried this and became deeply, deeply frustrated. It seemed nothing I did was working, and the situation was hopeless, so I stopped trying to set up my own Open Sim on my local machine. Yesterday however someone asked me if I ever got it working, and I told them no, but maybe I could look into it again.
So I did. Only to find that my first google search and attempt at setting it up again were successful. I love when things work out :)
Here are the instructions that I followed :
http://arianeb.wordpress.com/2010/04/14/setting-up-a-simple-open-sim-sandbox-on-your-hard-drive/
Saturday, August 14, 2010
Allow Inventory Drop
If it's set to true, anyone can drop inventory in, any object type except for scripts. The exception to this is that scripts can be transferred from object to object if llAllowInventoryDrop() is true, but the scripts are transferred in a non-running state, meaning they either need to be compiled again, or the object needs to be saved and re-rezzed.
Monday, August 02, 2010
Skinning Cats
Here are a few ways to do a click and drag thinger with a HUD. They all have their pros and cons.
1. Dragging out a selection box texture on a prim. This requires 2 prims, one for the actual box and one for an image under it (so you can see the box).
Pro: Looks cool and will drag a 2D selection box on the surface of a prim.
Con: Only affects the texture and doesn't move a prim. Well I guess that's not a con if you're into that kind of thing.
You can find the code for that at the LSL code receptacle on the wiki. http://wiki.secondlife.com/wiki/ClickAndDrag
2. Dragging a prim around using llDetectedTouchPos
Pros: Only uses one prim and can be dragged as far as you want in any direction.
Cons: Can only be dragged so fast because if you move your mouse off the surface of the prim, the touch event will stop and the prim won't move anymore. *Edit* Tahlie pointed out to me that the event doesn't actually stop, just that the prim isn't getting information on where to move anymore, and you can keep moving the prim if you move your mouse back over the prim.
//Written and given permission to duplicate by Tahlie Teskat3. Using a the UV coordinates of the texture of an invisible prim to drag another prim.
key owner;
// For move Function
vector LastTouchPos;
default {
// Reset Security
state_entry() {
owner = llGetOwner();
}
on_rez(integer rezzed) {
if (owner != llGetOwner()) llResetScript();
}
link_message(integer sender_num, integer num, string str, key id) {
if (num == 666 && str == "reset") llResetScript();
}
// Reset Security
touch_start(integer total) {
LastTouchPos = llDetectedTouchPos(0);
}
touch(integer total) {
vector delta;
vector touchPos = llDetectedTouchPos(0);
if (touchPos != <0.0,0.0,0.0>) delta = touchPos - LastTouchPos;
if (delta != <0.0,0.0,0.0>) llSetPos(llGetLocalPos() + delta);
if (touchPos != <0.0,0.0,0.0>) LastTouchPos = touchPos;
}
}
Pros: can click anywhere and the prim will follow. Can click and drag without any limit on speed.
Cons: only works with 1 prim at a time (in this script's current state), requires 2 prims, doesn't always drag directly under where your mouse is (again probably just the way the script is now, it needs some tweeks.) Put this script in the root and make that prim invisible, stretch it to however large of an area you want, and link it to another object you want to drag and make sure it's under the root object.
//written by Valent1ne
default
{
touch(integer total_number)
{
vector offset = <.58,.45,0>; //this sort of random vector is the offset, you'll have to play with it to get it to work just right. At least until I figure out a better way.
vector pos = llDetectedTouchUV(0) - offset;
llSetLinkPrimitiveParamsFast(LINK_ALL_CHILDREN, [PRIM_POSITION,pos]);
}
}
Tuesday, July 27, 2010
Remove inventory
Someone asked me tonight wanting to know how to get more than one script to delete, including itself. The answer was simple, have the other scripts delete first, then have the script self destruct. Remember LSL reads top to bottom, left to right. So if you have one function before the other, the one on the topmost line will run first.
llRemoveInventory("New Script 1");
llRemoveInventory("New Script 2");
llRemoveInventory(llGetScriptName());
Sunday, July 04, 2010
Hiding Object Name and Carriage Returns
llSetObjectName(""); //sets the name of the object to nothing
llSay(0, "This is some text \n and this will end up on the next line");
llSetObjectName("object"); //this is to set the name of the object back to what it was originally
Saturday, June 19, 2010
Tiny Smoke
Below the particle script is a rotation script, you can throw that in the prim or combine it with the top script; it will make the prim rotate.
float maxsysage = 0.0;
float maxspeed = 0.02;
float minspeed = 0.02;
float burstrad = 0.0;
integer burstcount = 20;
float burstrate = 0.01;
float outangle = 0.1;
float inangle = 0.001;
vector omega = <0.0,0.0,0.0>;
vector startcol = <1.0,>;
vector endcol = <.0, 0.0, 0.>;
float startalph = 0.1;
float endalph = 0.00;
vector startscale = <0.04,0.04,0.04>;
vector endscale = <.00,0.00,0.00>;
float maxage = 4.0;
vector accel = <0.0,>;
string texture = "cb722f94-f87a-2a53-e6df-0f5f03ce6f6d";
integer flight;
integer pilot;
ParticlesOn()
{
llParticleSystem([PSYS_PART_FLAGS,
PSYS_PART_INTERP_COLOR_MASK |
PSYS_PART_INTERP_SCALE_MASK |
PSYS_PART_FOLLOW_SRC_MASK |
PSYS_PART_FOLLOW_VELOCITY_MASK |
PSYS_PART_EMISSIVE_MASK,
PSYS_SRC_PATTERN,
PSYS_SRC_PATTERN_ANGLE,
PSYS_PART_START_COLOR, startcol,
PSYS_PART_START_ALPHA, startalph,
PSYS_PART_END_COLOR, endcol,
PSYS_PART_END_ALPHA, endalph,
PSYS_PART_START_SCALE, startscale,
PSYS_PART_END_SCALE, endscale,
PSYS_PART_MAX_AGE, maxage,
PSYS_SRC_ACCEL, accel,
PSYS_SRC_TEXTURE, texture,
PSYS_SRC_BURST_RATE, burstrate,
PSYS_SRC_INNERANGLE, inangle,
PSYS_SRC_OUTERANGLE, outangle,
PSYS_SRC_BURST_PART_COUNT, burstcount,
PSYS_SRC_BURST_RADIUS, burstrad,
PSYS_SRC_BURST_SPEED_MIN, minspeed,
PSYS_SRC_BURST_SPEED_MAX, maxspeed,
PSYS_SRC_MAX_AGE, maxsysage,
PSYS_SRC_OMEGA, omega ]);
}
ParticlesOff()
{
llParticleSystem([PSYS_PART_FLAGS,
PSYS_PART_INTERP_COLOR_MASK |
PSYS_PART_INTERP_SCALE_MASK |
PSYS_PART_FOLLOW_SRC_MASK |
PSYS_PART_FOLLOW_VELOCITY_MASK |
PSYS_PART_EMISSIVE_MASK,
PSYS_SRC_PATTERN,
PSYS_SRC_PATTERN_ANGLE,
PSYS_PART_START_COLOR, startcol,
PSYS_PART_START_ALPHA, startalph,
PSYS_PART_END_COLOR, endcol,
PSYS_PART_END_ALPHA, endalph,
PSYS_PART_START_SCALE, startscale,
PSYS_PART_END_SCALE, endscale,
PSYS_PART_MAX_AGE, 0.01,
PSYS_SRC_ACCEL, accel,
PSYS_SRC_TEXTURE, texture,
PSYS_SRC_BURST_RATE, burstrate,
PSYS_SRC_INNERANGLE, inangle,
PSYS_SRC_OUTERANGLE, outangle,
PSYS_SRC_BURST_PART_COUNT, burstcount,
PSYS_SRC_BURST_RADIUS, burstrad,
PSYS_SRC_BURST_SPEED_MIN, minspeed,
PSYS_SRC_BURST_SPEED_MAX, maxspeed,
PSYS_SRC_MAX_AGE, 0.01,
PSYS_SRC_OMEGA, omega ]);
}
default
{
state_entry()
{
llSetTimerEvent(0.0);
llParticleSystem([]);
ParticlesOn();
}
on_rez(integer sparam)
{
llResetScript();
}
link_message (integer sender, integer num, string msg, key id)
{
if (num == 0 && msg == "flameon")
{
ParticlesOn();
}
if(num == 0 && msg == "flameoff")
{
ParticlesOff();
}
}
}
default
{
state_entry()
{
llTargetOmega(<0,0,1>,PI,0.20);
}
}
Wednesday, May 26, 2010
And now for something completely unrelated.....
I have it set up with the default cylinder. If you want more vertices just push A (hotkey to select all), go to edit mode, click editing (looks like a sqaure with dots at the corners) and click subdivide.
To export your sculpty map, follow these steps.
1. Move your mouse right over the line between the top and bottom window and choose "split area"
2. Click the little box at the bottom left of the new window you just created and select "UV/image editor"
3. Click on Image > new, and set the dimensions for 256x256. Then, push F10 to go to the render menu, and click the "bake" tab. In the right column, click "Textures", and then click the large "Bake" button. You will see your colored sculpt map appear in the right window.
4. Once the image has been baked, click on image again, choose Save As, and select where you want to save your image. At the bottom of the save screen make sure you select to save your image as a Targa file.
I know there are plugins and junk to make sculpties in blender, but if you don't feel like using those or they're giving you trouble, this can be an easier way to make them without plugins. Just make sure you don't save over your sculptstart.blend file :)
Also, I know that SL will trim down your image to be 128x128 (and 32x33 verts) when you use it as a sculpt map but I always like to start high res and then let it be trimmed down as needed.
Dave's Giant Database Insertion Tutorial
- You have a web server and a place that this database/web script can go.
- You have a database and don't need help setting one up
- You have at least very basic knowledge of PHP and writing MySQL requests.
That being said, let's get started. The first thing you will need is to set up your database and know what you are going to store. For this example let's say you want to insert the name of an avatar into a database whenever the object is touched, and keep a running tab of how many times they have touched it.
Assume you have a database called "SL" with a table called "stats". Stats has two columns, "name" and "number". Name will be the name of the avatar (for this example it would need to be set as unique). Number will represent the number of times the prim was clicked.
Now what we are going to do is set up our PHP script. What will happen is that every time the prim is clicked, it will send a request to this PHP script, which will then update the database. Here is an example of what the PHP script should look like for this example.
<?php
$db = mysql_connect("localhost", "db_username", "your_password") or die ("<html><script language='JavaScript'>alert('Unable to connect to database! Please try again later.')</script></html>");
mysql_select_db("SL",$db);
$name = $_GET['name']; //$_GET takes variables that are passed from the url (see the LSL example)
$usertable = "stats";
$update = "INSERT INTO $usertable SET name = '$name', number = 1 ON DUPLICATE KEY UPDATE number = number + 1";
$result = mysql_query($update);
?>
And now for the LSL script that will send the request to the PHP page:
string owner_name;key owner_name_query;default
{state_entry()
{
}
touch_start(integer total_number)
{
owner_name_query = llRequestAgentData(llGetOwner(), DATA_NAME);
}
dataserver(key queryid, string data){
if (owner_name_query == queryid){owner_name = data;llHTTPRequest("http://www.yoursite.com/yourphppage.php?name=" + owner_name, [], "");
}
}}
Well I hope that is enough to get you started loading things into databases. Next time we can talk about how to get data back out of the database.
Sunday, May 23, 2010
Beacon
float delay = 0.01;
float k = 0;
integer toggle = 0;
default
{
state_entry()
{
llSetTimerEvent(delay);
}
timer(){
if(toggle == 0){
llSetLinkPrimitiveParamsFast(LINK_SET, [25, ALL_SIDES, k]);
k += 0.03; //changing this will change how fast the blink is
if (k >= .5){
toggle = 1;
}
}
if(toggle == 1){
llSetLinkPrimitiveParamsFast(LINK_SET, [25, ALL_SIDES, k]);
k -= 0.03;
if (k <= 0.04){ toggle = 0; } } } }
The neat trick is using llSetLinkPrimitiveParamsFast instead of llSetPrimitiveParams. Check out the video to see why :) The one using llSetLinkPrimitiveParamsFast is on the left. Nice and smooth :)
Oh! The one thing to look out for: you have to be careful changing the speed, do some math and make sure it won't try setting the glow under 0 or over 1. Otherwise you get a super annoying script error D:
Saturday, May 22, 2010
Remote control
Mmmmmkay so COKE asked me the other day about making a remote control for some curtains, like if you click a button then all the curtains should open or half shut or close. Well COKE I'll give you a real helpful snippet and hopefully you can figure out where to go from there. Of course if you need more help you're always welcome to ask more questions :P
Kay so here goes.
My super basic remote control script looks like this (it goes in the object that you're using to be the remote):
defaultAnd this is the script that would go in the curtains (it would need to be the same script that controls whether they're open or closed and whatnot):
{
state_entry()
{
}
touch_start(integer total_number)
{
llRegionSay(-999, "1");
}
}
defaultHere is an explanation of the llListen function. The parameters are like this: llListen( integer channel, string name, key id, string msg );(thanks wiki :) )
{
state_entry()
{
llListen(-999, "", "1bd1faad-303f-748e-bf5c-745d124e751e", "");
}
listen(integer channel, string name, key id, string message)
{
if(message == "1"){
llSay(0, "Hi everybody :)");
}
}
}
The parameters act as filters for what you want to listen for. This is great for cutting down on lag and makes sure the script doesn't have to sift through tons of unrelated chat. Channel is obviously the channel you want to listen for the message on (I used -999). Name will listen only for chat from specific av's or objects (I used "" to leave that blank). ID will filter for a specific object or avatar UUID. You'll notice that I used the UUID of a specific prim. You can get this really easily from the build menu using Emerald (see fig 1.). Msg will filter for a specific message, but since we will need to use different messages, you should leave that blank too using "".
Fig 1.
I think the "listen" event is pretty self explanatory. I have it set up so that if the message is "1", the prim will say a message. Sooooo, you can set up your remote control script to cycle through saying "open", "half_open", "close", and then set up your listener script to either open, set the curtains to half shut, or closed, based on the message.
Let me know if you have any more questions, you know where to find me :)
Friday, May 21, 2010
Hot Topics (Part 1)
Shila was working on a script that reads a notecard, and she wanted to know how to reset the script whenever the notecard is edited and saved. The code for this is pretty quick and simple. All you have to do is add the "changed" event to your code.
changed(integer change){
if ( change & CHANGED_INVENTORY){
llResetScript();
}
}
Tuesday, May 18, 2010
Get a bunch of info on someone (llRequestAgentData example)
key online_query;There are a few things you'll notice right away. First of all I have this set up so it gets the info of whoever touched the prim. The next thing is that I have four queries set up for each of the pieces of data we want to get, and finally inside the dataserver event we have four "if" statements that handle each of the queries. The name query returns the avatar's name as a string, their online status returns as an integer disguised as a string (either 1 or 0 depending on their online status), their birthday returns as a string in the format YYYY-MM-DD, and their payment info also returns as integers in string format, 0 for no payment info, 1 for pay info on file, and 3 for pay info used. Don't ask what happened to 2.
string name_query;
string birthday_query;
string payinfo_query;
string owner_name;
string online;
string birthday;
string payinfo;
default
{
touch_start(integer total_number)
{
key id = llDetectedKey(0);
name_query = llRequestAgentData(id, DATA_NAME);
online_query = llRequestAgentData(id, DATA_ONLINE);
birthday_query = llRequestAgentData(id, DATA_BORN);
payinfo_query = llRequestAgentData(id, DATA_PAYINFO);
}
dataserver(key queryid, string data)
{
//Find out their name --------------------------------------
if ( name_query == queryid )
{
owner_name = data;
llSay(0, "The name of the person is : " + owner_name );
}
//Find out if they are online-------------------------------
if ( online_query == queryid )
{
online = data;
if (online == "1"){
llSay(0, "he or she is online");
}
else
{
llSay(0, "he or she is offline");
}
}
//Find when their birthday is -------------------------------
if ( birthday_query == queryid )
{
birthday = data;
llSay(0, "Their birthday is "+ birthday);
}
//Find out what their payment info status is ----------------
if ( payinfo_query == queryid )
{
payinfo = data;
if (payinfo == "0"){
llSay(0, "They have no payment info on file");
}
if (payinfo == "1"){
llSay(0, "They have payment info on file");
}
if (payinfo == "3"){
llSay(0, "Their payment info has been used");
}//end if(payinfo == "3")
}//end query if
}//end dataserver
}//end default
So now you know how to get most of the data on someone's avi. If you want to do other things with this info you can put your functions in the dataserver event, inside the if statement pertaining to that piece of information.
Monday, May 17, 2010
Whoopie! (A quick sit detect script)
vector sitoffset=<0.0, 0.0, 0.1>; // sit position offset (x = front back, y = left right, z = updown)You don't have to do this, but I put in a sit target function (llSitTarget) just so that I could sit on the object easier. I would probably recommend this though, I had a rough time getting my av to sit down on the prim without it ("no room to sit here, try somewhere else"). All you would have to do to change this script to make it do what you want is put all your functions where " llSay(0, "zomgz!!");" is right now, and to implement it into another script just copy and paste everything in the "changed" event.
default{
state_entry(){
llSitTarget(sitoffset, ZERO_ROTATION);
}
changed(integer change)
{
if (change & CHANGED_LINK)
{
if (llAvatarOnSitTarget() != NULL_KEY)
{
llSay(0, "zomgz!!");
}
}
}
}
Happy sitting!
Sunday, May 16, 2010
Collision Detection Goodness
default{
state_entry()
{
llVolumeDetect(TRUE); // Starts llVolumeDetect
}
collision_start(integer total_number)
{
//Your functions will go here, for example the color changing and sound playing
llPlaySound(yoursound, 1);
}
}
Tuesday, May 04, 2010
Debug Assertion Failed!
Hello...This so does not have anything to do with LSL and not sure if you can help me but I am gonna throw it out to you anyway. I got a popup error in a project I was trying to compile. It read:
Debug Assertion Failed!
Program: D:\\3pt\MsPlatformSDK\2000_04\bin\RegSvr32.exe
File: oletyplb.cpp
Line: 32
Press Retry to debug the application
Abort Retry Ignore
I tried clicking retry but it gave me nothing. The other two options didn't help either.
Well, I'm not super great with C++ but I took a crack at the problem. Basically, from my understanding, the debug assertion is a part of the code that runs when it is compiled and if it returns false, stops compiling and gives you an annoying message so that you can go into the debugger before something explodes.
The part that I would look at is the "Line: 32" part. My guess is that something on that line in oletyplb.cpp is causing the compile to fail. Based on some of my research I found that the culprit is usually something like using an invalid pointer or trying to index an array beyond its boundaries.
Well I hope that helps, keep us updated on your progress!
Monday, May 03, 2010
Intro
Hi :) This is not really intended to be your typical blog, rather it will (hopefully) be a question and answer page for anything and everything related to LSL scripting. I also have a background in PHP, Javascript (and Processing), Actionscript 2.0, as well has HTML/CSS, so any questions related to those languages are fair game, although lets try to stick with questions that relate to LSL. That being said, feel free to post a comment to this post, or shoot me an email with your questions.
When asking a question, please leave your SL name and whether you would like to remain anonymous in the answer.
I hope to hear from you all soon!
Instructions
nucularsecrets@gmail.com
Any question is fair game, so don't be shy!
Featured
- OpenSim (1)
- Outline (1)
- Sculpties in Blender (1)
Followers
Contributors
Friends
Index
- changed (2)
- click and drag (1)
- dataserver (2)
- link_message (1)
- llAllowInventoryDrop (1)
- llAvatarOnSitTarget (1)
- llDetectedKey (2)
- llDetectedName (1)
- llDetectedTouchPos (1)
- llDetectedTouchUV (1)
- llGetOwner (2)
- llGetScriptName (1)
- llHTTPRequest (1)
- llListen (1)
- llParticleSystem (1)
- llRegionSay (1)
- llRemoveInventory (1)
- llRequestAgentData (2)
- llResetScript (1)
- llSay (3)
- llSetLinkPrimitiveParamsfast (2)
- llSetObjectName (1)
- llSetPos (1)
- llSetTimerEvent (1)
- llSitTarget (1)
- particles (1)
- PHP (1)
- timer (1)
- touch (1)
Blog Archive
-
►
2011
(1)
- ► Feb 27 - Mar 6 (1)
-
▼
2010
(18)
- ► May 23 - May 30 (3)
- ► May 16 - May 23 (5)
Copyright 2010 Nucular Secrets . Powered by Blogger
Blogger Templates created by Deluxe Templates Wordpress by thebookish