Creature Script Targeting Trouble

Error message

Deprecated function: implode(): Passing glue string after array is deprecated. Swap the parameters in drupal_get_feeds() (line 394 of /var/www/pied-piper.ermarian.net/includes/common.inc).
AuthorTopic: Creature Script Targeting Trouble
Shaper
Member # 7472
Profile Homepage #0
I'm having some trouble with getting a target in a new creature script I've designed. No matter how I try, the only way I can even get the script to register that an enemy is nearby is by attacking the creature who has the script. Then, even though it has a target, it won't go to state 3 (attacking state), or engage the target. I can't see what could be causing the problem, as an error never appears, and everything should be functioning normally.
begincreaturescript;

variables;

short i,target,r,m,t,rand;
short protector = -1;
short myattitude;
short abort = 0;
short scan;
short melee_or_missile = 0;

body;

beginstate INIT_STATE;
// Check for improperly set memory cells.

if (get_memory_cell(0) > 2) {
abort = TRUE;
print_str_color("elitenpc Error: Invalid memory cell value. (cell 0)",1);
print_str_color(" Valid movement types are 0-2.",1);
}

if (get_memory_cell(1) > 1855) {
abort = TRUE;
print_str_color("elitenpc Error: Invalid memory cell value. (cell 1)",1);
}

if (get_memory_cell(2) > 255) {
abort = TRUE;
print_str_color("elitenpc Error: Invalid memory cell value. (cell 2)",1);
}

if (get_memory_cell(3) > 199) {
abort = TRUE;
print_str_color("elitenpc Error: Invalid memory cell value. (cell 3)",1);
print_str_color(" Valid dialogue nodes are 0-199.",1);
}

if (get_memory_cell(4) + get_level(my_number()) > 100) {
abort = TRUE;
print_str_color("elitenpc Error: Invalid memory cell value. (cell 4)",1);
print_str_color(" A creature's level cannot exceed 100.",1);
}

if (get_memory_cell(5) > 39) {
abort = TRUE;
print_str_color("elitenpc Error: Invalid memory cell value. (cell 5)",1);
print_str_color(" Valid abilities are 0-39.",1);
}

if ((get_memory_cell(5) == 25) || (get_memory_cell(5) == 31)) {
abort = TRUE;
print_str_color("elitenpc Error: Invalid memory cell value. (cell 5)",1);
print_str_color(" Invalid ability.",1);
}

if (get_memory_cell(6) > 3) {
abort = TRUE;
print_str_color("elitenpc Error: Invalid memory cell value. (cell 6)",1);
print_str_color(" Valid strategies are 0-3.",1);
}

if (get_memory_cell(7) > 498) {
abort = TRUE;
print_str_color("elitenpc Error: Invalid memory cell value. (cell 7)",1);
print_str_color(" Valid items are 0-498.",1);
}

if (get_memory_cell(8) > 34) {
abort = TRUE;
print_str_color("elitenpc Error: Invalid memory cell value. (cell 8)",1);
print_str_color(" Valid statuses are 0-34.",1);
}

if (abort)
end();

// Next we set certain variables.

// Melee_or_missile checks whether the creature is a melee or missile combatant.
// This is important when scanning for targets.
if ((item_type_in_slot(my_number(),2) > 0) || (get_stat(ME,11) > 0) || (get_stat(ME,12) > 3))
melee_or_missile = 1;

// This one is the creature's attitude. This is to work around a bug.
myattitude = get_attitude(ME);

// Now we set some important characteristics about myself.

// Can I move?
if (get_memory_cell(0) == 2)
set_mobility(ME,0);

// Do I recieve a level bonus?
set_level(ME,get_level(my_number()) + get_memory_cell(4));

// Do I get a special ability?
if (get_memory_cell(5) > 0)
set_special_ability(get_memory_cell(5));

// Activate my permanent status, if I have one.
if (get_memory_cell(8) > 0) {
if (get_memory_cell(8) < 32)
set_char_status(ME,get_memory_cell(8) - 1,250,1,0);
if (get_memory_cell(8) == 33)
set_char_status(ME,1,-250,1,0);
if (get_memory_cell(8) == 34)
set_char_status(ME,2,-250,1,0);
if (get_memory_cell(8) == 35)
set_char_status(ME,3,-250,1,0);
}

break;

beginstate DEAD_STATE;
if (abort)
end();

// What should happen when I die?
// If cells 1 and 2 are 0, nothing.
if (get_memory_cell(1) + get_memory_cell(2) == 0)
end();

