Targeting - Vertical Firewall

Wrote new code? Fixed a bug? Want to discuss technical stuff? Feel free to post it here.

Moderator: Moderators

Historm
Human
Human
Posts: 27
Joined: 01 Jun 2011, 01:59
Noob?: No

Targeting - Vertical Firewall

#1 Post by Historm »

I am terribad.

But I wrote the following edit to the AI.pm and Attack.pm files.

The objective of this code is to allow kore to target the Firewall skill vertically if the attackSkillSlot block has a new setting called "useVertical" which is set to not zero and the skill is ground targeted.

can a real programmer look at this and implement it if it is good, please?

the new ai_skillUse2 in AI.pm

Code: Select all

sub ai_skillUse2 {
	my ($skill, $lvl, $maxCastTime, $minCastTime, $target, $prefix, $waitBeforeUse, $tag, $vertical) = @_;
	
	#check to use vertical, and if this skill is location cast, to prevent errors
	if ($vertical && ($skill->getTargetType == Skill::TARGET_LOCATION))	{
		#is declaring variables nessecary?
		#Can I just call this information in the if evals? 
		#do I need three arrays?
		#for @target_loc = @{$target->{pos_to}}{qw(x y)};, should I be using ->(pos) instead of ->(pos_to)?
		#can I this call a seperate function to make ai_skilluse2 cleaner?
		my @target_loc = @{$target->{pos_to}}{qw(x y)};
		my @my_loc = @{$skill->getOwner->{pos}}{qw(x y)};
		my @vertical_loc = (0 0);
		#based on the simple pathing algorithm that mobs have, I know where to firewall based on where the mob stands in relation to me
		#if the mob is farther horizontally than vertically, or if it is perfectly diagonal
		if (abs($my_loc[0] - $target_loc[0]) >= abs($my_loc[1] - $target_loc[1]))	{
			#if the mob is below me
			if ($my_loc[1] > $target_loc[1])	{
				$vertical_loc[1]--;
			}
			#else if the mob above me
			else if ($my_loc[1] < $target_loc[1])	{
				$vertical_loc[1]++;
			}
		}
		#else if the mob is farther vertically than horizontally
		else if (abs($my_loc[0] - $target_loc[0]) < abs($my_loc[1] - $target_loc[1]))	{
			#if the mobs is on my left
			if ($my_loc[0] > $target_loc[0])	{
				$vertical_loc[0]--;
			}
			#else if the mob on my right
			else if ($my_loc[0] < $target_loc[0])	{
				$vertical_loc[0]++;
			}
		}
		#if I haven't incremented, then I can't firewall.  so check if I have then process the skill
		if (abs($vertical_loc[0]) || abs($vertical_loc[1])) {
			#use the skill on the location.
			#if the mob is actually on my location, I did not increment the location array anyways.  who knows why that would happen, but it is handled.
			ai_skillUse(
				$skill->getHandle(),
				$lvl,
				$maxCastTime,
				$minCastTime,
				$my_loc[0] + $vertical_loc[0], $my_loc[1] + $vertical_loc[1],
				$tag, undef, $waitBeforeUse, $prefix
			)
			#Ideally right now I would move 2 cells down my firewall.
			#I don't know if this is the proper place to call the move function
			#but if it is, the pseudocode is something like
			#my @move_loc = (0 0);
			#if the mob is farther horizontally than vertically, or if it is perfectly diagonal
			#if (abs($my_loc[0] - $target_loc[0]) >= abs($my_loc[1] - $target_loc[1]))	{
			#	#if the mob is on my left
			#	if ($my_loc[0] > $target_loc[0])	{
			#		$move_loc[0]+=2;
			#	}
			#	#else if the mob on my right
			#	else if ($my_loc[0] < $target_loc[0])	{
			#		$move_loc[0]-=2;
			#	}
			#}
			##else if the mob is farther vertically than horizontally
			#else if (abs($my_loc[0] - $target_loc[0]) < abs($my_loc[1] - $target_loc[1]))	{
			#	#if the mobs is above me
			#	if ($my_loc[1] < $target_loc[1])	{
			#		$move_loc[0]-=2;
			#	}
			#	#else if the mob below me
			#	else if ($my_loc[1] > $target_loc[1])	{
			#		$move_loc[0]+=2;
			##	}
			#}
			#move (($my_loc[0] + move_loc[0]) ($my_loc[1] + move_loc[1]));
		}
	}
	else {
		ai_skillUse(
			$skill->getHandle(),
			$lvl,
			$maxCastTime,
			$minCastTime,
			$skill->getTargetType == Skill::TARGET_LOCATION ? (@{$target->{pos_to}}{qw(x y)})
				: $skill->getTargetType == Skill::TARGET_SELF ? ($skill->getOwner->{ID}, undef)
				: ($target->{ID}, undef),
			$tag, undef, $waitBeforeUse, $prefix
		)
	}
}
the new Attack.pm lines 581 to 591

