User:Allen Kerensky/Myriad Lite Preview 5/Bullet

From OpenSimulator

Jump to: navigation, search

Myriad Lite Bullet

Because of the skill-based nature of Myriad Lite, simple kinetic bullets are not enough.

Myriad Lite bullets can implement one of multiple damage values.

Setup

  1. Find a sandbox with Scripts disabled. If scripts run when you create the bullet, it WILL set the bullet physical, temp-on-rez, and run the cleanup timer which causes the bullet to die within 20 seconds
  2. Create an object to represent the bullet itself, such as a yellow, glowing, 0.050m sized sphere.
  3. While in the script-disabled area, Drag and Drop the bullet script from inventory into the bullet. ?
  4. Drop in a "puff of smoke" texture of your choice.
  5. Change the texture name in the bullet script.
  6. Set the bullet object to "Physical" and "Temp On Rez"
  7. Quickly take your bullet into inventory before the temp on rez deletes it.

Myriad_Lite_Bullet-v0.0.4-20120130.lsl

//============================================================================
// Myriad_Lite_Bullet-v0.0.4-20120130.lsl
// Copyright (c) 2012 By Allen Kerensky (OSG/SL)
// The Myriad RPG System was designed, written, and illustrated by Ashok Desai
// Myriad RPG licensed under the Creative Commons Attribution 2.0 UK: England and Wales
// http://creativecommons.org/licenses/by/2.0/uk/
// Myriad Lite software Copyright (c) 2011-2012 by Allen Kerensky (OSG/SL)
// Baroun's Adventure Machine Copyright (c) 2008-2011 by Baroun Tardis (SL)
// Myriad Lite and Baroun's Adventure Machine licensed under the
// Creative Commons Attribution-Share Alike-Non-Commercial 3.0 Unported
// http://creativecommons.org/licenses/by-nc-sa/3.0/
// You must agree to the terms of this license before making any use of this software.
// If you do not agree to this license, simply delete these materials.
// There is no warranty, express or implied, for your use of these materials.
//============================================================================
// Davada Gallant (John Girard), WWIIOLers
// Retrieved 2011-04-30 from http://wiki.secondlife.com/wiki/Bullet
// Copyright (c) 2009 Linden Research, Inc. Licensed under Creative Commons Attribution-Share Alike 3.0 (CC-BY-SA 3.0)
// Adapted to OSSL by Allen Kerensky (SL/OSG)
// 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
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

//============================================================================
// GLOBAL SETUP()
//============================================================================
SETUP(integer type) {
    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
}

//============================================================================
// 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 script 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()
    ]);
}
//============================================================================
// 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!
    }
}

//============================================================================
// STATE DEFAULT - where the program starts
//============================================================================
default {
    //------------------------------------------------------------------------
    // STATE_ENTRY - called if bullet rezzed onto the ground
    //------------------------------------------------------------------------
    state_entry() {
        SETUP(DAMAGE); // sets default damage value - may be overridden on rez
    }
    
    //------------------------------------------------------------------------
    // 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
    }
    
    //------------------------------------------------------------------------
    // 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)llGetOwner(),0,6));
            // 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)llGetOwner()+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(llGetOwner())+" 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
    }    
    
    //------------------------------------------------------------------------
    // 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