Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 13 additions & 31 deletions plugins/checkAggressive/checkAggressive.pl
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
# character or one of the character's slaves.
#
# How it works:
# - The plugin reads monster data from %monstersTable.
# - It uses the monster Ai value to determine whether the monster is aggressive.
# - The plugin reads monster data through MonstersTable helper functions.
# - It checks the monster AI mode through MonstersTable to determine whether
# the monster is aggressive.
# - It then checks whether the monster is still clean.
# - It also checks whether the monster is moving toward the character or a
# slave before returning true.
Expand All @@ -21,8 +22,7 @@
#
# How to configure it:
# This plugin does not require custom config.txt entries.
# Just enable it and make sure monsters_table.txt is loaded and includes the Ai
# column.
# Just enable it and make sure monsters_table.txt is loaded.
#
# Examples:
# 1. Use this plugin to improve how OpenKore recognizes aggressive monsters
Expand All @@ -32,7 +32,8 @@
# homunculus, mercenary, or other slave are also detected correctly.
#
# Notes:
# - This plugin depends on monsters_table.txt, not on a separate JSON database.
# - This plugin depends on monsters_table.txt via MonstersTable APIs, not on a
# separate JSON database.
# - A monster must be aggressive by AI, clean, and moving toward you or a
# slave before it is treated as aggressive by this plugin.
#
Expand All @@ -42,6 +43,7 @@ package checkAggressive;
use Plugins;
use Globals;
use Log qw(message error debug warning);
use MonstersTable qw(monster_exists monster_is_aggressive_by_ai monster_level);

Plugins::register('checkAggressive', 'checkAggressive', \&Unload, \&Unload);

Expand All @@ -54,39 +56,19 @@ package checkAggressive;
PLUGIN_NAME => 'checkAggressive',
};

my %ai_constant = (
'01' => 0x81, '02' => 0x83, '03' => 0x1089, '04' => 0x3885,
'05' => 0x2085, '06' => 0, '07' => 0x108B, '08' => 0x7085,
'09' => 0x3095, '10' => 0x84, '11' => 0x84, '12' => 0x2085,
'13' => 0x308D, '17' => 0x91, '19' => 0x3095, '20' => 0x3295,
'21' => 0x3695, '24' => 0xA1, '25' => 0x1, '26' => 0xB695,
'27' => 0x8084, 'ABR_PASSIVE' => 0x21, 'ABR_OFFENSIVE' => 0xA5
);

sub Unload {
Plugins::delHooks($hooks);
message "[".PLUGIN_NAME."] Plugin unloading or reloading.\n", 'success';
}

sub is_monster_ai_aggressive {
my ($ai_str) = @_;
$ai_str = uc($ai_str);

my $mode_value = exists $ai_constant{$ai_str}
? $ai_constant{$ai_str}
: $ai_constant{'06'};

return ($mode_value & 0x4) ? 1 : 0;
}

