LSL Wiki Mirror 7-7-7 : ExampleGun

HomePage :: PageIndex :: RecentChanges :: RecentlyCommented :: UserSettings ::
By ReadyJack: (moved)

This updated script fixes a serious bug when rezzing the bullet, cleans up some useless code and allows the user to either relax or ready the weapon by touching it.

Futzed with by StrifeOnizuka to fix a bug in the rez offset and a possible permission hole. this bug was inherited from the revolver script. On each attach it would corrupt the rez offset, eventualy going to zero or infinity, depending on if your avatar was taller then 2 meters. My guess is the original revolver script did a llResetScript on_rez then later that was removed. -BW

Pistol:
// Pistol // Ready Jack // 5.22.04 // 1.4

// Make sure these are right
string gBulletName = "Bullet";
string gShotSound = "Shot";
float gBulletSpeed = 75.0;
integer gBulletDamage = 50; // Passed to the bullet script via the rez param

// use a hold anim, you'll go 
// into the aim anim automatically when entering mouselook
string gAnim = "hold_R_handgun";
integer gGrip = ATTACH_RHAND;
string gGripMessage = "this weapon only fits in your right hand";
vector gAimOffsetConstant = <0.0, 0.0, 0.84>; // borrowed from the Revolver script
integer gEnableBullet;
integer gEnableSound;
integer gArmed;
vector gAimOffset;

say(string message)
{
    llOwnerSay(message);
}

getPerms()
{
    integer perms = llGetPermissions()
            | PERMISSION_TAKE_CONTROLS
            | PERMISSION_TRIGGER_ANIMATION
            | PERMISSION_ATTACH;
    llRequestPermissions(llGetOwner(), perms);        
}

verifyInventory()
{
    if (llGetInventoryKey(gBulletName) != NULL_KEY) {
            gEnableBullet = TRUE;
    } else {
        gEnableBullet = FALSE;
        say("bullet not found: " + gBulletName);
    }
    if (llGetInventoryKey(gShotSound) != NULL_KEY) {
        gEnableSound = TRUE;
    } else {
        gEnableSound = FALSE;
        say("sound not found: " + gShotSound);
    }
}

arm() {
    integer perm = PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION;
    if ((llGetPermissions() & perm) != perm ) {
        getPerms();
    } else {
        llTakeControls(CONTROL_ML_LBUTTON, TRUE, FALSE);
        llStartAnimation(gAnim);
        gArmed = TRUE;
    }
}

disarm() {
    if(llGetAgentSize(llGetPermissionsKey()) != ZERO_VECTOR)
        llStopAnimation(gAnim);
    llReleaseControls();    
    gArmed = FALSE;
}
    

default
{  
    state_entry()
    {
        verifyInventory();
    }
    
    touch_start(integer count)
    {
        if (llDetectedKey(0) != llGetOwner()) {
            return;
        } else if (!llGetAttached()) {
            getPerms();
        } else if (gArmed) {
            disarm();
        } else {
            arm();
        }
    }
    
    run_time_permissions(integer perms)
    {
        if (perms & (PERMISSION_TAKE_CONTROLS
                | PERMISSION_TRIGGER_ANIMATION
                | PERMISSION_ATTACH)) {
            if (!llGetAttached()) {
                llAttachToAvatar(gGrip);
            } else if (llGetAttached() != gGrip) {
                say(gGripMessage);
                llDetachFromAvatar();
            } else {
                verifyInventory();
                arm();
            }
        } else {
            say("insufficient permissions");
            if (llGetAttached()) llDetachFromAvatar();
        }   
    }
    
    attach(key avatar)
    {
        if (avatar != NULL_KEY) {
            // attaching
            vector size = llGetAgentSize(avatar);
            gAimOffset = gAimOffsetConstant;
            gAimOffset.z *= size.z / 2.0;
            getPerms();
        } else {
            // detaching
            if (gArmed) disarm();
        }
    }
        
    control(key avatar, integer levels, integer edges)
    {
        // mouse press
        if ((levels & CONTROL_ML_LBUTTON) && (edges & CONTROL_ML_LBUTTON)) {
        }

        // mouse release                
        if (!(levels & CONTROL_ML_LBUTTON) && (edges & CONTROL_ML_LBUTTON)) {
            if (gEnableSound) llTriggerSound(gShotSound, 1.0);
            rotation rot = llGetRot();
            vector aim = llRot2Fwd(rot);
            vector pos = llGetPos() + gAimOffset + (aim * 1.0);
            llRezObject(gBulletName, pos, aim * gBulletSpeed, rot, gBulletDamage);
        }
        
        // mouse down
        if ((levels & CONTROL_ML_LBUTTON) && !(edges & CONTROL_ML_LBUTTON)) {
        }
    }
}

Bullet:
// Bullet // Ready Jack // 6.23.04 // 1.3

// The other safety precautions seem unreliable if the bullet crosses 
// into another sim, but this die timer seems to work pretty well.
float gTimeToDie = 20.0;

default
{
    state_entry()
    {
        llSetPrimitiveParams([PRIM_TEMP_ON_REZ, TRUE]); // unreliable
        llSetStatus(STATUS_PHYSICS | STATUS_DIE_AT_EDGE, TRUE);
        //llSetBuoyancy(1.0); // uncomment for slow bullets
    }
      
    on_rez(integer start_param)
    {
        if (!start_param) return;
        
        llCollisionFilter("", llGetOwner(), FALSE);
        llSetDamage((float)start_param);
        llCollisionSound("", 1.0); // cancel default sound
        llSetTimerEvent(gTimeToDie);
    }

    collision_start(integer count)
    {
        integer type = llDetectedType(0);
        if (type & AGENT) {
            // tricky stuff like proprietary damage goes here
            llDie();
        } else if (llGetStartParameter()) {
            //llDie(); // uncomment to disallow ricochet, unreliable
        }
    }
    
    land_collision_start(vector pos) {
        //if (llGetStartParameter()) llDie(); // uncomment for no-bounce, unreliable
    }
    
    timer()
    {
        llDie();
    }
}

Props to Bel Muse, Water Rogers, Ezhar Fairlight and the author of the Revolver Script.


Examples
There is no comment on this page. [Display comments/form]