Post Reply Home » Forums » Ragnarok Online » RO Submissions

ck : RO Submissions

Posted: June 5th, 2007
xlr82xs

Code: Select all

package ClosedKore;

use Globals;
use Plugins;
use Settings;
use Log qw(message);
use Utils;


my ($initialized_hook, $start2_hook, $AI_pre_hook, $packet_privMsg_hook);
my %realTimeout;

sub initializeEliza {
#	use Chatbot::Eliza;
#	$bot = new Chatbot::Eliza "Kore", "elizascript.txt";
}

# Reset %timeout based on %realTimeout.
# Generate random timeout values.
sub initTimeouts {
	%timeout = () if (!%timeout);
	foreach my $key (keys %realTimeout) {
		$timeout{$key}{'timeout'} = $realTimeout{$key}{'timeout'};
		$timeout{$key}{'timeout'} += rand($realTimeout{$key}{'variance'}) if ($realTimeout{$key}{'variance'});
	}
	$timeout{'ai_resetTimeouts'}{'time'} = time;
	#print "Reset: $timeout{'ai_attack'}{'timeout'} - $timeout{'ai_resetTimeouts'}{'timeout'}\n";
}

sub parseTimeouts {
	my $file = shift;
	my $r_hash = shift;
	open(FILE, "<file> 0 && !$main::monsters_old{$main::ai_v{'ai_attack_ID_old'}}{'attackedByPlayer'} && !$main::monsters_old{$main::ai_v{'ai_attack_ID_old'}}{'ignore'}) {
					main::ai_items_take($main::monsters_old{$main::ai_v{'ai_attack_ID_old'}}{'pos'}{'x'}, $main::monsters_old{$main::ai_v{'ai_attack_ID_old'}}{'pos'}{'y'}, $main::monsters_old{$main::ai_v{'ai_attack_ID_old'}}{'pos_to'}{'x'}, $main::monsters_old{$main::ai_v{'ai_attack_ID_old'}}{'pos_to'}{'y'});
				} elsif (!main::ai_getAggressives()) {
					# Cheap way to suspend all movement to make it look real
					main::ai_clientSuspend(0, $main::timeout{'ai_attack_waitAfterKill'}{'timeout'});
				}

				## kokal start
				## mosters counting
				my $i = 0;
				my $found = 0;
				while ($main::monsters_Killed[$i]) {
					if ($main::monsters_Killed[$i]{'nameID'} eq $main::monsters_old{$main::ai_v{'ai_attack_ID_old'}}{'nameID'}) {
						$main::monsters_Killed[$i]{'count'}++;
						$found = 1;
						last;
					}
					$i++;
				}
				if (!$found) {
					$main::monsters_Killed[$i]{'nameID'} = $main::monsters_old{$main::ai_v{'ai_attack_ID_old'}}{'nameID'};
					$main::monsters_Killed[$i]{'name'} = $main::monsters_old{$main::ai_v{'ai_attack_ID_old'}}{'name'};
					$main::monsters_Killed[$i]{'count'} = 1;
				}
				## kokal end

			} else {
				message "Target lost\n", 1;
			}

		} elsif ($main::ai_seq[0] eq "attack") {
			$main::ai_v{'temp'}{'ai_follow_index'} = binFind(\@ai_seq, "follow");
			if ($main::ai_v{'temp'}{'ai_follow_index'} ne "") {
				$main::ai_v{'temp'}{'ai_follow_following'} = $main::ai_seq_args[$main::ai_v{'temp'}{'ai_follow_index'}]{'following'};
				$main::ai_v{'temp'}{'ai_follow_ID'} = $main::ai_seq_args[$main::ai_v{'temp'}{'ai_follow_index'}]{'ID'};
			} else {
				undef $main::ai_v{'temp'}{'ai_follow_following'};
			}

			$main::ai_v{'ai_attack_cleanMonster'} = (
			!($main::monsters{$main::ai_seq_args[0]{'ID'}}{'dmgFromYou'} == 0 && ($main::monsters{$main::ai_seq_args[0]{'ID'}}{'dmgTo'} > 0 || $main::monsters{$main::ai_seq_args[0]{'ID'}}{'dmgFrom'} > 0 || %{$main::monsters{$main::ai_seq_args[0]{'ID'}}{'missedFromPlayer'}} || %{$main::monsters{$main::ai_seq_args[0]{'ID'}}{'missedToPlayer'}} || %{$main::monsters{$main::ai_seq_args[0]{'ID'}}{'castOnByPlayer'}}))
			|| ($main::config{'attackAuto_party'} && ($main::monsters{$main::ai_seq_args[0]{'ID'}}{'dmgFromParty'} > 0 || $main::monsters{$main::ai_seq_args[0]{'ID'}}{'dmgToParty'} > 0))
			|| ($main::config{'attackAuto_followTarget'} && $main::ai_v{'temp'}{'ai_follow_following'} && ($main::monsters{$main::ai_seq_args[0]{'ID'}}{'dmgToPlayer'}{$main::ai_v{'temp'}{'ai_follow_ID'}} > 0 || $main::monsters{$main::ai_seq_args[0]{'ID'}}{'missedToPlayer'}{$main::ai_v{'temp'}{'ai_follow_ID'}} > 0 || $main::monsters{$main::ai_seq_args[0]{'ID'}}{'dmgFromPlayer'}{$main::ai_v{'temp'}{'ai_follow_ID'}} > 0))
			|| ($main::monsters{$main::ai_seq_args[0]{'ID'}}{'dmgToYou'} > 0 || $main::monsters{$main::ai_seq_args[0]{'ID'}}{'missedYou'} > 0)
			);
			$main::ai_v{'ai_attack_cleanMonster'} = 0 if ($main::monsters{$main::ai_seq_args[0]{'ID'}}{'attackedByPlayer'});
			$main::ai_v{'ai_attack_cleanMonster'} = 1 if ($main::mon_control{lc($main::monsters{$main::_}{'name'})}{'kill_steal'});

			$main::ai_v{'ai_attack_monsterDist'} = main::distance(\%{$main::chars[$main::config{'char'}]{'pos_to'}}, \%{$main::monsters{$main::ai_seq_args[0]{'ID'}}{'pos_to'}});

			if ($main::ai_seq_args[0]{'dmgToYou_last'} != $main::monsters{$main::ai_seq_args[0]{'ID'}}{'dmgToYou'}
			|| $main::ai_seq_args[0]{'missedYou_last'} != $main::monsters{$main::ai_seq_args[0]{'ID'}}{'missedYou'}
			|| $main::ai_seq_args[0]{'dmgFromYou_last'} != $main::monsters{$main::ai_seq_args[0]{'ID'}}{'dmgFromYou'}) {
				$main::ai_seq_args[0]{'ai_attack_giveup'}{'time'} = time;
			}
			$main::ai_seq_args[0]{'dmgToYou_last'} = $main::monsters{$main::ai_seq_args[0]{'ID'}}{'dmgToYou'};
			$main::ai_seq_args[0]{'missedYou_last'} = $main::monsters{$main::ai_seq_args[0]{'ID'}}{'missedYou'};
			$main::ai_seq_args[0]{'dmgFromYou_last'} = $main::monsters{$main::ai_seq_args[0]{'ID'}}{'dmgFromYou'};
			$main::ai_seq_args[0]{'missedFromYou_last'} = $main::monsters{$main::ai_seq_args[0]{'ID'}}{'missedFromYou'};
			if (!%{$main::ai_seq_args[0]{'attackMethod'}}) {
				if ($main::config{'attackUseWeapon'}) {
					$main::ai_seq_args[0]{'attackMethod'}{'distance'} = $main::config{'attackDistance'};
					$main::ai_seq_args[0]{'attackMethod'}{'type'} = "weapon";
				} else {
					$main::ai_seq_args[0]{'attackMethod'}{'distance'} = 30;
					undef $main::ai_seq_args[0]{'attackMethod'}{'type'};
				}
				$i = 0;
				while ($main::config{"attackSkillSlot_$i"} ne "") {
					if (main::percent_hp(\%{$main::chars[$main::config{'char'}]}) >= $main::config{"attackSkillSlot_$i"."_hp_lower"} && main::percent_hp(\%{$main::chars[$main::config{'char'}]}) <main>= $main::config{"attackSkillSlot_$i"."_sp_lower"} && main::percent_sp(\%{$main::chars[$main::config{'char'}]}) <main>= $main::skillsSP_lut{$main::skills_rlut{lc($main::config{"attackSkillSlot_$i"})}}{$main::config{"attackSkillSlot_$i"."_lvl"}}
					&& !($main::config{"attackSkillSlot_$i"."_stopWhenHit"} && amain::i_getMonstersWhoHitMe())
					&& (!$main::config{"attackSkillSlot_$i"."_maxUses"} || $main::ai_seq_args[0]{'attackSkillSlot_uses'}{$i} < $main::config{"attackSkillSlot_$i"."_maxUses"})
					&& $main::config{"attackSkillSlot_$i"."_minAggressives"} <main>= main::ai_getAggressives())
					&& (!$main::config{"attackSkillSlot_$i"."_monsters"} || main::existsInList($main::config{"attackSkillSlot_$i"."_monsters"}, $main::monsters{$main::ai_seq_args[0]{'ID'}}{'name'}))) {
						$main::ai_seq_args[0]{'attackSkillSlot_uses'}{$i}++;
						$main::ai_seq_args[0]{'attackMethod'}{'distance'} = $main::config{"attackSkillSlot_$i"."_dist"};
						$main::ai_seq_args[0]{'attackMethod'}{'type'} = "skill";
						$main::ai_seq_args[0]{'attackMethod'}{'skillSlot'} = $i;
						last;
					}
					$i++;
				}
			}

			if ($main::chars[$main::config{'char'}]{'sitting'}) {
				main::ai_setSuspend(0);
				main::stand();

			} elsif (!$main::ai_v{'ai_attack_cleanMonster'}) {
				# Drop target if it's already attacked by someone else
				message "Dropping target - you will not kill steal others\n", 1;
				$main::monsters{$main::ai_seq_args[0]{'ID'}}{'ignore'} = 1;
				main::sendAttackStop(\$main::remote_socket);
				shift @ai_seq;
				shift @ai_seq_args;

			} elsif ($main::ai_v{'ai_attack_monsterDist'} > $main::ai_seq_args[0]{'attackMethod'}{'distance'}) {
				# Move to target
				if (%{$main::ai_seq_args[0]{'char_pos_last'}} && %{$main::ai_seq_args[0]{'attackMethod_last'}}
				&& $main::ai_seq_args[0]{'attackMethod_last'}{'distance'} == $main::ai_seq_args[0]{'attackMethod'}{'distance'}
				&& $main::ai_seq_args[0]{'char_pos_last'}{'x'} == $main::chars[$main::config{'char'}]{'pos_to'}{'x'}
				&& $main::ai_seq_args[0]{'char_pos_last'}{'y'} == $main::chars[$main::config{'char'}]{'pos_to'}{'y'}) {
					$main::ai_seq_args[0]{'distanceDivide'}++;
				} else {
					$main::ai_seq_args[0]{'distanceDivide'} = 1;
				}
				if (int($main::ai_seq_args[0]{'attackMethod'}{'distance'} / $main::ai_seq_args[0]{'distanceDivide'}) == 0 || ($main::config{'attackMaxRouteDistance'} && $main::ai_seq_args[0]{'ai_route_returnHash'}{'solutionLength'} > $main::config{'attackMaxRouteDistance'}) || ($main::config{'attackMaxRouteTime'} && $main::ai_seq_args[0]{'ai_route_returnHash'}{'solutionTime'} > $main::config{'attackMaxRouteTime'})) {
					$main::monsters{$main::ai_seq_args[0]{'ID'}}{'attack_failed'}++;
					shift @ai_seq;
					shift @ai_seq_args;
					message "Dropping target - couldn't reach target\n",,1;
				} else {
					main::getVector(\%{$main::ai_v{'temp'}{'vec'}}, \%{$main::monsters{$main::ai_seq_args[0]{'ID'}}{'pos_to'}}, \%{$main::chars[$main::config{'char'}]{'pos_to'}});
					main::moveAlongVector(\%{$main::ai_v{'temp'}{'pos'}}, \%{$main::chars[$main::config{'char'}]{'pos_to'}}, \%{$main::ai_v{'temp'}{'vec'}},
					$main::ai_v{'ai_attack_monsterDist'} - ($main::ai_seq_args[0]{'attackMethod'}{'distance'} / $main::ai_seq_args[0]{'distanceDivide'}) + 1);

					%{$main::ai_seq_args[0]{'char_pos_last'}} = %{$main::chars[$main::config{'char'}]{'pos_to'}};
					%{$main::ai_seq_args[0]{'attackMethod_last'}} = %{$main::ai_seq_args[0]{'attackMethod'}};

					main::ai_setSuspend(0);
					if (@{$main::field{'field'}} > 1) {
						main::ai_route(\%{$main::ai_seq_args[0]{'ai_route_returnHash'}}, $main::ai_v{'temp'}{'pos'}{'x'}, $main::ai_v{'temp'}{'pos'}{'y'}, $main::field{'name'}, $main::config{'attackMaxRouteDistance'}, $main::config{'attackMaxRouteTime'}, 0, 0, 0, 0, $main::ai_seq_args[0]{'ID'});
					} else {
						main::move($main::ai_v{'temp'}{'pos'}{'x'}, $main::ai_v{'temp'}{'pos'}{'y'}, 0, $main::ai_seq_args[0]{'ID'});
					}
				}

			} elsif ((($main::config{'tankMode'} && $main::monsters{$main::ai_seq_args[0]{'ID'}}{'dmgFromYou'} == 0)
			|| !$main::config{'tankMode'})) {
				# Attack the target. In case of tanking, only attack if it hasn't been hit once.

				if ($main::ai_seq_args[0]{'attackMethod'}{'type'} eq "weapon" && timeOut(\%{$main::timeout{'ai_attack'}})) {
					if ($main::config{'tankMode'}) {
						main::sendAttack(\$main::remote_socket, $main::ai_seq_args[0]{'ID'}, 0);
					} else {
						main::sendAttack(\$main::remote_socket, $main::ai_seq_args[0]{'ID'}, 7);
					}
					$main::timeout{'ai_attack'}{'time'} = time;
					undef %{$main::ai_seq_args[0]{'attackMethod'}};
				} elsif ($main::ai_seq_args[0]{'attackMethod'}{'type'} eq "skill") {
					$main::ai_v{'ai_attack_method_skillSlot'} = $main::ai_seq_args[0]{'attackMethod'}{'skillSlot'};
					$main::ai_v{'ai_attack_ID'} = $main::ai_seq_args[0]{'ID'};
					undef %{$main::ai_seq_args[0]{'attackMethod'}};
					main::ai_setSuspend(0);
					if (!main::ai_getSkillUseType($main::skills_rlut{lc($main::config{"attackSkillSlot_$main::ai_v{'ai_attack_method_skillSlot'}"})})) {
						main::ai_skillUse($main::chars[$main::config{'char'}]{'skills'}{$main::skills_rlut{lc($main::config{"attackSkillSlot_$main::ai_v{'ai_attack_method_skillSlot'}"})}}{'ID'}, $main::config{"attackSkillSlot_$main::ai_v{'ai_attack_method_skillSlot'}"."_lvl"}, $main::config{"attackSkillSlot_$main::ai_v{'ai_attack_method_skillSlot'}"."_maxCastTime"}, $main::config{"attackSkillSlot_$main::ai_v{'ai_attack_method_skillSlot'}"."_minCastTime"}, $main::ai_v{'ai_attack_ID'});
					} else {
						main::ai_skillUse($main::chars[$main::config{'char'}]{'skills'}{$main::skills_rlut{lc($main::config{"attackSkillSlot_$main::ai_v{'ai_attack_method_skillSlot'}"})}}{'ID'}, $main::config{"attackSkillSlot_$main::ai_v{'ai_attack_method_skillSlot'}"."_lvl"}, $main::config{"attackSkillSlot_$main::ai_v{'ai_attack_method_skillSlot'}"."_maxCastTime"}, $main::config{"attackSkillSlot_$main::ai_v{'ai_attack_method_skillSlot'}"."_minCastTime"}, $main::monsters{$main::ai_v{'ai_attack_ID'}}{'pos_to'}{'x'}, $main::monsters{$main::ai_v{'ai_attack_ID'}}{'pos_to'}{'y'});
					}
					#				debug 'Auto-skill on monster: $main::skills_lut{$main::skills_rlut{lc($main::config{"attackSkillSlot_$main::ai_v{'ai_attack_method_skillSlot'}"})}} (lvl $main::config{"attackSkillSlot_$main::ai_v{'ai_attack_method_skillSlot'}"."_lvl"})\n', "ai";
				}

			} elsif ($main::config{'HitAndRun'} = "1") {
				my $flee_x;
				my $flee_y;
				while ($main::config{'attackDistance'} >= main::distance(\%{$main::chars[$main::config{'char'}]{'pos_to'}}, \%{$main::monsters{$main::ai_v{'ai_attack_ID'}}{'pos_to'}})) {
					if (($main::chars[$main::config{'char'}]{'pos'}{'x'}) - ($main::monsters{$main::ai_v{'ai_attack_ID'}}{'pos_to'}{'x'}) <0> 0) {
						$flee_x = $main::config{'runDistance'};
					} else {
						$flee_x = 0;
					}
					if (($main::chars[$main::config{'char'}]{'pos'}{'y'}) - ($main::monsters{$main::ai_v{'ai_attack_ID'}}{'pos_to'}{'y'}) <0> 0) {
						$flee_y = $main::config{'runDistance'};
					} else {
						$flee_y = 0;
					}
					$flee_x = ($main::chars[$main::config{'char'}]{'pos'}{'x'}) + $flee_x;
					$flee_y = ($main::chars[$main::config{'char'}]{'pos'}{'y'}) + $flee_y;
					$flee_x = 0 if ($flee_x <main> $main::field{'width'});
					$flee_y = 0 if ($flee_y <main> $main::field{'height'});
					if ($flee_x && $flee_y eq 0) {
						$flee_x = int(rand() * ($main::field{'width'} - 1));
						$flee_y = int(rand() * ($main::field{'height'} - 1));
					} elsif ($flee_x eq $main::field{'width'} && $flee_y eq $main::field{'height'}) {
						$flee_x = int(rand() * ($main::field{'width'} - 1));
						$flee_y = int(rand() * ($main::field{'height'} - 1));
					}
					main::move($flee_x, $flee_y);
				}
				message "Fleeing from target\n",,1;
			} elsif ($main::config{'tankMode'}) {
				if ($main::ai_seq_args[0]{'dmgTo_last'} != $main::monsters{$main::ai_seq_args[0]{'ID'}}{'dmgTo'}) {
					$main::ai_seq_args[0]{'ai_attack_giveup'}{'time'} = time;
				}
				$main::ai_seq_args[0]{'dmgTo_last'} = $main::monsters{$main::ai_seq_args[0]{'ID'}}{'dmgTo'};
			}
		}


		# Check for kill steal while moving
		if (main::binFind(\@ai_seq, "attack") ne ""
		&& (($main::ai_seq[0] eq "move" || $main::ai_seq[0] eq "route") && $main::ai_seq_args[0]{'attackID'})) {
			$main::ai_v{'temp'}{'ai_follow_index'} = main::binFind(\@ai_seq, "follow");
			if ($main::ai_v{'temp'}{'ai_follow_index'} ne "") {
				$main::ai_v{'temp'}{'ai_follow_following'} = $main::ai_seq_args[$main::ai_v{'temp'}{'ai_follow_index'}]{'following'};
				$main::ai_v{'temp'}{'ai_follow_ID'} = $main::ai_seq_args[$main::ai_v{'temp'}{'ai_follow_index'}]{'ID'};
			} else {
				undef $main::ai_v{'temp'}{'ai_follow_following'};
			}

			my $iD = $main::ai_seq_args[0]{'attackID'};
			$main::ai_v{'ai_attack_cleanMonster'} = (
			!($main::monsters{$iD}{'dmgFromYou'} == 0 && ($main::monsters{$iD}{'dmgTo'} > 0 || $main::monsters{$iD}{'dmgFrom'} > 0 || %{$main::monsters{$iD}{'missedFromPlayer'}} || %{$main::monsters{$iD}{'missedToPlayer'}} || %{$main::monsters{$iD}{'castOnByPlayer'}}))
			|| ($main::config{'attackAuto_party'} && ($main::monsters{$iD}{'dmgFromParty'} > 0 || $main::monsters{$iD}{'dmgToParty'} > 0))
			|| ($main::config{'attackAuto_followTarget'} && $main::ai_v{'temp'}{'ai_follow_following'} && ($main::monsters{$iD}{'dmgToPlayer'}{$main::ai_v{'temp'}{'ai_follow_ID'}} > 0 || $main::monsters{$iD}{'missedToPlayer'}{$main::ai_v{'temp'}{'ai_follow_ID'}} > 0 || $main::monsters{$iD}{'dmgFromPlayer'}{$main::ai_v{'temp'}{'ai_follow_ID'}} > 0))
			|| ($main::monsters{$iD}{'dmgToYou'} > 0 || $main::monsters{$iD}{'missedYou'} > 0)
			);
			$main::ai_v{'ai_attack_cleanMonster'} = 0 if ($main::monsters{$iD}{'attackedByPlayer'});
			$main::ai_v{'ai_attack_cleanMonster'} = 1 if ($main::mon_control{lc($main::monsters{$main::_}{'name'})}{'kill_steal'});

			if (!$main::ai_v{'ai_attack_cleanMonster'}) {
				message "Dropping target - you will not kill steal others\n",,1;
				main::sendAttackStop(\$main::remote_socket);
				$main::monsters{$main::ai_seq_args[0]{'ID'}}{'ignore'} = 1;

				shift @ai_seq;
				shift @ai_seq_args;
				if ($main::ai_seq[0] eq "route") {
					shift @ai_seq;
					shift @ai_seq_args;
				}
				shift @ai_seq;
				shift @ai_seq_args;
			}
		}
	}
}

