Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- =begin
- Documentation: https://elanthipedia.play.net/Lich_script_repository#combat-trainer
- =end
- custom_require.call(%w(common common-arcana common-healing common-items common-summoning common-travel drinfomon equipmanager events spellmonitor))
- class SetupProcess
- include DRC
- include DRCS
- include DRCT
- def initialize(settings)
- echo('New SetupProcess') if $debug_mode_ct
- @stance_override = settings.stance_override
- echo(" @stance_override: #{@stance_override}") if $debug_mode_ct
- @priority_defense = settings.priority_defense
- echo(" @priority_defense: #{@priority_defense}") if $debug_mode_ct
- end
- def execute(game_state)
- return true if game_state.done_cleaning_up?
- if game_state.stowing?
- echo('SetupProcess::clean_up') if $debug_mode_ct
- retreat
- if game_state.summoned_info(game_state.weapon_skill)
- if DRStats.moon_mage?
- bput('wear moon', 'telekinetic')
- else
- break_summoned_weapon(game_state.weapon_name)
- end
- else
- EquipmentManager.instance.stow_weapon(game_state.weapon_name)
- end
- game_state.next_clean_up_step
- return true
- end
- was_retreating = game_state.retreating?
- game_state.update_room_npcs
- if game_state.dancing?
- game_state.dance
- elsif game_state.retreating?
- determine_next_to_train(game_state, game_state.retreat_weapons, false)
- else
- determine_next_to_train(game_state, game_state.weapon_training, was_retreating)
- end
- if game_state.parrying
- check_stance(game_state)
- check_weapon(game_state)
- else
- check_weapon(game_state)
- check_stance(game_state)
- end
- false
- end
- private
- 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
- echo('new skill needed for training') if $debug_mode_ct
- game_state.reset_action_count
- if DRStats.moon_mage? && moon_used_to_summon_weapon.nil?
- echo('skipping summoned weapons because no moonblade available') if $debug_mode_ct
- weapon_training = weapon_training.reject { |skill, _| game_state.summoned_info(skill) }
- end
- new_weapon_skill = weapon_training.min_by { |skill, _| [DRSkill.getxp(skill), DRSkill.getrank(skill)] }.first
- game_state.update_weapon_info(new_weapon_skill)
- game_state.update_target_weapon_skill
- end
- def last_stance
- Flags['last-stance'][0] =~ /(\d+)%.* (\d+)%.* (\d+)%.* (\d+)/
- { 'EVASION' => Regexp.last_match(1).to_i, 'PARRY' => Regexp.last_match(2).to_i, 'SHIELD' => Regexp.last_match(3).to_i, 'SPARE' => Regexp.last_match(4).to_i }
- end
- def build_stance_string(vals)
- "stance set #{vals['EVASION']} #{vals['PARRY']} #{vals['SHIELD']}"
- end
- def check_stance(game_state, override = nil)
- return if @override_done
- if @stance_override
- pause
- waitrt?
- bput("stance set #{@stance_override}", 'Setting your')
- @override_done = true
- return
- end
- vals = { 'EVASION' => 0, 'PARRY' => 0, 'SHIELD' => 0, 'SPARE' => 0 }
- skill_map = { 'Parry Ability' => 'Parry', 'Shield Usage' => 'Shield' }
- previous = last_stance
- points = override || previous.values.inject(&:+)
- priority = if game_state.current_weapon_stance.nil?
- result = ['Evasion', 'Parry Ability', 'Shield Usage'].sort_by { |skill| [DRSkill.getxp(skill), skill] }
- result.rotate! if @priority_defense == result.last
- result
- else
- game_state.current_weapon_stance[0..1].sort_by { |skill| [DRSkill.getxp(skill), skill] } + [game_state.current_weapon_stance.last]
- end
- game_state.parrying = priority.index('Parry Ability') < 2
- priority.each do |skill|
- skill = skill_map[skill] if skill_map[skill]
- vals[skill.upcase] = points >= 100 ? 100 : points
- points -= vals[skill.upcase]
- end
- return if vals == previous
- return unless /maximum number of points \((\d+)/ =~ bput(build_stance_string(vals), 'Setting your Evasion stance to', 'is above your maximum number of points \(\d+')
- check_stance(game_state, Regexp.last_match(1).to_i)
- end
- def check_weapon(game_state)
- return if @last_seen_weapon_skill == game_state.weapon_skill
- @last_seen_weapon_skill = game_state.weapon_skill
- echo("checking weapons as #{game_state.last_weapon_skill.inspect}!=#{game_state.weapon_skill}") if $debug_mode_ct
- last_summoned = game_state.summoned_info(game_state.last_weapon_skill)
- next_summoned = game_state.summoned_info(game_state.weapon_skill)
- # Clean up the previous weapon
- if !last_summoned
- EquipmentManager.instance.stow_weapon(game_state.last_weapon_name)
- elsif !next_summoned && !DRStats.moon_mage?
- break_summoned_weapon(game_state.last_weapon_name)
- elsif !next_summoned && DRStats.moon_mage?
- if right_hand =~ /moon/ || left_hand =~ /moon/
- bput('wear moon', 'telekinetic')
- end
- end
- # Prepare the next weapon
- if next_summoned
- game_state.prepare_summoned_weapon(last_summoned)
- else
- EquipmentManager.instance.wield_weapon(game_state.weapon_name, game_state.weapon_skill)
- end
- end
- end
- class LootProcess
- include DRC
- include DRCI
- include DRCS
- include DRCH
- def initialize(settings)
- echo('New LootProcess') if $debug_mode_ct
- skinning = settings.skinning
- @skin = skinning['skin'] || false
- echo(" @skin: #{@skin}") if $debug_mode_ct
- @arrange_all = skinning['arrange_all'] || false
- echo(" @arrange_all: #{@arrange_all}") if $debug_mode_ct
- @arrange_count = skinning['arrange_count'] || 0
- echo(" @arrange_count: #{@arrange_count}") if $debug_mode_ct
- @tie_bundle = skinning['tie_bundle'] || false
- echo(" @tie_bundle: #{@tie_bundle}") if $debug_mode_ct
- @arrange_types = skinning['arrange_types'] || {}
- echo(" @arrange_types: #{@arrange_types}") if $debug_mode_ct
- @lootables = settings.lootables
- echo(" @lootables: #{@lootables}") if $debug_mode_ct
- thanatology = settings.thanatology
- @ritual_type = thanatology['ritual_type'].downcase
- echo(" @ritual_type: #{@ritual_type}") if $debug_mode_ct
- @rituals = get_data('spells').rituals
- echo(" @rituals: #{@rituals}") if $debug_mode_ct
- @last_ritual = nil
- echo(" @last_ritual: #{@last_ritual}") if $debug_mode_ct
- @necro_heal = thanatology['heal'] || false
- echo(" @necro_heal: #{@necro_heal}") if $debug_mode_ct
- @gem_nouns = get_data('items').gem_nouns
- echo(" @gem_nouns: #{@gem_nouns}") if $debug_mode_ct
- @spare_gem_pouch_container = settings.spare_gem_pouch_container
- echo(" @spare_gem_pouch_container: #{@spare_gem_pouch_container}") if $debug_mode_ct
- @gem_pouch_adjective = settings.gem_pouch_adjective
- echo(" @gem_pouch_adjective: #{@gem_pouch_adjective}") if $debug_mode_ct
- @loot_delay = 5 # in seconds
- @loot_timer = Time.now - @loot_delay
- echo(" @loot_timer: #{@loot_timer}") if $debug_mode_ct
- @loot_bodies = settings.loot_bodies
- echo(" @loot_bodies: #{@loot_bodies}") if $debug_mode_ct
- @loot_specials = settings.loot_specials
- echo(" @loot_specials: #{@loot_specials}") if $debug_mode_ct
- @dump_junk = settings.dump_junk
- echo(" @dump_junk: #{@dump_junk}") if $debug_mode_ct
- @dump_timer = Time.now - 300
- $arena = settings.arena
- end
- def execute(game_state)
- if (Time.now - @dump_timer > 300) && @dump_junk && DRRoom.room_objs.count >= 13
- fput 'DUMP JUNK'
- @dump_timer = Time.now
- end
- game_state.mob_died = false
- dispose_body(game_state)
- stow_lootables(game_state)
- if (game_state.mob_died || game_state.npcs.empty?) && game_state.finish_killing?
- echo('LootProcess::clean_up') if $debug_mode_ct
- game_state.next_clean_up_step
- end
- return true if game_state.finish_spell_casting? || game_state.stowing?
- false
- end
- def stow_loot(item, game_state)
- Flags.add('pouch-full', 'You think the .* pouch is too full to fit another gem into', 'You\'d better tie it up before putting')
- special = @loot_specials.find { |x| x['name'] == item }
- if special
- if 'already in your inventory' == bput("get #{item}", 'You pick up', 'There isn\'t any more room', 'You get', 'You need a free hand', 'You just can\'t', 'push you over the item limit', 'You stop as you realize the .* is not yours', 'Stow what', 'already in your inventory')
- bput("get other #{item}", 'You pick up', 'You get', 'You need a free hand', 'You just can\'t', 'push you over the item limit', 'You stop as you realize the .* is not yours', 'Stow what', 'already in your inventory')
- end
- pause 0.25
- bput("put #{item} in my #{special['bag']}", 'you put')
- return
- end
- if 'already in your inventory' == bput("stow #{item}", 'You pick up', 'You get', 'You need a free hand', 'There isn\'t any more room', 'You just can\'t', 'push you over the item limit', 'You stop as you realize the .* is not yours', 'Stow what', 'already in your inventory', 'The .* is not designed to carry anything')
- if @gem_nouns.include?(item)
- bput('stow gem', 'You pick up', 'You get', 'You need a free hand', 'You just can\'t', 'push you over the item limit', 'You stop as you realize the .* is not yours', 'Stow what', 'already in your inventory')
- else
- bput("stow other #{item}", 'You pick up', 'You get', 'You need a free hand', 'You just can\'t', 'push you over the item limit', 'You stop as you realize the .* is not yours', 'Stow what', 'already in your inventory')
- end
- end
- pause 0.25
- return unless Flags['pouch-full']
- bput("drop my #{item}", 'You drop', 'What were')
- unless @spare_gem_pouch_container
- game_state.unlootable(item)
- return
- end
- bput("remove my #{@gem_pouch_adjective} pouch", 'You remove')
- bput("stow my #{@gem_pouch_adjective} pouch", 'You put')
- bput("get #{@gem_pouch_adjective} pouch from my #{@spare_gem_pouch_container}", 'You get a')
- bput('wear my pouch', 'You attach')
- bput("stow #{item}", 'You pick')
- if Flags['pouch-full'].first =~ /tie it up/
- fput('close my pouch')
- else
- bput('tie my pouch', 'You tie')
- end
- end
- def stow_lootables(game_state)
- return unless @loot_bodies
- pair = [left_hand, right_hand]
- tried_loot = false
- @lootables
- .select { |item| game_state.lootable?(item) }
- .each do |item|
- item_reg = item.split.join('.*')
- matches = DRRoom.room_objs.grep(/\b#{item_reg}$/)
- tried_loot ||= !matches.empty?
- matches.each { |_| stow_loot(item, game_state); }
- end
- return unless tried_loot
- pause 1
- if left_hand != pair.first && !EquipmentManager.instance.is_listed_item?(DRC.left_hand)
- echo("out of room, failed to store #{left_hand}")
- game_state.unlootable(GameObj.left_hand.noun.downcase)
- dispose_trash(left_hand)
- end
- if right_hand != pair.last && !EquipmentManager.instance.is_listed_item?(DRC.right_hand)
- echo("out of room, failed to store #{right_hand}")
- game_state.unlootable(GameObj.right_hand.noun.downcase)
- dispose_trash(right_hand)
- end
- end
- def check_rituals(game_state)
- return true unless DRStats.necromancer?
- if @last_ritual.nil?
- if @necro_heal
- game_state.wounds = check_health
- echo "Severity to Wounds: #{game_state.wounds}" if $debug_mode_ct
- do_necro_ritual(DRRoom.dead_npcs.first, 'consume', game_state) unless game_state.wounds.empty?
- end
- do_necro_ritual(DRRoom.dead_npcs.first, @ritual_type, game_state) unless game_state.prepare_consume
- end
- return false if %w(consume harvest dissect).include?(@last_ritual)
- true
- end
- def do_necro_ritual(mob_noun, ritual, game_state)
- return unless DRStats.necromancer?
- return if game_state.construct?(mob_noun)
- do_necro_ritual(mob_noun, 'preserve', game_state) if %w(consume harvest arise).include?(ritual)
- perform_message = "perform #{ritual} on #{mob_noun}"
- case bput(perform_message, 'Rituals do not work upon constructs', 'Rituals do not work upon the undead', 'This ritual may only be performed on a corpse', @rituals['preserve'], @rituals['dissect'], @rituals['harvest'], @rituals['consume'], 'roundtime')
- when @rituals['preserve'], @rituals['dissect']
- @last_ritual = ritual
- return
- when @rituals['consume']
- @last_ritual = ritual
- game_state.prepare_consume = true if @necro_heal
- return
- when @rituals['harvest']
- @last_ritual = ritual
- waitrt?
- fput 'drop material'
- return
- when 'Rituals do not work upon constructs'
- game_state.construct(mob_noun)
- return
- end
- end
- def dispose_body(game_state)
- return unless @loot_bodies
- if DRRoom.dead_npcs.empty?
- @last_ritual = nil
- return
- end
- return if Time.now - @loot_timer < @loot_delay
- game_state.mob_died = true
- can_skin = check_rituals(game_state)
- if @skin && can_skin
- arrange_mob(DRRoom.dead_npcs.first, game_state)
- check_skinning(DRRoom.dead_npcs.first, game_state)
- end
- unless game_state.casting_consume || game_state.prepare_consume
- while 'and get ready to search it' == bput('loot', 'You search', 'I could not find what you were referring to', 'and get ready to search it')
- pause
- waitrt?
- end
- @last_ritual = nil
- end
- @loot_timer = Time.now
- end
- def arrange_mob(mob_noun, game_state)
- return unless @arrange_count > 0
- return unless game_state.skinnable?(mob_noun)
- arranges = 0
- type = @arrange_types[mob_noun] || 'skin'
- arrange_message = @arrange_all ? "arrange all for #{type}" : "arrange for #{type}"
- while arranges < @arrange_count
- arranges += 1
- case bput(arrange_message, 'You begin to arrange', 'You continue arranging', 'You make a mistake', 'You complete arranging', 'That creature cannot', 'That has already been arranged', 'Arrange what', 'cannot be skinned', 'You make a serious mistake in the arranging process')
- when 'You complete arranging', 'That has already been arranged', 'You make a serious mistake in the arranging process'
- break
- when 'Arrange what', 'cannot be skinned'
- game_state.unskinnable(mob_noun)
- return
- when 'That creature cannot'
- arranges = 0
- arrange_message = @arrange_all ? 'arrange all' : 'arrange'
- end
- waitrt?
- end
- end
- def check_skinning(mob_noun, game_state)
- return unless game_state.skinnable?(mob_noun)
- pause 0.25
- waitrt?
- if game_state.need_bundle
- case bput('tap my bundle', 'You tap a \w+ bundle that you are wearing', 'I could not find what you were referring to')
- when /lumpy/
- if @tie_bundle
- bput('tie bundle', 'TIE the bundle again')
- bput('tie bundle', 'you tie the bundle')
- bput('adjust bundle', 'You adjust')
- end
- game_state.need_bundle = false
- when /tight/
- game_state.need_bundle = false
- end
- end
- snap = [left_hand, right_hand]
- case bput('skin', 'roundtime', 'skin what', 'cannot be skinned', 'carrying far too many items', 'need a more appropriate weapon')
- when 'carrying far too many items'
- waitrt?
- fput 'get skin from bundle'
- fput 'drop skin'
- fput 'skin'
- when 'need a more appropriate weapon'
- echo('BUY A SKINNING KNIFE')
- @skin = false
- return
- when 'cannot be skinned'
- game_state.unskinnable(mob_noun)
- return
- end
- pause 1
- waitrt?
- if game_state.need_bundle && snap != [left_hand, right_hand]
- stored_moon = false
- if DRStats.moon_mage? && 'suspend' == bput('wear moon', 'suspend', 'already telekinetic', 'wear what')
- stored_moon = true
- elsif summoned = game_state.summoned_info(game_state.weapon_skill)
- break_summoned_weapon(game_state.weapon_name)
- else
- EquipmentManager.instance.stow_weapon(game_state.weapon_name)
- end
- if 'You get' == bput('get bundling rope', 'You get', 'What were you referring to', 'You need a free hand')
- fput('bundle')
- fput('wear bundle')
- if @tie_bundle
- bput('tie bundle', 'TIE the bundle again')
- bput('tie bundle', 'you tie the bundle')
- bput('adjust bundle', 'You adjust')
- end
- else
- dispose_trash(left_hand) if snap.first != left_hand && !EquipmentManager.instance.is_listed_item?(DRC.left_hand)
- dispose_trash(right_hand) if snap.last != right_hand && !EquipmentManager.instance.is_listed_item?(DRC.right_hand)
- end
- game_state.need_bundle = false
- unless stored_moon && 'you grab' == bput('get moon', 'you grab', 'What were')
- if summoned
- game_state.prepare_summoned_weapon(false)
- else
- EquipmentManager.instance.wield_weapon(game_state.weapon_name, game_state.weapon_skill)
- end
- end
- end
- dispose_trash(left_hand) if snap.first != left_hand && !EquipmentManager.instance.is_listed_item?(DRC.left_hand)
- dispose_trash(right_hand) if snap.last != right_hand && !EquipmentManager.instance.is_listed_item?(DRC.right_hand)
- end
- end
- class SafetyProcess
- include DRC
- include DRCH
- include DRCT
- def initialize
- echo('New SafetyProcess') if $debug_mode_ct
- Flags.add('ct-engaged', 'closes to pole weapon range on you', 'closes to melee range on you')
- Flags.add('ct-lodged', 'You feel an agonizing pain from the .* lodged in your (.*)\.')
- end
- def execute(game_state)
- custom_require.call('tendme') if bleeding? && !Script.running?('tendme')
- fix_standing
- tend_lodged
- game_state.danger = in_danger?(game_state.danger)
- keep_away if !game_state.danger && game_state.retreating?
- end
- private
- def tend_lodged
- return unless Flags['ct-lodged']
- bind_wound(Flags['ct-lodged'].last)
- Flags.reset('ct-lodged')
- end
- def keep_away
- return unless Flags['ct-engaged']
- Flags.reset('ct-engaged')
- retreat
- end
- def in_danger?(danger)
- return false if health >= 75
- unless danger
- Flags.reset('ct-engaged')
- retreat
- end
- fput 'exit' if health < 40
- keep_away
- true
- end
- end
- class SpellProcess
- include DRC
- include DRCA
- include DRCS
- include DRCH
- include DRCT
- def initialize(settings)
- echo('New SpellProcess') if $debug_mode_ct
- @buff_spells = settings.buff_spells
- echo(" @buff_spells: #{@buff_spells}") if $debug_mode_ct
- @offensive_spells = settings.offensive_spells
- echo(" @offensive_spells: #{@offensive_spells}") if $debug_mode_ct
- @offensive_spell_cycle = settings.offensive_spell_cycle
- echo(" @offensive_spell_cycle: #{@offensive_spell_cycle}") if $debug_mode_ct
- @spell_data = get_data('spells').spell_data
- @is_necro = settings.thanatology['necro'] || false
- echo(" @is_necro: #{@is_necro}") if $debug_mode_ct
- @necromancer_healing = settings.necromancer_healing
- echo(" @necromancer_healing: #{@necromancer_healing}") if $debug_mode_ct
- @empath_spells = settings.empath_healing
- echo(" @empath_spells: #{@empath_spells}") if $debug_mode_ct
- @osrel_timer = Time.now - 1000
- echo(" @osrel_timer: #{settings.osrel_timer}") if $debug_mode_ct
- @osrel_amount = settings.osrel_amount
- echo(" @osrel_amount: #{settings.osrel_amount}") if $debug_mode_ct
- @osrel_no_harness = settings.osrel_no_harness
- echo(" @osrel_no_harness: #{settings.osrel_no_harness}") if $debug_mode_ct
- @cast_only_to_train = settings.cast_only_to_train
- echo(" @cast_only_to_train: #{settings.cast_only_to_train}") if $debug_mode_ct
- @perc_health_timer = Time.now
- Flags.add('ct-spelllost', 'Your pattern dissipates with the loss of your target')
- Flags.add('ct-need-bless', ' passes through the .* with no effect')
- @offensive_spells
- .select { |spell| spell['expire'] }
- .each { |spell| add_spell_flag(spell['abbrev'], spell['expire']) }
- @buff_spells
- .values
- .select { |data| data['expire'] }
- .each { |data| add_spell_flag(data['abbrev'], data['expire']) }
- @spell_timers = {}
- @tk_ammo = settings.tk_ammo
- @tk_spell = @offensive_spells.find { |spell| spell['abbrev'] =~ /tkt|tks/i }
- return unless @tk_ammo
- fput("get #{@tk_ammo}")
- fput("drop #{@tk_ammo}")
- end
- def add_spell_flag(name, expire)
- Flags.add("ct-#{name}", expire)
- Flags["ct-#{name}"] = true
- end
- def execute(game_state)
- return true if game_state.stowing?
- check_timer(game_state)
- if Flags['ct-spelllost']
- game_state.casting = false
- Flags.reset('ct-spelllost')
- end
- check_osrel(game_state)
- if game_state.mob_died
- @offensive_spells
- .select { |spell| spell['expire'] }
- .reject { |spell| spell['cyclic'] }
- .each { |spell| Flags["ct-#{spell['abbrev']}"] = true }
- end
- check_slivers(game_state)
- check_consume(game_state)
- check_bless(game_state)
- check_ignite(game_state)
- check_health(game_state)
- check_buffs(game_state)
- check_offensive(game_state)
- check_current(game_state)
- if game_state.finish_spell_casting? && !game_state.casting
- echo('SpellProcess::clean_up') if $debug_mode_ct
- game_state.next_clean_up_step
- release_cyclics
- if @tk_ammo
- waitrt?
- pause
- fput("stow #{@tk_ammo}")
- end
- return true
- end
- false
- end
- private
- def check_slivers(game_state)
- return if game_state.casting
- return if @tk_ammo
- return unless @tk_spell
- return if DRSpells.slivers
- return if UserVars.moons['visible'].empty?
- fput('pre moonblade')
- pause
- fput("cast #{UserVars.moons['visible'].first}")
- fput('break moonblade')
- end
- def check_osrel(game_state)
- return if game_state.casting
- return unless @osrel_amount && DRSpells.active_spells['Osrel Meraud']
- return unless Time.now - @osrel_timer > 300
- @osrel_timer = Time.now
- infuse_om(!@osrel_no_harness, @osrel_amount)
- end
- def check_timer(game_state)
- return if game_state.cast_timer.nil? || (Time.now - game_state.cast_timer) <= 70
- game_state.cast_timer = nil
- fput('release spell') if game_state.casting
- game_state.casting = false
- end
- def check_bless(game_state)
- return if game_state.casting
- return unless @buff_spells['Bless']
- return unless Flags['ct-need-bless']
- Flags.reset('ct-need-bless')
- prepare('Bless', 1)
- cast("cast #{right_hand || left_hand}")
- end
- def check_ignite(game_state)
- return if @last_seen_weapon_name == game_state.weapon_name
- @last_seen_weapon_name = game_state.weapon_name
- return unless DRSpells.active_spells['Ignite']
- # Release the spell on the character
- bput('release ignite', 'The warm feeling in your hand goes away', 'Release what')
- # Wait for the spell on the weapon to be released (it can take a second or two to pulse)
- pause 1
- end
- def ready_to_cast?(game_state)
- Flags['ct-spellcast'] || (@prep_time && Time.now - game_state.cast_timer >= @prep_time)
- end
- def check_current(game_state)
- return unless game_state.casting
- return if game_state.check_charging? && game_state.check_charging?
- cast_spell(game_state) if ready_to_cast?(game_state)
- end
- def cast_spell(game_state)
- @before.each { |action| bput(action['message'], action['matches']) } if @before
- @custom_cast = "cast my #{game_state.weapon_name}" if game_state.casting_ignite
- @custom_cast = "cast #{game_state.wounds[game_state.wounds.keys.max].first}" if game_state.casting_consume
- cast(@custom_cast)
- @custom_cast = nil
- game_state.casting = false
- game_state.cast_timer = nil
- game_state.casting_ignite = false
- game_state.casting_consume = false if game_state.casting_consume
- if game_state.casting_moonblade
- if left_hand =~ /moon/ || game_state.brawling? || game_state.offhand?
- # The moonblade was summoned or refreshed while training something else
- bput('wear moon', 'telekinetic')
- end
- game_state.casting_moonblade = false
- end
- if @command
- pause 0.5 until DRRoom.npcs.include?('warrior')
- fput("command #{@command}")
- @command = nil
- end
- return unless @after
- @after.each { |action| bput(action['message'], action['matches']) }
- @after = nil
- end
- def check_spell_timer(data)
- Time.now - (@spell_timers[data['abbrev']] || Time.at(0)) >= data['recast_every']
- end
- def check_buff_conditions?(name, _data, game_state)
- return false if name == 'Ignite' && game_state.aimed_skill?
- true
- end
- def check_buffs(game_state)
- return if game_state.casting
- return if mana < 40
- recastable_buffs = @buff_spells
- .select { |_, data| data['recast'] || data['recast_every'] || data['expire'] }
- .select { |_name, data| data['expire'] ? Flags["ct-#{data['abbrev']}"] : true }
- .select { |name, data| check_buff_conditions?(name, data, game_state) }
- name, data = recastable_buffs.find do |name, data|
- if data['recast_every']
- check_spell_timer(data)
- elsif data['expire']
- true
- else
- !DRSpells.active_spells[name] || DRSpells.active_spells[name].to_i <= data['recast']
- end
- end
- echo("found buff missing: #{name}") if $debug_mode_ct && name
- game_state.casting_ignite = true if name == 'Ignite'
- if data['ritual']
- cast_ritual(data, game_state)
- else
- prepare_spell(data, game_state)
- end
- end
- def check_health(game_state)
- return if game_state.casting
- return unless DRStats.empath?
- return if health > 95
- if Time.now - @perc_health_timer > 30
- @perc_health_timer = Time.now
- @wounds = check_perc_health
- end
- echo('Healing') if $debug_mode_ct
- if @wounds.any?
- if @empath_spells['FOC']
- data = { 'abbrev' => 'foc', 'mana' => @empath_spells['FOC'].first, 'cambrinth' => @empath_spells['FOC'][1..-1] }
- elsif @empath_spells['HEAL']
- data = { 'abbrev' => 'heal', 'mana' => @empath_spells['HEAL'].first, 'cambrinth' => @empath_spells['HEAL'][1..-1] }
- end
- @wounds = {}
- prepare_spell(data, game_state) if data
- else
- data = { 'abbrev' => 'vh', 'mana' => @empath_spells['VH'].first, 'cambrinth' => @empath_spells['VH'][1..-1] }
- prepare_spell(data, game_state)
- end
- end
- def check_consume(game_state)
- return unless @is_necro
- return if game_state.casting
- return unless game_state.prepare_consume
- data = @necromancer_healing['Consume Flesh']
- game_state.casting_consume = true
- game_state.prepare_consume = false
- prepare_spell(data, game_state)
- end
- def check_offensive(game_state)
- return if game_state.casting
- return if game_state.npcs.empty?
- return if mana < 40
- ready_spells = @offensive_spells
- .select { |spell| spell['target_enemy'] ? game_state.npcs.include?(spell['target_enemy']) : true }
- .select { |spell| spell['min_threshold'] ? game_state.npcs.length >= spell['min_threshold'] : true }
- .select { |spell| spell['max_threshold'] ? game_state.npcs.length <= spell['max_threshold'] : true }
- .select { |spell| spell['expire'] ? Flags["ct-#{spell['abbrev']}"] : true }
- .select { |spell| game_state.dancing? ? spell['harmless'] : true }
- .select { |spell| spell['recast_every'] ? check_spell_timer(spell) : true }
- .select { |spell| @cast_only_to_train ? DRSkill.getxp(spell['skill']) <= 32 : true }
- .select { |spell| spell['cast_only_to_train'] ? DRSkill.getxp(spell['skill']) <= 32 : true }
- .select { |spell| spell['cyclic'] ? !DRSpells.active_spells[spell['name']] : true }
- .select { |spell| spell['night'] ? UserVars.sun['night'] : true }
- .select { |spell| spell['day'] ? UserVars.sun['day'] : true }
- .select { |spell| spell['slivers'] ? DRSpells.slivers : true }
- data = if @offensive_spell_cycle.empty?
- ready_spells.min_by { |spell| DRSkill.getxp(spell['skill']) }
- else
- name = @offensive_spell_cycle.find { |spell_name| ready_spells.find { |spell| spell['name'] == spell_name } }
- @offensive_spell_cycle.rotate!
- ready_spells.find { |spell| spell['name'] == name }
- end
- return if DRSkill.getxp(data['skill']) >= 34 && mana < 70 # make this a spell option
- prepare_spell(data, game_state)
- Flags.reset('ct-spelllost')
- end
- def cast_ritual(data, game_state)
- retreat
- if summoned = game_state.summoned_info(game_state.weapon_skill)
- break_summoned_weapon(game_state.weapon_name)
- else
- EquipmentManager.instance.stow_weapon(game_state.weapon_name)
- end
- fput('STANCE SET 100 80 0')
- prepare(data['abbrev'], data['mana'])
- fput("get my #{data['focus']}")
- invoke(data['focus'])
- pause 5
- waitrt?
- fput("stow my #{data['focus']}")
- unless summoned
- EquipmentManager.instance.wield_weapon(game_state.weapon_name, game_state.weapon_skill)
- end
- waitcastrt?
- cast
- game_state.prepare_summoned_weapon(false) if summoned
- end
- def prepare_spell(data, game_state)
- return unless data
- game_state.cast_timer = Time.now
- @prep_time = data['prep_time']
- echo("prepare spell: #{data}") if $debug_mode_ct
- if data['target_enemy']
- echo(" Target found: #{data['target_enemy']}") if $debug_mode_ct
- fput("face #{data['target_enemy']}")
- end
- release_cyclics if data['cyclic']
- command = 'pre'
- command = data['skill'] == 'Debilitation' ? 'pre' : 'tar' if data['skill']
- command = @spell_data[data['name']]['prep'] if @spell_data[data['name']]['prep']
- command = data['prep_type'] if data['prep_type']
- @spell_timers[data['abbrev']] = Time.now if data['recast_every']
- if data['moon']
- moon = UserVars.moons['visible'].first
- unless moon
- echo "No moon available to cast #{data['abbrev']}" if $debug_mode_ct
- unless Script.running? 'moonwatch'
- echo 'moonwatch is not running. Starting it now'
- custom_require.call('moonwatch')
- echo "Run `;e autostart('moonwatch')` to avoid this in the future"
- end
- @weather = bput('weather', 'inside', 'You glance up at the sky.') unless @weather
- if @weather =~ /inside/
- echo "*** You're inside and there are no available moons. You're going to have a hard time casting #{data['abbrev']}"
- end
- unless moon = UserVars.moons['visible'].first
- echo "Couldn't find any moons to cast #{data['abbrev']} with" if $debug_mode_ct
- return
- end
- end
- if data['abbrev'] == 'moonblade'
- game_state.casting_moonblade = true
- last_moon = moon_used_to_summon_weapon
- data['before'] = [{ 'message' => 'get moon', 'matches' => ['already holding that', 'You grab', 'referring to'] }]
- if UserVars.moons['visible'].include?(last_moon) && UserVars.moons[last_moon]['timer'] >= 4
- moon = last_moon
- data['cast'] = "cast #{moon} refresh"
- else
- data['before'] << { 'message' => 'drop moon', 'matches' => ['open your hand', 'referring to'] }
- data['cast'] = "cast #{moon}"
- end
- else
- data['cast'] = "cast #{moon}"
- end
- end
- prepare(data['abbrev'], data['mana'], command)
- game_state.casting = true
- game_state.cambrinth_charges(data['cambrinth'])
- @custom_cast = data['cast']
- @after = data['after']
- @command = data['command']
- Flags.reset("ct-#{data['abbrev']}") if data['expire']
- Flags.reset('ct-spellcast')
- @before = data['before']
- end
- end
- class AbilityProcess
- include DRCA
- def initialize(settings)
- echo('New AbilityProcess') if $debug_mode_ct
- @buffs = settings.buff_nonspells
- echo(" @buffs: #{@buffs}") if $debug_mode_ct
- @khri = @buffs.delete('khri') || []
- echo(" @khri: #{@khri}") if $debug_mode_ct
- @kneel_khri = settings.kneel_khri
- echo(" @kneel_khri: #{@kneel_khri}") if $debug_mode_ct
- end
- def execute(game_state)
- check_nonspell_buffs(game_state)
- false
- end
- private
- def check_nonspell_buffs(game_state)
- @buffs.each do |action, cooldown|
- timer = game_state.cooldown_timers[action]
- next unless !timer || (Time.now - timer).to_i > cooldown
- game_state.cooldown_timers[action] = Time.now
- fput action
- waitrt?
- end
- return if game_state.danger && @kneel_khri
- @khri
- .map { |name| "Khri #{name}" }
- .each do |name|
- timer = game_state.cooldown_timers[name]
- next unless !timer || (Time.now - timer).to_i > 30
- game_state.cooldown_timers[name] = Time.now if activate_khri?(@kneel_khri, name)
- end
- end
- end
- class ManipulateProcess
- include DRC
- include DRCT
- def initialize(settings)
- echo('New ManipulateProcess') if $debug_mode_ct
- @threshold = settings.manipulate_threshold
- echo(" @threshold: #{@threshold}") if $debug_mode_ct
- @last_manip = Time.now - 200
- end
- def execute(game_state)
- return if game_state.danger || @threshold.nil?
- @filtered_npcs = game_state.npcs
- manipulate if should_manipulate?
- end
- private
- def should_manipulate?
- @filtered_npcs.length >= @threshold && Time.now - @last_manip > 120
- end
- def manipulate
- bput('manip stop all', 'You relax your will', 'But you aren')
- bput("manipulate friendship #{@filtered_npcs.first}", 'You attempt to empathically manipulate', 'You strain')
- @last_manip = Time.now
- end
- end
- class TrainerProcess
- include DRC
- include DRCT
- def initialize(settings)
- echo('New TrainerProcess') if $debug_mode_ct
- @training_abilities = settings.training_abilities
- echo(" @training_abilities: #{@training_abilities}") if $debug_mode_ct
- @skill_map = { 'Hunt' => 'Perception', 'Pray' => 'Theurgy', 'PercMana' => 'Attunement',
- 'Perc' => 'Attunement', 'Astro' => 'Astrology', 'App' => 'Appraisal',
- 'App Quick' => 'Appraisal', 'App Careful' => 'Appraisal', 'Tactics' => 'Tactics',
- 'Scream' => 'Bardic Lore', 'Perc Health' => 'Empathy', 'Khri Prowess' => 'Debilitation',
- 'Stealth' => 'Stealth', 'Ambush Stun' => settings.stun_skill, 'Favor Orb' => 'Anything',
- 'Charged Maneuver' => 'Expertise', 'Meraud' => 'Theurgy' }
- @skill_map['Hunt'] = %w(Perception Scouting) if DRStats.ranger?
- @favor_god = settings.favor_god
- if settings.favor_goal && @favor_god && /delicate/ =~ bput("tap #{@favor_god} orb", 'The orb is delicate', 'I could not find')
- @training_abilities['Favor Orb'] = 300
- end
- @no_app = []
- @dont_stalk = settings.dont_stalk
- echo(" @dont_stalk: #{@dont_stalk}") if $debug_mode_ct
- @stun_weapon = settings.stun_weapon
- echo(" @stun_weapon: #{@stun_weapon}") if $debug_mode_ct
- @stun_weapon_skill = settings.stun_weapon_skill
- echo(" @stun_weapon_skill: #{@stun_weapon_skill}") if $debug_mode_ct
- @theurgy_supply_container = settings.theurgy_supply_container
- echo(" @theurgy_supply_container: #{@theurgy_supply_container}") if $debug_mode_ct
- @water_holder = settings.water_holder
- echo(" @water_holder: #{@water_holder}") if $debug_mode_ct
- @flint_lighter = settings.flint_lighter
- echo(" @flint_lighter: #{@flint_lighter}") if $debug_mode_ct
- end
- def execute(game_state)
- return if game_state.danger
- case select_ability(game_state)
- when 'PercMana'
- moon_mage_perc(game_state)
- when 'Perc'
- bput('perc', 'You reach out') unless game_state.retreating?
- when 'Perc Health'
- bput('perc heal', 'You close your eyes')
- when 'Astro'
- astrology(game_state)
- when 'App'
- appraise(game_state, '')
- when 'App Quick'
- appraise(game_state, 'quick')
- when 'App Careful'
- appraise(game_state, 'careful')
- when 'Tactics'
- bput(%w(weave bob circle).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') unless game_state.npcs.empty?
- when 'Hunt'
- bput('hunt', 'You take note of ', 'You find yourself unable to hunt in this area') unless game_state.retreating?
- when 'Pray'
- bput('pray meraud', 'You glance')
- when 'Scream'
- bput('Scream conc', 'Inhaling deeply', 'There is nothing', 'You open your mouth, then close it suddenly, looking somewhat like a fish') unless game_state.npcs.empty?
- when 'Khri Prowess'
- bput('khri prowess', 'Remembering the mantra of mind over matter', 'You\'re already using the Prowess meditation.', 'previous use of the Prowess', 'Your body is willing', 'Your mind and body are willing') unless game_state.npcs.empty?
- when 'Stealth'
- fput('stalk') if hide? && !@dont_stalk && !game_state.npcs.empty?
- bput('unhide', 'You come out of hiding', 'But you are not') if game_state.npcs.empty?
- when 'Ambush Stun'
- return ambush_stun(game_state)
- when 'Favor Orb'
- fput("rub my #{@favor_god} orb")
- when 'Charged Maneuver'
- game_state.use_charged_maneuvers = true
- when 'Meraud'
- meraud_commune(game_state)
- end
- waitrt?
- false
- end
- private
- def meraud_commune(game_state)
- unless (DRSkill.getrank('Theurgy') >= 300 || game_state.npcs.empty?) && !game_state.aimed_skill?
- reset_ability(game_state, 'Meraud')
- return
- end
- waitrt?
- EquipmentManager.instance.stow_weapon(game_state.weapon_name)
- fput "get #{@water_holder}"
- if /that/i =~ bput("sprinkle #{@water_holder} on #{checkname}", 'You sprinkle', 'Sprinkle that')
- fput "stow #{@water_holder}"
- EquipmentManager.instance.wield_weapon(game_state.weapon_name, game_state.weapon_skill)
- @training_abilities.delete('Meraud')
- return
- end
- bput "put #{@water_holder} in my #{@theurgy_supply_container}", 'You put', 'What were you referring to'
- fput "get #{@flint_lighter}", 'You get a', 'You are already'
- if 'referring to' == bput('get incense', 'You get', 'You are already', 'referring to')
- fput "stow #{@flint_lighter}", 'You put your', 'Stow what'
- EquipmentManager.instance.wield_weapon(game_state.weapon_name, game_state.weapon_skill)
- @training_abilities.delete('Meraud')
- return
- end
- fput 'light my incense with flint' # get messaging
- pause
- waitrt?
- fput "wave incense at #{checkname}"
- fput 'snuff incense'
- bput("put incense in my #{@theurgy_supply_container}", 'You put', 'What were you referring to')
- fput "stow #{@flint_lighter}", 'You put your', 'Stow what'
- pause 1
- EquipmentManager.instance.wield_weapon(game_state.weapon_name, game_state.weapon_skill)
- bput('commune meraud', 'Nothing happens.', 'you have attempted a commune too recently', 'You close your eyes and concentrate, letting your mind still and feeling your breathing grow shallow', 'the ground is already consecrated')
- pause
- waitrt?
- fix_standing
- end
- def ambush_stun(game_state)
- return false unless game_state.can_ambush_stun?
- dead_count = DRRoom.dead_npcs.size
- EquipmentManager.instance.stow_weapon(game_state.weapon_name)
- EquipmentManager.instance.wield_weapon(@stun_weapon, @stun_weapon_skill)
- if hide?
- bput('ambush stun', 'You must be hidden or invisible to ambush', 'You aren\'t close enough to attack', 'You don\'t have enough focus', 'You don\'t think you have enough focus', 'Roundtime')
- pause
- waitrt?
- end
- EquipmentManager.instance.stow_weapon(@stun_weapon)
- EquipmentManager.instance.wield_weapon(game_state.weapon_name, game_state.weapon_skill)
- DRRoom.dead_npcs.size > dead_count
- end
- def appraise(game_state, modifier)
- return if game_state.retreating?
- return if game_state.npcs.empty?
- target = (game_state.npcs - @no_app).first
- return unless target
- if 'Perhaps that' == bput("app #{target} #{modifier}", 'Taking stock of', 'It\'s dead', 'You can\'t determine anything about this creature.', 'I could not find', 'You cannot appraise that', 'roundtime', '^Perhaps that')
- @no_app << target
- end
- end
- def moon_mage_perc(game_state)
- return if game_state.retreating?
- retreat
- bput('perc mana', 'You reach out')
- end
- def astrology(game_state)
- return if game_state.retreating?
- retreat
- bput('predict weather', 'You predict that', 'You are far too', 'you lack the skill to grasp them fully')
- waitrt?
- fput('eng')
- end
- def reset_ability(game_state, ability_name)
- ability_info = @training_abilities.find { |name, _| name == ability_name }.last
- cooldown = ability_info.is_a?(Hash) ? ability_info[:cooldown] : ability_info.to_i
- game_state.cooldown_timers[ability_name] = Time.now - cooldown
- end
- def select_ability(game_state)
- ability = @training_abilities.find { |name, ability_info| check_ability(name, ability_info, game_state) }.first
- echo("Selected: #{ability}") if ability && $debug_mode_ct
- game_state.cooldown_timers[ability] = Time.now
- ability
- end
- def check_ability(name, ability_info, game_state)
- if game_state.casting
- return false if ['PercMana', 'App Careful'].include?(name)
- end
- check = ability_info.is_a?(Hash) ? ability_info[:check] : @skill_map[name]
- check = [check].flatten
- cooldown = ability_info.is_a?(Hash) ? ability_info[:cooldown] : ability_info.to_i
- expcheck = check.nil? || check.any? { |skill_to_check| DRSkill.getxp(skill_to_check) < 32 }
- return expcheck unless game_state.cooldown_timers[name]
- Time.now - game_state.cooldown_timers[name] >= cooldown ? expcheck : false
- end
- end
- class AttackProcess
- include DRC
- def initialize(settings)
- echo('New AttackProcess') if $debug_mode_ct
- @fatigue_regen_action = settings.fatigue_regen_action
- echo(" @fatigue_regen_action: #{@fatigue_regen_action}") if $debug_mode_ct
- @is_empath = DRStats.empath? && !settings.construct(false)
- echo(" @is_empath: #{@is_empath}") if $debug_mode_ct
- @undead = DRStats.empath? && settings.undead
- echo(" @undead: #{@undead}") if $debug_mode_ct
- @stealth_attack_aimed_action = settings.stealth_attack_aimed_action
- echo(" @stealth_attack_aimed_action: #{@stealth_attack_aimed_action}") if $debug_mode_ct
- Flags.add('ct-ranged-ready', 'You think you have your best shot possible now')
- Flags.add('ct-face-what', 'Face what')
- end
- def execute(game_state)
- check_face(game_state)
- if game_state.npcs.uniq.length == 1 && !game_state.stabbable?(game_state.npcs.uniq.first)
- game_state.no_stab_current_mob = true
- elsif game_state.mob_died && game_state.no_stab_current_mob
- game_state.no_stab_current_mob = false
- end
- if game_state.dancing? || (@is_empath && !@undead && !DRSpells.active_spells['Absolution'])
- if game_state.finish_killing?
- echo('AttackProcess::clean_up') if $debug_mode_ct
- game_state.next_clean_up_step
- else
- dance(game_state)
- end
- return false
- end
- if game_state.fatigue_low?
- fput(@fatigue_regen_action)
- return false
- end
- charged_maneuver = check_charged_maneuver(game_state)
- if game_state.thrown_skill?
- game_state.loaded = false
- attack_thrown(game_state)
- elsif game_state.aimed_skill?
- attack_aimed(charged_maneuver, game_state)
- else
- game_state.loaded = false
- attack_melee(charged_maneuver, game_state)
- end
- false
- end
- private
- def check_face(game_state)
- if Flags['ct-face-what']
- fput("eng #{game_state.npcs.first}")
- Flags.reset('ct-face-what')
- end
- end
- def attack_melee(charged_maneuver, game_state)
- waitrt?
- if charged_maneuver.empty?
- if game_state.backstab? || game_state.use_stealth_attack? || game_state.ambush?
- hide?
- end
- verb = game_state.melee_attack_verb
- command = game_state.offhand? ? "#{verb} left" : verb
- if (game_state.backstab? || game_state.ambush?) && hiding?
- if (game_state.backstab? && game_state.no_stab_current_mob) || (game_state.ambush? && !game_state.backstab?)
- command += ' back'
- else
- command.sub!(verb, 'backstab')
- end
- end
- fput(command)
- else
- use_charged_maneuver(charged_maneuver, game_state)
- end
- pause
- waitrt?
- if reget(5, 'You can\'t backstab that')
- if game_state.npcs.uniq.length == 1
- game_state.unstabbable(game_state.npcs.first)
- else
- game_state.no_stab_current_mob = true
- end
- end
- if reget(5, 'You aren\'t close enough to attack', 'It would help if you were closer')
- fput('eng')
- pause 6
- else
- game_state.action_taken
- end
- if reget(5, 'You need two hands')
- fput('stow left') if left_hand && left_hand !~ /\b#{game_state.weapon_name}/i
- fput('stow right') if right_hand && right_hand !~ /\b#{game_state.weapon_name}/i
- end
- end
- def attack_thrown(game_state)
- hurl = game_state.bound_weapon? && !game_state.use_weak_attacks?
- attack_action = hurl ? 'hurl' : 'lob'
- retrieve_action = hurl ? 'invoke' : "get my #{game_state.weapon_name}"
- bput(attack_action, 'roundtime', 'What are you trying to')
- waitrt?
- if game_state.weapon_name == 'blades'
- until /(Stow what|You put your)/ =~ bput('stow blade', 'Stow what', 'You pick up .*blade', 'You put your blades')
- end
- end
- case bput(retrieve_action, 'You are already holding', 'You pick up', 'You get', 'You catch', 'What were you')
- when 'What were you'
- # Workaround for a game bug when you lob an unblessed weapon at a noncorporeal mob
- # The weapon lands on the ground, not in the 'at feet' slot, and 'my' will not work
- bput("get #{game_state.weapon_name}", 'You pick up', 'You get')
- end
- game_state.action_taken
- end
- def shoot_aimed(command, game_state)
- case bput(command, 'isn\'t loaded', 'There is nothing', 'But your', 'you fire', 'you poach', 'I could not find', 'with no effect and falls to the ground', 'Face what', 'How can you poach if you are not hidden', 'your moving to fire went unobserved', 'notices your attempt to remain hidden', 'you don\'t feel like fighting right now', 'That weapon must be in your right hand to fire')
- when 'How can you poach if you are not hidden', 'notices your attempt to remain hidden'
- shoot_aimed('shoot', game_state)
- when 'you fire', 'you poach', 'your moving to fire went unobserved'
- game_state.action_taken
- when 'you don\'t feel like fighting right now', 'That weapon must be in your right hand to fire'
- pause 1
- shoot_aimed(command, game_state)
- end
- end
- def attack_aimed(charged_maneuver, game_state)
- game_state.selected_maneuver = charged_maneuver unless game_state.loaded
- game_state.loaded = false if game_state.mob_died && !(game_state.casting_consume || game_state.prepare_consume)
- game_state.clear_aim_queue if Flags['ct-ranged-ready']
- if game_state.loaded && game_state.done_aiming?
- if game_state.selected_maneuver.empty?
- command = if game_state.use_stealth_attack? && hide?
- @stealth_attack_aimed_action
- else
- 'shoot'
- end
- shoot_aimed(command, game_state)
- else
- use_charged_maneuver(game_state.selected_maneuver, game_state)
- game_state.action_taken
- end
- game_state.loaded = false
- waitrt?
- elsif game_state.loaded
- fput(game_state.next_aim_action)
- waitrt?
- else
- if game_state.dual_load? && DRSpells.active_spells['See the Wind']
- pause 0.5 until bput('load arrows', 'You reach into', 'already loaded', 'Such a feat would be impossible without the winds to guide')
- else
- pause 0.5 until bput('load', 'You reach into', 'You carefully load', 'already loaded')
- end
- waitrt?
- game_state.loaded = true
- if game_state.selected_maneuver.empty?
- game_state.set_aim_queue
- aim(game_state)
- Flags.reset('ct-ranged-ready')
- end
- end
- end
- def aim(game_state)
- case bput('aim', 'You begin to target', 'You are already', 'There is nothing else', 'Face what\?', 'You shift your target', 'Your repeating crossbow', 'Strangely, you don\'t feel like fighting right now')
- when 'Your repeating crossbow'
- case bput('push my cross', 'A rapid series of clicks', 'You attempt to ready your repeating crossbow')
- when 'A rapid series of clicks'
- aim(game_state)
- when 'You attempt to ready your repeating crossbow'
- game_state.loaded = false
- end
- when 'Face what?'
- game_state.clear_aim_queue
- when 'Strangely, you don\'t feel like fighting right now'
- pause 1
- aim(game_state)
- end
- end
- def dance(game_state)
- if game_state.npcs.empty?
- pause 1
- else
- game_state.set_dance_queue
- if /Face what/ =~ fput(game_state.next_dance_action)
- fput("eng #{game_state.npcs.first}")
- end
- waitrt?
- end
- end
- def check_charged_maneuver(game_state)
- return '' unless game_state.use_charged_maneuvers
- return '' unless game_state.charged_maneuver
- timer = game_state.cooldown_timers[game_state.charged_maneuver]
- return '' if timer && (Time.now - timer).to_i < 60
- echo "***Ready to use charged maneuver: #{game_state.charged_maneuver}***" if $debug_mode_ct
- game_state.charged_maneuver
- end
- def use_charged_maneuver(action, game_state)
- game_state.cooldown_timers[action] = Time.now
- attempt = bput("maneuver #{action}", 'You brace your', 'balanced and', 'Taking a full step back', 'You take a step back', 'You lower your shoulders', 'You angle to the side and ', 'rest a bit longer', 'You square up your feet')
- return if attempt == 'rest a bit longer'
- # Maneuvers have extra non-RT delays
- pause 7
- waitrt?
- game_state.use_charged_maneuvers = false
- end
- end
- class CombatTrainer
- include DRC
- attr_reader :running
- def stop
- echo 'Received stop signal' if $debug_mode_ct
- @stop = true
- end
- def set_args
- arg_definitions = [
- [
- { name: 'debug', regex: /debug/i, optional: true },
- { name: 'construct', regex: /construct/i, optional: true, description: 'Construct setting to override empath no attack settings.' },
- { name: 'undead', regex: /undead/i, optional: true, description: 'Allows hunting of undead by empaths when absolution is up.' },
- { name: 'dance', display: 'd#', regex: /d\d+/i, optional: true, description: 'Dance threshold, d2 would keep two enemies alive.' },
- { name: 'retreat', display: 'r#', regex: /r\d+/i, optional: true, description: 'Retreat threshold, r3 would stay at range with three or more enemies' }
- ]
- ]
- args = parse_args(arg_definitions, true)
- settings = get_settings(args.flex)
- settings.construct = args.construct
- settings.undead = args.undead
- settings.debug_mode = args.debug
- set_dance(args.dance, settings)
- set_retreat(args.retreat, settings)
- settings
- end
- def initialize
- settings = set_args
- setup(settings)
- settings.storage_containers.each { |container| fput("open my #{container}") }
- EquipmentManager.instance.refresh(settings)
- EquipmentManager.instance.wear_equipment_set?('standard')
- end
- def set_dance(message, settings)
- return unless message
- message =~ /d(\d+)/
- settings.dance_threshold = Regexp.last_match(1).to_i
- end
- def set_retreat(message, settings)
- return unless message
- message =~ /r(\d+)/
- settings.retreat_threshold = Regexp.last_match(1).to_i
- end
- def setup(settings)
- Flags.add('ct-spellcast', '^Your formation of a targeting pattern around .+ has completed\.', 'Your target pattern has finished forming around the area', '^You feel fully prepared to cast your spell\.')
- Flags.add('last-stance', 'Setting your Evasion stance to \d+%, your Parry stance to \d+%, and your Shield stance to \d+%. You have \d+ stance points left')
- bput('stance set 100 40 40', 'Setting your')
- pause 0.25 until Flags['last-stance']
- @stop = false
- @running = true
- $debug_mode_ct = UserVars.combat_trainer_debug || settings.debug_mode
- @game_state = GameState.new(settings)
- @combat_processes = make_processes(settings)
- end
- def make_processes(settings)
- [
- SetupProcess.new(settings),
- SpellProcess.new(settings),
- AbilityProcess.new(settings),
- LootProcess.new(settings),
- SafetyProcess.new,
- ManipulateProcess.new(settings),
- TrainerProcess.new(settings),
- AttackProcess.new(settings)
- ]
- end
- def start_combat
- EquipmentManager.instance.empty_hands
- loop do
- @combat_processes.each do |process|
- break if process.execute(@game_state)
- end
- pause 0.1
- if @game_state.done_cleaning_up?
- echo('CombatTrainer::clean_up') if $debug_mode_ct
- @running = false
- stop_script('tendme') if Script.running?('tendme')
- break
- end
- next unless @stop && !@game_state.cleaning_up?
- @game_state.next_clean_up_step
- @game_state.stop_weak_attacks
- @game_state.stop_analyze_combo
- end
- end
- end
- class GameState
- include DRCA
- include DRCS
- include DRC
- $thrown_skills = ['Heavy Thrown', 'Light Thrown']
- $aim_skills = %w(Bow Slings Crossbow)
- $ranged_skills = $thrown_skills + $aim_skills
- attr_accessor :mob_died, :last_weapon_skill, :danger, :parrying, :casting, :need_bundle, :cooldown_timers, :no_stab_current_mob, :loaded, :selected_maneuver, :cast_timer, :casting_moonblade, :casting_ignite, :use_charged_maneuvers, :casting_consume, :prepare_consume, :wounds
- def initialize(settings)
- echo('New GameState') if $debug_mode_ct
- # public
- @mob_died = false
- @last_weapon_skill = nil
- @danger = false
- @parrying = false
- @casting = false
- @need_bundle = true
- @cooldown_timers = {}
- @no_stab_current_mob = false
- @loaded = false
- @selected_maneuver = ''
- @cast_timer = nil
- @casting_moonblade = false
- @casting_ignite = false
- @use_charged_maneuvers = false
- @casting_consume = false
- @prepare_consume = false
- @wounds = {}
- # private
- @clean_up_step = nil
- @target_weapon_skill = -1
- @no_skins = []
- @constructs = []
- @no_stab_mobs = []
- @no_loot = []
- @dancing = false
- @retreating = false
- @action_count = 0
- @charges = nil
- @aim_queue = []
- @dance_queue = []
- @analyze_combo_array = []
- @dance_skill = settings.dance_skill
- echo(" @dance_skill: #{@dance_skill}") if $debug_mode_ct
- @target_action_count = settings.combat_trainer_action_count
- echo(" @target_action_count: #{@target_action_count}") if $debug_mode_ct
- @dance_threshold = settings.dance_threshold
- echo(" @dance_threshold: #{@dance_threshold}") if $debug_mode_ct
- @retreat_threshold = settings.retreat_threshold
- echo(" @retreat_threshold: #{@retreat_threshold}") if $debug_mode_ct
- @summoned_weapons = settings.summoned_weapons
- echo(" @summoned_weapons: #{@summoned_weapons}") if $debug_mode_ct
- @target_increment = settings.combat_trainer_target_increment
- echo(" @target_increment: #{@target_increment}") if $debug_mode_ct
- @stances = settings.stances
- echo(" @stances: #{@stances}") if $debug_mode_ct
- if @stances.find { |_key, stances| !(stances & %w(evasion parry shield)).empty? }
- echo 'Please update to the latest version of stance: settings!'
- @stances.keys do |key|
- settings = @stances[key]
- settings.map! { |x| { 'parry' => 'Parry Ability', 'shield' => 'Shield Usage', 'evasion' => 'Evasion' }[x] }
- (['Parry Ability', 'Shield Usage', 'Evasion'] - settings).each { |x| settings << x }
- @stances[key] = settings
- end
- echo "Modified stances: #{@stances}"
- end
- @weapons_to_train = settings.weapon_training
- echo(" @weapons_to_train: #{@weapons_to_train}") if $debug_mode_ct
- @use_stealth_attacks = settings.use_stealth_attacks
- echo(" @use_stealth_attacks: #{@use_stealth_attacks}") if $debug_mode_ct
- @ambush = settings.ambush
- echo(" @ambush: #{@ambush}") if $debug_mode_ct
- @backstab = settings.backstab
- echo(" @backstab: #{@backstab}") if $debug_mode_ct
- @charged_maneuvers = settings.charged_maneuvers
- echo(" @charged_maneuvers: #{@charged_maneuvers}") if $debug_mode_ct
- @fatigue_regen_threshold = settings.fatigue_regen_threshold
- echo(" @fatigue_regen_threshold: #{@fatigue_regen_threshold}") if $debug_mode_ct
- @aim_fillers = settings.aim_fillers
- echo(" @aim_fillers: #{@aim_fillers}") if $debug_mode_ct
- @aim_fillers_stealth = settings.aim_fillers_stealth
- echo(" @aim_fillers_stealth: #{@aim_fillers_stealth}") if $debug_mode_ct
- @dance_actions = settings.dance_actions
- echo(" @dance_actions: #{@dance_actions}") if $debug_mode_ct
- @dance_actions_stealth = settings.dance_actions_stealth
- echo(" @dance_actions_stealth: #{@dance_actions_stealth}") if $debug_mode_ct
- @ignored_npcs = settings.ignored_npcs
- echo(" @ignored_npcs: #{@ignored_npcs}") if $debug_mode_ct
- @dual_load = settings.dual_load
- echo(" @dual_load: #{@dual_load}") if $debug_mode_ct
- @summoned_weapons_element = settings.summoned_weapons_element
- echo(" @summoned_weapons_element: #{@summoned_weapons_element}") if $debug_mode_ct
- @summoned_weapons_ingot = settings.summoned_weapons_ingot
- echo(" @summoned_weapons_ingot: #{@summoned_weapons_ingot}") if $debug_mode_ct
- @stop_on_bleeding = settings.stop_hunting_if_bleeding
- echo(" @stop_on_bleeding: #{@stop_on_bleeding}") if $debug_mode_ct
- @cambrinth = settings.cambrinth
- echo(" @cambrinth: #{@cambrinth}") if $debug_mode_ct
- @stored_cambrinth = settings.stored_cambrinth
- echo(" @stored_cambrinth: #{@stored_cambrinth}") if $debug_mode_ct
- @cambrinth_cap = settings.cambrinth_cap
- echo(" @cambrinth_cap: #{@cambrinth_cap}") if $debug_mode_ct
- @use_weak_attacks = settings.use_weak_attacks
- echo(" @use_weak_attacks: #{@use_weak_attacks}") if $debug_mode_ct
- @analyze_combo_type = settings.analyze_combo_type
- echo(" @analyze_combo_type: #{@analyze_combo_type}") if $debug_mode_ct
- end
- def next_clean_up_step
- case @clean_up_step
- when nil
- @clean_up_step = if @stop_on_bleeding && bleeding?
- 'clear_magic'
- else
- 'kill'
- end
- when 'kill'
- @clean_up_step = 'clear_magic'
- when 'clear_magic'
- @clean_up_step = 'stow'
- when 'stow'
- @clean_up_step = 'done'
- end
- end
- def cleaning_up?
- !@clean_up_step.nil?
- end
- def finish_killing?
- @clean_up_step == 'kill'
- end
- def finish_spell_casting?
- @clean_up_step == 'clear_magic'
- end
- def stowing?
- @clean_up_step == 'stow'
- end
- def done_cleaning_up?
- @clean_up_step == 'done'
- end
- def update_weapon_info(weapon_skill)
- @last_weapon_skill = @current_weapon_skill
- @current_weapon_skill = weapon_skill
- end
- def weapon_skill
- @current_weapon_skill
- end
- def dance
- update_weapon_info(@dance_skill)
- end
- def skill_done?
- current_exp = DRSkill.getxp(weapon_skill)
- echo("action count: #{@action_count} vs #{@target_action_count}") if $debug_mode_ct
- echo("skill exp: #{current_exp} vs #{@target_weapon_skill}") if $debug_mode_ct
- @action_count >= @target_action_count || current_exp >= @target_weapon_skill
- end
- def update_room_npcs
- @dancing = npcs.length <= @dance_threshold || npcs.empty?
- @retreating = @retreat_threshold && npcs.length >= @retreat_threshold
- end
- def retreat_weapons
- weapon_training.select { |skill, _| $ranged_skills.include?(skill) }
- end
- def summoned_info(weapon_skill)
- @summoned_weapons.find { |summoned_skill| summoned_skill['name'] == weapon_skill }
- end
- def update_target_weapon_skill
- @target_weapon_skill = [34, DRSkill.getxp(current_weapon_skill) + @target_increment].min
- end
- def current_weapon_stance
- @stances[weapon_skill]
- end
- def skinnable?(mob_noun)
- !@no_skins.include?(mob_noun)
- end
- def unskinnable(mob_noun)
- echo("adding #{mob_noun} to no skin list: #{@no_skins}") if $debug_mode_ct
- @no_skins.push(mob_noun)
- end
- def construct?(mob_noun)
- @constructs.include?(mob_noun)
- end
- def construct(mob_noun)
- @constructs.push(mob_noun)
- end
- def stabbable?(mob_noun)
- !@no_stab_mobs.include?(mob_noun)
- end
- def unstabbable(mob_noun)
- @no_stab_mobs.push(mob_noun)
- end
- def lootable?(item)
- !@no_loot.include?(item.downcase)
- end
- def unlootable(item)
- @no_loot.push(item.downcase)
- end
- def weapon_training
- @weapons_to_train
- end
- def weapon_name
- weapon_training[weapon_skill]
- end
- def last_weapon_name
- weapon_training[@last_weapon_skill]
- end
- def thrown_skill?
- $thrown_skills.include?(weapon_skill)
- end
- def aimed_skill?
- $aim_skills.include?(weapon_skill)
- end
- def bound_weapon?
- item = EquipmentManager.instance.item_by_desc(weapon_name)
- item && item.bound
- end
- def offhand?
- weapon_skill == 'Offhand Weapon'
- end
- def brawling?
- weapon_skill == 'Brawling'
- end
- def use_stealth_attack?
- @use_stealth_attacks && use_stealth?
- end
- def ambush?
- @ambush && DRSkill.getxp('Backstab') < 34
- end
- def backstab?
- @backstab.include?(weapon_skill)
- end
- def dancing?
- @dancing
- end
- def retreating?
- @retreating
- end
- def charged_maneuver
- @charged_maneuvers[weapon_skill]
- end
- def fatigue_low?
- echo("***Fatigue: #{DRStats.fatigue}***") if $debug_mode_ct
- echo("***Target: #{@fatigue_regen_threshold}***") if $debug_mode_ct
- DRStats.fatigue < @fatigue_regen_threshold
- end
- def reset_action_count
- @action_count = 0
- end
- def action_taken
- @action_count += 1
- end
- def set_aim_queue
- echo("set_aim_queue #{@aim_fillers}:#{@aim_fillers_stealth}") if $debug_mode_ct
- @aim_queue = aim_stealth? ? @aim_fillers_stealth[weapon_skill].dup : @aim_fillers[weapon_skill].dup
- end
- def clear_aim_queue
- @aim_queue = []
- end
- def done_aiming?
- @aim_queue.empty?
- end
- def next_aim_action
- @aim_queue.shift
- end
- def set_dance_queue
- return unless @dance_queue.empty?
- echo("set_dance_queue #{@dance_actions}:#{@dance_actions_stealth}") if $debug_mode_ct
- @dance_queue = dance_stealth? ? @dance_actions_stealth.dup : @dance_actions.dup
- end
- def next_dance_action
- @dance_queue.shift
- end
- def cambrinth_charges(cambrinth)
- @charges = cambrinth.nil? || cambrinth.empty? ? nil : cambrinth.dup
- end
- def check_charging?
- return false if @charges.nil?
- find_cambrinth(@cambrinth, @stored_cambrinth, @cambrinth_cap)
- if @charges.empty?
- echo('check_charging?: done') if $debug_mode_ct
- cambrinth_charges(nil)
- invoke(@cambrinth)
- else
- next_charge = @charges.pop
- echo("check_charging?: #{next_charge}") if $debug_mode_ct
- charge(@cambrinth, next_charge)
- end
- stow_cambrinth(@cambrinth, @stored_cambrinth, @cambrinth_cap)
- true
- end
- def npcs
- DRRoom.npcs - @ignored_npcs
- end
- def dual_load?
- @dual_load && weapon_skill == 'Bow'
- end
- def prepare_summoned_weapon(weapon_already_summoned)
- info = summoned_info(weapon_skill)
- summon_weapon(UserVars.moons['visible'].first, @summoned_weapons_element, @summoned_weapons_ingot, weapon_skill) unless weapon_already_summoned
- shape_summoned_weapon(weapon_skill, @summoned_weapons_ingot) if weapon_already_summoned || DRStats.moon_mage?
- turn_summoned_weapon if info['turn']
- push_summoned_weapon if info['push']
- pull_summoned_weapon if info['pull']
- end
- def can_ambush_stun?
- !npcs.empty? && !aimed_skill?
- end
- def use_weak_attacks?
- @use_weak_attacks
- end
- def stop_weak_attacks
- @use_weak_attacks = false
- end
- def stop_analyze_combo
- @analyze_combo_type = nil
- end
- def melee_attack_verb
- if $arena
- arena_enemy = fput "watch #{game_state.npcs.first}"
- echo arena_enemy
- fput 'pedal' if arena_enemy.include? 'pedal'
- fput 'duck' if arena_enemy.include? 'duck'
- fput 'lean' if arena_enemy.include? 'lean'
- fput 'bob' if arena_enemy.include? 'bob'
- fput 'cower' if arena_enemy.include? 'cower'
- fput 'jump' if arena_enemy.include? 'jump'
- end
- if use_weak_attacks?
- brawling? ? 'punch' : 'jab'
- elsif !@analyze_combo_type.nil? && !offhand? && !brawling?
- update_analyze_array if @analyze_combo_array.empty?
- @analyze_combo_array.shift
- else
- 'attack'
- end
- end
- private
- def update_analyze_array
- result = bput("analyze #{@analyze_combo_type}", 'Analyze what\?', 'by landing a .*')
- waitrt?
- case result
- when 'Analyze what?'
- fput('face next')
- return []
- end
- text = result.match(/by landing a (.*)\.$/).to_a[1]
- @analyze_combo_array = list_to_nouns(text)
- end
- def dance_stealth?
- @dance_actions_stealth && !@dance_actions_stealth.empty? && use_stealth?
- end
- def aim_stealth?
- @aim_fillers_stealth && @aim_fillers_stealth[weapon_skill] && use_stealth?
- end
- def use_stealth?
- DRSkill.getxp('Stealth') < 32
- end
- attr_accessor :clean_up_step, :current_weapon_skill, :target_weapon_skill, :no_skins, :constructs, :no_stab_mobs, :no_loot, :dancing, :retreating, :action_count, :charges, :aim_queue, :dance_queue, :analyze_combo_array
- attr_reader :dance_skill, :target_action_count, :dance_threshold, :retreat_threshold, :summoned_weapons, :target_increment, :stances, :weapons_to_train, :use_stealth_attacks, :ambush, :backstab, :charged_maneuvers, :fatigue_regen_threshold, :aim_fillers, :aim_fillers_stealth, :dance_actions, :dance_actions_stealth, :ignored_npcs, :dual_load, :summoned_weapons_element, :summoned_weapons_ingot, :cambrinth, :stored_cambrinth, :cambrinth_cap, :use_weak_attacks, :analyze_combo_type
- end
- $COMBAT_TRAINER = CombatTrainer.new
- $COMBAT_TRAINER.start_combat
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement