EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   Quests::Custom (https://www.eqemulator.org/forums/forumdisplay.php?f=671)
-   -   Marching In Formations (https://www.eqemulator.org/forums/showthread.php?t=30774)

nenelan 03-09-2010 09:44 PM

Marching In Formations
 
I remember reading a while back that people hadn't been able to get a few mobs to march in formation. Going to post a bit of code that you can tinker with to your own liking.

For mine, I have one mob in zone called Strike Commander, here is the code for him.

Code:

sub EVENT_SPAWN {
        $targetid = 999666;  # What NPCID we are sending the patrol at.
        $minionid = 999671; # ID of the mob that follows the commander

}

sub EVENT_SAY {

        my $summon = quest::saylink("summon");
        my $attack = quest::saylink("attack");

        if ($text =~ /Hail/i) {
                quest::say("Greetings, $name.  Shall I [$summon] my minions for you to command?");
        }

        if ($text =~ /summon/i) {
                quest::depopall($minionid);
                quest::spawn2($minionid,0,0,$x+5,$y,$z,$h);
                quest::spawn2($minionid,0,0,$x+5,$y-10,$z,$h);
                quest::spawn2($minionid,0,0,$x+5,$y+10,$z,$h);
                quest::spawn2($minionid,0,0,$x+5,$y-5,$z,$h);
                quest::spawn2($minionid,0,0,$x+5,$y+5,$z,$h);
                quest::say("Minions spawned, shall we [$attack]?");
        }

        if ($text =~ /attack/i) {
                quest::shout("FOR HONOR!  MOVE OUT!");
                quest::signalwith($minionid,$targetid);
                  my $x_loc = 0;
                    my $y_loc = 0;
                    my $z_loc = 0;
                    my $opponent = $entity_list->GetMobByNpcTypeID($targetid);
                    if($opponent)
                    {
                        $x_loc = $opponent->GetX();
                        $y_loc = $opponent->GetY();
                        $z_loc = $opponent->GetZ();
                        quest::moveto($x_loc,$y_loc,$z_loc);
                  }
        }
}

sub EVENT_WAYPOINT_ARRIVE {
        quest::attacknpctype($targetid);
}

Next, we have our minions. All we need is a DB entry for them, as there should be none of them in zone, we spawn them when we need them. Any more in zone would send them to the target as well. Here is the code for my Strike Warriors.

Code:

sub EVENT_SIGNAL {

### This block of code to get my difference in location from my commander

        my $cid = 999670;  ## Commander's ID
        $x_dif = 0;
        $y_dif = 0;
        my $x = $npc->GetX();
        my $y = $npc->GetY();
            my $commander = $entity_list->GetMobByNpcTypeID($cid);
            if($commander)
            {
                $x_dif = $commander->GetX();
                $x_dif = $x - $x_dif;
                $y_dif = $commander->GetY();
                $y_dif = $y - $y_dif;
          }



### This block of code to send me at the NPCID that was passed as $signal.

        my $x_loc = 0;
            my $y_loc = 0;
            my $z_loc = 0;
           
        my $opponent = $entity_list->GetMobByNpcTypeID($signal);
            if($opponent)
            {
                $x_loc = $opponent->GetX();
                $y_loc = $opponent->GetY();
                $z_loc = $opponent->GetZ();
                $x_loc += $x_dif;
                $y_loc += $y_dif;
                quest::moveto($x_loc,$y_loc,$z_loc);
          }
}

Merely change the IDs in green to suit your task. You may also want to tinker with where the mobs spawn in relation to the Commander as well. This was used as my proof of concept and has since changed to, path them to several invisible NPCs (without attacking as this does), around the zone as a patrol would do. The only issue is that they keep their initial orientation, which does look odd if you have them go diagonally. Also, unless you spawn the commander at the center of the pack, and instead have him to a side as you have here, he will sometimes be before, to the side, or the diagonal of his troops. This does look fairly nice as one mob in the center of 8 more as a diamond formation though.

If anyone feels like cleaning this up, please do. It is quite messy and inelegant, but gets the job done for what I wanted it to. I would much rather have them follow the commander out, or lead him out, but I could not for the life of me get that to work.

RichardoX 03-11-2010 04:21 PM

This gave me some very good ideas. Thank you for your submission! :)

Akkadius 03-13-2010 01:12 AM

Heh, yeah I already had this in mind to mess with. This just does some of the work for me although I will be tweaking it a ton. Except for I had an ideal for an epic scene.

Thanks!

lich2594 10-24-2010 08:07 PM

I actually use a different method of formation, and I will show how one of my mini-events are done. I choose to use quest::moveto instead of the more complex ways of doing it, because I have noticed that a lot of formations tend to group up together which just looks crappy. They start out nice and smooth, but later end up all together or out of formation...

Here his how I do a little event in Old Commands, on my server. (The text and quests stuff has been removed, this only shows how the pathing works.)

a rescue soldier leader:
Code:

my $sx = undef; #spawn location x
my $sy = undef; #spawn location y
my $sz = undef; #spawn location z
my $sh = undef; #spawn location h
my $evstar = undef; #is event started
my $dervcount = undef; #cutthroat death count

sub EVENT_SPAWN {

        $sx = $npc->GetSpawnPointX(); #spawn location x
        $sy = $npc->GetSpawnPointY(); #spawn location y
        $sz = $npc->GetSpawnPointZ(); #spawn location z
        $sh = $npc->GetSpawnPointH(); #spawn location h
        $evstar = 0;
        $dervcount = 0;
       
        quest::spawn2(952,0,0,$x+5,$y-3,$z,$h);
        quest::spawn2(954,0,0,$x-5,$y,$z,$h);

}

sub EVENT_SIGNAL {

        if ($signal == 1) {
               
                if ($evstar == 1) {
               
                        $dervcount++;
                       
                        if ($dervcount == 3) {
                                quest::moveto($sx+50,$sy+50,$sz-9,$sh,1);
                                quest::signalwith(952,2,0);
                                quest::signalwith(954,2,0);
                        }
                        if ($dervcount == 5) {
                                quest::moveto($sx+250,$sy+50,$sz-87,$sh,1);
                                quest::signalwith(952,3,0);
                                quest::signalwith(954,3,0);
                        }
                        if ($dervcount == 7) {
                                quest::moveto($sx+225,$sy+250,$sz-62,$sh,1);
                                quest::signalwith(952,4,0);
                                quest::signalwith(954,4,0);
                        }
                        if ($dervcount == 10) {
                                quest::moveto($sx+200,$sy+400,$sz+25,$sh,1);
                                quest::signalwith(952,5,0);
                                quest::signalwith(954,5,0);
                        }
                        if ($dervcount == 14) {
                                quest::moveto($sx+210,$sy+475,$sz+5,$sh,1);
                                quest::signalwith(952,6,0);
                                quest::signalwith(954,6,0);
                                quest::signalwith(955,1,10);
                                quest::settimer(1,13);
                                quest::settimer(2,300);
                                $evstar = 2;
                        }
                       
                }
               
        }

}

sub EVENT_TIMER {

        if ($timer == 1) {
                quest::shout("Let's head back, soldiers!");
                quest::moveto($sx,$sy,$sz,$sh,1);
                quest::signalwith(952,7,0);
                quest::signalwith(954,7,0);
                quest::stoptimer(1);
        }
        if ($timer == 2) {
                quest::depopall(952);
                quest::depopall(954);
                quest::depopall(955);
                quest::depop();
                quest::stoptimer(2);
        }
}

sub EVENT_DEATH {

        quest::depopall(952);
        quest::depopall(954);
        quest::depopall(955);

}


(NPCID) 952.pl & 954.pl
Code:

my $sx = undef; #spawn location x
my $sy = undef; #spawn location y
my $sz = undef; #spawn location z
my $sh = undef; #spawn location h

sub EVENT_SPAWN {

        $sx = $npc->GetSpawnPointX();
        $sy = $npc->GetSpawnPointY();
        $sz = $npc->GetSpawnPointZ();
        $sh = $npc->GetSpawnPointH();

}

sub EVENT_SIGNAL {

        if ($signal == 1) {
                quest::moveto($sx,$sy,$sz,$sh,1);
        }
        if ($signal == 2) {
                quest::moveto($sx+50,$sy+50,$sz-9,$sh,1);
        }
        if ($signal == 3) {
                quest::moveto($sx+250,$sy+50,$sz-87,$sh,1);
        }
        if ($signal == 4) {
                quest::moveto($sx+225,$sy+250,$sz-62,$sh,1);
        }
        if ($signal == 5) {
                quest::moveto($sx+200,$sy+400,$sz+25,$sh,1);
        }
        if ($signal == 6) {
                quest::moveto($sx+210,$sy+475,$sz+5,$sh,1);
        }
        if ($signal == 7) {
                quest::moveto($sx,$sy,$sz,$sh,1);
        }

}

a dervish cutthroad
Code:

sub EVENT_DEATH {

        quest::signalwith(953,1,0);

}


How this works, is that when the players are on the quest (and the event can only be triggered if the player is on the quest) their task is to kill 15 dervish. As you can see, each time they kill one - it sends a signal that is counted. On count X the NPCs will walk to a closer location (in formation).

This is only a 3 NPC formation, but can be applied in as many numbers as you would like. I find this method much more simple than the other methods that are out there.

Enjoy!


All times are GMT -4. The time now is 12:12 AM.

Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.