Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Help needed with gun script

Mako Davidson
Registered User
Join date: 27 Jun 2006
Posts: 56
03-21-2007 09:03
I am using the following script as a gun script. The problem I am having is that after a while the bullets in the gun fail to rez from eye point of my avatar and travel toward the target and instead rez from above my avatars head and travel toward the target, making it inaccurate. The only way it returns to normal is if I reset the script manually, detach the object and re attach. The other problem is that if I am wearing the gun when I log in to Second Life it won't work until I detach and re attach. Can anyone suggest how to rectify this situation. I am a novice scripter. So any advice would be appreciated.

// Gun script
// John Linden

// where the gun attaches itself if you click on it
// switch this to ATTACH_LHAND if you are left-handed
integer gAttachPart = ATTACH_RHAND;

// this is a permission combination we check for many times
// I define it here so we don't have to keep typing it
// guns need to take controls, attach themselves, and possibly
// trigger animations
// NOTE: since I can't initialize to an expression (even if it is
// all constants), this moved to default { state_entry() }
integer gDesiredPerm;
// Indicates whether wearer has yet given permission
integer gHavePermissions;

// Bullet travel speed
float gBulletSpeed = 40.0;

// when we last fired a shot
float gLastFireTime = 0;
// how long it takes to reload when tapping
float gTapReloadTime = 0.05;
// how long it takes to reload when holding
float gHoldReloadTime = 0.5;
// how long it takes when we're out of ammo
float gOutOfAmmoReloadTime = 1.5;
// how many shots before reload is necessary
integer gAmmoClipSize = 7;
// how much ammo we have right now
integer gAmmo;
string Bullet="blitz";
// HACK: how far away the eye is from the avatar's center (approximately)
vector gEyeOffset = <0.0, 0.0, 0.75>;
integer Handle1;
integer Handle2;
integer Handle3;

say(string msg)
{
llSay(0, msg);
}
debug(string msg)
{
// llSay(0, msg);
}
func_debug(string msg)
{
// llSay(0, msg);
}


// the gun has only one state

