Group Guard

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: Group Guard
Agent
Member # 2820
Profile #0
Check out my first script!

// groupguard.txt v1.03
// by Keep[EZ] <net4less@sbcglobal.net>
// Version 1.0 - Released July 23, 2004, ready for test in the wild
// Version 1.03 - Fixed quite a things that were really bugging me

// A more advanced guard script. Retains all the functionality of the original
// while giving it the ability to work together with other guards. When attacking,
// the guard will issue a call out to all the other characters in its group, which
// will hopefully respond by coming to its aid. When the guard receives a message,
// he will attempt to approach the calling character while noting the distressed
// character's latest location. If that character should die, the guard still tries
// to go to the deceased's position. For no real reason except to make the guards
// more lively, I made them fidget and patrol much more often. These guards will drop
// treasure unless you change the summon level line in the INIT_STATE. These guards
// won't actively hunt down the party, though they will be alerted, and as a side
// effect, will automatically target the party if there is no other choice.

// Memory Cells:
// Cell 0 - How creature moves.
// 0 - If 0, wander randomly.
// 1 - Stands still until a target appears.
// 2 - Completely immobile, even if target appears.
// 3 - Walk to a waypoint and then back to start. Use Cell 4 to
// indicate a waypoint.
// Cell 1,2 - Stuff done flag. If both 0, nothing. Otherwise when this
// is killed, set to 1.
// Cell 3 - Dialogue node to start with if talked to. if left at 0, this
// character doesn't talk.
// Cell 4 - If Cell 0, is not 3, this value is ignore. Otherwise, it is
// the number of a waypoint. This guard spends its time walking to that
// waypoint and back.
// Cell 9 - The group this guard belongs to; has to be 1-7

// Even if it isn't part of a group, the guard will still resond to ANY messages given
// to it so be careful when using this script along with other scripts that broadcast.
// If the guard is not part of a group, it will broadcast to creatures within 16 spaces.

begincreaturescript;

variables;

// loc_x and loc_y contain the coordinates of the character the guard is trying to help
// time_after counts how many turns have passed since the guard has had no one to help
short i,loc_x,loc_y,time_after = 0;
short gone_to_waypoint = 0;
short helping_char = -1; // the character that called for help
short no_message = 0; // counts how many turns the guard has had no messages

body;

beginstate INIT_STATE;
if (get_memory_cell(0) == 2)
set_mobility(ME,0);

set_char_script_mode(ME,1); // act even at distance
if ((get_memory_cell(9) <= 7) && (get_memory_cell(9) > 0))
add_char_to_group(ME,get_memory_cell(9));
if (get_attitude(ME) >= 10)
set_mobility(ME,1);
set_summon_level(ME,0); // change 0 to 1 if you don't want the guard dropping treasure

break;

beginstate DEAD_STATE;
// Set the appropriate stuff done flag for this character being dead
if ((get_memory_cell(1) != 0) || (get_memory_cell(2) != 0))
set_flag(get_memory_cell(1),get_memory_cell(2),1);
if (what_group_in(ME) > 0) { // dying call for help
alert_char(1000 + what_group_in(ME));
give_char_message(1000 + what_group_in(ME),my_number());
}
else broadcast_message_from_x_y(my_loc_x(),my_loc_y(),my_number(),16);
break;

beginstate START_STATE;
// Has the town gone hostile?
if (get_attitude(ME) >= 10) {
alert_char(ME);
set_mobility(ME,1);
}

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

// Look for a target, attack it if visible
if (select_target(ME,8,0)) {
set_state_continue(3);
}

// Have I been hit? Strike back!
if (who_hit_me() >= 0) {
set_target(ME,who_hit_me());
set_state_continue(3);
}

// If I have a message, go help the character whose number is the same as the message
// Otherwise, just peacefully move around. Go back to start, if I'm too far
// from where I started.
if ((my_current_message() >= 0) && (helping_char == -1)) { // current message will keep changing, so helping_char stores the first message
helping_char = my_current_message();
no_message = 0; // automatically breaks the 'not having messages' streak/counter
}
if (helping_char >= 0) {
if (helping_char != my_number()) {
stop_moving(ME); // make sure he forgets the old path
if (char_ok(helping_char)) { // document last location of helping_char while he's alive
approach_char(ME,helping_char,1);
loc_x = char_loc_x(helping_char);
loc_y = char_loc_y(helping_char);
}
else { // else he died, so move to last known location
helping_char = -1;
if (move_to_loc_x_y(ME,loc_x,loc_y))
time_after = get_current_tick(); // time since there was no helping_char
}
}
if ((my_current_message() == -1) && (am_i_doing_action() == FALSE)) {
no_message = no_message + 1;
if (no_message >= 20) {
helping_char = -1; // if there was no messsage for 20 turns, probably no need to help anyone
time_after = get_current_tick();
}
}
}
if ((helping_char == -1) && (tick_difference(time_after,get_current_tick()) >= 10)) {
// tick_difference thrown in to make sure he doesn't go away in case he's needed
if (my_dist_from_start() >= 6) {
if (get_ran(1,1,100) < 40)
return_to_start(ME,1);
}
else if (get_memory_cell(0) == 0) {
fidget(ME,100);
}
else if (get_memory_cell(0) == 3) {
// march to waypoint and back
if (gone_to_waypoint == 0) {
if (approach_waypoint(ME,get_memory_cell(4),1))
gone_to_waypoint = 1;
}
else if (gone_to_waypoint == 1) {
if (return_to_start(ME,1))
gone_to_waypoint = 0;
}

}
}

