// Francis was here
// Constants
integer sensorDistance = 10;
list hug_cmd = [ "hug", "/hug" ];
integer linkChannel = 598242;
string linkStringRequest = "HUG_TARGET_=^..^=REQUEST";
string linkStringStart = "HUG_TARGET_=^..^=START";
string linkStringAnim = "HUG_TARGET_=^..^=ANIM";
string linkStringReset = "HUG_TARGET_=^..^=RESET";
string animName = "hug";
integer animTime = 15;
vector posOffset1 = <0.3, 0, 0>;
vector posOffset2 = <0, 0, 0>;
// Not Constants
string avTarget = "";
vector avPos = ZERO_VECTOR;
key avKey = NULL_KEY;
rotation avRot = ZERO_ROTATION;
string avName = "";
integer avFindName = TRUE;
string checkMatch( string str, list prefixes ) {
integer numElements = llGetListLength( prefixes );
integer i;
integer lastChar;
string curPrefix;
string curStr = llToLower( str );
for( i=0; i<numElements; i++ ) {
curPrefix = llList2String(prefixes, i);
lastChar = llStringLength( curPrefix );
lastChar -= 1;
if ( llGetSubString(curStr, 0, lastChar) == curPrefix )
return curPrefix;
}
return "";
}
integer setAvTarget( string message, string match ) {
integer mesgLen = llStringLength( message );
integer matchLen = llStringLength( match );
if ( mesgLen <= matchLen + 1 ) {
avTarget = "";
return FALSE;
}
else {
mesgLen -= 1;
avTarget = llGetSubString( message, matchLen+1, mesgLen );
avTarget = llToLower( avTarget );
return TRUE;
}
}
usageMessage() {
llInstantMessage( llGetOwner(), "Usage: Face your target and Say '/hug [person's
name]' or '/1hug [person's name]'" );
}
default
{
state_entry() {
if ( llGetAttached() )
llRequestPermissions(llGetOwner(),PERMISSION_TRIGGER_ANIMATION);
usageMessage();
}
on_rez( integer startcode ) {
llResetScript();
}
attach( key k ) {
if ( k != NULL_KEY )
llResetScript();
}
run_time_permissions(integer parm) {
if( parm & PERMISSION_TRIGGER_ANIMATION ) {
llListen( 0, "", llGetOwner(), "" );
llListen( 1, "", llGetOwner(), "" );
}
}
sensor(integer total_number) {
if ( avFindName ) {
integer i;
for ( i = 0; i < total_number; i++ ) {
vector pos;
rotation rot;
if ( llSubStringIndex(llToLower(llDetectedName(i)), avTarget) >= 0
&& llDetectedKey(i) != llGetOwner() ) {
avName = llDetectedName(i);
llInstantMessage( llGetOwner(), "You have offered to hug " + avName + "." );
llMessageLinked( LINK_SET, linkChannel, linkStringRequest, llDetectedKey(i) );
avPos = llDetectedPos(i);
avRot = llDetectedRot(i);
avName = llList2String( llParseString2List( avName, [" "], [] ), 0 );
avKey = llDetectedKey(i);
return;
}
}
}
else {
vector pos;
vector size = llGetAgentSize( llGetOwner() );
float mass = size.x * size.y * size.z;
avPos = llDetectedPos(0);
avRot = llDetectedRot(0);
//mass = mass * 1000;
pos = avPos + posOffset1 * avRot;
llMoveToTarget( pos, .5 );
llSleep(.6);
pos = avPos + posOffset2 * avRot;
llMoveToTarget( pos, .5 );
llSleep(.6);
llMoveToTarget( pos, 1 );
//llLookAt( avPos, mass/2, mass/20 );
//llApplyRotationalImpulse( mass*<1,1,1>, FALSE );
//llSleep(3);
//llStopLookAt();
//return;
// Okay, first say a nice message
string origName = llGetObjectName();
string owner;
owner = llKey2Name( llGetOwner() );
owner = llList2String( llParseString2List( owner, [" "], [] ), 0 );
llSetObjectName( owner );
llSay( 0, "/me gives " + avName + " a big hug." );
llSetObjectName( origName );
// And then, do the anim
llMessageLinked( LINK_SET, linkChannel, linkStringAnim, NULL_KEY );
llStartAnimation( animName );
llSleep( animTime );
llStopAnimation( animName );
llStopMoveToTarget();
}
}
no_sensor() {
llInstantMessage( llGetOwner(), "Couldn't find hug target, '" + avTarget + "'"
);
llMessageLinked( LINK_SET, linkChannel, linkStringReset, NULL_KEY );
}
link_message( integer sender, integer i, string s, key k ) {
if ( i == linkChannel && s == linkStringStart ) {
avFindName = FALSE;
llSensor( "", avKey, AGENT, sensorDistance, PI );
}
}
listen(integer channel,string name,key id,string message) {
string match;
match = checkMatch( message, hug_cmd );
if( match != "" ) {
if ( !setAvTarget( message, match ) )
usageMessage();
else {
avFindName = TRUE;
llSensor( "", NULL_KEY, AGENT, sensorDistance, PI );
}
}
}
}