sub on_ai_check_Aggressiveness {
my ($self, $args) = @_;

my $monster = $args->{monster};
my $ID = $monster->{ID};

return unless (exists $monstersTable{$monster->{nameID}});
return unless (is_monster_ai_aggressive($monstersTable{$monster->{nameID}}{Ai}));
return unless (monster_exists($monster->{nameID}));
return unless monster_is_aggressive_by_ai($monster->{nameID});

my $found_clean = 0;
my $found_moving = 0;
Expand All @@ -101,7 +83,7 @@ sub on_ai_check_Aggressiveness {

return unless ($found_clean && $found_moving);

debug "[".PLUGIN_NAME."] Monster $monster at ($monster->{pos}{x} $monster->{pos}{y}) | Lvl $monstersTable{$monster->{nameID}}{Level} | is Aggressive, clean, and coming to us\n";
debug "[".PLUGIN_NAME."] Monster $monster at ($monster->{pos}{x} $monster->{pos}{y}) | Lvl ".monster_level($monster->{nameID})." | is Aggressive, clean, and coming to us\n";

$args->{return} = 1;
return;
Expand All @@ -114,14 +96,14 @@ sub on_ai_slave_check_Aggressiveness {
my $ID = $monster->{ID};
my $slave = $args->{slave};

return unless (exists $monstersTable{$monster->{nameID}});
return unless (is_monster_ai_aggressive($monstersTable{$monster->{nameID}}{Ai}));
return unless (monster_exists($monster->{nameID}));
return unless monster_is_aggressive_by_ai($monster->{nameID});

return unless (Misc::slave_checkMonsterCleanness($slave, $ID) || Misc::checkMonsterCleanness($ID));

return unless (Misc::objectIsMovingTowards($monster, $slave) || Misc::objectIsMovingTowards($monster, $char));

debug "[".PLUGIN_NAME."] Monster $monster at ($monster->{pos}{x} $monster->{pos}{y}) | Lvl $monstersTable{$monster->{nameID}}{Level} | is Aggressive towards slave, clean, and coming to him\n";
debug "[".PLUGIN_NAME."] Monster $monster at ($monster->{pos}{x} $monster->{pos}{y}) | Lvl ".monster_level($monster->{nameID})." | is Aggressive towards slave, clean, and coming to him\n";

$args->{return} = 1;
return;
Expand Down
39 changes: 9 additions & 30 deletions plugins/checkLooter/checkLooter.pl
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
#
# How it works:
# - When OpenKore runs the check_attackLooter hook, this plugin looks up the
# target monster in %monstersTable.
# - It reads the monster Ai value from monsters_table.txt.
# - It converts that AI type into mode flags and checks whether the MD_LOOTER
# bit is enabled.
# target monster through MonstersTable helper functions.
# - It reads the monster AI value from monsters_table.txt through
# monster_is_looter_by_ai.
# - It checks whether the looter flag is enabled for that AI mode.
# - If the monster is not a looter, the plugin sets $args->{return} = 1.
#
# How to configure it:
Expand All @@ -29,8 +29,8 @@
# behavior where extended checks and looter checks are handled separately.
#
# Notes:
# - This plugin depends on monsters_table.txt having Ai data for each monster.
# - If a monster is missing from %monstersTable, the plugin logs a warning and
# - This plugin depends on monsters_table.txt having AI data for each monster.
# - If a monster is missing from MonstersTable, the plugin logs a warning and
# leaves the hook result unchanged.
#
package checkLooter;
Expand All @@ -39,6 +39,7 @@ package checkLooter;
use Plugins;
use Globals;
use Log qw(debug warning);
use MonstersTable qw(monster_exists monster_is_looter_by_ai);

use constant {
PLUGIN_NAME => 'checkLooter',
Expand All @@ -50,15 +51,6 @@ package checkLooter;
['check_attackLooter', \&oncheck_attackLooter, undef],
);

my %ai_constant = (
'01' => 0x81, '02' => 0x83, '03' => 0x1089, '04' => 0x3885,
'05' => 0x2085, '06' => 0, '07' => 0x108B, '08' => 0x7085,
'09' => 0x3095, '10' => 0x84, '11' => 0x84, '12' => 0x2085,
'13' => 0x308D, '17' => 0x91, '19' => 0x3095, '20' => 0x3295,
'21' => 0x3695, '24' => 0xA1, '25' => 0x1, '26' => 0xB695,
'27' => 0x8084, 'ABR_PASSIVE' => 0x21, 'ABR_OFFENSIVE' => 0xA5
);

=pod
/// Monster mode definitions to clear up code reading. [Skotlex]
enum e_mode {
Expand Down Expand Up @@ -102,14 +94,12 @@ sub oncheck_attackLooter {
my ($hook, $args) = @_;
return 0 if (!$args->{monster} || $args->{monster}->{nameID} eq '');

if (!exists $monstersTable{$args->{monster}->{nameID}}) {
if (!monster_exists($args->{monster}->{nameID})) {
warning "[checkLooter] Monster {name '$args->{monster}->{name}'} {ID '$args->{monster}->{nameID}'} not found\n", 'checkLooter';
return;
}

my $mob = $monstersTable{$args->{monster}->{nameID}};
my $ai = $mob->{Ai};
my $is_looter = is_monster_ai_looter($ai);
my $is_looter = monster_is_looter_by_ai($args->{monster}->{nameID});
if (!$is_looter) {
debug "[checkLooter] [False] $args->{monster} ($args->{monster}->{nameID}) is not a Looter\n", 'checkLooter';
$args->{return} = 1;
Expand All @@ -118,15 +108,4 @@ sub oncheck_attackLooter {
}
}

sub is_monster_ai_looter {
my ($ai_str) = @_;
$ai_str = uc($ai_str);

my $mode_value = exists $ai_constant{$ai_str}
? $ai_constant{$ai_str}
: $ai_constant{'06'};

return ($mode_value & 0x2) ? 1 : 0;
}

1;
36 changes: 19 additions & 17 deletions plugins/eCast/eCast.pl
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ package eCast;
use Translation qw(T TF);
use Utils;
use AI;
use MonstersTable qw(monster_exists monster_field monster_hp monster_level);
use POSIX qw(floor);

use constant {
Expand Down Expand Up @@ -109,7 +110,8 @@ sub onUnload {
Plugins::delHooks($hooks);
}

# TODO: Revisar
# Extends default monster condition checks with additional database/runtime
# filters used by attackSkillSlot, equipAuto, attackComboSlot and monsterSkill.
sub extendedCheck {
my (undef, $args) = @_;

Expand All @@ -129,18 +131,17 @@ sub extendedCheck {
}
}

if (!exists $monstersTable{$args->{monster}->{nameID}}) {
if (!monster_exists($args->{monster}->{nameID})) {
Log::warning("eCast: Monster {name '$args->{monster}->{name}'} {ID '$args->{monster}->{nameID}'} not found\n", 'eCast');
return 0;
}

my $ID = $args->{monster}->{nameID};
my $mob = $monstersTable{$args->{monster}->{nameID}};

my $element = $mob->{Element};
my $element_lvl = $mob->{ElementLevel};
my $race = $mob->{Race};
my $size = $mob->{Size};
my $element = monster_field($ID, 'Element');
my $element_lvl = monster_field($ID, 'ElementLevel');
my $race = monster_field($ID, 'Race');
my $size = monster_field($ID, 'Size');

if ($args->{monster}->{element} && $args->{monster}->{element} ne '') {
$element = $args->{monster}->{element};
Expand Down Expand Up @@ -192,12 +193,12 @@ sub extendedCheck {
}

if ($config{$args->{prefix} . '_hpLeft'}
&& !inRange(($mob->{HP} + $args->{monster}->{deltaHp}),$config{$args->{prefix} . '_hpLeft'})) {
&& !inRange((monster_hp($ID) + $args->{monster}->{deltaHp}),$config{$args->{prefix} . '_hpLeft'})) {
return $args->{return} = 0;
}

if ($config{$args->{prefix} . '_Level'}
&& !inRange(($mob->{Level}),$config{$args->{prefix} . '_Level'})) {
&& !inRange((monster_level($ID)),$config{$args->{prefix} . '_Level'})) {
return $args->{return} = 0;
}

Expand All @@ -210,7 +211,7 @@ sub hasFreeCellBehind {
my $charPos = calcPosFromPathfinding($field, $char);
my $targetPos = calcPosFromPathfinding($field, $monster);

my $dir = map_calc_dir_xy($charPos->{x}, $charPos->{y}, $targetPos->{x}, $targetPos->{x});
my $dir = map_calc_dir_xy($charPos->{x}, $charPos->{y}, $targetPos->{x}, $targetPos->{y});

my ($x, $y);

Expand Down Expand Up @@ -275,11 +276,11 @@ sub map_calc_dir_xy {
}
}

# TODO: Revisar
# Add live HP information to packet messages when possible.
sub onPacketSkillUse { monsterHp($monsters{$_[1]->{targetID}}, $_[1]->{disp}) if $_[1]->{disp} }

# TODO: Revisar
sub onPacketSkillUseNoDmg {
# Track element changes from self-targeted NPC_CHANGE* skills.
sub onPacketSkillUseNoDamage {
my (undef,$args) = @_;
return 1 unless $monsters{$args->{targetID}} && $monsters{$args->{targetID}}{nameID};
if (
Expand All @@ -292,16 +293,17 @@ sub onPacketSkillUseNoDmg {
}
}

# TODO: Revisar
# Add live HP information to normal attack packet messages when possible.
sub onPacketAttack { monsterHp($monsters{$_[1]->{targetID}}, $_[1]->{msg}) if $_[1]->{msg} }

# TODO: Revisar
# Inject current/base HP information into a packet message buffer.
sub monsterHp {
my ($monster, $message) = @_;
return 1 unless $monster && $monster->{nameID};
my $ID = int($monster->{nameID});
return 1 unless my $monsterInfo = $monstersTable{$ID};
$$message =~ s~(?=\n)~TF(" (Hp: %d/%d)", $monsterInfo->{HP} + $monster->{deltaHp}, $monsterInfo->{HP})~se;
my $base_hp = monster_hp($ID);
return 1 unless defined $base_hp;
$$message =~ s~(?=\n)~TF(" (Hp: %d/%d)", $base_hp + $monster->{deltaHp}, $base_hp)~se;
}

1;
Loading
Loading