Code: Select all

			ai_skillUse2(
				$skill,
				$config{"attackSkillSlot_${slot}_lvl"} || $char->getSkillLevel($skill),
				$config{"attackSkillSlot_${slot}_maxCastTime"},
				$config{"attackSkillSlot_${slot}_minCastTime"},
				$config{"attackSkillSlot_${slot}_isSelfSkill"} ? $char : $target,
				"attackSkillSlot_${slot}",
				undef,
				"attackSkill",
				$config{"attackSkillSlot_${slot}_useVertical"},
			);
Kaspy
Halfway to Eternity
Halfway to Eternity
Posts: 398
Joined: 08 Jun 2012, 15:42
Noob?: No
Location: Brazil

Re: Targeting - Vertical Firewall

#2 Post by Kaspy »

[EN]
There I took a look at your plugin completely, but I believe it can serve as an example:
http://forums.openkore.com/viewtopic.php?t=15129

[PT-BR]
Não dei uma olhada por completo no seu plugin, mas acredito que isso possa servir de exemplo:
http://forums.openkore.com/viewtopic.php?t=15129
Image
User avatar
kLabMouse
Administrator
Administrator
Posts: 1301
Joined: 24 Apr 2008, 12:02

Re: Targeting - Vertical Firewall

#3 Post by kLabMouse »

FreeCast is something Other.
It allow to Cast while moving.

This look more like an old Plugin, used to make Mage Fire Walls.
I donno if I still have it, or anyone else.
Historm
Human
Human
Posts: 27
Joined: 01 Jun 2011, 01:59
Noob?: No

Re: Targeting - Vertical Firewall

#4 Post by Historm »

Code: Select all

sub ai_skillUse2 {
	my ($skill, $lvl, $maxCastTime, $minCastTime, $target, $prefix, $waitBeforeUse, $tag) = @_;
	if ($skill->getIDN() == 18) {
		my @target_loc = @{$target->{pos_to}}{qw(x y)};
		my @my_loc = @{$skill->getOwner->{pos_to}}{qw(x y)};
		my @vertical_loc = (0,0);
		#based on the simple pathing algorithm that mobs have, I know where to firewall based on where the mob stands in relation to me
		#if the mob is farther horizontally than vertically, or if it is perfectly diagonal
		if (($my_loc[0] != $target_loc[0]) && (abs($my_loc[0] - $target_loc[0]) >= abs($my_loc[1] - $target_loc[1])))   {
			
			if ($my_loc[1] > $target_loc[1])   {message "the mob is below me\n";
			$vertical_loc[1]--;
			}
			
			else {message "the mob is above me\n";
			$vertical_loc[1]++;
			}
		}
		#else if the mob is farther vertically than horizontally
		elsif ($my_loc[1] != $target_loc[1]) {
			#if the mobs is on my left
			if ($my_loc[0] > $target_loc[0])   {message "the mob is on my left\n";
			$vertical_loc[0]--;
			}
			#else if the mob on my right
			else {message "the mob is on my right\n";
			$vertical_loc[0]++;
			}
		}
		message "Targeting for Firewall: I am standing on $my_loc[0] $my_loc[1]\n";
		message "Targeting for Firewall: My target is standing on $target_loc[0] $target_loc[1]\n";
		message "Targeting for Firewall: I am casting on ($my_loc[0] + $vertical_loc[0]) ($my_loc[1] + $vertical_loc[1])\n";
		ai_skillUse(
		$skill->getHandle(),
		$lvl,
		$maxCastTime,
		$minCastTime,
		$my_loc[0] + $vertical_loc[0], $my_loc[1] + $vertical_loc[1],
		$tag, undef, $waitBeforeUse, $prefix
		);
		my @move_loc = (0,0);
        #if the mob is farther horizontally than vertically, or if it is perfectly diagonal
        if (($my_loc[0] != $target_loc[0]) &&(abs($my_loc[0] - $target_loc[0]) >= abs($my_loc[1] - $target_loc[1])))   {
		#if the mob is on my left
			if ($my_loc[0] > $target_loc[0])   {message "the mob is on my left\n";
				$move_loc[0]+=2;
			}
		#else if the mob on my right
			else {message "the mob is on my right\n";
				$move_loc[0]-=2;
			}
        }
		#else if the mob is farther vertically than horizontally
		elsif ($my_loc[1] != $target_loc[1])   {
		#if the mobs is above me
			if ($my_loc[1] < $target_loc[1])   {message "the mob is above me\n";
				$move_loc[0]-=2;
			}
		#else if the mob below me
			else {message "the mob is below me\n";
				$move_loc[0]+=2;
			}
        }
		message "Moving for Firewall: I am moving to ($my_loc[0] + $move_loc[0]) ($my_loc[1] + $move_loc[1])\n";
		$char->move(($my_loc[0] + $move_loc[0]),($my_loc[1] + $move_loc[1]));
	}
	else {
		ai_skillUse(
			$skill->getHandle(),
			$lvl,
			$maxCastTime,
			$minCastTime,
			$skill->getTargetType == Skill::TARGET_LOCATION ? (@{$target->{pos_to}}{qw(x y)})
				: $skill->getTargetType == Skill::TARGET_SELF ? ($skill->getOwner->{ID}, undef)
				: ($target->{ID}, undef),
			$tag, undef, $waitBeforeUse, $prefix
		)
	}
}
I looked at the plugin for freecast, and it was helpful for some things, but what I need to do here is not add one more thing to do when something happens.