default
{
on_rez(integer start_param)
{
llListenRemove(Handle1);
llListenRemove(Handle2);
llListenRemove(Handle3);
Handle1 = llListen(0,"",llGetOwner(),"blitz";);
Handle2 = llListen(0,"",llGetOwner(),"orbit";);
Handle3 = llListen(0,"",llGetOwner(),"pull";);
gAmmo = gAmmoClipSize;
func_debug("on_rez";);
vector size = llGetAgentSize(llGetOwner());
gEyeOffset.z = gEyeOffset.z * (size.z / 2.0);

llOwnerSay("Press 'M' to enter mouslook and the mouse button to fire";);
llOwnerSay("'blitz', 'orbit', 'pull', type eatch to change modes, 'holster','unholster', to holster/unholster weapon";);
}
state_entry()
{
llListenRemove(Handle1);
llListenRemove(Handle2);
llListenRemove(Handle3);
Handle1 = llListen(0,"",llGetOwner(),"blitz";);
Handle2 = llListen(0,"",llGetOwner(),"orbit";);
Handle3 = llListen(0,"",llGetOwner(),"pull";);
func_debug("default state_entry";);
gHavePermissions = FALSE;
gDesiredPerm = (PERMISSION_TAKE_CONTROLS
| PERMISSION_TRIGGER_ANIMATION);
gAmmo = gAmmoClipSize;
llResetTime();
}
listen (integer channel, string name, key id, string message)
{
string temp_message = llToUpper(message);
integer strlong = llStringLength(message);
if(message=="blitz";)
{
Bullet="blitz";
llOwnerSay("blitz enabled";);
}
if(message=="orbit";)
{
Bullet="orbit";
llOwnerSay("orbit enabled";);
}
if(message=="pull";)
{
Bullet="pull";
llOwnerSay("pull enabled";);
}
}
// the player has touched us (left-clicked)
// give directions
touch_start(integer tnum)
{
}

// Player attaches us, either by dragging onto self or from pie menu
attach(key av_key)
{
func_debug("attach";);

if (av_key != NULL_KEY)
{
// Can't attach if we don't own it
if ( av_key != llGetOwner() )
{
return;
}

//
// Always request permissions on attach, as we may be re-rezzing on login
llRequestPermissions(av_key, gDesiredPerm);

// run_time_permissions() is executed after this call
} else
{
func_debug(" detach";);

if ( gHavePermissions )
{
// we are being detached
llStopAnimation("hold_R_handgun";);
llReleaseControls();
llSetRot(<0.0, 0.0, 0.0, 1.0>;);
gHavePermissions = FALSE;
}
}
}

// this is called whenever llRequestPermissions() returns
// i.e. the user has responded or dismissed the dialog
// perm is the permissions we now have
run_time_permissions(integer perm)
{
func_debug("run_time_permissions";);

// see if we now have the permissions we need
if ( (perm & gDesiredPerm) == gDesiredPerm )
{
func_debug(" got perms";);

// we got the permissions we asked for
gHavePermissions = TRUE;
llTakeControls(CONTROL_ML_LBUTTON, TRUE, FALSE);
llStartAnimation("hold_R_handgun";);
} else
{
func_debug(" didn't get perms";);

// we didn't get them, kill ourselves
llDie();
}
}


// the player has used the controls, process them
control(key owner, integer level, integer edge)
{
func_debug("control";);

// has our gun reloaded?
float time = llGetTime();

// see if av has fired
// (edge & level) == down edges, (edge & !level) == up edges
// repeat rate is faster for tapping than holding
if ( ( ((edge & level) & CONTROL_ML_LBUTTON)
&& (time > gTapReloadTime) )
|| ( (time > gHoldReloadTime)
&& (level & CONTROL_ML_LBUTTON) ) )
{
// if player is out of ammo, must wait for reload
if ( (gAmmo >= 1) || (time > gOutOfAmmoReloadTime) )
{
// bang!
llTriggerSound("pistol_shot.wav", 1.0);
llResetTime(); // we fired, set timer back to 0

// HACK: gun shoots from gun pos, mouselook looks
// from player's eye, so we try to move the gun
// up to the eye. but we really don't
// know where it is, so we guess (see gEyeOffset)
vector my_pos = llGetPos() + gEyeOffset;
rotation my_rot = llGetRot();
vector my_fwd = llRot2Fwd(my_rot)*2.5;

// Rez a bullet!
llRezObject(Bullet,
my_pos+my_fwd,
my_fwd * gBulletSpeed,
my_rot,
0);

// decrease ammo count
--gAmmo;
if ( gAmmo > 0 )
{
// still bullets left
}
else if ( gAmmo == 0 )
{
// we just ran out of shots
// play reload sound here after a delay
llTriggerSound("pistol_reload.wav", 1.0);
llStartAnimation("reload";);
llSetTimerEvent(gOutOfAmmoReloadTime);
}
else // gAmmo < 0
{
// we've just fired first round of new clip
gAmmo = gAmmoClipSize - 1;
}
}
else
{
debug("Can't shoot, reloading...";);
}
}

} // control
timer()
{
gAmmo = gAmmoClipSize;
llSetTimerEvent(0);
}
} // default state
Ordinal Malaprop
really very ordinary
Join date: 9 Sep 2005
Posts: 4,607
03-21-2007 09:35
That script has been horribly hacked up and contains a lot of junk, but your specific issue is coming from the following lines being in the on_rez() event for some reason:

vector size = llGetAgentSize(llGetOwner());
gEyeOffset.z = gEyeOffset.z * (size.z / 2.0);

Therefore, every time you rez the gun it changes the eye offset. If you take those two lines out and put them in the state_entry() event, where they were in the original script afaik, it will only happen once.
_____________________
http://ordinalmalaprop.com/forum/ - visit Ordinal's Scripting Colloquium for scripting discussion with actual working BBCode!

http://ordinalmalaprop.com/engine/ - An Engine Fit For My Proceeding, my Aethernet Journal

http://www.flickr.com/groups/slgriefbuild/ - Second Life Griefbuild Digest, pictures of horrible ad griefing and land spam, and the naming of names