// 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 (target_ok() == FALSE)
set_state(START_STATE);
do_attack();

// give message every time when attacking and doesn't have anyone to help
// NOTE: In general, this means that there will only be 1 broadcast every 7
// turns per group.

if (helping_char == -1) {
if (what_group_in(ME) > 0) {
alert_char(1000 + what_group_in(ME));
give_char_message(1000 + what_group_in(ME),my_number());
helping_char = my_current_message();
}
else broadcast_message_from_x_y(my_loc_x(),my_loc_y(),my_number(),16);
}

break;

beginstate TALKING_STATE;
if (get_memory_cell(3) == 0) {
print_str("Talking: It doesn't respond.");
end();
}
begin_talk_mode(get_memory_cell(3));
break;
EDIT: The script works very well in my opinion, except in this situation: Someone (possibly one of my guards that aren't part of a group) broadcasts a message. A guard in range picks it up and goes to help, but he won't tell the others in his group. This could be easily solved, but the code must be as efficient as possible, and I only want them broadcasting messages WHEN THERE IS NEW INFORMATION.

Does anyone have any ideas?

[ Sunday, July 25, 2004 18:53: Message edited by: Keep ]

--------------------
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
Agent
Member # 2820
Profile #1
Bump. Oh, yes, and do you think the 20 turn wait is a little much?

EDIT: I just read something disturbing in Kelandon's latest article and decided to whip this slightly modified version of the script together. My computer is an Athlon 64 3000+ with 512 MB of DDR400 RAM and a NVGF 5200 VC, so I can't really tell the difference myself, I'm afraid.

// groupguard.txt v1.03b
// by Keep[EZ] <net4less@sbcglobal.net>
// Version 1.0 - Released July 23, 2004, ready for test in the wild
// Version 1.03 - Fixed quite a things that were really bugging me
// Version 1.03b - Is there a performance difference between 1.03 and 1.03b?

// A more advanced guard script. Retains all the functionality of the original
// while giving it the ability to work together with other guards. When attacking,
// the guard will issue a call out to all the other characters in its group, which
// will hopefully respond by coming to its aid. When the guard receives a message,
// he will attempt to approach the calling character while noting the distressed
// character's latest location. If that character should die, the guard still tries
// to go to the deceased's position. For no real reason except to make the guards
// more lively, I made them fidget and patrol much more often. These guards will drop
// treasure unless you change the summon level line in the INIT_STATE. These guards
// won't actively hunt down the party, though they will be alerted, and as a side
// effect, will automatically target the party if there is no other choice.

// Memory Cells:
// Cell 0 - How creature moves.
// 0 - If 0, wander randomly.
// 1 - Stands still until a target appears.
// 2 - Completely immobile, even if target appears.
// 3 - Walk to a waypoint and then back to start. Use Cell 4 to
// indicate a waypoint.
// Cell 1,2 - Stuff done flag. If both 0, nothing. Otherwise when this
// is killed, set to 1.
// Cell 3 - Dialogue node to start with if talked to. if left at 0, this
// character doesn't talk.
// Cell 4 - If Cell 0, is not 3, this value is ignore. Otherwise, it is
// the number of a waypoint. This guard spends its time walking to that
// waypoint and back.
// Cell 9 - The group this guard belongs to; has to be 1-7

// Even if it isn't part of a group, the guard will still resond to ANY messages given
// to it so be careful when using this script along with other scripts that broadcast.
// If the guard is not part of a group, it will broadcast to creatures within 16 spaces.

begincreaturescript;

variables;

// loc_x and loc_y contain the coordinates of the character the guard is trying to help
// time_after counts how many turns have passed since the guard has had no one to help
short i,loc_x,loc_y,time_after = 0;
short gone_to_waypoint = 0;
short helping_char = -1; // the character that called for help
short no_message = 0; // counts how many turns the guard has had no messages

body;

beginstate INIT_STATE;
if (get_memory_cell(0) == 2)
set_mobility(ME,0);

set_char_script_mode(ME,1); // act even at distance
if ((get_memory_cell(9) <= 7) && (get_memory_cell(9) > 0))
add_char_to_group(ME,get_memory_cell(9));
if (get_attitude(ME) >= 10)
set_mobility(ME,1);
set_summon_level(ME,0); // change 0 to 1 if you don't want the guard dropping treasure

break;

beginstate DEAD_STATE;
// Set the appropriate stuff done flag for this character being dead
if ((get_memory_cell(1) != 0) || (get_memory_cell(2) != 0))
set_flag(get_memory_cell(1),get_memory_cell(2),1);
if (what_group_in(ME) > 0) { // dying call for help
alert_char(1000 + what_group_in(ME));
give_char_message(1000 + what_group_in(ME),my_number());
}
else broadcast_message_from_x_y(my_loc_x(),my_loc_y(),my_number(),16);
break;

beginstate START_STATE;
// Has the town gone hostile?
if (get_attitude(ME) >= 10) {
alert_char(ME);
set_mobility(ME,1);
}

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

// Look for a target, attack it if visible
if (select_target(ME,8,0)) {
set_state_continue(3);
}

// Have I been hit? Strike back!
if (who_hit_me() >= 0) {
set_target(ME,who_hit_me());
set_state_continue(3);
}

// If I have a message, go help the character whose number is the same as the message
// Otherwise, just peacefully move around. Go back to start, if I'm too far
// from where I started.
if ((my_current_message() >= 0) && (helping_char == -1)) { // current message will keep changing, so helping_char stores the first message
helping_char = my_current_message();
no_message = 0; // automatically breaks the 'not having messages' streak/counter
}
if (helping_char >= 0) {
set_state_continue(4); // state that deals with messages
}
if ((helping_char == -1) && (tick_difference(time_after,get_current_tick()) >= 10)) {
// tick_difference thrown in to make sure he doesn't go away in case he's needed
if (my_dist_from_start() >= 6) {
if (get_ran(1,1,100) < 40)
return_to_start(ME,1);
}
else if (get_memory_cell(0) == 0) {
fidget(ME,100);
}
else if (get_memory_cell(0) == 3) {
// march to waypoint and back
if (gone_to_waypoint == 0) {
if (approach_waypoint(ME,get_memory_cell(4),1))
gone_to_waypoint = 1;
}
else if (gone_to_waypoint == 1) {
if (return_to_start(ME,1))
gone_to_waypoint = 0;
}

}
}

// 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 (target_ok() == FALSE)
set_state(START_STATE);
do_attack();

// give message every time when attacking and doesn't have anyone to help
// NOTE: In general, this means that there will only be 1 broadcast every 7
// turns per group.

if (helping_char == -1) {
if (what_group_in(ME) > 0) {
alert_char(1000 + what_group_in(ME));
give_char_message(1000 + what_group_in(ME),my_number());
helping_char = my_current_message();
print_named_str(ME,"calls for help!");
}
else broadcast_message_from_x_y(my_loc_x(),my_loc_y(),my_number(),16);
}

break;

beginstate 4; // if I had someone to help...
if (helping_char != my_number()) {
stop_moving(ME); // make sure he forgets the old path
if (char_ok(helping_char)) { // document last location of helping_char while he's alive
approach_char(ME,helping_char,1);
loc_x = char_loc_x(helping_char);
loc_y = char_loc_y(helping_char);
}
else { // else he died, so move to last known location
helping_char = -1;
if (move_to_loc_x_y(ME,loc_x,loc_y))
time_after = get_current_tick(); // time since there was no helping_char
}
}
if ((my_current_message() == -1) && (am_i_doing_action() == FALSE)) {
no_message = no_message + 1;
if (no_message >= 20) {
helping_char = -1; // if there was no messsage for 20 turns, probably no need to help anyone
time_after = get_current_tick();
}
}
set_state(START_STATE);
break;

beginstate TALKING_STATE;
if (get_memory_cell(3) == 0) {
print_str("Talking: It doesn't respond.");
end();
}
begin_talk_mode(get_memory_cell(3));
break;


[ Sunday, July 25, 2004 19:36: Message edited by: Keep ]

--------------------
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
Off With Their Heads
Member # 4045
Profile Homepage #2
Er, just FYI: I just remembered that this part of the article may be wrong. I'm going to have to test it and see if I see any difference between the two kinds of code.

--------------------
Arancaytar: Every time you ask people to compare TM and Kel, you endanger the poor, fluffy kittens.
Smoo: Get ready to face the walls!
Ephesos: In conclusion, yarr.

Kelandon's Pink and Pretty Page!!: the authorized location for all things by me
The Archive of all released BoE scenarios ever
Posts: 7968 | Registered: Saturday, February 28 2004 08:00