PDA

View Full Version : Fleeing Turkeys Thanksgiving Event


trevius
11-21-2008, 03:45 AM
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 :)

# 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);

}

MNWatchdog
11-21-2008, 05:39 AM
:-D Neat script. Should work well for well for a Club the Baby Seals event in Iceclad. :-D

trevius
11-23-2008, 10:37 AM
I edited the code some and tweaked it a bit more too. One of the things I added was a way for it to run from the closest client, instead of just the highest client entityID in range. But, the main thing I added is an area limitation so you can set the min/max x/y to set it to only run in that area. I think all little issues have been worked out. Feel free to try putting this script on an NPC near the PoK portal in the Overthere, just to check it out quickly. It is pretty fun lol. Or, feel free to check out Storm Haven in the week or so after Thanksgiving when it will be running for all levels and easy to get to :)

unknownhost
11-23-2008, 04:14 PM
just wanted to say...


this is freaking hillarious! good creative original work Trevius!

joligario
11-23-2008, 06:26 PM
Too bad you can't add a custom .mp3 to the event... I would play Benny Hill's theme song.

trevius
11-23-2008, 06:38 PM
Too bad you can't add a custom .mp3 to the event... I would play Benny Hill's theme song.

LMFAO! That would be hilarious! So fitting for the event! If only there was a way to load MP3s and play them via a quest command and a link from the net.

I still have more work to do on it and maybe 1 or 2 more event parts for the total event, but it should be pretty awesome when it is all done lol. The pathing part that was submitted in this thread should be complete though. If I do any more tweaks, I will update the script here with them. A couple of my players and me were having fun just testing this script and getting it all tuned last night. We even joked about how funny it would be to have a Giant Raid version that the whole raid has to chase to make it run slower :P

I always try to come up with original ideas for events, and this one came to me when I was thinking about Thanksgiving and the phrase "chicken chasing" came to mind. LOL, I think this event fits that phrase pretty well. With all of the work I put into it, it is kinda sad that it will only be temporary. But, I do think the running code can be useful in other permanent encounters on my server in the future. So, it is all worth it :)


Note:
Due to the huge numbers of checks this script runs, you probably would want to make sure you aren't logging quests when you are running it. I know my logs were getting huge when I had an issue with the quest that was spitting out errors non-stop while it was running. Basically, you can check if it is an issue by starting the script, and let it run around you for a couple of minutes and check to see if your log files are growing at an insane rate. At one point, I had 12GBs of quest error logs lol. That issue was resolved though, so hopefully this isn't a problem for anyone. I wanted to make sure to point it out incase anyone saw a problem with it creating huge logs.