// If cell 1 is less than 300, set a flag to 1.
if (get_memory_cell(1) < 300) {
set_flag(get_memory_cell(get_memory_cell(1),get_memory_cell(2),1)
end(); }

// If cell 1 is a value between 310 and 400, call a state.
if ((get_memory_cell(1) > 309) && (get_memory_cell(1) < 401)) {
if (get_memory_cell(2) == 1)
run_scenario_script(get_memory_cell(1));
else run_town_script(get_memory_cell(1));
end(); }

break;

beginstate START_STATE;
if (abort)
end();

// Sustain my permanent status, if I have one.
if (get_memory_cell(8) > 0) {
if (get_memory_cell(8) < 32)
set_char_status(ME,get_memory_cell(8) - 1,250,1,0);
if (get_memory_cell(8) == 33)
set_char_status(ME,1,-250,1,0);
if (get_memory_cell(8) == 34)
set_char_status(ME,2,-250,1,0);
if (get_memory_cell(8) == 35)
set_char_status(ME,3,-250,1,0);
}

// Has one of my comrades found a target?
if (my_current_message() == 1)
alert_char(ME);

// If I have a target for some reason, go attack it
if (target_ok()) {
if (dist_to_char(get_target()) <= 16) {
scan = get_current_tick();
broadcast_char_message(8,1,1)
set_state(3); }
else set_target(ME,-1);
}

// Have I been hit by nearby living creature? Strike back!
if (who_hit_me() >= 0) {
if (dist_to_char(who_hit_me()) <= 2 && char_ok(who_hit_me()) == TRUE) {
set_target(ME,who_hit_me());
scan = get_current_tick();
broadcast_char_message(8,1,1);
set_state(3);
}
}

// If no one close, we defend ourselves against ranged attackers.
if (who_hit_me() >= 0) {
// Target may have been killed since it struck.
if (char_ok(who_hit_me()) == TRUE) {
set_target(ME,who_hit_me());
scan = get_current_tick();
broadcast_char_message(8,1,1);
set_state(3);
}
}

// Start looking for a target.

if (melee_or_missile == 0) {
r = 1;
while (r < 8) {
select_target(ME,r,2);
if (target_ok())
select_target(ME,r,1);
if (target_ok())
select_target(ME,r,0);
if (target_ok()) {
scan = get_current_tick();
broadcast_char_message(8,1,1);
set_state(3); }
r = r + 2; }
}
if (melee_or_missile == 1) {
select_target(ME,8,2);
if (target_ok())
select_target(ME,8,1);
if (target_ok())
select_target(ME,8,0);
if (target_ok()) {
scan = get_current_tick();
broadcast_char_message(8,1,1);
set_state(3); }
}

// Finally, if I've been hit, but can't find a target, we hunt
// down the attacker. (This undermines a popular strategy of
// hasting an archer, having him fire into the room, and then
// stepping back out so that the creature won't fight back.)
if (who_hit_me() >= 0) {
// Attacker may have been killed since it struck.
if (char_ok(who_hit_me()) == TRUE) {
approach_char(ME,who_hit_me(),0); }
}

// Do I have someone to protect me? Then stay close to it till my health is
// at least %50 of its maximum value. If I'm wounded badly, find someone to
// protect me untill my health is at least %50. Otherwise, just peacefully
// move around.

// A part of this code may seem odd, but it's to avoid a major bug with the call
// 'dist_to_char'. Apparently, it can't accept variables without breaking down.

if ((get_health(ME) >= get_max_health(ME) / 2) || ((can_see_char(protector) == 0)
&& (dist_to_char(get_ran(protector,protector,1)) > 5))) {
protector = -1; }

if ((get_health(ME) < get_max_health(ME) / 3) && (protector == -1) && (enemies_nearby(20) == 0)) {
// Am I friendly or neutral? Then find a good character to protect me.
// (Maybe even the party!)
if (myattitude <= 4) {
// Dodging yet another bug with the call 'get_nearest_good_char'.
// If you use this call with a friendly or neutral character, the
// call will return the number of the character running the script.
// Therefore, we switch the attitude of the creature momentarily so
// the call works correctly, then switch it back.
set_attitude(ME,10);
protector = get_nearest_good_char(5);
set_attitude(ME,myattitude); }
// Am I hostile? Then find an evil character to protect me.
else if (myattitude >= 10) {
// The call 'get_nearest_evil_char' has this problem as well.
set_attitude(ME,3);
protector = get_nearest_evil_char(5);
set_attitude(ME,myattitude); }
if (approach_char(ME,protector,2) == 1) {
fidget(ME,60);
}

}

// Otherwise, just peacefully move around. Go back to start, if I'm too far
// from where I started and on't have a protector.
if ((protector == -1) && ((my_dist_from_start() >= 6) || ((my_dist_from_start() > 0) && (get_memory_cell(0) > 0)))) {
if (get_ran(1,1,100) < 40) {
return_to_start(ME,1);
}
} else if (get_memory_cell(0) == 0) {
fidget(ME,45);
}

// if we're in combat and the above didn't give me anything to do, just
// stop now. Otherwise, game will keep running script, and that eats up CPU time.
if (am_i_doing_action() == FALSE) {
end_combat_turn();
}
break;

beginstate 3; // attacking
if (abort)
end();

// Sustain my permanent status, if I have one.
if (get_memory_cell(8) > 0) {
if (get_memory_cell(8) < 32)
set_char_status(ME,get_memory_cell(8) - 1,250,1,0);
if (get_memory_cell(8) == 33)
set_char_status(ME,1,-250,1,0);
if (get_memory_cell(8) == 34)
set_char_status(ME,2,-250,1,0);
if (get_memory_cell(8) == 35)
set_char_status(ME,3,-250,1,0);

// Should I scan for a new target?
if (tick_difference(scan,get_current_tick()) > 3) {
if (melee_or_missile == 0) {
select_target(ME,1,2);
if (target_ok())
select_target(ME,1,1);
if (target_ok())
select_target(ME,1,0);
}
if (melee_or_missile == 1) {
select_target(ME,8,2);
if (target_ok())
select_target(ME,8,1);
if (target_ok())
select_target(ME,8,0);
}

// Is my current target ok?
if (target_ok() == FALSE) {
// Do I have another target nearby?
select_target(ME,2,2);
if (target_ok())
select_target(ME,2,1);
if (target_ok())
select_target(ME,2,0);
// If I don't, go back to the start state.
if (target_ok())
set_state(START_STATE);
else scan = get_current_tick();
}
do_attack_tactic(get_memory_cell(6));

break;

beginstate TALKING_STATE;

if (get_memory_cell(3) > 0)
begin_talk_mode(get_memory_cell(3));
else print_str("Talking: It doesn't respond.");

break;
I think the problem is in either the start state or the attacking state. Any ideas? :confused:

EDIT: Modified one of the conditionals, because it caused the width of the post to get mildly out of control. Also added my signature. :)

[ Saturday, September 09, 2006 13:32: Message edited by: Nioca ]

--------------------
Scenarios need reviews! Please rate these scenarios at the CSR after playing them!
AmnesiaDileciaThe Empire's New GroveExpress Delivery
Twilight ValleyWitch HuntWhere the Rivers MeetFoul Hordes
Posts: 2686 | Registered: Friday, September 8 2006 07:00
The Establishment
Member # 6
Profile #1
While I don't have time at this moment to debug your script, perhaps I can offer a little advice. Make use of the print_num() command to get a feel for the flow of logic with these scripts. I know sometimes I have counterintuitive (at least to me) results. Then modify your script around those if possible.

--------------------
Your flower power is no match for my glower power!
Posts: 3726 | Registered: Tuesday, September 18 2001 07:00
Shaper
Member # 7472
Profile Homepage #2
Got it fixed, thanks *i. Turns out, I had most of my target_ok conditionals backwards, which stopped target-finding cold, and a couple misplaced brackets was the reason for the attack state not activating.

That being said, I feel like a complete idiot.

On a different note, do you have to be registered at the Codex to submit codes?

--------------------
Scenarios need reviews! Please rate these scenarios at the CSR after playing them!
AmnesiaDileciaThe Empire's New GroveExpress Delivery
Twilight ValleyWitch HuntWhere the Rivers MeetFoul Hordes
Posts: 2686 | Registered: Friday, September 8 2006 07:00
Agent
Member # 2820
Profile #3
Yes, you do need to register. I'm afraid most people will not have a chance to see it, but at least you'll get it out there.

--------------------
Thuryl: I mean, most of us don't go around consuming our own bodily fluids, no matter how delicious they are.
====
Alorael: War and violence would end if we all had each other's babies!
====
Drakefyre: Those are hideous mangos.
Posts: 1415 | Registered: Thursday, March 27 2003 08:00