Ice Bullets

From Second Life Wiki
Jump to: navigation, search

Created by Kira Komarov based on some tricks on Wizardry and Steamworks.

ChangeLog

  • 18 December 2011

Fix for names larger than 24 characters.

Introduction

I have been asked to create a subtle assassination device that would kill an avatar on a SIM with land damage turned on. The purpose was to make the bullets vanish as soon as the task had been accomplished and to make them hard to detect. I know some kids have fun with similar devices on their SIM, so knock yourselves out with it.

Features and Limitations

  • The rezzer uses an endless menu to grab the names of the avatars around.
  • The ice bullet is transparent and very small sized and hard to select individually.
  • You need a clear line of sight, on any collision the bullet will destroy itself.
  • If the bullet does not reach its target for any reason, it will destroy itself after a timeout (30 seconds).
  • The bullet is homing, it makes course-corrections every 1 seconds.
  • When the target is reached, the bullet destroys itself.

Setup

  1. Create a primitive and set the texture to a transparent texture. Make the prim as small as possible - you may even use a nano sphere. Name the primitive *.
  2. Copy the Ice Bullet script into the primitive from step 1 named *.
  3. Take the bullet into your inventory.
  4. Create a new primitive and place the bullet inside it.
  5. Copy the script Pea Shooter and place it in the primitive from step 4.

You are set. Click the primitive to select a target. You may also wear the primitive from step 4 as an attachment or add the components to some other attachment.

Code

Ice Bullet - should be placed in a small, transparent textured sphere and the object should be named *.

//////////////////////////////////////////////////////////
// [K] Kira Komarov - 2011, License: GPLv3              //
// Please see: http://www.gnu.org/licenses/gpl.html     //
// for legal details, rights of fair usage and          //
// the disclaimer and warranty conditions.              //
//////////////////////////////////////////////////////////
//Gremlin: Ice Bullet, see Ice Bullet Peashooter
////
integer Key2Number(key objKey) {
  return ((integer)("0x"+llGetSubString((string)objKey,-8,-1)) & 0x3FFFFFFF) ^ 0xBFFFFFFF;
}
 
integer tgtID = 0;
key tgtKey = NULL_KEY;
integer nTgT = 0;
 
init() {
    llSetStatus(STATUS_DIE_AT_EDGE | STATUS_PHYSICS, TRUE);
    llSetDamage(100.0);
}
 
integer flag = 0;
 
default
{
    at_target(integer tnum, vector targetpos, vector ourpos) {
        if(tgtKey == NULL_KEY) return;
        llSetTimerEvent(0);
        llDie();
    }
    collision_start(integer num_detected) {
        llDie();
    }
    timer() {
        llSetTimerEvent(0);
        llTargetRemove(nTgT);
        vector pos = llList2Vector(llGetObjectDetails(tgtKey, [OBJECT_POS]), 0);
        nTgT = llTarget(pos, 1.0);
        llMoveToTarget(pos, 0.5);
        llSetTimerEvent(1);
    }
    on_rez(integer param) {
        tgtID = param;
        llSensorRepeat("", "", AGENT_BY_LEGACY_NAME, 96, TWO_PI, llGetRegionTimeDilation()); 
    }
    sensor(integer num_detected) {
        integer itra;
        for(itra=0; itra<num_detected; ++itra) {
            tgtKey = llDetectedKey(itra);
            if(Key2Number(tgtKey) == tgtID) { 
                llSensorRemove();
                vector pos = llList2Vector(llGetObjectDetails(tgtKey, [OBJECT_POS]), 0);
                nTgT = llTarget(pos, 0.01);
                init();
                llSensorRepeat("", NULL_KEY, flag=1, 0.1, 0.1, 30);
                llMoveToTarget(pos, 0.045);
                llSetTimerEvent(1);
                return;
            }
        }
    }
    no_sensor() {
        if(flag--) {
            return;
        }
        llDie();
    }
}

Pea Shooter - placed in the object rezzing the Ice Bullet.

 
//////////////////////////////////////////////////////////
// [K] Kira Komarov - 2011, License: GPLv3              //
// Please see: http://www.gnu.org/licenses/gpl.html     //
// for legal details, rights of fair usage and          //
// the disclaimer and warranty conditions.              //
//////////////////////////////////////////////////////////
//Gremlin: Ice Bullet Peashooter, see Ice Bullet
////
integer Key2Number(key objKey) {
  return ((integer)("0x"+llGetSubString((string)objKey,-8,-1)) & 0x3FFFFFFF) ^ 0xBFFFFFFF;
}
 
list mFwd() {
    if(mitra+1>llGetListLength(menu_items)) return cList;
    cList = llListInsertList(llListInsertList(llList2List(menu_items, ++mitra, (mitra+=9)), ["<= Back"], 0), ["Next =>"], 2);
    return cList;
} 
 
list mBwd() {
    if(mitra-19<0) return cList;
    cList = llListInsertList(llListInsertList(llList2List(menu_items, (mitra-=19), (mitra+=9)), ["<= Back"], 0), ["Next =>"], 2);
    return cList;
}
 
list tgtKeys = [];
list tgtNames = [];
 
list menu_items = [];
integer mitra = 0;
list cList = [];
 
integer comHandle = 0;
 
default
{
    touch_start(integer total_number) {
        if(llDetectedKey(0) != llGetOwner()) return;
        llSensor("", "", AGENT, 96, TWO_PI);
    }
    sensor(integer num_detected) {
        integer itra;
        for(itra=0, mitra=0, menu_items=[]; itra<num_detected; ++itra) {
            tgtKeys += llDetectedKey(itra);
            tgtNames += llGetSubString(llDetectedName(itra), 0, 23);
            menu_items += llGetSubString(llDetectedName(itra), 0, 23);
        }
        cList = llListInsertList(llListInsertList(llList2List(menu_items, mitra, (mitra+=9)), ["<= Back"], 0), ["Next =>"], 2);
        integer comChannel = ((integer)("0x"+llGetSubString((string)llGetOwner(),-8,-1)) & 0x3FFFFFFF) ^ 0xBFFFFFFF;
        comHandle = llListen(comChannel, "", llGetOwner(), "");
        llDialog(llGetOwner(), "\nSelect target:\n", menu_items, comChannel);
    }
    listen(integer channel, string name, key id, string message) {
        llListenRemove(comHandle);
        llRezObject("*", llGetPos() + <0,0,3>, ZERO_VECTOR, ZERO_ROTATION, Key2Number(llList2Key(tgtKeys, llListFindList(tgtNames, (list)llGetSubString(message,0,23)))));
    }
}

Hacks

  • One could make the rezzer continuously scan a range for avatars and rez bullets as necessary without intervention - giving you true plow experience.