From ad015476bac1f7e777817d99f72db3c3200960b6 Mon Sep 17 00:00:00 2001 From: mdr55 <98430078+mdr55@users.noreply.github.com> Date: Sun, 26 Jan 2025 09:35:13 +1100 Subject: [PATCH 01/11] Update combat-trainer.lic --- combat-trainer.lic | 66 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 7 deletions(-) diff --git a/combat-trainer.lic b/combat-trainer.lic index 9d067a05c7..37aed31c52 100644 --- a/combat-trainer.lic +++ b/combat-trainer.lic @@ -163,13 +163,16 @@ class SetupProcess def determine_next_to_train(game_state, weapon_training, ending_ranged) return unless game_state.skill_done? || !weapon_training[game_state.weapon_skill] || ending_ranged - unless @ignore_weapon_mindstate + # skip_all_weapon_max_check is a kludge for a transient condition from blacklisting a skill with + # all remaining skills at 34 + unless @ignore_weapon_mindstate || game_state.skip_all_weapon_max_check # check if all weapons are maxed exp to prevent rapid cycling if weapon_training.reject { |skill, _| DRSkill.getxp(skill) == 34 }.empty? echo 'all weapons locked, not switching' if $debug_mode_ct return end end + game_state.skip_all_weapon_max_check = false echo('new skill needed for training') if $debug_mode_ct @@ -3677,11 +3680,12 @@ class AttackProcess echo "attack_aimed::aiming_trainables:skill: #{skill}" if $debug_mode_ct return unless skill - # if aiming_trainable is locked, don't continue to train it! - return if DRSkill.getxp(skill) > 32 - weapon_name = game_state.wield_offhand_weapon(skill) + # get information for offhand_gain_check + game_state.offhand_last_exp = DRSkill.getxp(skill) + game_state.last_offhand_skill = skill + actions = if skill.eql?('Tactics') $tactics_actions elsif @use_overrides_for_aiming_trainables @@ -4178,10 +4182,10 @@ class GameState :casting, :casting_cfb, :casting_cfw, :casting_nr, :casting_consume, :casting_cyclic, :casting_moonblade, :casting_regalia, :casting_sorcery, :casting_weapon_buff, :charges, :charges_total, :clean_up_step, :constructs, :cooldown_timers, :current_weapon_skill, - :currently_whirlwinding, :dance_queue, :dancing, :danger, :hide_on_cast, :last_action_count, :last_exp, + :currently_whirlwinding, :dance_queue, :dancing, :danger, :hide_on_cast, :last_action_count, :last_exp, :last_offhand_skill, :last_regalia_type, :last_weapon_skill, :loaded, :mob_died, :need_bundle, - :no_loot, :no_skins, :no_stab_current_mob, :no_stab_mobs, :parrying, :prepare_cfb, :prepare_cfw, :prepare_nr, - :prepare_consume, :regalia_cancel, :reset_stance, :retreating, :starlight_values, + :no_loot, :no_skins, :no_stab_current_mob, :no_stab_mobs, :offhand_last_exp, :parrying, :prepare_cfb, :prepare_cfw, :prepare_nr, + :prepare_consume, :regalia_cancel, :reset_stance, :retreating, :skip_all_weapon_max_check, :starlight_values, :swap_regalia_type, :target_weapon_skill, :use_charged_maneuvers, :whirlwind_trainables, :wounds @@ -4228,6 +4232,7 @@ class GameState @wounds = {} @blessed_room = false @charges_total = nil + @skip_all_weapon_max_check = false # private @clean_up_step = nil @@ -4290,6 +4295,9 @@ class GameState @gain_check = settings.combat_trainer_gain_check echo(" @gain_check: #{@gain_check}") if $debug_mode_ct + @offhand_gain_check = settings.combat_trainer_offhand_gain_check + echo(" @offhand_gain_check: #{@offhand_gain_check}") if $debug_mode_ct + @strict_weapon_stance = settings.strict_weapon_stance echo(" @strict_weapon_stance: #{@strict_weapon_stance}") if $debug_mode_ct @@ -4324,6 +4332,14 @@ class GameState @weapons_to_train.each { |skill_name, _weapon_name| @no_gain_list[skill_name] = 0 } echo(" @no_gain_list: #{@no_gain_list}") if $debug_mode_ct + @offhand_last_exp = -1 + @last_offhand_skill = "" + @offhand_blacklist = [] + + @offhand_no_gain_list = Hash.new(0) + @aiming_trainables.each { |skill_name| @offhand_no_gain_list[skill_name] = 0 } + echo(" @offhand_no_gain_list: #{@offhand_no_gain_list}") if $debug_mode_ct + @use_stealth_attacks = settings.use_stealth_attacks echo(" @use_stealth_attacks: #{@use_stealth_attacks}") if $debug_mode_ct @@ -4853,7 +4869,12 @@ class GameState if (@no_gain_list[weapon_skill] > @gain_check) then DRC.message("WARNING: Suppressing #{weapon_skill} due to skill not training") @weapons_to_train.delete(weapon_skill) + # must suppress for offhand too - doesn't make sense to train in offhand if mainhand doesn't train + it breaks code + @offhand_blacklist |= [weapon_skill] return true + + # kludge for rare transient condition in gain_check (most of mainhand skills blacklisted & remaining all at 34) + @skip_all_weapon_max_check = true if @weapons_to_train.all? { |skill_name, _weapon_name| DRSkill.getxp(skill_name) == 34} end # if weapon is at 34, don't black list but do (try to) switch weapons. @@ -5312,6 +5333,37 @@ class GameState options -= weapon_training.select { |_skill, weapon| damaris_weapon_options.include?(weapon) }.keys # remove all weapons part of the same Damaris weapon group since they're the same item options -= weapon_training.select { |_skill, weapon| swappable_weapon?(weapon) }.keys # remove swappable weapons because they might be swapped into a two-handed state options -= @summoned_weapons.map { |info| info['name'] } # remove summoned weapons because they may not exist for offhand use + + # offhand_gain_check code: add in some extra logic to stop training an offhand wielded + # weapon that is not gaining any MS at all. Reduces the opportunity cost. + # blacklist on the offhand will not blacklist on mainhand by intent, as offhand has accuracy penalties + # the code will modify the options list if active + if @offhand_gain_check then + + # if we know answer is empty list, go right to the end and bypass unwanted side effects + return nil if ((options - @offhand_blacklist) == []) + + # @offland_last_exp and @last_offhand_skill are picked up off in the attack_aimed code where the offhand commands are sent + offhand_current_exp = DRSkill.getxp(@last_offhand_skill) + + # keep track of no gain occurences + if (offhand_current_exp <= @offhand_last_exp) && (offhand_current_exp != 34) then + @offhand_no_gain_list[@last_offhand_skill] += 1 + else + @offhand_no_gain_list[@last_offhand_skill] = 0 + end + + # blacklist weapon if gain check failed + if (@offhand_no_gain_list[last_offhand_skill] > @offhand_gain_check) then + DRC.message("WARNING: Suppressing #{last_offhand_skill} in offhand due to skill not training") + @offhand_blacklist |= [@last_offhand_skill] + end + options -= @offhand_blacklist + + # temporarily lock out skill if mindlocked + options -= [@last_offhand_skill] if offhand_current_exp == 34 + end + echo "determine_aiming_skill::options: #{options}" if $debug_mode_ct sort_by_rate_then_rank(options).first end From 8455397f503b48ab526b93a8b170f4e553d5f8c1 Mon Sep 17 00:00:00 2001 From: mdr55 <98430078+mdr55@users.noreply.github.com> Date: Sun, 26 Jan 2025 09:46:43 +1100 Subject: [PATCH 02/11] Update combat-trainer.lic --- combat-trainer.lic | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/combat-trainer.lic b/combat-trainer.lic index 37aed31c52..2e88681694 100644 --- a/combat-trainer.lic +++ b/combat-trainer.lic @@ -4874,7 +4874,7 @@ class GameState return true # kludge for rare transient condition in gain_check (most of mainhand skills blacklisted & remaining all at 34) - @skip_all_weapon_max_check = true if @weapons_to_train.all? { |skill_name, _weapon_name| DRSkill.getxp(skill_name) == 34} + @skip_all_weapon_max_check = true if @weapons_to_train.all? { |skill_name, _weapon_name| DRSkill.getxp(skill_name) == 34 } end # if weapon is at 34, don't black list but do (try to) switch weapons. @@ -5340,28 +5340,28 @@ class GameState # the code will modify the options list if active if @offhand_gain_check then - # if we know answer is empty list, go right to the end and bypass unwanted side effects - return nil if ((options - @offhand_blacklist) == []) + # if we know answer is empty list, go right to the end and bypass unwanted side effects + return nil if ((options - @offhand_blacklist) == []) - # @offland_last_exp and @last_offhand_skill are picked up off in the attack_aimed code where the offhand commands are sent - offhand_current_exp = DRSkill.getxp(@last_offhand_skill) + # @offland_last_exp and @last_offhand_skill are picked up off in the attack_aimed code where the offhand commands are sent + offhand_current_exp = DRSkill.getxp(@last_offhand_skill) - # keep track of no gain occurences - if (offhand_current_exp <= @offhand_last_exp) && (offhand_current_exp != 34) then - @offhand_no_gain_list[@last_offhand_skill] += 1 - else - @offhand_no_gain_list[@last_offhand_skill] = 0 - end + # keep track of no gain occurences + if (offhand_current_exp <= @offhand_last_exp) && (offhand_current_exp != 34) then + @offhand_no_gain_list[@last_offhand_skill] += 1 + else + @offhand_no_gain_list[@last_offhand_skill] = 0 + end - # blacklist weapon if gain check failed - if (@offhand_no_gain_list[last_offhand_skill] > @offhand_gain_check) then - DRC.message("WARNING: Suppressing #{last_offhand_skill} in offhand due to skill not training") - @offhand_blacklist |= [@last_offhand_skill] - end - options -= @offhand_blacklist - - # temporarily lock out skill if mindlocked - options -= [@last_offhand_skill] if offhand_current_exp == 34 + # blacklist weapon if gain check failed + if (@offhand_no_gain_list[last_offhand_skill] > @offhand_gain_check) then + DRC.message("WARNING: Suppressing #{last_offhand_skill} in offhand due to skill not training") + @offhand_blacklist |= [@last_offhand_skill] + end + options -= @offhand_blacklist + + # temporarily lock out skill if mindlocked + options -= [@last_offhand_skill] if offhand_current_exp == 34 end echo "determine_aiming_skill::options: #{options}" if $debug_mode_ct From 339a290517da4b927b4f3b9c7cc3d3d7dea1bc97 Mon Sep 17 00:00:00 2001 From: mdr55 <98430078+mdr55@users.noreply.github.com> Date: Sun, 26 Jan 2025 09:50:23 +1100 Subject: [PATCH 03/11] Update combat-trainer.lic --- combat-trainer.lic | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/combat-trainer.lic b/combat-trainer.lic index 2e88681694..80b234d36e 100644 --- a/combat-trainer.lic +++ b/combat-trainer.lic @@ -4871,10 +4871,11 @@ class GameState @weapons_to_train.delete(weapon_skill) # must suppress for offhand too - doesn't make sense to train in offhand if mainhand doesn't train + it breaks code @offhand_blacklist |= [weapon_skill] - return true # kludge for rare transient condition in gain_check (most of mainhand skills blacklisted & remaining all at 34) @skip_all_weapon_max_check = true if @weapons_to_train.all? { |skill_name, _weapon_name| DRSkill.getxp(skill_name) == 34 } + + return true end # if weapon is at 34, don't black list but do (try to) switch weapons. From 31e2591eb9d46d5e0ae0de26c74bea1bd3d08ba9 Mon Sep 17 00:00:00 2001 From: mdr55 <98430078+mdr55@users.noreply.github.com> Date: Sun, 26 Jan 2025 09:55:32 +1100 Subject: [PATCH 04/11] Update combat-trainer.lic --- combat-trainer.lic | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/combat-trainer.lic b/combat-trainer.lic index 80b234d36e..5e5ff51b60 100644 --- a/combat-trainer.lic +++ b/combat-trainer.lic @@ -5353,7 +5353,7 @@ class GameState else @offhand_no_gain_list[@last_offhand_skill] = 0 end - + # blacklist weapon if gain check failed if (@offhand_no_gain_list[last_offhand_skill] > @offhand_gain_check) then DRC.message("WARNING: Suppressing #{last_offhand_skill} in offhand due to skill not training") From 39b7ec6f639d360c7b8ff8007fc8e1ec680b1647 Mon Sep 17 00:00:00 2001 From: mdr55 <98430078+mdr55@users.noreply.github.com> Date: Sun, 26 Jan 2025 11:16:46 +1100 Subject: [PATCH 05/11] Update combat-trainer.lic Co-authored-by: Mahtra <93822896+MahtraDR@users.noreply.github.com> --- combat-trainer.lic | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/combat-trainer.lic b/combat-trainer.lic index 5e5ff51b60..6f64e35f4e 100644 --- a/combat-trainer.lic +++ b/combat-trainer.lic @@ -5342,7 +5342,7 @@ class GameState if @offhand_gain_check then # if we know answer is empty list, go right to the end and bypass unwanted side effects - return nil if ((options - @offhand_blacklist) == []) + return nil if (options - @offhand_blacklist).empty? # @offland_last_exp and @last_offhand_skill are picked up off in the attack_aimed code where the offhand commands are sent offhand_current_exp = DRSkill.getxp(@last_offhand_skill) From 54fd562c1245da987e0092baec2b5a5bf2ce555d Mon Sep 17 00:00:00 2001 From: mdr55 <98430078+mdr55@users.noreply.github.com> Date: Sun, 26 Jan 2025 11:29:20 +1100 Subject: [PATCH 06/11] Update combat-trainer.lic --- combat-trainer.lic | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/combat-trainer.lic b/combat-trainer.lic index 6f64e35f4e..c2018dad3f 100644 --- a/combat-trainer.lic +++ b/combat-trainer.lic @@ -5348,21 +5348,21 @@ class GameState offhand_current_exp = DRSkill.getxp(@last_offhand_skill) # keep track of no gain occurences - if (offhand_current_exp <= @offhand_last_exp) && (offhand_current_exp != 34) then + if (offhand_current_exp <= @offhand_last_exp) && (offhand_current_exp != 34) @offhand_no_gain_list[@last_offhand_skill] += 1 else @offhand_no_gain_list[@last_offhand_skill] = 0 end # blacklist weapon if gain check failed - if (@offhand_no_gain_list[last_offhand_skill] > @offhand_gain_check) then + unless @offhand_no_gain_list[last_offhand_skill] <= @offhand_gain_check DRC.message("WARNING: Suppressing #{last_offhand_skill} in offhand due to skill not training") @offhand_blacklist |= [@last_offhand_skill] end options -= @offhand_blacklist # temporarily lock out skill if mindlocked - options -= [@last_offhand_skill] if offhand_current_exp == 34 + options -= [@last_offhand_skill] unless offhand_current_exp < 34 end echo "determine_aiming_skill::options: #{options}" if $debug_mode_ct From 284752ad37212ed95b0aeba70331e6b1888de38d Mon Sep 17 00:00:00 2001 From: mdr55 <98430078+mdr55@users.noreply.github.com> Date: Sun, 26 Jan 2025 11:30:14 +1100 Subject: [PATCH 07/11] Update combat-trainer.lic --- combat-trainer.lic | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/combat-trainer.lic b/combat-trainer.lic index c2018dad3f..6b770aead7 100644 --- a/combat-trainer.lic +++ b/combat-trainer.lic @@ -4333,8 +4333,8 @@ class GameState echo(" @no_gain_list: #{@no_gain_list}") if $debug_mode_ct @offhand_last_exp = -1 - @last_offhand_skill = "" - @offhand_blacklist = [] + @last_offhand_skill = String.new + @offhand_blacklist = Array.new @offhand_no_gain_list = Hash.new(0) @aiming_trainables.each { |skill_name| @offhand_no_gain_list[skill_name] = 0 } From eda53583e8b7f4a90c81d1516e86b71dd4baa53c Mon Sep 17 00:00:00 2001 From: mdr55 <98430078+mdr55@users.noreply.github.com> Date: Sun, 26 Jan 2025 11:49:01 +1100 Subject: [PATCH 08/11] Update combat-trainer.lic to align with base yaml --- combat-trainer.lic | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/combat-trainer.lic b/combat-trainer.lic index 6b770aead7..a136757f09 100644 --- a/combat-trainer.lic +++ b/combat-trainer.lic @@ -4853,7 +4853,7 @@ class GameState echo("last_action_count: #{@last_action_count}") if $debug_mode_ct # gain_check code: logic to account for a skill that is not gaining any MS at all - if @gain_check && (weapon_skill != nil) then + if (@gain_check > 0) && (weapon_skill != nil) then # only check for mindstate movement if there was actually some action in the last CT cycle if (@action_count > @last_action_count) then if (current_exp <= @last_exp) && (current_exp != 34) && (@weapons_to_train.size > 1) then @@ -5339,7 +5339,7 @@ class GameState # weapon that is not gaining any MS at all. Reduces the opportunity cost. # blacklist on the offhand will not blacklist on mainhand by intent, as offhand has accuracy penalties # the code will modify the options list if active - if @offhand_gain_check then + if @offhand_gain_check > 0 # if we know answer is empty list, go right to the end and bypass unwanted side effects return nil if (options - @offhand_blacklist).empty? From 77bdd98e37177a8621e8f565b422369bac656a11 Mon Sep 17 00:00:00 2001 From: mdr55 <98430078+mdr55@users.noreply.github.com> Date: Sun, 26 Jan 2025 11:54:29 +1100 Subject: [PATCH 09/11] Update base.yaml --- profiles/base.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/profiles/base.yaml b/profiles/base.yaml index 1e1f6bb07f..21af224bc8 100644 --- a/profiles/base.yaml +++ b/profiles/base.yaml @@ -381,6 +381,13 @@ combat_trainer_ignore_weapon_mindstate: false combat_trainer_target_increment: 3 # how many actions to do if you dont hit the mindstate goal before swapping weapons combat_trainer_action_count: 10 +# roughly number of consecutive mainhand attack rounds that need to not gain mindstate (34/34, mob too low or constant misses) before a weapon switch is forced or blacklisted +# default is 0 (off). If activated, suggest value of 5 to start +combat_trainer_gain_check: 0 +# roughly number of consecutive offhand attack rounds that need to not gain mindstate (34/34, mob too low or constant misses) before a weapon switch is forced or blacklisted +# default is 0 (off). If activated, suggest value of 2 to start +combat_trainer_offhand_gain_check: 0 + dual_load: false # use_stealth_attacks true will train stealth by hiding and attacking/backstabbing from stealth. Thieves also use backstab: below use_stealth_attacks: false From bcc17388c9509d53c603c007e6a017875bc42390 Mon Sep 17 00:00:00 2001 From: Mahtra <93822896+MahtraDR@users.noreply.github.com> Date: Sun, 26 Jan 2025 14:41:55 +1300 Subject: [PATCH 10/11] Update combat-trainer.lic --- combat-trainer.lic | 1 - 1 file changed, 1 deletion(-) diff --git a/combat-trainer.lic b/combat-trainer.lic index aaf05cc4a4..f8bed5de56 100644 --- a/combat-trainer.lic +++ b/combat-trainer.lic @@ -4384,7 +4384,6 @@ class GameState @offhand_no_gain_list = Hash.new(0) @aiming_trainables.each { |skill_name| @offhand_no_gain_list[skill_name] = 0 } echo(" @offhand_no_gain_list: #{@offhand_no_gain_list}") if $debug_mode_ct - @focus_threshold_active = false @focus_threshold = settings.combat_trainer_focus_threshold echo(" @focus_threshold: #{@focus_threshold}") if $debug_mode_ct From 22adab92dbcb17d1d49792c66cc70b8ed2ab39e4 Mon Sep 17 00:00:00 2001 From: Mahtra <93822896+MahtraDR@users.noreply.github.com> Date: Sun, 26 Jan 2025 15:25:42 +1300 Subject: [PATCH 11/11] Update combat-trainer.lic --- combat-trainer.lic | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/combat-trainer.lic b/combat-trainer.lic index f8bed5de56..86ff8f01bd 100644 --- a/combat-trainer.lic +++ b/combat-trainer.lic @@ -4901,7 +4901,7 @@ class GameState echo("last_action_count: #{@last_action_count}") if $debug_mode_ct # gain_check code: logic to account for a skill that is not gaining any MS at all - if (@gain_check > 0) && (weapon_skill != nil) then + if (@gain_check > 0) && !weapon_skill.nil? # only check for mindstate movement if there was actually some action in the last CT cycle if (@action_count > @last_action_count) then if (current_exp <= @last_exp) && (current_exp != 34) && (@weapons_to_train.size > 1) then