View Single Post
  #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