What I am trying to do is completely replace one process with a different process under certain conditions.

When the AI calls for the Firewall skill to be used, I want to use a different targeting than what ai_skillUse2 calls for, I want it to run my code and not the ai code. That may be easy to do, but I am not pretending to know what I am doing. I have no clue how to make that happen.

So I have successfully edited the AI.pm file to create the effect I want. The code works perfectly, the AI will do perfect vertical firewalls all of the time, except there is one problem and that is with the part of the code that moves the character down the firewall.

Code: Select all

		my @move_loc = (0,0);
        #if the mob is farther horizontally than vertically, or if it is perfectly diagonal
        if (($my_loc[0] != $target_loc[0]) &&(abs($my_loc[0] - $target_loc[0]) >= abs($my_loc[1] - $target_loc[1])))   {
		#if the mob is on my left
			if ($my_loc[0] > $target_loc[0])   {message "the mob is on my left\n";
				$move_loc[0]+=2;
			}
		#else if the mob on my right
			else {message "the mob is on my right\n";
				$move_loc[0]-=2;
			}
        }
		#else if the mob is farther vertically than horizontally
		elsif ($my_loc[1] != $target_loc[1])   {
		#if the mobs is above me
			if ($my_loc[1] < $target_loc[1])   {message "the mob is above me\n";
				$move_loc[0]-=2;
			}
		#else if the mob below me
			else {message "the mob is below me\n";
				$move_loc[0]+=2;
			}
        }
		message "Moving for Firewall: I am moving to ($my_loc[0] + $move_loc[0]) ($my_loc[1] + $move_loc[1])\n";
		$char->move(($my_loc[0] + $move_loc[0]),($my_loc[1] + $move_loc[1]));
The problem is that what is happening is that the character moves before casting firewall, resulting in a not-vertical firewall. I want the bot to Use the Skill first, and Move second.

I don't know how to make this happen, can someone please help?
Historm
Human
Human
Posts: 27
Joined: 01 Jun 2011, 01:59
Noob?: No

Re: Targeting - Vertical Firewall

#5 Post by Historm »

Update on my progress.

The following plugin, combined with my edit of ai_skilluse2 produces the desired effect - but
with the following issue(s)
1. Sometimes this plugin runs multiple times, moving the character 2, then 2 more, then 2 more, and so on.
2a. Sometimes this plugin causes the ai to lock up, because it tries to move over a dead or blocked cell.
2b. Does not check to see if we are in a good position (in relation to other cells we could stand on) to cast a vfwall.
3. Does not check to see if the monster has moved since we cast the firewall. This is more of a problem with passive and cast sensing mobs, and it isn't really something that in the explicit sense a vertical firewall plugin is meant to handle, if a mage is going to vfwall and then draw a mob into it, this plugin is meant to handle just the firewall, and movement part.

Going forward with this, I want to figure out how to make a plugin that intercepts and replaces a firewall skill use instead of editing the ai.pm file.
What I would ideally like to make happen is write the plugin to only cast the firewall, leaving out the movement.
Instead, the movement portion would be handled by a separate plugin function that completely controls movement:
1. Analyzes the area around itself and picks the best spot to vfwall.
2. Moves to the nearest cell that puts the most cells containing a firewall in the path between itself and the target.

Code: Select all

package firewallMove;

use strict;
use Plugins;
use Globals;
use Translation qw(T TF);
use Log qw(message warning error);
use AI;
use skill;
use Misc;
use Network;
use Network::Send;
use Utils;
use Math::Trig;
use Utils::Benchmark;
use Utils::PathFinding;


