/* 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().
}
}