Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Need Help: Guns detecting you're in mouselook

Korwyn Obscure
Registered User
Join date: 25 Jan 2007
Posts: 31
04-13-2008 19:26
Alright, for the life of me and a few others we can't figure this one out.

I'm currently working on some guns for the BNJRPS system, and have come across an issue.

The BNJRPS system supports a ready pose and an attack pose, but the creator of the system has told me that we could put our own controls on the poses in, and just leave those spots blank on the controlling notecard.

The weapon in question is a rifle and thus we want to have the following availible.

1) A prone position for when doing sniper like duty (working)
2) When standing and moving and NOT actively on the hunt, the weapon would be in a ready pose, not aimed. Similar to why the military has a 'port arms' position that you learn.
3) When standing and actively going to use the weapon (gone into mouselook) we want to be able to have it automatically go to the shouldered and aiming pose.

The part we're hitting. Using the llGetAgentInfo for being in mouselook is 'working' however it's not automatic. If I go into mouselook and do the /99ready command again it'll switch to the proper pose. come out of mouse look it stays aimed, and do the /99ready again and it'll go to the carry pose.

So it's detecting if mouselook is active, but it's not automatically switching out.

So from there, we started looking at some freebie weapons that do this. got lots of them around, and there are open source scripts like Eric Lindens popgun script.

on these weapons they have a carry pose and then you go into mouselook it will automatically switch to an aiming pose.

They even have llStopAnimation commands for when the object is detached to ensure the animations don't continue.

The problem? The act of going into the aiming pose can't be found in the script at all.

Nope, it's not there. But if I make a tube with just that popgun script in it, other then getting the obvious errors on it not finding the bullet or the sounds, everything works as you'd expect it. When you go into mouselook it goes into the aiming pose.

So, if me and 3 of my friends can find it, maybe you all can explain where this is happening in this script...

Here is the popgun script with denotations in it.

//
// Popgun
//
// This script is a basic gun- it waits for a mouseclick in mouselook and
// then fires a bullet in the direction the user is facing.
// It also animates the avatar holding it, to create a convining hold and
// firing look for the gun.
//
// This script can be used as a good basis for other weapons.
//

float SPEED = 20.0; // Speed of arrow in meters/sec
integer LIFETIME = 7; // How many seconds will bullets live
// before deleting themselves
float DELAY = 0.2; // Delay between shots to impose

vector vel; // Used to store velocity of arrow to be shot
vector pos; // Used to store position of arrow to be shot
rotation rot; // Used to store rotation of arrow to be shot

integer have_permissions = FALSE; // Indicates whether wearer has yet given permission
// to take over their controls and animation.

integer armed = TRUE; // Used to impose a short delay between firings

string instruction_held_1 = "Use Mouselook (press 'M') to shoot me.";
string instruction_held_2 = "Choose 'Detach' from my menu to take me off.";
// Echoed to wearer when they are holding the bow
string instruction_not_held =
"Choose 'Acquire->attach->left hand' from my menu to wear and use me.";
// Echoed to toucher if not worn


fire()
{
//
// This subroutine creates and fires an arrow
//
if (armed)
{
//
// Actually fires the arrow
//
armed = FALSE;
rot = llGetRot(); // Get current avatar mouselook direction
vel = llRot2Fwd(rot); // Convert rotation to a direction vector
pos = llGetPos(); // Get position of avatar to create arrow
pos = pos + vel; // Create arrow slightly in direction of travel
pos.z += 0.75; // Correct creation point upward to eye point
// from hips, so that in mouselook we see arrow
// travelling away from the camera.
vel = vel * SPEED; // Multiply normalized vector by speed

//llStartAnimation("shoot_R_handgun";); // Trigger the bow release animation
llTriggerSound("shoot", 1.0); // Make the sound of the arrow being shot
llRezObject("bullet", pos, vel, rot, LIFETIME);
// Create the actual arrow from object
// inventory, and set its position, velocity,
// and rotation. Pass a parameter to it to
// tell it how long to live.

llSetTimerEvent(DELAY); // Wait until can fire again
}
}

