
////////////////////////////////////////////
// Hunter Script
//
// Written by Xylor Baysklef
// adapted by Damanios Thetan
////////////////////////////////////////////
/////////////// CONSTANTS ///////////////////
float REFRESH_RATE = 5.0;
vector TEXT_COLOR = <1, 0, 0>;
// Prefixes
//string FIND = "find";
//list PREFIXES = [ FIND ];
integer COMMAND_CHANNEL = 3;
// Commands
//string STOP_FIND = "stop finding";
// Message Numbers
integer FIND_CHAN = 4000;
integer STOP_CHAN = 4001;
integer PARTICLE_SYSTEM = 5000;
// This is the sepertaor to use instead of
// a comma.
string FIELD_SEPERATOR = "~!~";
///////////// END CONSTANTS /////////////////
///////////// GLOBAL VARIABLES ///////////////
key gOwner;
string gTarget;
integer gTypes;
integer gShowList;
string gMoveTo = "";
/////////// END GLOBAL VARIABLES /////////////
// This function converts a list of data into
// a string with a seperator between each value.
string ListToString(list data, string seperator) {
integer Length = llGetListLength(data);
// Just return an empty string if the list is empty.
if (Length == 0)
return "";
string Result;
integer i;
integer Type;
// Loop through all but the last entry.
for (i = 0; i < Length - 1; i++) {
Type = llGetListEntryType(data, i);
Result += (string) Type + seperator + llList2String(data, i) + seperator;
}
// Add the last entry, without a seperator at the end.
Type = llGetListEntryType(data, -1);
Result += (string) Type + seperator + llList2String(data, -1);
return Result;
}
StartFinding() {
llSetText(gTarget, TEXT_COLOR, 1.0);
llSensor (gTarget, "",gTypes, 96.0, PI);//gTypes
llSensorRepeat(gTarget, "",gTypes, 96.0, PI, REFRESH_RATE);
}
StopFinding() {
llSetText("", TEXT_COLOR, 1.0);
llSensorRemove();
llMessageLinked(LINK_SET, STOP_CHAN, "", "");
}
default {
state_entry() {
// Listen for everything from owner.
gOwner = llGetOwner();
llListen(COMMAND_CHANNEL, "", gOwner, "");
// Reset old system.
llMessageLinked(LINK_SET, STOP_CHAN, "", "");
llSetText("", TEXT_COLOR, 1.0);
// Flags
// PSYS_PART_EMISSIVE_MASK;
// PSYS_PART_BOUNCE_MASK;
// PSYS_PART_INTERP_COLOR_MASK;
// PSYS_PART_INTERP_SCALE_MASK;
// PSYS_PART_WIND_MASK;
// PSYS_PART_FOLLOW_SRC_MASK;
// PSYS_PART_FOLLOW_VELOCITY_MASK;
// PSYS_PART_TARGET_POS_MASK;
integer Flags = PSYS_PART_EMISSIVE_MASK |
PSYS_PART_INTERP_COLOR_MASK |
PSYS_PART_INTERP_SCALE_MASK |
PSYS_PART_TARGET_POS_MASK;
// Choose a pattern from the following:
// PSYS_SRC_PATTERN_EXPLODE
// PSYS_SRC_PATTERN_DROP
// PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY
// PSYS_SRC_PATTERN_ANGLE_CONE
// PSYS_SRC_PATTERN_ANGLE
integer Pattern = PSYS_SRC_PATTERN_DROP;
// Send a default particle system setup.
llMessageLinked(LINK_SET, PARTICLE_SYSTEM, ListToString([
PSYS_PART_MAX_AGE, 3.0,
PSYS_PART_FLAGS, Flags,
//PSYS_PART_START_COLOR, startColor,
//PSYS_PART_END_COLOR, endColor,
PSYS_PART_START_SCALE, <0.5, 0.5, 0.5>,
PSYS_PART_END_SCALE, <0.1, 0.1, 0.1>,
PSYS_SRC_PATTERN, Pattern,
PSYS_SRC_BURST_RATE, 0.25,
//PSYS_SRC_ACCEL, push,
PSYS_SRC_BURST_PART_COUNT, 1,
//PSYS_SRC_BURST_RADIUS, radius,
PSYS_SRC_BURST_SPEED_MIN, 100.0,
PSYS_SRC_BURST_SPEED_MAX, 100.0,
//PSYS_SRC_TARGET_KEY,target,
PSYS_SRC_INNERANGLE, 1.54,
PSYS_SRC_OUTERANGLE, 1.55,
PSYS_SRC_OMEGA, <0, 0, 0>,
PSYS_SRC_MAX_AGE, 0.0,
//PSYS_SRC_TEXTURE, texture,
PSYS_PART_START_ALPHA, 1.0,
PSYS_PART_END_ALPHA, 1.0
], FIELD_SEPERATOR), "");
//gTarget = "Park Bench";
//StartFinding();
}
on_rez(integer param) {
if (llGetOwner() != gOwner)
llResetScript();
}
touch_start(integer num_detected) {
if (llDetectedKey(0) != llGetOwner())
return;
}
no_sensor() {
//llSay(0, "test");
llMessageLinked(LINK_SET, STOP_CHAN, "", "");
}
sensor(integer num) {
list Found;
integer i;
for (i = 0; i < num; i++) {
//if (llDetectedOwner(i) == "7d4a9636-d5d1-419d-8459-7679ccde6672")
Found += [llDetectedKey(i)];
if (gMoveTo != "" && llGetSubString(llToLower(llDetectedName(i)),0,llStringLength(gMoveTo)
- 1) == llToLower(gMoveTo))
{
llMoveToTarget(llDetectedPos(i),1);
llTarget(llDetectedPos(i),1);
llLookAt(llDetectedPos(i),10,1);
gMoveTo = llDetectedName(i);
llWhisper(0,"Moving to " + gMoveTo);
}
if (gShowList)
llWhisper(0,llDetectedName(i) + ": " + (string) llKey2Name(llDetectedOwner(i)) +
": " + (string) llDetectedPos(i));
}
gShowList = FALSE;
//llSay(0, (string) num);
llMessageLinked(LINK_SET, FIND_CHAN, ListToString(Found, FIELD_SEPERATOR), "");
}
at_target(integer num,vector tpos,vector opos)
{
llStopMoveToTarget();
llStopLookAt();
llWhisper(0,gMoveTo + " reached!");
llTargetRemove(num);
gMoveTo = "";
}
listen(integer channel, string name, key id, string mesg) {
// Check for commands.
if (mesg == "stop") {
StopFinding();
llStopMoveToTarget();
llStopLookAt();
return;
}
if (llGetSubString(mesg,0,3) == "move")
{
gMoveTo = llGetSubString(mesg,5,9999);
gTypes = AGENT | PASSIVE | SCRIPTED;
if (gMoveTo == "") {
gMoveTo = gTarget;
}
StartFinding();
return;
}
gTarget = "";
gMoveTo ="";
if (mesg == "all")
gTypes = AGENT | PASSIVE | SCRIPTED;
else if (mesg == "objects")
gTypes = PASSIVE | SCRIPTED;
else if (mesg == "list")
gShowList= TRUE;
else if (mesg == "nolist")
gShowList= FALSE;
else if (mesg == "agents")
gTypes = AGENT;
else if (mesg == "scripts")
gTypes = SCRIPTED;
else if (mesg == "active")
gTypes = ACTIVE;
else if (mesg == "passive")
gTypes = PASSIVE;
else {
gTarget = mesg;
gTypes = AGENT | PASSIVE | SCRIPTED;
}
StartFinding();
}
link_message(integer sender, integer channel, string data, key id) {
}
}
///////////////////////////////
target
///////////////////////
////////////////////////////////////////////
// Target Script
//
// Written by Xylor Baysklef
////////////////////////////////////////////
/////////////// CONSTANTS ///////////////////
integer DEATH_CHAN = 2184384941;
// Message Numbers
integer FIND_CHAN = 4000;
integer STOP_CHAN = 4001;
integer PARTICLE_SYSTEM = 5000;
// This is the sepertaor to use instead of
// a comma.
string FIELD_SEPERATOR = "~!~";
///////////// END CONSTANTS /////////////////
///////////// GLOBAL VARIABLES ///////////////
list gParticleSystem;
integer gTargetNum;
vector gColor;
string gName;
/////////// END GLOBAL VARIABLES /////////////
// This function turns a string into a list, using a
// field seperator. It assumes the string was produced
// by the function ListToString.
list StringToList(string data, string FIELD_SEPERATOR) {
list Result;
// First split up the string using the field seperator.
list Parsed = llParseString2List(data, [FIELD_SEPERATOR], []);
integer Length = llGetListLength(Parsed);
// Make sure the list is of even length.
if (Length % 2 != 0) {
llSay(0, "StringToList::Invalid String");
return;
}
// Loop through the list, two at a time. The first
// entry of each pair is the type, the second is the value.
integer i;
for (i = 0; i < Length; i += 2) {
integer Type = (integer) llList2String(Parsed, i);
string Value = llList2String(Parsed, i + 1);
if (Type == TYPE_INTEGER) {
Result += (integer) Value;
}
else if (Type == TYPE_FLOAT) {
Result += (float) Value;
}
else if (Type == TYPE_VECTOR) {
Result += (vector) Value;
}
else if (Type == TYPE_ROTATION) {
Result += (rotation)Value;
}
else if (Type == TYPE_KEY) {
Result += (key) Value;
}
else // TYPE_STRING
Result += Value;
}
return Result;
}
float MetaToColor( float M1, float M2, float Hue ) {
float Color;
// Calculate Color from Meta values
if (Hue < 0.0)
Hue += 1.0;
if (Hue > 1.0)
Hue -= 1.0;
if (Hue * 6.0 < 1.0)
Color = M1 + ((M2 - M1) * Hue * 6.0);
else if (Hue * 2.0 < 1.0)
Color = M2;
else if (Hue * 3.0 < 2.0)
Color = M1 + ((M2 - M1) * ((2.0/3.0) - Hue) * 6.0);
else
Color = M1;
return Color;
}
vector HSL_To_RGB(vector HSL) {
float Hue = HSL.x;
float Sat = HSL.y;
float Lum = HSL.z;
float Red;
float Green;
float Blue;
if (Sat == 0.0) {
Red = Lum;
Green = Lum;
Blue = Lum;
}
else {
float Meta1;
float Meta2;
if (Lum <= 0.5)
Meta2 = Lum * (1.0 + Sat);
else
Meta2 = Lum + Sat - (Lum * Sat);
Meta1 = 2.0 * Lum - Meta2;
Red = MetaToColor( Meta1, Meta2, Hue + 1.0/3.0 );
Green = MetaToColor( Meta1, Meta2, Hue );
Blue = MetaToColor( Meta1, Meta2, Hue - 1.0/3.0 );
}
return <Red, Green, Blue>;
}
float TargetToHue(integer num) {
return ((float) num) / 16.0;
integer RingNum = num / 6;
if (num > 12)
num *= 2;
integer RingPos = num % 6;
integer Side = RingPos % 2;
float Hue = (float) (RingPos / 2) * 0.166666666;
if (Side)
Hue += 0.5;
Hue += RingNum * 0.0833333333;
return Hue;
}
Initialize() {
//gName = llGetObjectName();
// Check for a name change.
//llSetTimerEvent(5.0);
//list Parsed = llParseString2List(gName, [" "], []);
//gTargetNum = (integer) llList2String(Parsed, -1);
gTargetNum = llGetStartParameter() - 1;
vector HSL;
HSL.x = TargetToHue(gTargetNum);
HSL.y = 1.0;
HSL.z = 0.5;
//if (gTargetNum > 12)
// HSL.y = 0.75;
//if (gTargetNum == 15)
// HSL.z = 1.0;
gColor = HSL_To_RGB(HSL);
llSetColor(gColor, ALL_SIDES);
//llSay(0, "Initializing Target #" + (string) gTargetNum);
}
default {
state_entry() {
Initialize();
}
touch_start(integer num_detected) {
if (llDetectedKey(0) != llGetOwner())
return;
}
on_rez(integer param) {
if (param == 0)
return;
Initialize();
llListen(DEATH_CHAN, "", "", "die");
}
listen(integer channel, string name, key id, string mesg) {
llDie();
}
link_message(integer sender, integer channel, string data, key id) {
if (channel == PARTICLE_SYSTEM) {
gParticleSystem = StringToList(data, FIELD_SEPERATOR);
return;
}
if (channel == STOP_CHAN) {
llParticleSystem([]);
return;
}
if (channel == FIND_CHAN) {
list Keys = StringToList(data, FIELD_SEPERATOR);
key Key = llList2Key(Keys, gTargetNum);
if (Key == NULL_KEY) {
llParticleSystem([]);
return;
}
llParticleSystem(gParticleSystem + [
PSYS_PART_START_COLOR, gColor,
PSYS_PART_END_COLOR, gColor,
PSYS_SRC_TARGET_KEY, Key ]);
return;
}
}
}