Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[script] [combat-trainer] Don't face/engage when using Innocence #5792

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
21 changes: 15 additions & 6 deletions combat-trainer.lic
Original file line number Diff line number Diff line change
Expand Up @@ -2230,6 +2230,7 @@ class AbilityProcess
timer = game_state.cooldown_timers['Battle Cry']
return unless !timer || (Time.now - timer).to_i > @battle_cry_cooldown
return unless game_state.npcs.length > 0
return unless game_state.is_engaging_allowed?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Battle cries are Bardic. Would a Bard ever be using Innocence?


Flags.reset('ct-battle-cry-not-facing')

Expand Down Expand Up @@ -2507,7 +2508,7 @@ class TrainerProcess
waitrt?
fix_standing
when /^Tactics$/i
bput($tactics_actions.sample, 'roundtime', 'There is nothing else', 'Face what', 'You must be closer', 'You must be standing', 'Strangely, you don\'t feel like fighting right now', 'flying too high for you to attack') unless game_state.npcs.empty?
bput($tactics_actions.sample, 'roundtime', 'There is nothing else', 'Face what', 'You must be closer', 'You must be standing', 'Strangely, you don\'t feel like fighting right now', 'flying too high for you to attack') unless game_state.npcs.empty? || !game_state.is_engaging_allowed?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not super familiar with Innocence (I just read its entry on elanthipedia), so maybe this is a dumb question. Why would someone using Innocence also be training Tactics?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's fair, there are a couple "should never happen" examples here -- see also training Astrology, since Innocence is an empath signature spell. However, it also felt like is_engaging_allowed? could potentially be broader than whether or not you have Innocence cast, so I tried to cover pretty much any case that would lead to a face or engage command being issued. If that doesn't make sense I could also see this being restricted to only cases that would actually happen for an empath using the spell.

when /^Analyze$/i
analyze(game_state, 0)
when /^Hunt$/i
Expand Down Expand Up @@ -2567,7 +2568,7 @@ class TrainerProcess
when /^Collect$/i
game_state.sheath_whirlwind_offhand
retreat
put('engage') unless game_state.npcs.empty? || game_state.retreating?
put('engage') unless game_state.npcs.empty? || game_state.retreating? || !game_state.is_engaging_allowed?
Copy link
Contributor

@rpherbig rpherbig May 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about making a function on game_state (engage?) that encapsulates this repeated set of conditionals? See lines 2621, 2812, 3358, etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I thought about that. Also considered making is_engaging_allowed? defined as "not cast Innocence and not retreating"

There are some cases where we'll completely skip some actions when retreating that we should be able to do while using Innocence, so they're not quite the same thing, but there is a lot of repeat/overlap.

Maybe it would make sense to also include game_state.npcs.empty? in the check too. In that case, it doesn't hurt anything to issue a face or engage command but it's still pointless.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could also address a number of the other concerns. "Why would an empath..." "Why would someone using Innocence..."

Generalizes more to "prevent us from issuing a face or engage command when it would be either bad or wrong"

collect(@forage_item)
waitrt?
game_state.wield_whirlwind_offhand
Expand Down Expand Up @@ -2617,7 +2618,7 @@ class TrainerProcess

game_state.sheath_whirlwind_offhand if game_state.currently_whirlwinding
retreat
fput('engage') unless game_state.npcs.empty? || game_state.retreating?
fput('engage') unless game_state.npcs.empty? || game_state.retreating? || !game_state.is_engaging_allowed?
bput("get my #{@almanac}", 'You get', 'What were')
if training_skill
bput("turn #{@almanac} to #{training_skill}", 'You turn', 'You attempt to turn')
Expand Down Expand Up @@ -2762,6 +2763,7 @@ class TrainerProcess
return if game_state.npcs.empty?
return if fail_count > @analyze_retry_count
return if DRSkill.getxp('Tactics') >= @combat_training_abilities_target
return unless game_state.is_engaging_allowed?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not super familiar with Innocence (I just read its entry on elanthipedia), so maybe this is a dumb question. Why would someone using Innocence also be using Analyze?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Misconfiguration? It should be safe to return here regardless, as the two are mutually exclusive.

case bput('analyze', 'roundtime', 'Analyze what', 'Your analysis reveals a massive opening', /You reveal an? .* (?:weakness|opening)/, /Your analysis reveals an? .* (?:weakness|opening)/, 'You fail to find any holes', 'There is nothing else', 'Face what', 'You must be closer', 'You must be standing', 'Strangely, you don\'t feel like fighting right now', 'flying too high for you to attack', 'Bumbling, you slip') # unless
when 'Analyze what'
case bput('face next', 'There is nothing else', 'You turn', 'What are you trying', 'Face what')
Expand Down Expand Up @@ -2807,7 +2809,7 @@ class TrainerProcess
if DRSkill.getrank('Astrology') <= 120
DRCMM.predict('weather')
waitrt?
fput('engage')
fput('engage') if game_state.is_engaging_allowed?
else
retreat
check_heavens(game_state)
Expand Down Expand Up @@ -3039,6 +3041,8 @@ class AttackProcess
end

def attack_melee(charged_maneuver, game_state)
return unless game_state.is_engaging_allowed?

waitrt?

maneuver_success = false
Expand Down Expand Up @@ -3351,7 +3355,7 @@ class AttackProcess
def execute_aiming_action?(action, game_state)
case bput(action, 'Roundtime', 'close enough', 'What are you', 'There is nothing', 'must be closer', 'Bumbling, you slip')
when 'close enough', 'must be closer'
return false if game_state.retreating?
return false if game_state.retreating? || !game_state.is_engaging_allowed?
fput('engage')
pause 2.5
when 'What are you', 'There is nothing'
Expand Down Expand Up @@ -3407,7 +3411,7 @@ class AttackProcess
end

def dance(game_state)
if game_state.npcs.empty?
if game_state.npcs.empty? || !game_state.is_engaging_allowed?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do dance actions break Innocence? If not, should this check be moved to line 3420?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the engage on line 3416 will break Innocence. Any face or engage will. (But for whatever reason, support won't, and implicitly facing the next target with a target bob etc won't...)

But dance commands like weave and circle require you to be at pole range or closer, which is incompatible with Innocence which keeps enemies entirely disengaged if it works.

pause 1
else
game_state.set_dance_queue
Expand Down Expand Up @@ -3981,6 +3985,10 @@ class GameState
!@clean_up_step.nil?
end

def is_engaging_allowed?
!DRSpells.active_spells['Innocence']
end

def is_offense_allowed?
return true if is_permashocked?
return true if @construct_mode
Expand Down Expand Up @@ -4777,6 +4785,7 @@ class GameState
def perform_analyze?(combo_type, expertise_requirement)
return false if combo_type != 'flame' && !Flags["ct-#{combo_type}-ready"] && DRStats.barbarian?
return false if DRSkill.getrank('Expertise') < expertise_requirement
return false unless is_engaging_allowed?

result = bput("analyze #{combo_type}", 'cannot repeat', 'Analyze what\?', 'by landing an? .*', 'You need to hold', 'You must be closer', 'You fail to find any','What are you trying to attack\?')
waitrt?
Expand Down