EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   Development::Bots (https://www.eqemulator.org/forums/forumdisplay.php?f=676)
-   -   Bot healing. Questions about options, control and configurations. (https://www.eqemulator.org/forums/showthread.php?t=41781)

c0ncrete 03-04-2018 07:50 AM

After some fooling around with some concepts, this is where I ended up. All of this was done without any source code modification. I intentionally added notes where things did not work as you might expect. I had to kludge together some logic because bots don't return owner-related information correctly via Perl for such reasons. All required "QnD" plugins included.

in <EQEMU_DIR>\plugins\MySQL.pl
Code:

# USAGE: plugin::SelectHashref($dbh, $sql);
# NOTE: (weakly) coded to only allow for SELECT statements
sub SelectHashref {

        my ($dbh, $sql) = @_;

        return () unless $dbh && (ref $dbh) =~ /^DBI/; # validate DBI handle
        return () unless $dbh->ping;                  # validate connection
        return () unless $sql && $sql =~ /^SELECT /;  # validate sql query

        my $sth = $dbh->prepare($sql);

        $sth->execute();

        return $sth->fetchrow_hashref();
}

in <EQEMU_DIR>\plugins\Bots.pl
Code:

# USAGE: plugin::GetGroupedBots($client)
sub GetGroupedBots {

        my @b;

        if (my $g = shift->GetGroup()) {
                for (my $i = 0; $i < 6; $i++) {
                        next unless my $m = $g->GetMember($i);
                        next if $m->IsClient() ||
                                $m->IsNPC()    ||
                                $m->IsPet();
                        push(@b, $m);
                }
        }
        return @b;
}

in <EQEMU_DIR>\quests\global\global_player.pl
Code:

sub EVENT_SAY {

        $text =~ /#pingme/  ? plugin::Debug("PING") :        # making sure this works
        $text =~ /#healme/  ? BotHealMe() :                  # scripted 'bot heal' command
        return;
}

sub BotHealMe {

        foreach my $bot (plugin::GetGroupedBots($client)) {
       
                # HasOwner() always returns 1 for a bot
                return unless $bot && $bot->HasOwner();

                # GetOwner() causes script to fail
                # my $botOwner = $bot->GetOwner();

                # GetOwnerID() always returns 0 for a bot
                # this behavior is reflected in #showstats
                my $ownerID = $bot->GetOwnerID();
               
                my $botName  = $bot->GetCleanName();
                plugin::Debug("$botName is probably a bot.");
               
                # returns value of bot_data.bot_id from database if mob is a bot
                # NOTE: corresponding value will not exist in npc_types.id
                my $botID = $bot->GetNPCTypeID();

                # returns entityID
                my $botEntityID = $bot->GetID();
               
                # get the info we need from the database
                # correct owner_id is found here
                my $dbh = plugin::LoadMysql();
                my $sql = "SELECT * FROM bot_data WHERE bot_id = $botID LIMIT 1";
                my $res = plugin::SelectHashref($dbh, $sql);
               
                # debugging vomit
                foreach my $key (keys %$res) {
                        my $val = $res->{$key};
                        plugin::Debug("$key => $val");
                }
               
                # will not despawn a bot because
                # the server expects nullptr or NPC as owner
                # quest::depop($botID);
               
                # will not spawn a bot because
                # the server gets nullptr if npc_types.id not found
                # quest::spawn2($botID,0,0,$x,$y,$z,$h);

                # EXAMPLES OF LOGIC THAT MIGHT GO HERE
                # 1. verify bot ownership
                # 2. determine best available spell for situation
                # 3. cast selected spell (see methods below)
                #    GetClass()
                #    GetCasterLevel()
                #    GetSpellIDFromSlot()
                #    IsBeneficialAllowed()
                #    CheckLoS()
                #    CastSPell()
                #    IsCasting()
                #    InterruptSpell()
                #    SpellFinished()
                #    CastingSpellID()
               
                # NOTE: this should get a list of all spells available to a bot
                #
                # my $botLevel = $bot->GetLevel();
                # my $sql = "SELECT * FROM bot_spells_entries WHERE npc_spells_id = (
                #    SELECT spells_id FROM bot_data WHERE bot_id = $botID LIMIT 1
                # ) AND ($botLevel BETWEEN minlevel AND maxlevel)";
        }
}


c0ncrete 03-05-2018 10:43 PM

I've made a small patch that allows for easier manipulation of bots via Perl. The patch was applied to source that was up to date at the time of this posting. I've got a lot of other ideas on how to manage this. Anything that I choose to retain for my custom server will be there. A link is available in my signature.

jaspen 03-06-2018 11:11 AM

Thanks c0ncrete for looking into options for greater bot control. Also thanks for sharing with the community. I hope to get to a point where I can contribute as well. I would love to see this project continually get better as a whole.

I notice other classes being healed differently so I took a peak at the bot code. In SpellType_Heal Necromancers were configured to only be healed if less than 40% health. So that answered my question. I will update my initial post accordingly.

I don't really have any coding experience. Obviously I can look at some of the code and half ass follow what it is doing. Once I become more comfortable and knowledgeable I will start modifying and compiling custom settings. I have a lot of ideas I want to test out! :)

Thanks for everyone's help!

EDIT: Well, I can't edit my original post with the conclusion and answer so everyone will just have to read the whole thing to get it.

c0ncrete 03-07-2018 06:38 AM

I'm getting serious about how to approach this over in another thread.
You lucked out and hit three areas I love to screw about with.
Scripting, bots and their AI, and poking around databases.


All times are GMT -4. The time now is 01:06 PM.

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