Plugins::register('Fire Wall Movement', 'experimental vertical firewall dodge', \&onUnload);
my $hook1 = Plugins::addHook('AI_post', \&call);
my $ID;
my $target;
my %timeout;
my (@my_loc, @target_loc, @move_loc);

sub onUnload {
Plugins::delHooks('AI_post', $hook1);
}

sub call {my $i = AI::findAction("attack");
	if (defined $i) {
		my $args = AI::args($i);
		$ID = $args->{ID};
		$target = Actor::get($ID);
		@target_loc = @{$target->{pos_to}}{qw(x y)};
		@my_loc = @{$char->{pos_to}}{qw(x y)};
		@move_loc = (0,0);
		}
	if (AI::action eq "skill_use" && main::timeOut(\%timeout)) {
		my $args = AI::args(AI::action);
		my $s = $args->{skillHandle};
		if ($s eq "MG_FIREWALL") {
		move();
	   }
	}

}
sub move {
	#if the mob is farther horizontally than vertically, or if it is perfectly diagonal
	if (($my_loc[0] != $target_loc[0]) &&(abs($my_loc[0] - $target_loc[0]) >= abs($my_loc[1] - $target_loc[1])))   {
	#if the mob is on my left
		if ($my_loc[0] > $target_loc[0])   {message "the mob is on my left\n";
			$move_loc[0]+=2;
		}
	#else if the mob on my right
		else {message "the mob is on my right\n";
			$move_loc[0]-=2;
		}
	}
	#else if the mob is farther vertically than horizontally
	elsif ($my_loc[1] != $target_loc[1])   {
	#if the mobs is above me
		if ($my_loc[1] < $target_loc[1])   {message "the mob is above me\n";
			$move_loc[1]-=2;
		}
	#else if the mob below me
		else {message "the mob is below me\n";
			$move_loc[1]+=2;
		}
	}
	message "Moving for Firewall: I am moving to ($my_loc[0] + $move_loc[0]) ($my_loc[1] + $move_loc[1])\n";
	$char->move(($my_loc[0] + $move_loc[0]),($my_loc[1] + $move_loc[1]));$timeout{time} = time;
	$timeout{time} = time;
	$timeout{timeout} = 1;
}
return 1;
Historm
Human
Human
Posts: 27
Joined: 01 Jun 2011, 01:59
Noob?: No

Re: Targeting - Vertical Firewall

#6 Post by Historm »

Specific Question:

When hooking packet_pre/skill_cast, how do I modify the packet's arguments?

I know how to access them and return their values, but I cannot figure out how to change what those values are.

I am making some progress and learning alot, some assistance here would be very nice.
MiBo
Noob
Noob
Posts: 6
Joined: 04 Dec 2012, 07:15
Noob?: Yes

Re: Targeting - Vertical Firewall

#7 Post by MiBo »

Historm wrote:Specific Question:

When hooking packet_pre/skill_cast, how do I modify the packet's arguments?

I know how to access them and return their values, but I cannot figure out how to change what those values are.

I am making some progress and learning alot, some assistance here would be very nice.
Hi, did u find the solution already?
If not, I could try to help you. I just started today with developing openkore + plugins but still, I'm a developer so I think I can help you. Would be just nice if you would post the code that you have with a line like:
# $xxx should become "abc"
so I can try to help you.

Best regards


// EDIT: kk I think i got what u want to do. Searched a bit for your used function....
Found this:

Code: Select all

if ($self->{hook_prefix} eq 'Network::Receive') {
			Plugins::callHook("packet_pre/$handler->[0]", \%args);
		} else {
			Plugins::callHook("$self->{hook_prefix}/packet_pre/$handler->[0]", \%args);
		}
in src\Network\PacketParser.pm.
Now the following link: http://www.perlmonks.org/?node_id=6758

So, normally every parameter in perl is passed by reference (this is what you're searching for imho).
So if you wanna get the param you do smth like

Code: Select all

my $shittyVar = shift;
If you wanna manipulate the Var now before your return your function, you have to declare it like this:

Code: Select all

my $shittyVar = shift;
$$shittyVar = "redeclare yo";
You dont need to use access via @_ param because the callHook function passes the parameter explicit as a reference ("\%args" = the backslash is the indicator for the explicit reference).

Hope this helps you a bit.

Regards,
MiBo
Historm
Human
Human
Posts: 27
Joined: 01 Jun 2011, 01:59
Noob?: No

Re: Targeting - Vertical Firewall

#8 Post by Historm »

Very helpful.

I have done a better job with the vertical firewall casting, and I have also started modifying the runfromtarget code in attack.pm so that it will consider hiding behind firewalls better than moving farther away from the mob. I have quite a bit to work on it, however.

Your lesson to teach me how to modify the /%args passed through hooks was very helpful, thanks.