Showing posts with label llRezObject. Show all posts
Showing posts with label llRezObject. Show all posts

Wednesday, July 30, 2008

Second Life Physics Scripting - Pinball #23 - llRez and llDie

The next feature is to remove the ball when it hits the back wall and then to have it respawn when the user presses the page up key.

The first problem is that the ball has to remove itself. There doesn't seem to be a way to have a script remove another object.

I first set out to have the ball remove itself when it had a collision with the back wall. The problem with this is that the back wall is linked and the collision name had "pinball 1.4" which may change over time and that this collision only occured once when the ball was first placed on the table since it is all one linked set.

The next solution is to send a message to the ball when the back wall is hit and I did this with the chat system llSay.


if (llDetectedName(0) == "ball")
{
...
//llPushObject(llDetectedKey(0), pos3, <0,0,0>, FALSE);

llSay(1296,"byebye");

}

This was as simple as removing the push and adding the llSay. The next step is to have the ball listen for the message.

integer listen_handle;

default
{
state_entry()
{
listen_handle = llListen( 1296, "backwall", NULL_KEY, "" );
}
listen(integer channel, string name, key id, string message)
{

//llOwnerSay("ball listen, heard = "+name);
if ((channel==1296) && (llToLower(message) == "balldied"))
{
//llOwnerSay("Ball died!");
llDie();
}
}

}

The ball is listening for the object backwall to say "byebye" on channel 1296. At first I thought this would be too slow, but it seems very quick and the ball goes away before bouncing back onto the table.

Make sure you keep a copy of the ball in your inventory because when it dies you don't want to have to recreate the scripts over and over.

The next step is the spawning of the ball (llRez) when the user presses the page up key. I did this in the PayAndKeyboard script in root table object. This is the same script that handles the key presses to move the puck flipper.


RezBall()
{
if (!in_play)
{
in_play = TRUE;

// find the size of the this table
vector sz = llList2Vector(llGetPrimitiveParams([PRIM_SIZE]),0);

vector pos = llGetPos();
//llOwnerSay("pos = "+(string)pos);
vector up = llVecNorm(pos * llGetLocalRot());
up = up * ((sz.z/2) + 0.21); // add the size of the ball
//llOwnerSay("up = "+(string)up);

pos = pos + up;
//llOwnerSay("rez pos = "+(string) pos);

llRezObject("ball",pos,<0,0,0>,ZERO_ROTATION,0);
}
}

I wrote a separate function for the rez ball. This still has problems as I think it rezes the ball too low on the table, but it has a neat effect in that the ball sort of oozes out of the table. It needs looking into at some point.

Next is the event to rez the ball.

control(key id, integer held, integer change)
{
... puck flipper code

// page up key
if ((held&CONTROL_UP) && (change&CONTROL_UP))
{
if (!in_play)
{
llSay(0," here we go!!!");
}
RezBall();
}
}


Then we have to have a way to reset the in_play flag so the user can press the "page up" key again and have the ball rez. This is as simple as adding the listen method the same as we used for the ball. Both the ball and this PayAndKeyboard script will both hear the same message from the backwall.

state_entry()
{

listen_handle = llListen( 1296, "backwall", NULL_KEY, "" );
llSetTimerEvent(30);

... other initialization code
}

listen(integer channel, string name, key id, string message)
{
if ((channel==1296) && (llToLower(message) == "balldied"))
{
llSay(0,"Oops, drain. Press 'Page Up' to start another ball.");
in_play = FALSE;
llSetTimerEvent(30);
}
}

As you can see I also added some timer events. This is so the table is actually doing something when people first walk up to it. A teaser to get people interested. 30 seconds after every drain, then timer goes off. If the ball isn't already in play (because someone pushed page up), then a new ball is spawned.

timer()
{
if (!in_play)
{
llSay(0,"Autoplay starting");
RezBall();
}
llSetTimerEvent(0);
}

Tuesday, July 29, 2008

Second Life Physics Scripting - Pinball #22 - llRezObject ball

I'm beginning to think I can use a different blog entry title and may change to Second Life Game Scripting on the next one since I'm no longer really dealing with physics and have moved onto building the game elements?

The next step is to spawn the ball (llRezObject) when the game starts, and to remove the ball when it hits the back wall. I decided to make the first attempt fairly simple and just rez the ball in the center of the table when the up key is pressed. This seemed pretty straight forward and didn't seem to take very long. Reading up on how to do it took most of the time. Here is the code that I used to rez the ball from inventory.


control(key id, integer held, integer change)
{
... code for the flipper controls ...
if ((held&CONTROL_UP) && (change&CONTROL_UP))
{
if (!in_play)
{
in_play = TRUE;

llSay(0," here we go!!!");

// find the size of the this table
vector sz = llList2Vector(llGetPrimitiveParams([PRIM_SIZE]),0);

vector pos = llGetPos();
llOwnerSay("pos = "+(string)pos);
vector up = llVecNorm(pos * llGetLocalRot());
up = up * ((sz.z/2) + 0.21); // add the size of the ball
llOwnerSay("up = "+(string)up);

pos = pos + up;
llOwnerSay("rez pos = "+(string) pos);

llRezObject("ball",pos,<0,0,0>,ZERO_ROTATION,0);
}
}
}


Adding the ball to inventory was pretty simple. Select the root object and drag the ball from my inventory into the root object's contents. The contents are the same place all the scripts are stored. The first time I did this it took me a while to figure out that you could also store objects in the contents, not just scripts.

Next up I have to change the collision script on the back wall to derez the ball instead of bouncing it back. Then I'll have to send a message to the root prim so I can reset the in_play flag so the person can rez another ball. From there it's a matter of giving each player a set number of balls and keeping track of a high score. Getting closer to a full circle game....