You are on page 1of 3

// // // // // // // //

Swarm script by Apotheus Silverman with mods from Riptide Ramos This script is my implementation of the well-known swarm algorithm which can be found in numerous open-source programs. Due to the specifics of the SL environment, I have strayed from some of the traditional rules slightly. Regardless, the end effect is indistiguishable from the original algorithm.

// Configurable parameters // Determines whether or not to enable STATUS_SANDBOX. integer sandbox = FALSE; // Timer length float timer_length = 0.7; // Die after this many seconds integer kill_time = 300; // How much force to apply with each impulse float force_modifier = 1.0; // How much force to apply when repulsed by another like me float repulse_force_modifier = 0.5; // How much friction to use on a scale from 0 to 1. // Note that friction takes effect each timer cycle, so the lower the timer leng th, // the more the friction you specify here will take effect, thereby increasing a ctual // friction applied. float friction = 0.6; // How much to modify rotation damping. Higher numbers produce slower rotation. float rotation_modifier = 80; // Does this object "swim" in air or water? // 2 = air // 1 = water // 0 = both integer flight_mode = 2; // *** Don't change anything below unless you *really* know what you're doing ** * // Collision function collide(vector loc) { vector mypos = llGetPos(); float mass = llGetMass(); // Apply repulse force vector impulse = llVecNorm(mypos - loc); llApplyImpulse(impulse * repulse_force_modifier * mass, FALSE); // Update rotation llLookAt(mypos + llGetVel(), mass * 0.5, mass * rotation_modifier); } // This function is called whether the sensor senses anything or not sensor_any() {

// Die after reaching kill_time if (kill_time != 0 && llGetTime() >= kill_time) { llDie(); } // Get my position and mass vector mypos = llGetPos(); // Check for air/water breach if (flight_mode == 1) { // water if (mypos.z >= llWater(mypos)) collide(<mypos.x, mypos.y, } } else if (flight_mode == 2) { // air if (mypos.z <= llWater(mypos)) collide(<mypos.x, mypos.y, } } } default { state_entry() { llSay(0, "Fishy spawned."); // Sandbox llSetStatus(STATUS_SANDBOX, sandbox); llSetStatus(STATUS_BLOCK_GRAB, FALSE); // Initialize physics behavior llSetBuoyancy(1.0); llSetStatus(STATUS_PHYSICS, TRUE); llSetStatus(STATUS_PHANTOM, FALSE); // Initialize sensor llSensorRepeat(llGetObjectName(), NULL_KEY, ACTIVE SCRIPTED, 96, PI, tim er_length); } collision_start(integer total_number) { collide(llDetectedPos(0)); } land_collision_start(vector position) { vector mypos = llGetPos(); collide(mypos - llGroundNormal(mypos)); } no_sensor() { sensor_any(); } sensor(integer total_number) { sensor_any(); // Populate neighbors with the positions of the two nearest neighbors. vector mypos = llGetPos(); float mass = llGetMass();

{ mypos.z + 0.3> );

{ mypos.z - 0.3> );

list neighbors = []; integer i; vector v1; vector v2; float d1 = 100; float d2 = 100; for (i = 0; i < total_number; i++) { vector current_pos = llDetectedPos(i); float cur_dist = llVecDist(mypos, current_pos); if ( cur_dist < d1 ) { // Shift list down, take over top slot. d2 = d1; v2 = v1; d1 = cur_dist; v1 = current_pos; } else if ( cur_dist < d2 ) { // Replace second slot only d2 = cur_dist; v2 = current_pos; } } // Process movement // Apply friction llApplyImpulse(-(llGetVel() * friction * mass), FALSE); // Apply force if (llGetListLength(neighbors) == 2) { vector neighbor1 = llList2Vector(neighbors, 0); vector neighbor2 = llList2Vector(neighbors, 1); vector target = neighbor2 + ((neighbor1 - neighbor2) * 0.5); vector impulse = llVecNorm(target - mypos); llSetForce(impulse * force_modifier * mass, FALSE); } // Update rotation llLookAt(llGetPos() + llGetVel(), mass * 0.5, mass * rotation_modifier); } on_rez(integer start_param) { llResetTime(); } }

You might also like