User:Allen Kerensky/Myriad Lite/Myriad Lite Turret Bullet-Preview6.lsl

From OpenSimulator

< User:Allen Kerensky | Myriad Lite
Revision as of 10:28, 12 August 2012 by Allen Kerensky (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Myriad_Lite_Turret_Bullet-Preview6.lsl

// Myriad_Lite_Turret_Bullet-Preview6.lsl
// Copyright (c) 2012 by Allen Kerensky (OSG/SL) All Rights Reserved.
// This work is dual-licensed under
// Creative Commons Attribution (CC BY) 3.0 Unported
// http://creativecommons.org/licenses/by/3.0/
// - or -
// Modified BSD License (3-clause)
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright notice, 
//   this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
// * Neither the name of Myriad Lite nor the names of its contributors may be
//   used to endorse or promote products derived from this software without
//   specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
// NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// The Myriad RPG System was designed, written, and illustrated by Ashok Desai
// Myriad RPG System licensed under:
// Creative Commons Attribution (CC BY) 2.0 UK: England and Wales
// http://creativecommons.org/licenses/by/2.0/uk/
 
string  VERSION = "0.0.0"; // version number
string  VERDATE = "20120511"; // version date
 
// Includes Keknehv's Particle Script v1.2
 
//============================================================================
// MESSAGE FORMAT REFERENCE
//============================================================================
// CHANMYRIAD IN - RPEVENT|str event message
// CHANPLAYER OUT - DEPRECATED - TOHIT|str attackdice|key who/whatwashit|key bulletowner|str bulletname
// CHANPLAYER OUT - RANGEDCOMBAT|str attackdice|key who/whatwashit|key bulletowner|str bulletname
 
//============================================================================
// Bullet Configuration
//============================================================================
string RICOCHET = "nebs_smoke_particle_01";  // puff-of-smoke texture to show on bullet hits/ricochets - put this texture in bullet prim
string SOUND = ""; // a ricochet sound
float  BOUYANCY = 1.0;      // how buoyant is the bullet for physics
float  TIMEOUT  = 20.0;     // control timer to force bullet to die
 
// Myriad config
integer MINDAMAGE = 1; // minimum valid damage value for weapon
integer MAXDAMAGE = 5; // maximum valid damage value for weapon
integer DAMAGE = 1; // default how much damage do you want this weapon to cause? can be overriden on rez!
string DIV = "|"; // divider between parts of Myriad API messages
integer CHANMYRIAD = -999; // channel to send Myriad RP events to
 
// turret coordination
integer CHANOBJECT; // bullet-specific channel
key SHOOTERKEY; // key of who shot us
 
//============================================================================
// GLOBAL DIE()
// This kludge is to try very hard to force bullets to eventually die on OpenSims.
// Requested by Lani Global (OSgrid)
//============================================================================
DIE() {
    while ( TRUE == TRUE ) { // this will always be true, forming an infinite loop
        llDie(); // just keep trying to die, forever... one will eventually work!
    }
}
 
//============================================================================
// Keknehv's Particle Script v1.2
//============================================================================
// Retrieved 2011-04-30 from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryKeknehvParticles
// 1.0 -- 5/30/05
// 1.1 -- 6/17/05
// 1.2 -- 9/22/05 (Forgot PSYS_SRC_MAX_AGE)
//     This function may be used in anything you choose, including and not limited to commercial products. 
//     Just copy the MakeParticles() function; it will function without any other variables in a different script
//         ( You can, of course, rename MakeParticles() to something else, such as StartFlames() )
MAKEPARTICLES(string texture) {
    if ( texture == "" || texture == NULL_KEY ) { // no texture set, no reason to show particles
        llParticleSystem([ ]); // shut off any particles that were somehow running
        return; // exit early since we're not going to show more particles without a texture to show
    }
    // This is the function that actually starts the particle system.    
    llParticleSystem([                   //KPSv1.0  
    PSYS_PART_FLAGS , 0 //Comment out any of the following masks to deactivate them
    //| PSYS_PART_BOUNCE_MASK           //Bounce on object's z-axis
    | PSYS_PART_WIND_MASK             //Particles are moved by wind
    | PSYS_PART_INTERP_COLOR_MASK       //Colors fade from start to end
    | PSYS_PART_INTERP_SCALE_MASK       //Scale fades from beginning to end
    //| PSYS_PART_FOLLOW_SRC_MASK         //Particles follow the emitter
    //| PSYS_PART_FOLLOW_VELOCITY_MASK    //Particles are created at the velocity of the emitter
    //| PSYS_PART_TARGET_POS_MASK       //Particles follow the target
    | PSYS_PART_EMISSIVE_MASK           //Particles are self-lit (glow)
    //| PSYS_PART_TARGET_LINEAR_MASK    //Undocumented--Sends particles in straight line?
    //,PSYS_SRC_TARGET_KEY , NULL_KEY,   //Key of the target for the particles to head towards
    //Choose one of these as a pattern:
    //PSYS_SRC_PATTERN_DROP                 Particles start at emitter with no velocity
    //PSYS_SRC_PATTERN_EXPLODE              Particles explode from the emitter
    //PSYS_SRC_PATTERN_ANGLE                Particles are emitted in a 2-D angle
    //PSYS_SRC_PATTERN_ANGLE_CONE           Particles are emitted in a 3-D cone
    //PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY     Particles are emitted everywhere except for a 3-D cone
    ,PSYS_SRC_PATTERN,           PSYS_SRC_PATTERN_EXPLODE
    ,PSYS_SRC_TEXTURE,           texture            //UUID of the desired particle texture, or inventory name
    ,PSYS_SRC_MAX_AGE,           1.0                //Time, in seconds, for particles to be emitted. 0 = forever
    ,PSYS_PART_MAX_AGE,          5.0                //Lifetime, in seconds, that a particle lasts
    ,PSYS_SRC_BURST_RATE,        0.02               //How long, in seconds, between each emission
    ,PSYS_SRC_BURST_PART_COUNT,  1                  //Number of particles per emission
    ,PSYS_SRC_BURST_RADIUS,      0.01                //Radius of emission
    ,PSYS_SRC_BURST_SPEED_MIN,   0.01                //Minimum speed of an emitted particle
    ,PSYS_SRC_BURST_SPEED_MAX,   1.0                //Maximum speed of an emitted particle
    ,PSYS_SRC_ACCEL,             <0.05,0.05,0.05>     //Acceleration of particles each second
    ,PSYS_PART_START_COLOR,      <1.0,1.0,1.0>      //Starting RGB color
    ,PSYS_PART_END_COLOR,        <0.5,0.5,0.5>      //Ending RGB color, if INTERP_COLOR_MASK is on 
    ,PSYS_PART_START_ALPHA,      0.9                //Starting transparency, 1 is opaque, 0 is transparent.
    ,PSYS_PART_END_ALPHA,        0.0                //Ending transparency
    ,PSYS_PART_START_SCALE,      <0.5,0.5,0.0>      //Starting particle size
    ,PSYS_PART_END_SCALE,        <1.0,1.0,0.0>      //Ending particle size, if INTERP_SCALE_MASK is on
    ,PSYS_SRC_ANGLE_BEGIN,       PI                 //Inner angle for ANGLE patterns
    ,PSYS_SRC_ANGLE_END,         PI                 //Outer angle for ANGLE patterns
    ,PSYS_SRC_OMEGA,             <0.0,0.0,0.0>       //Rotation of ANGLE patterns, similar to llTargetOmega()
    ]);
    if ( SOUND != "" ) llPlaySound(SOUND,1.0); // play sound on hit if configured
}
 
//============================================================================
// GLOBAL SETUP()
//============================================================================
SETUP(integer type) {
    CHANOBJECT = (integer)("0x"+llGetSubString(llGetKey(),0,6)); // turret will tell us its key on shoot
    llListen(CHANOBJECT,"",NULL_KEY,""); // setup listener to get shooting turret's key    
    if ( llGetStatus(STATUS_PHYSICS) == FALSE ) { // is the bullet a physics object?
        llSetStatus(STATUS_PHYSICS, TRUE); // if not, make it one
    }
    llSetStatus(STATUS_DIE_AT_EDGE, TRUE); // set bullet to die if it crosses a region edge
    llSetPrimitiveParams([PRIM_TEMP_ON_REZ,TRUE]); // set bullet to be temp-on-rez to cleanup and not count against prim limits
    llSetBuoyancy(BOUYANCY); // make bullet float so it flies
    if ( type >= MINDAMAGE && type <= MAXDAMAGE ) { // is the damage value passed on rez valid?
        DAMAGE = type; // yes it is, override bullet default
    }
    llSetDamage((float)DAMAGE); // set the Linden Lab Combat System damage value to the same as Myriad damage class
    llSetTimerEvent(TIMEOUT); // start the timeout timer to try to force bullet to die too
}
 
//============================================================================
// STATE DEFAULT - where the program starts
//============================================================================
default {
    //------------------------------------------------------------------------
    // COLLISION_START - we just hit an object or avatar
    //------------------------------------------------------------------------
    collision_start(integer collisions) {
        while(collisions--) { // step through each collision event counting down
            // calculate the dynamic channel of who/what we hit
            integer dynchan = (integer)("0x"+llGetSubString((string)SHOOTERKEY,0,6));
            if ( dynchan == 0 ) { return;} // did not get the turret UUID in chat
            // send a ranged combat check to the HUD of the shooter
            // hitting with a bullet is not an automatic "you hit for damage"
            // instead it triggers the shooter to make a ranged combat skill check against their victim
            // if the skill check succeeds, THEN the shot is applied against the victim's armor 
            llRegionSay(dynchan,"RANGEDCOMBAT"+DIV+(string)DAMAGE+DIV+(string)llDetectedKey(collisions)+DIV+(string)SHOOTERKEY+DIV+llGetObjectName());
 
            key who = llDetectedKey(collisions); // get the key of what or who we hit
            // llGetObjectDetails returns avatar key as "owner" of the avatar itself
            // so if key of what we hit matches owner's key, we hit an avatar themselves rather than someone's object
            key owner = llList2Key(llGetObjectDetails(who,[OBJECT_OWNER]),0); // get the owner of the key of what we hit
 
            if ( who == owner ) { // so, did we hit an actual avatar?
                // yes, so as a basic anti-cheat, let's announce to the region that someone is being shot at by someone else
                llRegionSay(CHANMYRIAD,"RPEVENT"+DIV+llKey2Name(SHOOTERKEY)+" shot at "+llDetectedName(collisions)+"!");
            }
        }
        // TODO Shrapnel?
        // TODO Through and through?
        MAKEPARTICLES(RICOCHET); // show the bullet impact
        DIE(); // jump to infinite die loop to cleanup this bullet
    }
 
    //------------------------------------------------------------------------
    // LAND_COLLISION - what to do if bullet hits the ground
    //------------------------------------------------------------------------
    land_collision_start( vector collisions) {
        collisions = <0,0,0>; // LSLINT
        MAKEPARTICLES(RICOCHET); // show the poof of smoke from the ricochet, movie style
        DIE(); // jump to the infinite die loop to clean up this bullet
    }    
 
    //------------------------------------------------------------------------
    // LISTEN - get shooting objects key after rez
    //------------------------------------------------------------------------
    listen(integer channel,string name,key id,string msg) {
        channel = 0; // LSLint
        name = ""; // LSLint
        msg = ""; // LSLint
        SHOOTERKEY = id; // store shooterID
    }
 
    //------------------------------------------------------------------------
    // ON_REZ - called when bullet is rezzed by firearm
    //------------------------------------------------------------------------
    on_rez(integer start_param) {
        SETUP(start_param); // pass any start param to setup as a request to set a custom damage value, if valid, it will be used
    }
 
    //------------------------------------------------------------------------
    // STATE_ENTRY - called if bullet rezzed onto the ground
    //------------------------------------------------------------------------
    state_entry() {
        SETUP(DAMAGE); // sets default damage value - may be overridden on rez
    }
 
    //------------------------------------------------------------------------
    // TIMER - trigger bullet to die after a given time, if all else fails
    //------------------------------------------------------------------------
    timer() {
        DIE(); // timer expired, jump to infinite die loop to cleanup this bullet
    }
}
//============================================================================
// END
//============================================================================
Personal tools
General
About This Wiki