Go Back   EQEmulator Home > EQEmulator Forums > Development > Development::Bots

Development::Bots Forum for bots.

Reply
 
Thread Tools Display Modes
  #16  
Old 03-04-2018, 07:50 AM
c0ncrete's Avatar
c0ncrete
Dragon
 
Join Date: Dec 2009
Posts: 719
Default

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)";
	}
}
__________________
I muck about @ The Forge.
say(rand 99>49?'try '.('0x'.join '',map{unpack 'H*',chr rand 256}1..2):'incoherent nonsense')while our $Noport=1;
Reply With Quote
  #17  
Old 03-05-2018, 10:43 PM
c0ncrete's Avatar
c0ncrete
Dragon
 
Join Date: Dec 2009
Posts: 719
Default

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.
__________________
I muck about @ The Forge.
say(rand 99>49?'try '.('0x'.join '',map{unpack 'H*',chr rand 256}1..2):'incoherent nonsense')while our $Noport=1;
Reply With Quote
  #18  
Old 03-06-2018, 11:11 AM
jaspen
Hill Giant
 
Join Date: Apr 2016
Posts: 107
Default

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.
Reply With Quote
  #19  
Old 03-07-2018, 06:38 AM
c0ncrete's Avatar
c0ncrete
Dragon
 
Join Date: Dec 2009
Posts: 719
Default

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.
__________________
I muck about @ The Forge.
say(rand 99>49?'try '.('0x'.join '',map{unpack 'H*',chr rand 256}1..2):'incoherent nonsense')while our $Noport=1;
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 08:24 PM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3