So I call llSensor("", "", ....) ?
Nope that didn't do it...
I'd really appreciate it if someone would help me fix this - I can promise the source for my conversation code as a reward! It's a pretty easy to use keyword-oriented command syntax, kind of like the old ultima games used.
Here's my code - just make a ball prim and drop it in. There's supposed to be a linked prim with that ai conversation code in it but I hacked up the listen event to listen to the following:
follow - should follow you
kill - should reset to follow mode
auto - this is the mode I'm having problems with
activate these by saying /navi follow, /navi kill, or /navi auto
When you type in /navi auto she'll start telling you what she's doing. Every now and then she'll say "looking for someone" and then whether or not the person found is on her list of people she's previously greeted. If she gets "00000000-0000-0000-0000-000000000000" she simply says the id and name. This is caught in the else side of the if(CustomerSensor == 0) statement in the sensor() event and then passed to greet_someone() to do the comparison - greet_someone used to do the looping and whatnot internally but I changed it to this to see if it fixed the problem...
BTW, sorry for the indention - my text editor sets tabs to 4 spaces a piece while IE sets them to 8 spaces each...
list dances = [ "BackFlip","dance1", "dance2", "dance3", "dance4" ];
integer WHICH = 0;
integer TOTAL = 5;
integer PERMS = 0;
integer boolReturn = 0;
integer boolReturning = 0;
integer selfdance = 0;
string ownerName;
vector ownerPos;
string shopMessage;
integer naviport = 1337;
integer ownerSaid;
key saidID;
float particle_color_cycle = 0.0;
integer CustomSensor = 0;
integer HIGH_BEAMS = 0;
integer MODE_FOLLOW = 0;
integer MODE_AUTO = 1;
integer MODE_ATTRACT = 2;
integer MODE_DANCE = 3;
integer MODE_SHOPGREET = 4;
integer MODE_RAVE = 5;
integer MODE_TELL = 6;
float current_rotation = 0;
vector rotation_axis = <0, 0, 1>;
vector rotation_offset = <0, 0, .1>;
integer ticks = 0;
integer tickdelay = 0;
integer ticksToBeBig = 0;
integer ticksToSayHi = 0;
integer ticktimeout = 3;
integer current_mode = 0;
float burst_time = 0;
float floatdist = 0.1; // This is the distance we bob up and down.
float floatmod = 0.025;
float floaty;
integer flippertog;
float floatbase;
list avatarsGreeted = [];
string avatarGreeting = NULL_KEY;
vector avatarPos;
rotation avatarRot;
vector offset =<-1,0.6,1>;
vector attractobject;
vector HOVER_BEHIND = <-1,0.6,1>;
vector HOVER_INFRONT = <1, 0, 1>;
vector HOVER_ATWAIST = <1, 0, .4>;
vector HOVER_ATFEET = <1, 0, 0>;
integer listenCallback = 0;
integer Detected;
float abs(float v)
{
if(v < 0)
return -1 * v;
else
return v;
}
mySetParticles() {
vector START_SCALE = < 0.1, 0.9, 0.0 >;
vector END_SCALE = < 0.9, 0.1, 0.0 >;
float red = 0.0;
float green = 0.0;
float blue = 0.0;
if(particle_color_cycle < 0.333)
{
red = abs(0.333 - particle_color_cycle) * 3;
}
if(particle_color_cycle > 0.667)
{
red = (particle_color_cycle - 0.667) * 3;
}
if(particle_color_cycle < 0.667)
{
green = 1 - abs(particle_color_cycle - 0.333) * 3;
}
if(particle_color_cycle > 0.333)
{
blue = 1 - abs(particle_color_cycle - 0.667) * 3;
}
vector START_COLOR = < red, green, blue >;
llSetColor(START_COLOR, 0);
vector END_COLOR = START_COLOR * 0.8;
float START_ALPHA = 0.5 ;
float END_ALPHA = 0.1;
integer INTERP_COLOR = TRUE;
integer INTERP_SCALE = TRUE;
integer EMISSIVE = TRUE;
string TEXTURE = "Navi Texture";
float AGE = 2.00;
float RATE = 0.03;
integer COUNT = 10;
float LIFE = 0.0;
integer PATTERN = PSYS_SRC_PATTERN_ANGLE_CONE;
float RADIUS = 0.00;
float ANGLE_BEGIN = 0;
float ANGLE_END = 0.30;
vector OMEGA = < 0.00, 0.00, 2.00 >;
integer FOLLOW_SRC = FALSE;
integer FOLLOW_VELOCITY = TRUE;
integer WIND = TRUE;
integer BOUNCE = TRUE;
float SPEED_MIN = 0.70;
float SPEED_MAX = 1.20;
vector ACCEL = < 0.00, 0.00, -0.40 >;
integer TARGET_POS = FALSE;
key TARGET = llGetKey();
if(HIGH_BEAMS == 0) {
RATE = 0.05;
COUNT = 2;
FOLLOW_VELOCITY = FALSE;
WIND = FALSE;
SPEED_MIN = 0;
ACCEL = <0, 0, 0>;
PATTERN = PSYS_SRC_PATTERN_DROP;
} else {
}
list particle_parameters = [
PSYS_PART_FLAGS, (
( EMISSIVE * PSYS_PART_EMISSIVE_MASK ) |
( BOUNCE * PSYS_PART_BOUNCE_MASK ) |
( INTERP_COLOR * PSYS_PART_INTERP_COLOR_MASK ) |
( INTERP_SCALE * PSYS_PART_INTERP_SCALE_MASK ) |
( WIND * PSYS_PART_WIND_MASK ) |
( FOLLOW_SRC * PSYS_PART_FOLLOW_SRC_MASK ) |
( FOLLOW_VELOCITY * PSYS_PART_FOLLOW_VELOCITY_MASK ) |
( TARGET_POS * PSYS_PART_TARGET_POS_MASK ) ),
PSYS_PART_START_COLOR, START_COLOR,
PSYS_PART_END_COLOR, END_COLOR,
PSYS_PART_START_ALPHA, START_ALPHA,
PSYS_PART_END_ALPHA, END_ALPHA,
PSYS_PART_START_SCALE, START_SCALE,
PSYS_PART_END_SCALE, END_SCALE,
PSYS_SRC_PATTERN, PATTERN,
PSYS_SRC_BURST_PART_COUNT, COUNT,
PSYS_SRC_BURST_RATE, RATE,
PSYS_PART_MAX_AGE, AGE,
PSYS_SRC_ACCEL, ACCEL,
PSYS_SRC_BURST_RADIUS, RADIUS,
PSYS_SRC_BURST_SPEED_MIN, SPEED_MIN,
PSYS_SRC_BURST_SPEED_MAX, SPEED_MAX,
PSYS_SRC_TARGET_KEY, TARGET,
PSYS_SRC_ANGLE_BEGIN, ANGLE_BEGIN,
PSYS_SRC_ANGLE_END, ANGLE_END,
//PSYS_SRC_INNERANGLE, INNERANGLE,
//PSYS_SRC_OUTERANGLE, OUTERANGLE,
PSYS_SRC_OMEGA, OMEGA,
PSYS_SRC_MAX_AGE, LIFE,
PSYS_SRC_TEXTURE, TEXTURE
];
llParticleSystem( particle_parameters );
}
startup()
{
floatbase = offset.z;
flippertog = TRUE;
vector pos = llGetPos();
llSetScale(<0.02, 0.02, 0.02>

;
llSetStatus(STATUS_ROTATE_Z,TRUE);
key id = llGetOwner();
lookForOwner();
if(listenCallback > 0)
llListenRemove(listenCallback);
listenCallback = llListen(0, "", NULL_KEY, ""

;
llMinEventDelay(.05);
llSetTimerEvent(.3); // reset the alarm clock
naviTitle();
}
floatcountplus()
{
offset = <offset.x,offset.y,floatbase>; //Return to base z offset.
if (flippertog == TRUE)//Going up?
{
floaty = floaty + floatmod;
if (floaty > floatdist) // We just added, are we capped?
flippertog = FALSE;
} else {
floaty = floaty - floatmod;
if (floaty < -floatdist) // We just added, are we capped?
flippertog = TRUE;
}
floatbase = offset.z;
offset = <offset.x,offset.y,offset.z+floaty>;
}
lookForOwner() {
llSensorRemove();
llSensorRepeat("",llGetOwner(),AGENT,200,2*PI,.5);
}
integer particles_on = 1;
integer greet_someone(string name, key id, vector pos, rotation myrot) {
if(id == NULL_KEY) {
llOwnerSay("id = " + (string)id + " name = " + name);
return -1;
}
integer index = llListFindList(avatarsGreeted, [name]);
if(index == -1) {
llOwnerSay("Greeting " + name);
avatarsGreeted += [name];
avatarGreeting = name;
Detected = 1;
avatarPos = pos;
avatarRot = myrot;
llMoveToTarget(pos+offset*avatarRot,.3);
llLookAt(pos, .1 , 1);
return 1;
}
llOwnerSay("Already greeted: " + name);
return -1;
}
naviTitle() {
llSetText("Navi", <.2, 1, .2>, 1.0);
}
default
{
state_entry()
{
startup();
}
listen(integer channel, string name, key id, string message)
{
string command = llGetSubString(message, 6, llStringLength(message));
integer first_space = 0;
string first_command = NULL_KEY;
string message_remainder = NULL_KEY;
//I know now there are more efficient ways to do this... this was my first parser
for(first_space = 0; first_space < llStringLength(command); first_space++)
{
if(llGetSubString(command, first_space, first_space) == " "

{
first_command = llGetSubString(command, 0, first_space - 1);
message_remainder = llGetSubString(command, first_space + 1, llStringLength(command));
}
}
if(first_command == NULL_KEY)
first_command = command;
if(llGetSubString(message, 0, 4) == "/navi"

{
saidID = id;
if(id == llGetOwner()) {
ownerSaid = TRUE;
} else {
ownerSaid = FALSE;
}
saidID = (string)id;
if(first_command == "kill"

{
particles_on = 0;
mySetParticles();
current_mode = MODE_FOLLOW;
offset = HOVER_BEHIND;
HIGH_BEAMS = 0;
lookForOwner();
}
if(first_command == "shopgreet" && ownerSaid == TRUE)
{
avatarsGreeted = [];
if(message_remainder != NULL_KEY) {
current_mode = MODE_SHOPGREET;
ownerPos = llGetPos();
shopMessage = message_remainder;
HIGH_BEAMS = 1;
llSensorRemove();
llSensorRepeat("","",AGENT,20,2*PI,2);
llSay(0, "Ok I'm going to tell people " + message_remainder);
} else {
llSay(0, "Tell me what you would like to say like {/navi shopgreet message}"

;
}
}
llMessageLinked(LINK_ALL_OTHERS, naviport, first_command, (key)name);
if(first_command == "follow"

{
current_mode = MODE_FOLLOW;
offset = HOVER_BEHIND;
HIGH_BEAMS = 0;
lookForOwner();
}
if(first_command == "auto"

{
avatarsGreeted = [];
current_mode = MODE_AUTO;
offset = HOVER_BEHIND;
HIGH_BEAMS = 0;
lookForOwner();
}
}
}
link_message(integer sender_num, integer num, string str, key id) {
//this is how we process commands from the ai script - since its not present, this code should never run.
string first_command = (string)id;
if(first_command == ""

{
llSay(0, str);
return;
}
if(first_command == "glow"

{
if(particles_on == 1) {
particles_on = 0;
llParticleSystem( [] );
}
else
{
particles_on = 1;
mySetParticles(); // touch to reset/turn on the particles
}
}
if(ownerSaid == TRUE && first_command == "follow"

{
current_mode = MODE_FOLLOW;
offset = HOVER_BEHIND;
HIGH_BEAMS = 0;
lookForOwner();
}
if(ownerSaid == TRUE && first_command == "auto"

{
avatarsGreeted = [];
current_mode = MODE_AUTO;
offset = HOVER_BEHIND;
HIGH_BEAMS = 0;
lookForOwner();
}
if(ownerSaid == TRUE && first_command == "attract"
{
avatarsGreeted = [];
current_mode = MODE_ATTRACT;
offset = HOVER_INFRONT;
HIGH_BEAMS = 1;
lookForOwner();
}
if((ownerSaid == TRUE && first_command == "dance"

|| first_command == "danceplease"

{
if(ownerSaid == TRUE)
selfdance = 1;
llRequestPermissions(saidID, PERMISSION_TRIGGER_ANIMATION);
current_mode = MODE_DANCE;
HIGH_BEAMS = 1;
llSensorRemove();
llSensorRepeat("",saidID,AGENT,5,2*PI,.5);
}
if(first_command == "rave"

{
current_mode = MODE_RAVE;
HIGH_BEAMS = 1;
}
if(first_command == "tell"

{
current_mode = MODE_TELL;
HIGH_BEAMS = 0;
}
if(first_command == "big"

{
llSetScale(<.1, .1, .1>

;
//stay big for five seconds
ticksToBeBig = 15;
}
if(str != NULL_KEY)
llSay(0, str);
}
on_rez(integer start_param)
{
startup();
}
no_sensor() {
llOwnerSay("Noone here!"

;
if(current_mode == MODE_AUTO || current_mode == MODE_ATTRACT) {
lookForOwner();
}
}
sensor(integer total_number)
{
Detected = 0;
if(CustomSensor == 0)
{
if(current_mode == MODE_FOLLOW) {
ownerName = llDetectedName(0);
floatcountplus();
vector pos = llDetectedPos(0);
ownerPos = pos;
llMoveToTarget(pos+offset*llDetectedRot(0), .3);
llLookAt(pos, .1 , 1);
}
if(current_mode == MODE_DANCE || current_mode == MODE_ATTRACT || current_mode == MODE_AUTO) {
floatcountplus();
if(((current_mode == MODE_AUTO || current_mode == MODE_ATTRACT) && boolReturn == 1) ||
(current_mode == MODE_DANCE))
{
vector pos = llDetectedPos(0);
ownerPos = pos;
llOwnerSay("Moving auto/dance/attract"

;
llMoveToTarget(pos+offset*llDetectedRot(0), .3);
llLookAt(pos, .1 , 1);
}
}
if(current_mode == MODE_SHOPGREET) {
Detected = 0;
integer i;
for(i = 0; i < total_number && Detected == 0; i++) {
if(greet_someone(llDetectedName(i), llDetectedKey(i), llDetectedPos(i), llDetectedRot(i)) == 1) {
ticks = 4;
return;
}
}
}
}else { // CustomSensor != 0
CustomSensor = 0;
if(current_mode == MODE_ATTRACT | current_mode == MODE_AUTO) {
Detected = 0;
integer i;
llOwnerSay("Looking for someone!"

;
for(i = 0; i < total_number && Detected == 0; i++) {
if(greet_someone(llDetectedName(i), llDetectedKey(i), llDetectedPos(i), llDetectedRot(i)) == 1) {
llOwnerSay("Found someone"

;
boolReturn = 0;
ticksToSayHi = 3;
ticks = 10;
if(current_mode == MODE_AUTO) {
particle_color_cycle = 0.5;
mySetParticles();
}
return;
}
}
//this code is run when the above loop falls through without finding someone
//boolReturn tells the system that its currently looking for its owner
//and ticks is how many timer() events to go by until the next piece of logic executes
boolReturn = 1;
ticks = 10;
if(current_mode == MODE_AUTO) {
particle_color_cycle = 0.333;
mySetParticles();
}
lookForOwner();
}
}
}
timer() {
if(ticksToSayHi > 0) {
ticksToSayHi --;
if(ticksToSayHi == 0) {
llSay(0, "Hey Listen " + avatarGreeting);
llSetText("Hey!", <1, .7, .2>, 1.0 );
}
}
if(ticksToBeBig > 0) {
ticksToBeBig--;
if(ticksToBeBig == 0) {
llSetStatus(STATUS_PHYSICS, FALSE);
llSetScale(<0.02, 0.02, 0.02>

;
llSetStatus(STATUS_PHYSICS, TRUE);
}
}
if(particles_on == 0)
{
llParticleSystem( [ ] );
llSetColor(<.8, .8, .8>, 0);
}
if(current_mode == MODE_FOLLOW)
{
particle_color_cycle += 0.05;
if(particle_color_cycle > 1.0)
particle_color_cycle -= 1.0;
mySetParticles();
naviTitle();
return;
}
if(current_mode == MODE_AUTO)
{ //this is the mode I'm having problems with
mySetParticles();
if(ticks == 0) { // timer is up!
if(boolReturn == 0) { //we WEREN'T hovering around our owner so let's go do that on the next sensor sweep
particle_color_cycle = 0.333;
mySetParticles();
boolReturn = 1;
lookForOwner();
ticks = 10;
} else {
// boolReturn != 0, so it's time to go look for someone to greet
particle_color_cycle = 0.677;
mySetParticles();
CustomSensor = 1;
llSensorRemove();
llSensor("", "", AGENT, 20, 2*PI);
ticks = 10;
}
} else {
//decrement ticks
ticks--;
}
}
if(current_mode == MODE_ATTRACT) //this is how mode_auto used to look when it worked better
{
particle_color_cycle += 0.05;
if(particle_color_cycle > 1.0)
particle_color_cycle -= 1.0;
mySetParticles();
if(avatarGreeting == NULL_KEY) {
CustomSensor = 1;
llSensorRemove();
llSensor("", "", AGENT, 40, 2*PI);
} else {
llMoveToTarget(avatarPos+offset*avatarRot,.3);
ticktimeout = 4;
ticks += 1;
if(ticks > 1) {
boolReturn = 1;
lookForOwner();
}
if(ticks > ticktimeout) {
avatarGreeting = NULL_KEY;
boolReturn = 0;
boolReturning = 0;
ticks = 0;
}
}
return;
}
if(current_mode == MODE_DANCE)
{
naviTitle();
particle_color_cycle += 0.09;
if(particle_color_cycle > 1.0)
particle_color_cycle -= 1.0;
mySetParticles();
vector myoffset = HOVER_INFRONT;
myoffset = myoffset*llAxisAngle2Rot(rotation_axis, current_rotation);
current_rotation = current_rotation + .5;
if(current_rotation > 2*PI) {
current_rotation = current_rotation - 2*PI;
}
llMoveToTarget(attractobject+myoffset,.05);
llLookAt(attractobject, .1 , 1);
ticks += 1;
ticktimeout = 4;
if(ticks > ticktimeout) {
ticks = 0;
if(selfdance == 1) {
PERMS = llGetPermissions();
if (PERMS & PERMISSION_TRIGGER_ANIMATION)
{
llStopAnimation(llList2String(dances, WHICH - 1));
WHICH = (integer)llFrand(TOTAL);
llStartAnimation(llList2String(dances, WHICH));
}
}
return;
}
}
if(current_mode == MODE_SHOPGREET)
{
particle_color_cycle = .333;
mySetParticles();
if(ticks > 0) {
ticks -= 1;
} else {
naviTitle();
llSay(0, "Hi! I'm a {Navi} {fairy}! " + ownerName + " has asked me to {greet} anyone coming by!"

;
llSay(0, "You can talk to me by saying {/navi word} Try {/navi wordlist} to get you started"

;
llSay(0, shopMessage);
llMoveToTarget(ownerPos, 1);
}
return;
}
if(current_mode == MODE_RAVE)
{
particle_color_cycle = .333;
mySetParticles();
return;
}
if(current_mode == MODE_TELL)
{
particle_color_cycle = .5;
mySetParticles();
return;
}
}
touch(integer i) {
llSay(0, "Hi! I'm a {Navi}! If you want to talk to me say {/navi word}. You might want to try {/navi wordlist} to get you started"

;
}
}