sub timeOut {
	my ($r_time, $compare_time) = @_;
	if ($compare_time ne "") {
		return (time - $r_time > $compare_time);
	} else {
		return (time - $$r_time{'time'} > $$r_time{'timeout'});
	}
}

# statConvert(stat)
# where stat is agi or str or dex etc etc
# returns the id code

sub statConvert {
		my $stat = shift;
		my $ID;
			if ($stat eq "str") {
				$ID = 0x0D;
			} elsif ($stat eq "agi") {
				$ID = 0x0E;
			} elsif ($stat eq "vit") {
				$ID = 0x0F;
			} elsif ($stat eq "int") {
				$ID = 0x10;
			} elsif ($stat eq "dex") {
				$ID = 0x11;
			} elsif ($stat eq "luk") {
				$ID = 0x12;
			} else {
				$ID = 0;
			}
			return $ID;
		}

sub unload_cb {
	Plugins::delHook('start2', $start2_hook);
	Plugins::delHook('initialized', $initialized_hook);
	Plugins::delHook('AI_pre_hook', $AI_pre_hook);
	Plugins::delHook('packet_privMsg', $packet_privMsg_hook);
	Plugins::delHook('Command_post', $input_hook);
	Plugins::delHook('AI_pre', $autoadd_hook);
	Plugins::delHook('AI_pre', $automap_hook);
	Plugins::delHook('AI_pre', $autosave_hook);
	Plugins::delHook('AI_pre', $closedattack_hook);
	Plugins::delHook('start3', $initializedEliza_hook);
}

sub reload_cb {
	&unload_cb;
}

Plugins::register('ClosedKore', 'The ClosedKore Plugin', \&unload_cb, \&reload_cb);
$start2_hook = Plugins::addHook('start2', \&addParseFile);
$initialized_hook = Plugins::addHook('initialized', \&initTimeouts);
$AI_pre_hook = Plugins::addHook('AI_pre', \&resetTimeouts);
$packet_privMsg_hook = Plugins::addHook('packet_privMsg', \&packet_privMsg_cb);
$input_hook = Plugins::addHook('Command_post', \&input);
$autoadd_hook = Plugins::addHook('AI_pre', \&autoadd);
$automap_hook = Plugins::addHook('AI_pre', \&automap);
$autosave_hook = Plugins::addHook('AI_pre', \&autosave);
$closedattack_hook = Plugins::addHook('AI_pre', \&closedattack);
$initializeEliza_hook = Plugins::addHook('start3', \&initializeEliza);

return 1;
Posted: June 5th, 2007
xlr82xs
this is fairly old, but there were requests for "new" information :-/
Ready to join the community? Click here and see all of the benefits!
blue large dotWho is online
Users browsing this forum: No registered users and 7 guests
Post Reply