/*********************************************** * Script: Guarded NPC (pair with Bodyguard) * * Author: Walker White * ***********************************************/ // guardednpc.txt // A basicnpc that can send targetting requests to other characters. // Walker M. White // Revision 1.0, // March 30, 2004 // Revision history: // 1.0: Initial release into the wild. // Permission is granted for free use of this script in scenarios, provided that // these header comments are retained and modifications are dutifully documented // throughout. // This script extends basicnpc.txt, except that it may send messages to // other members of its group (namely bodyguards). Anytime the guardednpc is // hit, it sends the character number of the attacker to the bodyguards. // Depending on the tolerance of the bodyguard, it will drop what ever it // is doing to attack the miscreant, hence protecting this character. // The memory cells used in this file are as follows: // Cell 0: Mobility (as per basicnpc) // Cell 1: Stuff done flag 1 (as per basicnpc) // Cell 2: Stuff done flag 2 (as per basicnpc) // Cell 3: Dialog node (as per basicnpc) // Cell 4: Group to add this character to. The character is added to this group // upon initialization. The character must be in the same group as the // bodyguard or the guard will not receive any messages. Be careful not // to have any group conflicts when using this script. // NOTE: // An important observation is the you should never use this script in areas // where characters are _broadcasting_ messages. There is currently no way in // AvernumScript to check the sender of the message (as terrain can send // messages, there is no such thing). We control this issue in the script by // sending messages to the group instead of broadcasting. As a result, the // bodyguards will respond to ANY message, assuming that they all came from // this character. This can have some unintended results. // An easy modification of this script (which I leave to the reader) is to // broadcast -1 to the bodyguards if this character dies. begincreaturescript; variables; short i,target; short my_group; body; beginstate INIT_STATE; if (get_memory_cell(0) == 2) { set_mobility(ME,0); } // If memory cell 4 is non-zero, add us to that group. if (get_memory_cell(4) > 1 && get_memory_cell(4) < 8) { add_char_to_group(my_number(),get_memory_cell(4)); } 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); } break; beginstate START_STATE; // 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); } } // 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()); set_state_continue(3); } } // Look for a target, and attack it if visible if (select_target(ME,8,0)) { set_state_continue(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()); set_state_continue(3); } } // Otherwise, just peacefully move around. Go back to start, if I'm too far // from where I started. if ((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,25); } // 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); } // Have I been hit by a living creature? Yell to my group for help! if (who_hit_me() >= 0 && char_ok(who_hit_me()) == TRUE) { give_char_message(1000 + what_group_in(ME),who_hit_me()); } // Continue the attack. do_attack(); 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;