EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   Quests::Custom (https://www.eqemulator.org/forums/forumdisplay.php?f=671)
-   -   "a_brave_rat" AKA: make the static more dynamic (https://www.eqemulator.org/forums/showthread.php?t=41779)

c0ncrete 02-20-2018 02:52 PM

"a_brave_rat" AKA: make the static more dynamic
 
This is an unfinished example of how you can easily add a lot of flavor to any generic NPC with scripting alone. I wrote it years ago and never did much with it, so I thought I'd share to maybe help spark some creativity.

(a_cave_rat.pl @ tutorialb)

Code:

my %instance = ();


sub AI_YellForHelp
{
        my $npc_num        = substr($npc->GetName(),-3);
        my $signal        = scalar 911 . scalar 0 . scalar $instance{$npc_num} . scalar 0 . scalar $npc_num;

        # tell a_cave_rat which variant is yelling for help.
        quest::signalwith(189453,$signal);
}


sub EVENT_SPAWN
{

        # ==== HIDDEN (GENDER) NPC VARIATION ==== #

        # 0 = female
        # 1 = male
        # 2 = adolescent
        my $variant = int(rand(3));
        my $npc_num = substr($npc->GetName(),-3);

        $instance{$npc_num} = $variant;

        # ==== VISIBLE (SIZE) NPC VARIATION ==== #
       
        my $SizeMult = sub { .01 * ( $_[0] + int rand $_[1] - $_[0] ) };
        # randomly changes size by percentage mutiples in range provided
        # (example below is between 75% to 125% of original size)
        $npc->ChangeSize( $npc->GetSize() * $SizeMult->(75, 125) );

}


sub EVENT_ATTACK
{
        $client->Message(7, "You have a strange feeling this might not end well...");
        quest::setnexthpevent(50);
}


sub EVENT_HP
{

        if($hpevent == 50)
        {
                # 25% chance to call for help
                if(int(rand(100) >= 75)
                {
                        quest::emote("squeaks loudly.");
                        AI_YellForHelp();
                }
        }

}

sub EVENT_SIGNAL
{

        my $strSignal = scalar $signal;

        if (length $strSignal == 9 && substr($strSignal, 0, 3) == 911)
        {
                my $otherType  = int(substr($strSignal, 4, 1));
                my $otherNumber =    substr($strSignal, 6, 3);
       
                my $myNumber = substr($npc->GetName(),-3);
                my $myType  = $instance{$myNumber};

                # TO DO: implement range/LOS check.

                if($npc->IsEngaged())
                {
                        quest::shout("DEBUG: $myNumber is busy and can't help $");
                }
                # we got a request for help from variant 0 (female)
                elsif($otherType == 0 && $myType == 1)
                {
                        # TO DO: assist if male (%75).
                        quest::shout("DEBUG: $myNumber is thinking about helping (0->1 @ 75%)");
                }
                # we got a request for help from variant 1 (male)
                elsif($otherType == 1 && $myType == 1)
                {
                        # TO DO: assist if male (50%).
                        quest::shout("DEBUG: $myNumber is thinking about helping (1->1 @ 50%)");
                }
                # we got a request for help from variant 2 (adolescent)
                elsif($otherType == 2)
                {
                        if($myType == 0)
                        {
                                # TO DO: assist if female (100%).
                                quest::shout("DEBUG: $myNumber is thinking about helping (2->0 @ 100%)");
                        }
                        elsif($myType == 2)
                        {
                                # TO DO: assist if adolescent (25%).
                                quest::shout("DEBUG: $myNumber is thinking about helping (2->2 @ 25%)");
                        }
                }
        }

}

sub EVENT_DEATH
{

        # delete dead rat's instance data
        my $npc_num = substr($npc->GetName(),-3);
        delete($instance{$npc_num});

}


c0ncrete 02-21-2018 04:28 PM

This one works with current server builds. The previous one was from a long time ago and did not work. I've changed the size scaling to use an existing plugin and removed all debug messages. Rats will now assist as originally intended (I'd never gotten that far before). Comments added so you can more easily see what is going on.

Code:

my %instance = ();

sub AI_YellForHelp
{
        # signal will be used as a fixed-length, delimited string
        # [key below]
        # 911  = HALP
        # 0    = delimeter
        # 0-2  = "gender" variation of rat in distress
        # 0    = delimeter
        # ***  = number of rat in distress (end of name)
        my $npc_num        = substr($npc->GetName(), -3);
        my $signal        = scalar 911 . scalar 0
                        . scalar $instance{$npc_num} . scalar 0
                        . scalar $npc_num;

        # tell every rat which variant is requesting help
        quest::signalwith(189453, $signal);
}

sub AI_Assist
{
        my $tar = shift;
       
        # rat to assist
        $rat = $entity_list->GetMob("a_cave_rat$tar");
       
        # troubled rat's enemies
        my @enemies = $rat->GetHateList();

        # copied (slightly altered) most of this from the following post
        # http://www.eqemulator.org/forums/showpost.php?p=200059&postcount=4
        foreach $entry (@enemies)
        {
                my $ent = $entry->GetEnt();
                my $dmg = $entry->GetDamage();
                my $amt = $entry->GetHate();

                next if (!$ent);

                # ATTACK!
                if($npc->CheckAggro($ent)) {
                        $npc->SetHate($ent, $tot, $dmg);
                }
                else {
                        $npc->AddToHateList($ent, $tot, $dmg, 0, 0, 0);
                }
        }

}

# ========================
# ===== START EVENTS =====
# ========================

sub EVENT_DEATH
{
        # delete instance data
        my $npc_num = substr($npc->GetName(),-3);       
        delete($instance{$npc_num});
}

sub EVENT_SPAWN
{
        # randomly assign a "gender" variation
        # 0 = female
        # 1 = male
        # 2 = adolescent
        my $variant = int(rand(3));
        my $npc_num = substr($npc->GetName(),-3);

        # store variant info
        $instance{$npc_num} = $variant;

        # randomly resize to 75% - 125% of original
        my $SizeVariation = sub {
                $_[0]->GetSize() * ( .01 * plugin::RandomRange($_[1], $_[2]) )
        };
        $npc->ChangeSize( $SizeVariation->($npc, 75, 125) );
       
        # set initial health trigger
        quest::setnexthpevent(50);
}

sub EVENT_ATTACK
{
        # flavor, because why not?
        $client->Message(7, "You have a strange feeling this might not end well...");
}
       
sub EVENT_HP
{
        # 25% chance to request assistance @ 50% health
        if ($hpevent == 50 && int rand 101 > 24)
        {
                quest::emote("lets out a squeak so piercing your hair stands on end!");
                AI_YellForHelp();
        }
}

sub EVENT_SIGNAL
{
        # NOTE: $npc in here is ALWAYS the rat recieving the signal

        my $strSignal = scalar $signal;
       
        # signal sanity check
        if (length $strSignal == 9 && substr($strSignal, 0, 3) == 911)
        {
                # other rat (in distress)
                my $otherType  = int(substr($strSignal, 4, 1));
                my $otherNumber =    substr($strSignal, 6, 3);
               
                # this rat (potential add)
                my $myNumber = substr($npc->GetName(),-3);
                my $myType  = $instance{$myNumber};

                # we are engaged and unable to assist
                if ($npc->IsEngaged()) { return; }
               
                ###########################################
                # TO DO: implement a range/LOS check here #
                ###########################################
               
                # we got a request for help from variant 0 (female)
                if ($otherType == 0 && $myType == 1)
                {
                        # 75% chance for a male to assist
                        if (int rand 101 > 74) { AI_Assist($otherNumber); }
                }
                # we got a request for help from variant 1 (male)
                elsif ($otherType == 1 && $myType == 1)
                {
                        # 50% chance to for a male to assist
                        if (int rand 101 > 49) { AI_Assist($otherNumber); }
                }
                # we got a request for help from variant 2 (adolescent)
                elsif ($otherType == 2)
                {
                        if ($myType == 0)
                        {
                                # 100% chance for a female to assist
                                AI_Assist($otherNumber);
                        }
                        elsif ($myType == 2)
                        {
                                # 25% chance for an adolescent to assist
                                if (int rand 101 > 74) { AI_Assist($otherNumber); }
                        }
                }
        }
}

# ======================
# ===== END EVENTS =====
# ======================

# END OF FILE -- ZONE: tutorialb (415) -- ID: 189453 -- a_cave_rat



All times are GMT -4. The time now is 02:40 PM.

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