For a custom event on my server, I am working on a multi-part event for Thanksgiving. Part of that event will be for players to chase and kill Gobblers (AKA Turkeys). I wrote a script that I thought might be useful to others either as a reference, or to do something similar.
What this script does, is it looks for clients withing a certain range of it. If it finds a client, it starts running around in a distanced area of the client. It will follow them to an extent, but always stays at range. If they try to chase it, it will just run from them like mad. It is set so that when it is running, it will stay in the same quadrant relative to the client, so it won't cross them trying to get to another loc nearby. The key to this event is to invite a friend to do it with you. If 2 players get within a certain range of the Gobblers, they slow their speed and don't run nearly as far from the clients. So, then they can actually kill them. But, solo, they are nearly impossible even for the fastest bard.
The setup for using this script as-is, would be set in The Overthere and would use the Cockatrice race #96. The Cockatrice should be set to about run speed 5 or 6, and should be set to Type H so it won't aggro. You can also make it immune to spells, speed changes etc, so that they aren't too easy to kill. I am going to have mine setup to only be killable by a special NO RENT bane weapon that is specifically made for this quest.
This quest should be pretty easy to test in just about any scenario, but it works best in outdoor zones. For indoor, it would require more code to help define the shape of the room they are in. Even if no one really wants to use it for chicken chasing, I think it has some interesting stuff for finding nearby clients that should be useful to almost any admin that makes custom events
Code:
# Fleeing Gobbler Script
######################################################
#Define the Max And Close X, Y, And Z distances to use
######################################################
# Set x, y, And z to the Max distance desired
my $xmax = 250;
my $ymax = 250;
my $zmax = 50;
# Set x, y, And z to the Close distance that causes them to stop running if multiple clients are in range
my $xclose = 50;
my $yclose = 50;
my $zclose = 50;
# Define a Limited Area for the NPC to stay within
my $xbordermin = 430;
my $xbordermax = 1870;
my $ybordermin = 1850;
my $ybordermax = 3405;
######################################################
my $reset_timers = 0;
sub EVENT_SPAWN {
quest::say("Gobble, Gobble, Gobble...");
quest::emote("runs like mad");
$npc->MoveTo(1530, 3062, $z); #Set this to the loc the NPC will run to first after spawning
quest::settimer("runaway",5);
$npc->SetOOCRegen(0);
}
sub EVENT_TIMER {
if ($timer eq "runaway") {
quest::stoptimer("runaway");
if($reset_timers == 0) {
quest::settimer("fullheal",5);
quest::settimer("depop",60);
$reset_timers = 1;
}
my $list_check = 0;
#Variable to check if more than 1 player Is within range
my $multiple_clients = undef;
for ($list_check = 0; $list_check < 2000; $list_check++) {
$client_search = $entity_list->GetClientByID($list_check);
if ($client_search) {
# quest::say("I found client $client_search");
#Client X, Y, Z
my $c_x = $client_search->GetX();
my $c_y = $client_search->GetY();
my $c_z = $client_search->GetZ();
#NPC X, Y, Z
my $n_x = $npc->GetX();
my $n_y = $npc->GetY();
my $n_z = $npc->GetZ();
#NPC Coord - Client Coord
my $xdiff = $n_x - $c_x;
my $ydiff = $n_y - $c_y;
my $zdiff = $n_z - $c_z;
#Convert the Difference to a Positive Integer (square it)
my $xdist = $xdiff * $xdiff;
my $ydist = $ydiff * $ydiff;
my $zdist = $zdiff * $zdiff;
#Square the Max Distance Settings for Comparing With Distance
my $xmax2 = $xmax * $xmax;
my $ymax2 = $ymax * $ymax;
my $zmax2 = $zmax * $zmax;
#Square the Close Distance Settings for Comparing With Distance
my $xclose2 = $xclose * $xclose;
my $yclose2 = $yclose * $yclose;
my $zclose2 = $zclose * $zclose;
#Find a direction to run away from the Client
my $run_x = undef;
my $run_y = undef;
my $new_x = undef;
my $new_y = undef;
# quest::say("Client is at X $c_x, Y $c_y, Z $c_z.");
# quest::say("My Distance is X $xdiff, Y $ydiff, Z $zdiff.");
if ($xdist < $xmax2 && $ydist < $ymax2 && $zdist < $zmax2) {
$reset_timers = 0;
if ($xdist < $xclose2 && $ydist < $yclose2 && $zdist < $zclose2) {
$multiple_clients = $multiple_clients + 1;
if($multiple_clients <= 1) {
$closest_x = 0;
$closest_y = 0;
}
if($multiple_clients >= 2) {
#Make the NPC slow down And run in a smaller range if more than 1 client Is near
quest::modifynpcstat("runspeed", 2);
my $message = quest::ChooseRandom(1,2,3,4,5,6,7,8,9,10);
if($message == 1) {
quest::say("Gobble, gobble, trapped! ..Gobble.");
}
if($message == 2) {
quest::emote("wanders about in fear");
}
}
if($multiple_clients <= 1) {
quest::modifynpcstat("runspeed", 6);
}
}
else {
quest::modifynpcstat("runspeed", 6);
}
quest::stoptimer("fullheal");
quest::stoptimer("depop");
if($xdiff < $closest_x || $closest_x == 0) {
$closest_x = $xdiff; }
if($ydiff < $closest_y || $closest_y == 0) {
$closest_y = $ydiff; }
if($closest_x < 0) {
$run_x = quest::ChooseRandom(-200, -150, -125, -100, -75); }
if($closest_y < 0) {
$run_y = quest::ChooseRandom(-200, -150, -125, -100, -75); }
if($closest_x >= 0) {
$run_x = quest::ChooseRandom(75, 100, 125, 150, 200); }
if($closest_y >= 0) {
$run_y = quest::ChooseRandom(75, 100, 125, 150, 200); }
$new_x = $c_x + $run_x;
$new_y = $c_y + $run_y;
if($new_x > $xbordermax) {
$new_x = $c_x - $run_x; }
if($new_x < $xbordermin) {
$new_x = $c_x - $run_x; }
if($new_y > $ybordermax) {
$new_y = $c_y - $run_y; }
if($new_y < $ybordermin) {
$new_y = $c_y - $run_y; }
$npc->MoveTo($new_x, $new_y, $z);
}
}
}
quest::settimer("runaway",2);
}
if ($timer eq "fullheal") {
quest::stoptimer("fullheal");
my $cheal = $npc->GetMaxHP();
$npc->SetHP($cheal);
}
if ($timer eq "depop") {
quest::stoptimer("depop");
quest::stoptimer("fullheal");
quest::stoptimer("runaway");
quest::depop();
}
}
sub EVENT_SIGNAL {
#Check if a Gobbler Is spawned
if ($signal == 1) {
quest::signalwith(2700768,1,0); }
}
sub EVENT_DEATH {
quest::addloot(4595);
quest::stoptimer("depop");
quest::stoptimer("fullheal");
quest::stoptimer("runaway");
quest::say("Gobble...Gobble...Gobbbbb...");
}
sub EVENT_KILLED_MERIT {
# quest::summonitem(4595);
}