Skip to content
Merged
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
10 changes: 10 additions & 0 deletions control/config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ friendlyAID
showTime
showTimeDomains
showTimeDomainsFormat
# Wx map text and portal overlay thresholds
wx_map_maxAutoSize 300
wx_map_monsterSticking 1
wx_map_npcSticking 1
Expand Down Expand Up @@ -413,6 +414,7 @@ noAutoSkill 0
portalCompile 1
portalRecord 2
portalRecord_recompileAfter 1
portalUpdatePosition 1
missDamage 0

tankersList
Expand Down Expand Up @@ -861,6 +863,10 @@ avoidObstaclesDefaultPortals {
# inLockOnly 0
# notWhileSitting 0
# notWhileCasting 0
# notWhileBeingCasted
# whileBeingCasted
# whenNoNearPartyMemberCasting
# whenNearPartyMemberCasting
# whileCasting 0
# notInTown 0
# inTown 0
Expand Down Expand Up @@ -921,6 +927,8 @@ avoidObstaclesDefaultPortals {
# target_whenStatusActive
# target_whenStatusInactive
# target_notWhileSitting 0
# target_notWhileBeingCasted
# target_whileBeingCasted
# target_hp
# target_deltaHp
# target_isJob
Expand All @@ -947,6 +955,8 @@ avoidObstaclesDefaultPortals {
# target_totalMisses
# target_whenStatusActive
# target_whenStatusInactive
# target_notWhileBeingCasted
# target_whileBeingCasted
# target_whenGround
# target_whenNotGround
# target_dist
Expand Down
4 changes: 3 additions & 1 deletion control/priority.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@
# Example (remove the comment character to activate them):
#Hydra
#Obeaune
#all
#all

all
6 changes: 6 additions & 0 deletions control/routeweights.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ WARPTOSAVEMAP 200
# Use airship
AIRSHIP 200

# Additional route cost added for each 1 zeny actually spent while routing.
ZENY 0.1

# Additional route cost added for each travel ticket consumed while routing.
TICKET 100

# Maps where you can exit to the same place you came from,
# which confuses routing if added to portals thoughtlessly.
bat_room 10000
Expand Down
42 changes: 42 additions & 0 deletions control/timeouts.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# The value of each variable is reffered as "x".

# Server connection timeouts
# Wait x seconds for each login-stage reply before treating the connection as stalled.
master 12
gamelogin 12
charlogin 12
Expand All @@ -19,28 +20,39 @@ reconnect_backoff 30,60,120,180,300,600,600,900,900,1800
# Add a random amount of seconds to reconnect time, up to a maximum of reconnect_random seconds.
reconnect_random 20

setTitle 0.2

# Wait x seconds for a poseidon reply before disconnecting
# Ignore this if you don't use Poseidon Server
poseidon_wait_reply 15

# Activate AI after x seconds after the map's loaded
ai 1

# Retry move commands every x seconds, and give up if movement does not progress within x seconds.
ai_move_retry 0.4
ai_move_giveup 1.2

# How often to prune actors whose reported positions drift implausibly far from our predicted location.
avoidDistantActors 1

# Wait x seconds before trying to resume standby behavior for homunculus and mercenary AI.
ai_homunculus_standby 2
ai_mercenary_standby 2

# Send the attack packet every x seconds, if it hasn't been send already
ai_attack 1
# Homunculus and mercenary attack packet cadence.
ai_homunculus_attack 1
ai_mercenary_attack 1

ai_attack_after_skill 0.5
# Wait x seconds after finishing a skill before regular attack logic resumes.

# Delay between short melee re-engage attempts while dancing around a target.
ai_homunculus_dance_attack_melee 0.2

# Delay between dance-style re-engage attempts for mercenary melee and ranged attacks.
ai_mercenary_dance_attack_melee 0.2
ai_mercenary_dance_attack_ranged 0.2

Expand All @@ -56,6 +68,7 @@ ai_attack_failedLOS 12
# Give up attacking a monster if it can't be reached within x seconds
ai_attack_giveup 6

# Every x seconds, let homunculus and mercenary AI look for a valid monster target.
ai_homunculus_check_monster_auto 0.2
ai_mercenary_check_monster_auto 0.2

Expand All @@ -71,11 +84,14 @@ ai_attack_main 0.1
ai_homunculus_attack_main 0.1
ai_mercenary_attack_main 0.1

# How far ahead to predict target reachability when deciding whether to keep chasing/attacking.
ai_future_reachability_lookup 0.7

# Time budget before trying anti-stuck recovery, and cooldown before retrying a previously failed target.
ai_attack_unstuck 2.75
ai_attack_unfail 12

# Time to wait before route logic considers itself stuck and tries to recover.
ai_route_unstuck 2

# Pause for the specified number of seconds after taking something,
Expand All @@ -95,6 +111,7 @@ ai_take .4

# Give up if unable to pickup item after x seconds
ai_take_giveup 3
# Give up gathering a specific item after x seconds.
ai_items_gather_giveup 3

# Every x seconds, check items for gathering
Expand All @@ -109,6 +126,15 @@ ai_transfer_items 0.15
# Delay between map_loaded and send ignoreAll command
ai_ignoreAll 3

# Delay before executing queued look packets.
ai_look 0.2


# Delay auto-accepting or auto-refusing party invites.
ai_partyAuto 3

# Follow recovery, actor info refresh, courtesy replies, auto-deal handling,
# automatic invite denials, respawn delay, and stale actor cleanup timers.
ai_follow_lost_end 10
ai_getInfo 2
ai_thanks_set 8
Expand Down Expand Up @@ -139,23 +165,27 @@ ai_sit_wait 0
# hp/sp sufficiency, do so when the specified number of seconds elapsed
ai_safe_stand_up 2

# Skill/item/equipment action cadence and their give-up windows.
ai_skill_use 0.75
ai_skill_use_giveup 1
ai_item_use_auto 0.5
ai_item_equip_auto 0.75
ai_equipAuto_skilluse_giveup 5
ai_equip_giveup 2

# Delays used by the different auto-teleport triggers.
ai_teleport 1
ai_teleport_away 3
ai_teleport_idle 4
ai_teleport_portal 2
ai_teleport_hp 3
ai_teleport_safe_force 120

# Retry cadence and post-request delay for teleport attempts.
ai_teleport_retry 0.5
ai_teleport_delay 0.5

# Wait x seconds for a portal transition to complete before continuing route logic.
ai_portal_wait 0.5

# These timeouts are used in missing portals logic
Expand All @@ -167,23 +197,28 @@ ai_route_calcRoute 1
ai_route_npcTalk 10

# These timeouts are used in npc conversation (Task::TalkNPC)
ai_npc_talk_wait_to_answer 1.5
ai_npc_talk_wait_after_close_to_cancel 0.5
ai_npc_talk_wait_after_cancel_to_destroy 0.5

# Wait x seconds before sending the next "continue" step in an NPC dialog.
ai_npc_talk_wait_before_continue 0.7

# Auto-buy sequence pacing and NPC/packet give-up windows.
ai_buyAuto 5
ai_buyAuto_wait 2
ai_buyAuto_wait_giveup_npc 15
ai_buyAuto_wait_before_buy 2
ai_buyAuto_wait_after_packet_giveup 15
ai_buyAuto_wait_after_restart 2

# Auto-sell sequence pacing and NPC/packet give-up windows.
ai_sellAuto 2
ai_sellAuto_wait_giveup_npc 15
ai_sellAuto_wait_before_sell 2
ai_sellAuto_wait_after_packet_giveup 15

# Auto-storage sequence pacing, periodic checks, item-use delay, and overall give-up windows.
ai_storageAuto 2
ai_storageAuto_getAutoCheck 2
ai_storageAuto_giveup 15
Expand All @@ -194,6 +229,7 @@ ai_cartAuto 0.15

# delay between checking if we need to do any cartAuto functions
ai_cartAutoCheck 3
# Avoidance checks, vending/shop actions, and buyer shop polling intervals.
ai_avoidcheck 0.5
ai_shop 4
ai_shop_useskill_delay 5
Expand All @@ -208,6 +244,7 @@ ai_route_escape 8
# Don't change the following timeouts!
ai_sync 12

# xKore sync, keepalive, welcome text, and patch-server wait timers.
injectSync 5
injectKeepAlive 12
welcomeText 4
Expand All @@ -216,9 +253,14 @@ patchserver 120
# Time to wait before load map in xKore mode
ai_clientSuspend 1

# Fine-grained delays used by route position prediction and meeting-position reachability checks.
ai_route_position_prediction_delay 0.05
meetingPosition_future_reachability_lookup 0.3

# If a target is predicted to move into attack range/LOS soon, wait up to x seconds
# before rerouting or dropping it. Shared by player and slave attack AI.
ai_attack_allowed_waitForTarget 0.3

# Default command spacing for the macro and eventMacro plugins.
macro_delay 1
eventMacro_delay 1
23 changes: 14 additions & 9 deletions plugins/avoidObstacles/avoidObstacles.pl
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ package avoidObstacles;
use Globals;
use Misc;
use Plugins;
use Skill;
use Utils;
use Log qw(error message debug warning);
use Data::Dumper;
Expand Down Expand Up @@ -895,7 +896,11 @@ sub getObstacleName {
}

if (defined $obstacle->{type} && !ref $obstacle->{type} && $obstacle->{type} ne '') {
return "Spell $obstacle->{type}" if $obstacle->{type} =~ /^\d+$/;
if ($obstacle->{type} =~ /^\d+$/) {
my $skill_name = eval { Skill->new(idn => $obstacle->{type})->getName() };
return $skill_name if defined $skill_name && $skill_name ne '' && $skill_name !~ /^Unknown(?: \d+)?$/;
return "Spell $obstacle->{type}";
}
return $obstacle->{type};
}

Expand Down Expand Up @@ -1339,7 +1344,7 @@ sub on_route_step {
my ($best_step, $best_score) = choose_best_route_step($args->{current_calc_pos}, $args->{solution}, $max_route_step, $prohibited_cells, $danger_cells);
if (!defined $best_step) {
if (scalar keys %{$route_portal_positions}) {
debug "[" . PLUGIN_NAME . "] No safe local route_step found, but the planned route uses a portal; keeping the current step selection.\n", 'route', 1;
debug "[" . PLUGIN_NAME . "] No safe local route_step found, but the planned route uses a portal; keeping the current step selection.\n", 'route', 2;
return;
}
warning "[" . PLUGIN_NAME . "] No safe local route_step found; local client path would cross a prohibited cell. Requesting repath.\n";
Expand All @@ -1348,7 +1353,7 @@ sub on_route_step {
}

if ($best_step != $args->{route_step}) {
debug "[" . PLUGIN_NAME . "] route_step adjusted from $args->{route_step} to $best_step (danger score $best_score).\n", 'route';
debug "[" . PLUGIN_NAME . "] route_step adjusted from $args->{route_step} to $best_step (danger score $best_score).\n", 'route', 2;
$args->{route_step} = $best_step;
}
}
Expand All @@ -1367,13 +1372,13 @@ sub add_obstacle {
return unless $pos;

if (exists $removed_obstacle_still_in_list{$actor->{ID}}) {
debug "[" . PLUGIN_NAME . "] Re-adding obstacle $actor after it returned to view.\n";
debug "[" . PLUGIN_NAME . "] Re-adding obstacle $actor after it returned to view.\n", 'route', 2;
remove_obstacle_contributions($actor->{ID}) if exists $obstaclesList{$actor->{ID}};
delete $obstaclesList{$actor->{ID}};
delete $removed_obstacle_still_in_list{$actor->{ID}};
}

debug "[" . PLUGIN_NAME . "] Adding obstacle $actor on location $pos->{x} $pos->{y}.\n";
debug "[" . PLUGIN_NAME . "] Adding obstacle $actor on location $pos->{x} $pos->{y}.\n", 'route', 2;

remove_obstacle_contributions($actor->{ID}) if exists $obstaclesList{$actor->{ID}};

Expand Down Expand Up @@ -1445,7 +1450,7 @@ sub move_obstacle {
my $pos = get_actor_position($actor);
return unless $pos;

debug "[" . PLUGIN_NAME . "] Moving obstacle $actor to $pos->{x} $pos->{y}.\n";
debug "[" . PLUGIN_NAME . "] Moving obstacle $actor to $pos->{x} $pos->{y}.\n", 'route', 2;

remove_obstacle_contributions($actor->{ID});

Expand Down Expand Up @@ -1473,9 +1478,9 @@ sub remove_obstacle {

if (($type eq 'monster' || $type eq 'player') && defined $reason && $reason eq 'disappeared') {
$removed_obstacle_still_in_list{$actor->{ID}} = 1;
debug "[" . PLUGIN_NAME . "] Keeping obstacle $actor cached after it moved out of sight.\n";
debug "[" . PLUGIN_NAME . "] Keeping obstacle $actor cached after it moved out of sight.\n", 'route', 2;
} else {
debug "[" . PLUGIN_NAME . "] Removing obstacle $actor from " . ($pos ? "$pos->{x} $pos->{y}" : 'unknown position') . ".\n";
debug "[" . PLUGIN_NAME . "] Removing obstacle $actor from " . ($pos ? "$pos->{x} $pos->{y}" : 'unknown position') . ".\n", 'route', 2;
remove_obstacle_contributions($actor->{ID});
delete $obstaclesList{$actor->{ID}};
delete $removed_obstacle_still_in_list{$actor->{ID}};
Expand Down Expand Up @@ -1564,7 +1569,7 @@ sub on_AI_pre_manual_removed_obstacle_still_in_list {
my $target = Actor::get($obstacle_ID);
next OBSTACLE if $target;

debug "[" . PLUGIN_NAME . "] Removing cached obstacle $obstacle->{name} ($obstacle->{type}) from $obstacle->{pos_to}{x} $obstacle->{pos_to}{y}.\n";
debug "[" . PLUGIN_NAME . "] Removing cached obstacle $obstacle->{name} ($obstacle->{type}) from $obstacle->{pos_to}{x} $obstacle->{pos_to}{y}.\n", 'route', 2;
remove_obstacle_contributions($obstacle_ID);
delete $obstaclesList{$obstacle_ID};
delete $removed_obstacle_still_in_list{$obstacle_ID};
Expand Down
34 changes: 34 additions & 0 deletions plugins/eCast/eCast.pl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# - monsterSkill
#
# Extra checks provided by this plugin:
# - Blocks skill casts while self is under statuses that prevent casting
# - target_Element
# - target_notElement
# - target_Race
Expand Down Expand Up @@ -101,6 +102,7 @@ package eCast;
Plugins::register(PLUGIN_NAME, 'Extends Skill Selection and Placement', \&onUnload);

my $hooks = Plugins::addHooks(
['checkSelfCondition', \&extendedSelfCheck, undef],
['checkMonsterCondition', \&extendedCheck, undef],
['packet_skilluse', \&onPacketSkillUse, undef],
['packet/skill_use_no_damage', \&onPacketSkillUseNoDamage, undef],
Expand Down Expand Up @@ -135,11 +137,43 @@ package eCast;
isAIMode_TakesFixed_1_Damage_Magic => 'isAIMode_TakesFixed_1_Damage_Magic',
isAIMode_TakesFixed_1_Damage_None => 'isAIMode_TakesFixed_1_Damage_None',
);
my @self_cast_blocking_statuses = qw(
EFST_HANDICAPSTATE_DEEPSILENCE
HEALTHSTATE_SILENCE
EFST_HEALTHSTATE_SILENCE
EFST_BODYSTATE_STUN
EFST_BODYSTATE_FREEZING
EFST_BODYSTATE_STONECURSE
EFST_HANDICAPSTATE_LIGHTNINGSTRIKE
EFST_HANDICAPSTATE_CRYSTALLIZATION
EFST_BODYSTATE_SLEEP
);

sub onUnload {
Plugins::delHooks($hooks);
}

sub extendedSelfCheck {
my (undef, $args) = @_;
my $prefix = $args->{prefix};

return unless defined $prefix;
return unless $prefix =~ /^(?:attackSkillSlot|attackComboSlot|useSelf_skill|partySkill|monsterSkill)_/;
return unless $char;

my @active_blockers = grep { $char->statusActive($_) } @self_cast_blocking_statuses;
return unless @active_blockers;

debug(
"Will not cast $config{$prefix} because self has cast-blocking status(es): "
. join(', ', @active_blockers)
. "\n",
'eCast',
1
);
$args->{return} = 0;
}

# TODO: Revisar
sub extendedCheck {
my (undef, $args) = @_;
Expand Down
Loading
Loading