/* Do not remove the headers from this file! see /USAGE for more info. */ /* * Handle the ability of 'monsters' to 'target' other objects. * * One can rewrite this to, say, pick a random target instead of concentrating * on one person, but be careful that query_target() must continually return * the same object between get_target()'s */ void stop_attacking(); private nosave object target; private nosave object array other_targets = ({}); #ifdef TARGETTING_IS_RANDOM private nosave int explicit; // Attack the person we just switch_to()'ed #endif object query_target() { return target; } object array query_targets() { return ({ target }) + other_targets; } /* Find someone to attack. Return zero if we're dead or asleep or * have no one to attack. */ //:FUNCTION get_target //Get someone to attack from our attackers list object get_target() { int x, n = sizeof(other_targets); object tmp; #ifdef TARGETTING_IS_RANDOM if(!explicit) { x = random(n + 1); if (x < n) // target == n means keep the current target { tmp = other_targets[x]; other_targets[x] = target; target = tmp; } } else explicit = 0; #endif // Make sure they are alive and in the same room as us. If not, find // someone else. while(!target || target->query_ghost() || (member_array(target, deep_useful_inv(parser_root_environment(environment(this_object())))) == -1)) { if(!n) return (target = 0); x = random(n); target = other_targets[x]; other_targets[x..x] = ({ }); n--; } return target; } //:FUNCTION switch_to //Make the specified target the primary target void switch_to(object who) { #ifdef TARGETTING_IS_RANDOM explicit = 1; #endif if(who == target) return; if(target) other_targets += ({ target }); other_targets -= ({ who }); target = who; } //:FUNCTION stop_hitting_me //remove the previous object from the target list void stop_hitting_me() { if(previous_object() == target) target = 0; other_targets -= ({ previous_object() }); } /* This stops attacking "who". It also takes care of stoping them * from attacking us. stop_fight() or stop_fight(0) stops all * combat. */ //:FUNCTION stop_fight //stop fighting with object ob (handles making sure they stop fighting //with us too). stop_fight(0) stops all fights. varargs void stop_fight(object who) { if(!who || undefinedp(who)) { if(target) target->stop_hitting_me(); other_targets->stop_hitting_me(); target = 0; other_targets = ({}); stop_attacking(); return; } if(who == target) target = 0; else other_targets -= ({ who }); who->stop_hitting_me(); if(query_targets() == ({ 0 })) { // If there are no targets left, stop_attacking(); // remove the heart_beat(). } }