default
{
state_entry()
//
// This routine is called whenever the script is edited and restarted. So if you
// are editing the bow while wearing it, this code will re-request permissions
// to animate and capture controls.
//
{
if (!have_permissions)
{
llRequestPermissions(llGetOwner(),
PERMISSION_TRIGGER_ANIMATION| PERMISSION_TAKE_CONTROLS);
}
}
on_rez(integer param)
{
//
// Called when the gun is created from inventory.
//
llPreloadSound("shoot";); // Preload shooting sound so you hear it
}

run_time_permissions(integer permissions)
{
//
// This routine is called when the user accepts the permissions request
// (sometimes this is automatic)
// so on receiving permissions, start animation and take controls.
//
if (permissions == PERMISSION_TRIGGER_ANIMATION| PERMISSION_TAKE_CONTROLS)
{
if (!have_permissions)
{
llWhisper(0, instruction_held_1);
llWhisper(0, instruction_held_2);
}
llTakeControls(CONTROL_ML_LBUTTON, TRUE, FALSE);
llStartAnimation("hold_R_handgun";);
have_permissions = TRUE;
}
}

attach(key attachedAgent)
{
//
// If attached/detached from agent, change behavior
//
if (attachedAgent != NULL_KEY)
{
// Bow has been attached or rezzed from inventory, so
// ask for needed permissions.
llRequestPermissions(llGetOwner(),
PERMISSION_TRIGGER_ANIMATION| PERMISSION_TAKE_CONTROLS);
}
else
{
// Bow has been detached from avatar, so stop animation and release controls
if (have_permissions)
{
llStopAnimation("hold_R_handgun";);
llStopAnimation("aim_R_handgun";);
llReleaseControls();
llSetRot(<0,0,0,1>;);
have_permissions = FALSE;
}
}
}

control(key name, integer levels, integer edges)
{
// This function is called when the mouse button or other controls
// are pressed, and the controls are being captured.
//
// Note the logical AND (single &;) used - the levels and edges
// variables passed in are bitmasks, and must be checked with
// logical compare.
//
// Checking for both edge and level means that the button has just
// been pushed down, which is when we want to fire the arrow!
//
if ( ((edges & CONTROL_ML_LBUTTON) == CONTROL_ML_LBUTTON)
&&;((levels & CONTROL_ML_LBUTTON) == CONTROL_ML_LBUTTON) )
{
// If left mousebutton is pressed, fire arrow
fire();
}
}

touch_end(integer num)
{
// If touched, remind user how to enter mouselook and shoot
if (have_permissions)
{
llWhisper(0, instruction_held_1);
llWhisper(0, instruction_held_2);
}
else
{
llWhisper(0, instruction_not_held);
}
}

timer()
{
// After timer expires, allow user to shoot bow again
llSetTimerEvent(0.0);
armed = TRUE;
}

}
Korwyn Obscure
Registered User
Join date: 25 Jan 2007
Posts: 31
04-15-2008 10:35
Alright, everyone I've taken that one to can't see where it's happening.

So here is my script.

First here is what's happening.

1) The prone part works
2) The non prone part works... once
3) To get it to work again you have to type the /99ready to get it to check the status of mouselook or not again
4) you can see where I put debug llSay commands in for while I was in my workshop to see where things were happening. It's once again working manually and when the debugging is not commented out it'll give the proper responces.
5) The timer appears to not be looping, thus it's not doing the check till you reset the script or force the timer to reset with the ready command.

Here is the code. Where is the timer failing to loop? That appears to be where the main failure it.

**************
key owner;
integer channel = 99;
string anim = "TSRifleCarry";
integer view;
integer prone = FALSE;
integer ready = TRUE;
integer aim = FALSE;

Timer()
{
//llSay(0,"Timer Active. AIM = " + (string)aim + " prone = " + (string)prone + " ready = " + (string)ready);//debugging
view = llGetAgentInfo(llGetOwner());
if (view & AGENT_MOUSELOOK)
{
llStopAnimation(anim);
if (aim == FALSE)
{
llPlaySound("1aca9dbc-9d71-2b01-9880-a2007e88dc63",1.0);
}
llSay(0,"In Mouselook";); //debugging
anim="TSRifleAim";
aim = TRUE;
ready = FALSE;
prone = FALSE;
integer perm = llGetPermissions();
if(perm & PERMISSION_TRIGGER_ANIMATION)
{
llSay(0,"Starting Animation" + anim); //debugging
llStartAnimation (anim);
//Timer(); This will cause it to work, if the debug text is in. Once the debug texting is out it gives a stack heap collision.
}
}
else
{
llStopAnimation(anim);
if (ready == FALSE)
{
llPlaySound("9a731231-2fb9-34d4-5025-611c76c6e894",1.0);
}
llSay(0,"Out of Mouselook";);//debugging
anim="TSRifleCarry";
ready = TRUE;
aim = FALSE;
prone = FALSE;
integer perm = llGetPermissions();
if(perm & PERMISSION_TRIGGER_ANIMATION)
{
llSay(0,"Starting Animation: " +anim);//debugging
llStartAnimation (anim);
//Timer();This will cause it to work, if the debug text is in. Once the debug texting is out it gives a stack heap collision.
}

}
}


default
{

state_entry()
{
llListen( channel, "", llGetOwner(), "" );
llSetTimerEvent(0.5);
llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION);
Timer();
}

listen( integer channel, string name, key id, string message )
{
if (message == "ready";)
{
llSay(0,"Ready!";); //debugging
llStopAnimation(anim);
llSay(0, "Stopping animation: " + anim); //debugging
llResetTime();
Timer();

}


else if (message == "prone";)
{
llStopAnimation(anim);
llSetTimerEvent(0.0);
anim="TSProneshooter";
ready = FALSE;
aim = FALSE;
prone = TRUE;
integer perm = llGetPermissions();
if(perm & PERMISSION_TRIGGER_ANIMATION)
{
llStartAnimation (anim);

}


}


}
}
*********
Yumi Murakami
DoIt!AttachTheEarOfACat!
Join date: 27 Sep 2005
Posts: 6,860
04-15-2008 11:29
You are declaring a global function called Timer, and then specifying a state. Because the timer() you've defined is a global function rather than an event handler in the default state, llSetTimerEvent doesn't call it. Timer() needs to be inside the default {} bracket.
Korwyn Obscure
Registered User
Join date: 25 Jan 2007
Posts: 31
04-15-2008 12:09
GAH!

Thank you Yumi will try next availible moment.