Advertisement
Guest User

Untitled

a guest
Sep 23rd, 2016
135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 67.02 KB | None | 0 0
  1. =begin
  2. Documentation: https://elanthipedia.play.net/Lich_script_repository#combat-trainer
  3. =end
  4.  
  5. custom_require.call(%w(common common-arcana common-healing common-items common-summoning common-travel drinfomon equipmanager events spellmonitor))
  6.  
  7. class SetupProcess
  8. include DRC
  9. include DRCS
  10. include DRCT
  11.  
  12. def initialize(settings)
  13. echo('New SetupProcess') if $debug_mode_ct
  14.  
  15. @stance_override = settings.stance_override
  16. echo(" @stance_override: #{@stance_override}") if $debug_mode_ct
  17. @priority_defense = settings.priority_defense
  18. echo(" @priority_defense: #{@priority_defense}") if $debug_mode_ct
  19. end
  20.  
  21. def execute(game_state)
  22. return true if game_state.done_cleaning_up?
  23. if game_state.stowing?
  24. echo('SetupProcess::clean_up') if $debug_mode_ct
  25. retreat
  26. if game_state.summoned_info(game_state.weapon_skill)
  27. if DRStats.moon_mage?
  28. bput('wear moon', 'telekinetic')
  29. else
  30. break_summoned_weapon(game_state.weapon_name)
  31. end
  32. else
  33. EquipmentManager.instance.stow_weapon(game_state.weapon_name)
  34. end
  35. game_state.next_clean_up_step
  36. return true
  37. end
  38.  
  39. was_retreating = game_state.retreating?
  40. game_state.update_room_npcs
  41. if game_state.dancing?
  42. game_state.dance
  43. elsif game_state.retreating?
  44. determine_next_to_train(game_state, game_state.retreat_weapons, false)
  45. else
  46. determine_next_to_train(game_state, game_state.weapon_training, was_retreating)
  47. end
  48.  
  49. if game_state.parrying
  50. check_stance(game_state)
  51. check_weapon(game_state)
  52. else
  53. check_weapon(game_state)
  54. check_stance(game_state)
  55. end
  56. false
  57. end
  58.  
  59. private
  60.  
  61. def determine_next_to_train(game_state, weapon_training, ending_ranged)
  62. return unless game_state.skill_done? || !weapon_training[game_state.weapon_skill] || ending_ranged
  63.  
  64. echo('new skill needed for training') if $debug_mode_ct
  65.  
  66. game_state.reset_action_count
  67.  
  68. if DRStats.moon_mage? && moon_used_to_summon_weapon.nil?
  69. echo('skipping summoned weapons because no moonblade available') if $debug_mode_ct
  70. weapon_training = weapon_training.reject { |skill, _| game_state.summoned_info(skill) }
  71. end
  72. new_weapon_skill = weapon_training.min_by { |skill, _| [DRSkill.getxp(skill), DRSkill.getrank(skill)] }.first
  73. game_state.update_weapon_info(new_weapon_skill)
  74.  
  75. game_state.update_target_weapon_skill
  76. end
  77.  
  78. def last_stance
  79. Flags['last-stance'][0] =~ /(\d+)%.* (\d+)%.* (\d+)%.* (\d+)/
  80. { '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 }
  81. end
  82.  
  83. def build_stance_string(vals)
  84. "stance set #{vals['EVASION']} #{vals['PARRY']} #{vals['SHIELD']}"
  85. end
  86.  
  87. def check_stance(game_state, override = nil)
  88. return if @override_done
  89. if @stance_override
  90. pause
  91. waitrt?
  92. bput("stance set #{@stance_override}", 'Setting your')
  93. @override_done = true
  94. return
  95. end
  96. vals = { 'EVASION' => 0, 'PARRY' => 0, 'SHIELD' => 0, 'SPARE' => 0 }
  97. skill_map = { 'Parry Ability' => 'Parry', 'Shield Usage' => 'Shield' }
  98. previous = last_stance
  99. points = override || previous.values.inject(&:+)
  100.  
  101. priority = if game_state.current_weapon_stance.nil?
  102. result = ['Evasion', 'Parry Ability', 'Shield Usage'].sort_by { |skill| [DRSkill.getxp(skill), skill] }
  103. result.rotate! if @priority_defense == result.last
  104. result
  105. else
  106. game_state.current_weapon_stance[0..1].sort_by { |skill| [DRSkill.getxp(skill), skill] } + [game_state.current_weapon_stance.last]
  107. end
  108.  
  109. game_state.parrying = priority.index('Parry Ability') < 2
  110.  
  111. priority.each do |skill|
  112. skill = skill_map[skill] if skill_map[skill]
  113. vals[skill.upcase] = points >= 100 ? 100 : points
  114. points -= vals[skill.upcase]
  115. end
  116.  
  117. return if vals == previous
  118. 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+')
  119. check_stance(game_state, Regexp.last_match(1).to_i)
  120. end
  121.  
  122. def check_weapon(game_state)
  123. return if @last_seen_weapon_skill == game_state.weapon_skill
  124. @last_seen_weapon_skill = game_state.weapon_skill
  125.  
  126. echo("checking weapons as #{game_state.last_weapon_skill.inspect}!=#{game_state.weapon_skill}") if $debug_mode_ct
  127.  
  128. last_summoned = game_state.summoned_info(game_state.last_weapon_skill)
  129. next_summoned = game_state.summoned_info(game_state.weapon_skill)
  130.  
  131. # Clean up the previous weapon
  132. if !last_summoned
  133. EquipmentManager.instance.stow_weapon(game_state.last_weapon_name)
  134. elsif !next_summoned && !DRStats.moon_mage?
  135. break_summoned_weapon(game_state.last_weapon_name)
  136. elsif !next_summoned && DRStats.moon_mage?
  137. if right_hand =~ /moon/ || left_hand =~ /moon/
  138. bput('wear moon', 'telekinetic')
  139. end
  140. end
  141.  
  142. # Prepare the next weapon
  143. if next_summoned
  144. game_state.prepare_summoned_weapon(last_summoned)
  145. else
  146. EquipmentManager.instance.wield_weapon(game_state.weapon_name, game_state.weapon_skill)
  147. end
  148. end
  149. end
  150.  
  151. class LootProcess
  152. include DRC
  153. include DRCI
  154. include DRCS
  155. include DRCH
  156.  
  157. def initialize(settings)
  158. echo('New LootProcess') if $debug_mode_ct
  159. skinning = settings.skinning
  160.  
  161. @skin = skinning['skin'] || false
  162. echo(" @skin: #{@skin}") if $debug_mode_ct
  163.  
  164. @arrange_all = skinning['arrange_all'] || false
  165. echo(" @arrange_all: #{@arrange_all}") if $debug_mode_ct
  166.  
  167. @arrange_count = skinning['arrange_count'] || 0
  168. echo(" @arrange_count: #{@arrange_count}") if $debug_mode_ct
  169.  
  170. @tie_bundle = skinning['tie_bundle'] || false
  171. echo(" @tie_bundle: #{@tie_bundle}") if $debug_mode_ct
  172.  
  173. @arrange_types = skinning['arrange_types'] || {}
  174. echo(" @arrange_types: #{@arrange_types}") if $debug_mode_ct
  175.  
  176. @lootables = settings.lootables
  177. echo(" @lootables: #{@lootables}") if $debug_mode_ct
  178.  
  179. thanatology = settings.thanatology
  180. @ritual_type = thanatology['ritual_type'].downcase
  181. echo(" @ritual_type: #{@ritual_type}") if $debug_mode_ct
  182.  
  183. @rituals = get_data('spells').rituals
  184. echo(" @rituals: #{@rituals}") if $debug_mode_ct
  185.  
  186. @last_ritual = nil
  187. echo(" @last_ritual: #{@last_ritual}") if $debug_mode_ct
  188.  
  189. @necro_heal = thanatology['heal'] || false
  190. echo(" @necro_heal: #{@necro_heal}") if $debug_mode_ct
  191.  
  192. @gem_nouns = get_data('items').gem_nouns
  193. echo(" @gem_nouns: #{@gem_nouns}") if $debug_mode_ct
  194.  
  195. @spare_gem_pouch_container = settings.spare_gem_pouch_container
  196. echo(" @spare_gem_pouch_container: #{@spare_gem_pouch_container}") if $debug_mode_ct
  197.  
  198. @gem_pouch_adjective = settings.gem_pouch_adjective
  199. echo(" @gem_pouch_adjective: #{@gem_pouch_adjective}") if $debug_mode_ct
  200.  
  201. @loot_delay = 5 # in seconds
  202. @loot_timer = Time.now - @loot_delay
  203. echo(" @loot_timer: #{@loot_timer}") if $debug_mode_ct
  204.  
  205. @loot_bodies = settings.loot_bodies
  206. echo(" @loot_bodies: #{@loot_bodies}") if $debug_mode_ct
  207.  
  208. @loot_specials = settings.loot_specials
  209. echo(" @loot_specials: #{@loot_specials}") if $debug_mode_ct
  210.  
  211. @dump_junk = settings.dump_junk
  212. echo(" @dump_junk: #{@dump_junk}") if $debug_mode_ct
  213. @dump_timer = Time.now - 300
  214.  
  215. $arena = settings.arena
  216. end
  217.  
  218. def execute(game_state)
  219. if (Time.now - @dump_timer > 300) && @dump_junk && DRRoom.room_objs.count >= 13
  220. fput 'DUMP JUNK'
  221. @dump_timer = Time.now
  222. end
  223. game_state.mob_died = false
  224. dispose_body(game_state)
  225. stow_lootables(game_state)
  226. if (game_state.mob_died || game_state.npcs.empty?) && game_state.finish_killing?
  227. echo('LootProcess::clean_up') if $debug_mode_ct
  228. game_state.next_clean_up_step
  229. end
  230. return true if game_state.finish_spell_casting? || game_state.stowing?
  231. false
  232. end
  233.  
  234. def stow_loot(item, game_state)
  235. Flags.add('pouch-full', 'You think the .* pouch is too full to fit another gem into', 'You\'d better tie it up before putting')
  236.  
  237. special = @loot_specials.find { |x| x['name'] == item }
  238. if special
  239. 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')
  240. 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')
  241. end
  242. pause 0.25
  243. bput("put #{item} in my #{special['bag']}", 'you put')
  244. return
  245. end
  246.  
  247. 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')
  248. if @gem_nouns.include?(item)
  249. 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')
  250. else
  251. 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')
  252. end
  253. end
  254. pause 0.25
  255. return unless Flags['pouch-full']
  256. bput("drop my #{item}", 'You drop', 'What were')
  257. unless @spare_gem_pouch_container
  258. game_state.unlootable(item)
  259. return
  260. end
  261. bput("remove my #{@gem_pouch_adjective} pouch", 'You remove')
  262. bput("stow my #{@gem_pouch_adjective} pouch", 'You put')
  263. bput("get #{@gem_pouch_adjective} pouch from my #{@spare_gem_pouch_container}", 'You get a')
  264. bput('wear my pouch', 'You attach')
  265. bput("stow #{item}", 'You pick')
  266. if Flags['pouch-full'].first =~ /tie it up/
  267. fput('close my pouch')
  268. else
  269. bput('tie my pouch', 'You tie')
  270. end
  271. end
  272.  
  273. def stow_lootables(game_state)
  274. return unless @loot_bodies
  275.  
  276. pair = [left_hand, right_hand]
  277. tried_loot = false
  278. @lootables
  279. .select { |item| game_state.lootable?(item) }
  280. .each do |item|
  281. item_reg = item.split.join('.*')
  282. matches = DRRoom.room_objs.grep(/\b#{item_reg}$/)
  283. tried_loot ||= !matches.empty?
  284. matches.each { |_| stow_loot(item, game_state); }
  285. end
  286. return unless tried_loot
  287. pause 1
  288. if left_hand != pair.first && !EquipmentManager.instance.is_listed_item?(DRC.left_hand)
  289. echo("out of room, failed to store #{left_hand}")
  290. game_state.unlootable(GameObj.left_hand.noun.downcase)
  291. dispose_trash(left_hand)
  292. end
  293. if right_hand != pair.last && !EquipmentManager.instance.is_listed_item?(DRC.right_hand)
  294. echo("out of room, failed to store #{right_hand}")
  295. game_state.unlootable(GameObj.right_hand.noun.downcase)
  296. dispose_trash(right_hand)
  297. end
  298. end
  299.  
  300. def check_rituals(game_state)
  301. return true unless DRStats.necromancer?
  302.  
  303. if @last_ritual.nil?
  304. if @necro_heal
  305. game_state.wounds = check_health
  306. echo "Severity to Wounds: #{game_state.wounds}" if $debug_mode_ct
  307. do_necro_ritual(DRRoom.dead_npcs.first, 'consume', game_state) unless game_state.wounds.empty?
  308. end
  309.  
  310. do_necro_ritual(DRRoom.dead_npcs.first, @ritual_type, game_state) unless game_state.prepare_consume
  311. end
  312. return false if %w(consume harvest dissect).include?(@last_ritual)
  313. true
  314. end
  315.  
  316. def do_necro_ritual(mob_noun, ritual, game_state)
  317. return unless DRStats.necromancer?
  318. return if game_state.construct?(mob_noun)
  319.  
  320. do_necro_ritual(mob_noun, 'preserve', game_state) if %w(consume harvest arise).include?(ritual)
  321. perform_message = "perform #{ritual} on #{mob_noun}"
  322. 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')
  323. when @rituals['preserve'], @rituals['dissect']
  324. @last_ritual = ritual
  325. return
  326. when @rituals['consume']
  327. @last_ritual = ritual
  328. game_state.prepare_consume = true if @necro_heal
  329. return
  330. when @rituals['harvest']
  331. @last_ritual = ritual
  332. waitrt?
  333. fput 'drop material'
  334. return
  335. when 'Rituals do not work upon constructs'
  336. game_state.construct(mob_noun)
  337. return
  338. end
  339. end
  340.  
  341. def dispose_body(game_state)
  342. return unless @loot_bodies
  343. if DRRoom.dead_npcs.empty?
  344. @last_ritual = nil
  345. return
  346. end
  347. return if Time.now - @loot_timer < @loot_delay
  348.  
  349. game_state.mob_died = true
  350. can_skin = check_rituals(game_state)
  351. if @skin && can_skin
  352. arrange_mob(DRRoom.dead_npcs.first, game_state)
  353. check_skinning(DRRoom.dead_npcs.first, game_state)
  354. end
  355. unless game_state.casting_consume || game_state.prepare_consume
  356. 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')
  357. pause
  358. waitrt?
  359. end
  360. @last_ritual = nil
  361. end
  362. @loot_timer = Time.now
  363. end
  364.  
  365. def arrange_mob(mob_noun, game_state)
  366. return unless @arrange_count > 0
  367. return unless game_state.skinnable?(mob_noun)
  368.  
  369. arranges = 0
  370. type = @arrange_types[mob_noun] || 'skin'
  371. arrange_message = @arrange_all ? "arrange all for #{type}" : "arrange for #{type}"
  372. while arranges < @arrange_count
  373. arranges += 1
  374. 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')
  375. when 'You complete arranging', 'That has already been arranged', 'You make a serious mistake in the arranging process'
  376. break
  377. when 'Arrange what', 'cannot be skinned'
  378. game_state.unskinnable(mob_noun)
  379. return
  380. when 'That creature cannot'
  381. arranges = 0
  382. arrange_message = @arrange_all ? 'arrange all' : 'arrange'
  383. end
  384. waitrt?
  385. end
  386. end
  387.  
  388. def check_skinning(mob_noun, game_state)
  389. return unless game_state.skinnable?(mob_noun)
  390.  
  391. pause 0.25
  392. waitrt?
  393. if game_state.need_bundle
  394. case bput('tap my bundle', 'You tap a \w+ bundle that you are wearing', 'I could not find what you were referring to')
  395. when /lumpy/
  396. if @tie_bundle
  397. bput('tie bundle', 'TIE the bundle again')
  398. bput('tie bundle', 'you tie the bundle')
  399. bput('adjust bundle', 'You adjust')
  400. end
  401. game_state.need_bundle = false
  402. when /tight/
  403. game_state.need_bundle = false
  404. end
  405. end
  406.  
  407. snap = [left_hand, right_hand]
  408. case bput('skin', 'roundtime', 'skin what', 'cannot be skinned', 'carrying far too many items', 'need a more appropriate weapon')
  409. when 'carrying far too many items'
  410. waitrt?
  411. fput 'get skin from bundle'
  412. fput 'drop skin'
  413. fput 'skin'
  414. when 'need a more appropriate weapon'
  415. echo('BUY A SKINNING KNIFE')
  416. @skin = false
  417. return
  418. when 'cannot be skinned'
  419. game_state.unskinnable(mob_noun)
  420. return
  421. end
  422. pause 1
  423. waitrt?
  424. if game_state.need_bundle && snap != [left_hand, right_hand]
  425. stored_moon = false
  426. if DRStats.moon_mage? && 'suspend' == bput('wear moon', 'suspend', 'already telekinetic', 'wear what')
  427. stored_moon = true
  428. elsif summoned = game_state.summoned_info(game_state.weapon_skill)
  429. break_summoned_weapon(game_state.weapon_name)
  430. else
  431. EquipmentManager.instance.stow_weapon(game_state.weapon_name)
  432. end
  433. if 'You get' == bput('get bundling rope', 'You get', 'What were you referring to', 'You need a free hand')
  434. fput('bundle')
  435. fput('wear bundle')
  436. if @tie_bundle
  437. bput('tie bundle', 'TIE the bundle again')
  438. bput('tie bundle', 'you tie the bundle')
  439. bput('adjust bundle', 'You adjust')
  440. end
  441. else
  442. dispose_trash(left_hand) if snap.first != left_hand && !EquipmentManager.instance.is_listed_item?(DRC.left_hand)
  443. dispose_trash(right_hand) if snap.last != right_hand && !EquipmentManager.instance.is_listed_item?(DRC.right_hand)
  444. end
  445. game_state.need_bundle = false
  446. unless stored_moon && 'you grab' == bput('get moon', 'you grab', 'What were')
  447. if summoned
  448. game_state.prepare_summoned_weapon(false)
  449. else
  450. EquipmentManager.instance.wield_weapon(game_state.weapon_name, game_state.weapon_skill)
  451. end
  452. end
  453. end
  454. dispose_trash(left_hand) if snap.first != left_hand && !EquipmentManager.instance.is_listed_item?(DRC.left_hand)
  455. dispose_trash(right_hand) if snap.last != right_hand && !EquipmentManager.instance.is_listed_item?(DRC.right_hand)
  456. end
  457. end
  458.  
  459. class SafetyProcess
  460. include DRC
  461. include DRCH
  462. include DRCT
  463.  
  464. def initialize
  465. echo('New SafetyProcess') if $debug_mode_ct
  466. Flags.add('ct-engaged', 'closes to pole weapon range on you', 'closes to melee range on you')
  467. Flags.add('ct-lodged', 'You feel an agonizing pain from the .* lodged in your (.*)\.')
  468. end
  469.  
  470. def execute(game_state)
  471. custom_require.call('tendme') if bleeding? && !Script.running?('tendme')
  472. fix_standing
  473. tend_lodged
  474. game_state.danger = in_danger?(game_state.danger)
  475. keep_away if !game_state.danger && game_state.retreating?
  476. end
  477.  
  478. private
  479.  
  480. def tend_lodged
  481. return unless Flags['ct-lodged']
  482. bind_wound(Flags['ct-lodged'].last)
  483. Flags.reset('ct-lodged')
  484. end
  485.  
  486. def keep_away
  487. return unless Flags['ct-engaged']
  488. Flags.reset('ct-engaged')
  489. retreat
  490. end
  491.  
  492. def in_danger?(danger)
  493. return false if health >= 75
  494.  
  495. unless danger
  496. Flags.reset('ct-engaged')
  497. retreat
  498. end
  499.  
  500. fput 'exit' if health < 40
  501.  
  502. keep_away
  503. true
  504. end
  505. end
  506.  
  507. class SpellProcess
  508. include DRC
  509. include DRCA
  510. include DRCS
  511. include DRCH
  512. include DRCT
  513.  
  514. def initialize(settings)
  515. echo('New SpellProcess') if $debug_mode_ct
  516.  
  517. @buff_spells = settings.buff_spells
  518. echo(" @buff_spells: #{@buff_spells}") if $debug_mode_ct
  519.  
  520. @offensive_spells = settings.offensive_spells
  521. echo(" @offensive_spells: #{@offensive_spells}") if $debug_mode_ct
  522.  
  523. @offensive_spell_cycle = settings.offensive_spell_cycle
  524. echo(" @offensive_spell_cycle: #{@offensive_spell_cycle}") if $debug_mode_ct
  525.  
  526. @spell_data = get_data('spells').spell_data
  527.  
  528. @is_necro = settings.thanatology['necro'] || false
  529. echo(" @is_necro: #{@is_necro}") if $debug_mode_ct
  530.  
  531. @necromancer_healing = settings.necromancer_healing
  532. echo(" @necromancer_healing: #{@necromancer_healing}") if $debug_mode_ct
  533.  
  534. @empath_spells = settings.empath_healing
  535. echo(" @empath_spells: #{@empath_spells}") if $debug_mode_ct
  536.  
  537. @osrel_timer = Time.now - 1000
  538. echo(" @osrel_timer: #{settings.osrel_timer}") if $debug_mode_ct
  539.  
  540. @osrel_amount = settings.osrel_amount
  541. echo(" @osrel_amount: #{settings.osrel_amount}") if $debug_mode_ct
  542.  
  543. @osrel_no_harness = settings.osrel_no_harness
  544. echo(" @osrel_no_harness: #{settings.osrel_no_harness}") if $debug_mode_ct
  545.  
  546. @cast_only_to_train = settings.cast_only_to_train
  547. echo(" @cast_only_to_train: #{settings.cast_only_to_train}") if $debug_mode_ct
  548.  
  549. @perc_health_timer = Time.now
  550.  
  551. Flags.add('ct-spelllost', 'Your pattern dissipates with the loss of your target')
  552. Flags.add('ct-need-bless', ' passes through the .* with no effect')
  553.  
  554. @offensive_spells
  555. .select { |spell| spell['expire'] }
  556. .each { |spell| add_spell_flag(spell['abbrev'], spell['expire']) }
  557. @buff_spells
  558. .values
  559. .select { |data| data['expire'] }
  560. .each { |data| add_spell_flag(data['abbrev'], data['expire']) }
  561.  
  562. @spell_timers = {}
  563.  
  564. @tk_ammo = settings.tk_ammo
  565. @tk_spell = @offensive_spells.find { |spell| spell['abbrev'] =~ /tkt|tks/i }
  566. return unless @tk_ammo
  567. fput("get #{@tk_ammo}")
  568. fput("drop #{@tk_ammo}")
  569. end
  570.  
  571. def add_spell_flag(name, expire)
  572. Flags.add("ct-#{name}", expire)
  573. Flags["ct-#{name}"] = true
  574. end
  575.  
  576. def execute(game_state)
  577. return true if game_state.stowing?
  578.  
  579. check_timer(game_state)
  580. if Flags['ct-spelllost']
  581. game_state.casting = false
  582. Flags.reset('ct-spelllost')
  583. end
  584. check_osrel(game_state)
  585. if game_state.mob_died
  586. @offensive_spells
  587. .select { |spell| spell['expire'] }
  588. .reject { |spell| spell['cyclic'] }
  589. .each { |spell| Flags["ct-#{spell['abbrev']}"] = true }
  590. end
  591. check_slivers(game_state)
  592. check_consume(game_state)
  593. check_bless(game_state)
  594. check_ignite(game_state)
  595. check_health(game_state)
  596. check_buffs(game_state)
  597. check_offensive(game_state)
  598. check_current(game_state)
  599. if game_state.finish_spell_casting? && !game_state.casting
  600. echo('SpellProcess::clean_up') if $debug_mode_ct
  601. game_state.next_clean_up_step
  602. release_cyclics
  603. if @tk_ammo
  604. waitrt?
  605. pause
  606. fput("stow #{@tk_ammo}")
  607. end
  608. return true
  609. end
  610. false
  611. end
  612.  
  613. private
  614.  
  615. def check_slivers(game_state)
  616. return if game_state.casting
  617. return if @tk_ammo
  618. return unless @tk_spell
  619. return if DRSpells.slivers
  620. return if UserVars.moons['visible'].empty?
  621.  
  622. fput('pre moonblade')
  623. pause
  624. fput("cast #{UserVars.moons['visible'].first}")
  625. fput('break moonblade')
  626. end
  627.  
  628. def check_osrel(game_state)
  629. return if game_state.casting
  630. return unless @osrel_amount && DRSpells.active_spells['Osrel Meraud']
  631. return unless Time.now - @osrel_timer > 300
  632. @osrel_timer = Time.now
  633. infuse_om(!@osrel_no_harness, @osrel_amount)
  634. end
  635.  
  636. def check_timer(game_state)
  637. return if game_state.cast_timer.nil? || (Time.now - game_state.cast_timer) <= 70
  638.  
  639. game_state.cast_timer = nil
  640. fput('release spell') if game_state.casting
  641. game_state.casting = false
  642. end
  643.  
  644. def check_bless(game_state)
  645. return if game_state.casting
  646. return unless @buff_spells['Bless']
  647. return unless Flags['ct-need-bless']
  648. Flags.reset('ct-need-bless')
  649.  
  650. prepare('Bless', 1)
  651. cast("cast #{right_hand || left_hand}")
  652. end
  653.  
  654. def check_ignite(game_state)
  655. return if @last_seen_weapon_name == game_state.weapon_name
  656. @last_seen_weapon_name = game_state.weapon_name
  657. return unless DRSpells.active_spells['Ignite']
  658.  
  659. # Release the spell on the character
  660. bput('release ignite', 'The warm feeling in your hand goes away', 'Release what')
  661. # Wait for the spell on the weapon to be released (it can take a second or two to pulse)
  662. pause 1
  663. end
  664.  
  665. def ready_to_cast?(game_state)
  666. Flags['ct-spellcast'] || (@prep_time && Time.now - game_state.cast_timer >= @prep_time)
  667. end
  668.  
  669. def check_current(game_state)
  670. return unless game_state.casting
  671. return if game_state.check_charging? && game_state.check_charging?
  672.  
  673. cast_spell(game_state) if ready_to_cast?(game_state)
  674. end
  675.  
  676. def cast_spell(game_state)
  677. @before.each { |action| bput(action['message'], action['matches']) } if @before
  678.  
  679. @custom_cast = "cast my #{game_state.weapon_name}" if game_state.casting_ignite
  680. @custom_cast = "cast #{game_state.wounds[game_state.wounds.keys.max].first}" if game_state.casting_consume
  681. cast(@custom_cast)
  682. @custom_cast = nil
  683.  
  684. game_state.casting = false
  685. game_state.cast_timer = nil
  686.  
  687. game_state.casting_ignite = false
  688. game_state.casting_consume = false if game_state.casting_consume
  689.  
  690. if game_state.casting_moonblade
  691. if left_hand =~ /moon/ || game_state.brawling? || game_state.offhand?
  692. # The moonblade was summoned or refreshed while training something else
  693. bput('wear moon', 'telekinetic')
  694. end
  695.  
  696. game_state.casting_moonblade = false
  697. end
  698.  
  699. if @command
  700. pause 0.5 until DRRoom.npcs.include?('warrior')
  701. fput("command #{@command}")
  702. @command = nil
  703. end
  704.  
  705. return unless @after
  706. @after.each { |action| bput(action['message'], action['matches']) }
  707. @after = nil
  708. end
  709.  
  710. def check_spell_timer(data)
  711. Time.now - (@spell_timers[data['abbrev']] || Time.at(0)) >= data['recast_every']
  712. end
  713.  
  714. def check_buff_conditions?(name, _data, game_state)
  715. return false if name == 'Ignite' && game_state.aimed_skill?
  716.  
  717. true
  718. end
  719.  
  720. def check_buffs(game_state)
  721. return if game_state.casting
  722. return if mana < 40
  723.  
  724. recastable_buffs = @buff_spells
  725. .select { |_, data| data['recast'] || data['recast_every'] || data['expire'] }
  726. .select { |_name, data| data['expire'] ? Flags["ct-#{data['abbrev']}"] : true }
  727. .select { |name, data| check_buff_conditions?(name, data, game_state) }
  728.  
  729. name, data = recastable_buffs.find do |name, data|
  730. if data['recast_every']
  731. check_spell_timer(data)
  732. elsif data['expire']
  733. true
  734. else
  735. !DRSpells.active_spells[name] || DRSpells.active_spells[name].to_i <= data['recast']
  736. end
  737. end
  738. echo("found buff missing: #{name}") if $debug_mode_ct && name
  739. game_state.casting_ignite = true if name == 'Ignite'
  740. if data['ritual']
  741. cast_ritual(data, game_state)
  742. else
  743. prepare_spell(data, game_state)
  744. end
  745. end
  746.  
  747. def check_health(game_state)
  748. return if game_state.casting
  749. return unless DRStats.empath?
  750. return if health > 95
  751.  
  752. if Time.now - @perc_health_timer > 30
  753. @perc_health_timer = Time.now
  754. @wounds = check_perc_health
  755. end
  756.  
  757. echo('Healing') if $debug_mode_ct
  758. if @wounds.any?
  759. if @empath_spells['FOC']
  760. data = { 'abbrev' => 'foc', 'mana' => @empath_spells['FOC'].first, 'cambrinth' => @empath_spells['FOC'][1..-1] }
  761. elsif @empath_spells['HEAL']
  762. data = { 'abbrev' => 'heal', 'mana' => @empath_spells['HEAL'].first, 'cambrinth' => @empath_spells['HEAL'][1..-1] }
  763. end
  764. @wounds = {}
  765. prepare_spell(data, game_state) if data
  766. else
  767. data = { 'abbrev' => 'vh', 'mana' => @empath_spells['VH'].first, 'cambrinth' => @empath_spells['VH'][1..-1] }
  768. prepare_spell(data, game_state)
  769. end
  770. end
  771.  
  772. def check_consume(game_state)
  773. return unless @is_necro
  774. return if game_state.casting
  775. return unless game_state.prepare_consume
  776.  
  777. data = @necromancer_healing['Consume Flesh']
  778. game_state.casting_consume = true
  779. game_state.prepare_consume = false
  780. prepare_spell(data, game_state)
  781. end
  782.  
  783. def check_offensive(game_state)
  784. return if game_state.casting
  785. return if game_state.npcs.empty?
  786. return if mana < 40
  787. ready_spells = @offensive_spells
  788. .select { |spell| spell['target_enemy'] ? game_state.npcs.include?(spell['target_enemy']) : true }
  789. .select { |spell| spell['min_threshold'] ? game_state.npcs.length >= spell['min_threshold'] : true }
  790. .select { |spell| spell['max_threshold'] ? game_state.npcs.length <= spell['max_threshold'] : true }
  791. .select { |spell| spell['expire'] ? Flags["ct-#{spell['abbrev']}"] : true }
  792. .select { |spell| game_state.dancing? ? spell['harmless'] : true }
  793. .select { |spell| spell['recast_every'] ? check_spell_timer(spell) : true }
  794. .select { |spell| @cast_only_to_train ? DRSkill.getxp(spell['skill']) <= 32 : true }
  795. .select { |spell| spell['cast_only_to_train'] ? DRSkill.getxp(spell['skill']) <= 32 : true }
  796. .select { |spell| spell['cyclic'] ? !DRSpells.active_spells[spell['name']] : true }
  797. .select { |spell| spell['night'] ? UserVars.sun['night'] : true }
  798. .select { |spell| spell['day'] ? UserVars.sun['day'] : true }
  799. .select { |spell| spell['slivers'] ? DRSpells.slivers : true }
  800. data = if @offensive_spell_cycle.empty?
  801. ready_spells.min_by { |spell| DRSkill.getxp(spell['skill']) }
  802. else
  803. name = @offensive_spell_cycle.find { |spell_name| ready_spells.find { |spell| spell['name'] == spell_name } }
  804. @offensive_spell_cycle.rotate!
  805. ready_spells.find { |spell| spell['name'] == name }
  806. end
  807. return if DRSkill.getxp(data['skill']) >= 34 && mana < 70 # make this a spell option
  808. prepare_spell(data, game_state)
  809. Flags.reset('ct-spelllost')
  810. end
  811.  
  812. def cast_ritual(data, game_state)
  813. retreat
  814. if summoned = game_state.summoned_info(game_state.weapon_skill)
  815. break_summoned_weapon(game_state.weapon_name)
  816. else
  817. EquipmentManager.instance.stow_weapon(game_state.weapon_name)
  818. end
  819. fput('STANCE SET 100 80 0')
  820. prepare(data['abbrev'], data['mana'])
  821. fput("get my #{data['focus']}")
  822. invoke(data['focus'])
  823. pause 5
  824. waitrt?
  825. fput("stow my #{data['focus']}")
  826. unless summoned
  827. EquipmentManager.instance.wield_weapon(game_state.weapon_name, game_state.weapon_skill)
  828. end
  829. waitcastrt?
  830. cast
  831. game_state.prepare_summoned_weapon(false) if summoned
  832. end
  833.  
  834. def prepare_spell(data, game_state)
  835. return unless data
  836. game_state.cast_timer = Time.now
  837. @prep_time = data['prep_time']
  838. echo("prepare spell: #{data}") if $debug_mode_ct
  839. if data['target_enemy']
  840. echo(" Target found: #{data['target_enemy']}") if $debug_mode_ct
  841. fput("face #{data['target_enemy']}")
  842. end
  843. release_cyclics if data['cyclic']
  844. command = 'pre'
  845. command = data['skill'] == 'Debilitation' ? 'pre' : 'tar' if data['skill']
  846. command = @spell_data[data['name']]['prep'] if @spell_data[data['name']]['prep']
  847. command = data['prep_type'] if data['prep_type']
  848.  
  849. @spell_timers[data['abbrev']] = Time.now if data['recast_every']
  850.  
  851. if data['moon']
  852. moon = UserVars.moons['visible'].first
  853. unless moon
  854. echo "No moon available to cast #{data['abbrev']}" if $debug_mode_ct
  855. unless Script.running? 'moonwatch'
  856. echo 'moonwatch is not running. Starting it now'
  857. custom_require.call('moonwatch')
  858. echo "Run `;e autostart('moonwatch')` to avoid this in the future"
  859. end
  860.  
  861. @weather = bput('weather', 'inside', 'You glance up at the sky.') unless @weather
  862. if @weather =~ /inside/
  863. echo "*** You're inside and there are no available moons. You're going to have a hard time casting #{data['abbrev']}"
  864. end
  865.  
  866. unless moon = UserVars.moons['visible'].first
  867. echo "Couldn't find any moons to cast #{data['abbrev']} with" if $debug_mode_ct
  868. return
  869. end
  870. end
  871. if data['abbrev'] == 'moonblade'
  872. game_state.casting_moonblade = true
  873. last_moon = moon_used_to_summon_weapon
  874. data['before'] = [{ 'message' => 'get moon', 'matches' => ['already holding that', 'You grab', 'referring to'] }]
  875. if UserVars.moons['visible'].include?(last_moon) && UserVars.moons[last_moon]['timer'] >= 4
  876. moon = last_moon
  877. data['cast'] = "cast #{moon} refresh"
  878. else
  879. data['before'] << { 'message' => 'drop moon', 'matches' => ['open your hand', 'referring to'] }
  880. data['cast'] = "cast #{moon}"
  881. end
  882. else
  883. data['cast'] = "cast #{moon}"
  884. end
  885. end
  886. prepare(data['abbrev'], data['mana'], command)
  887. game_state.casting = true
  888. game_state.cambrinth_charges(data['cambrinth'])
  889. @custom_cast = data['cast']
  890. @after = data['after']
  891. @command = data['command']
  892. Flags.reset("ct-#{data['abbrev']}") if data['expire']
  893. Flags.reset('ct-spellcast')
  894. @before = data['before']
  895. end
  896. end
  897.  
  898. class AbilityProcess
  899. include DRCA
  900.  
  901. def initialize(settings)
  902. echo('New AbilityProcess') if $debug_mode_ct
  903.  
  904. @buffs = settings.buff_nonspells
  905. echo(" @buffs: #{@buffs}") if $debug_mode_ct
  906.  
  907. @khri = @buffs.delete('khri') || []
  908. echo(" @khri: #{@khri}") if $debug_mode_ct
  909.  
  910. @kneel_khri = settings.kneel_khri
  911. echo(" @kneel_khri: #{@kneel_khri}") if $debug_mode_ct
  912. end
  913.  
  914. def execute(game_state)
  915. check_nonspell_buffs(game_state)
  916. false
  917. end
  918.  
  919. private
  920.  
  921. def check_nonspell_buffs(game_state)
  922. @buffs.each do |action, cooldown|
  923. timer = game_state.cooldown_timers[action]
  924. next unless !timer || (Time.now - timer).to_i > cooldown
  925. game_state.cooldown_timers[action] = Time.now
  926. fput action
  927. waitrt?
  928. end
  929. return if game_state.danger && @kneel_khri
  930. @khri
  931. .map { |name| "Khri #{name}" }
  932. .each do |name|
  933. timer = game_state.cooldown_timers[name]
  934. next unless !timer || (Time.now - timer).to_i > 30
  935. game_state.cooldown_timers[name] = Time.now if activate_khri?(@kneel_khri, name)
  936. end
  937. end
  938. end
  939.  
  940. class ManipulateProcess
  941. include DRC
  942. include DRCT
  943.  
  944. def initialize(settings)
  945. echo('New ManipulateProcess') if $debug_mode_ct
  946.  
  947. @threshold = settings.manipulate_threshold
  948. echo(" @threshold: #{@threshold}") if $debug_mode_ct
  949.  
  950. @last_manip = Time.now - 200
  951. end
  952.  
  953. def execute(game_state)
  954. return if game_state.danger || @threshold.nil?
  955. @filtered_npcs = game_state.npcs
  956. manipulate if should_manipulate?
  957. end
  958.  
  959. private
  960.  
  961. def should_manipulate?
  962. @filtered_npcs.length >= @threshold && Time.now - @last_manip > 120
  963. end
  964.  
  965. def manipulate
  966. bput('manip stop all', 'You relax your will', 'But you aren')
  967. bput("manipulate friendship #{@filtered_npcs.first}", 'You attempt to empathically manipulate', 'You strain')
  968. @last_manip = Time.now
  969. end
  970. end
  971.  
  972. class TrainerProcess
  973. include DRC
  974. include DRCT
  975.  
  976. def initialize(settings)
  977. echo('New TrainerProcess') if $debug_mode_ct
  978. @training_abilities = settings.training_abilities
  979. echo(" @training_abilities: #{@training_abilities}") if $debug_mode_ct
  980.  
  981. @skill_map = { 'Hunt' => 'Perception', 'Pray' => 'Theurgy', 'PercMana' => 'Attunement',
  982. 'Perc' => 'Attunement', 'Astro' => 'Astrology', 'App' => 'Appraisal',
  983. 'App Quick' => 'Appraisal', 'App Careful' => 'Appraisal', 'Tactics' => 'Tactics',
  984. 'Scream' => 'Bardic Lore', 'Perc Health' => 'Empathy', 'Khri Prowess' => 'Debilitation',
  985. 'Stealth' => 'Stealth', 'Ambush Stun' => settings.stun_skill, 'Favor Orb' => 'Anything',
  986. 'Charged Maneuver' => 'Expertise', 'Meraud' => 'Theurgy' }
  987.  
  988. @skill_map['Hunt'] = %w(Perception Scouting) if DRStats.ranger?
  989. @favor_god = settings.favor_god
  990. if settings.favor_goal && @favor_god && /delicate/ =~ bput("tap #{@favor_god} orb", 'The orb is delicate', 'I could not find')
  991. @training_abilities['Favor Orb'] = 300
  992. end
  993.  
  994. @no_app = []
  995.  
  996. @dont_stalk = settings.dont_stalk
  997. echo(" @dont_stalk: #{@dont_stalk}") if $debug_mode_ct
  998.  
  999. @stun_weapon = settings.stun_weapon
  1000. echo(" @stun_weapon: #{@stun_weapon}") if $debug_mode_ct
  1001.  
  1002. @stun_weapon_skill = settings.stun_weapon_skill
  1003. echo(" @stun_weapon_skill: #{@stun_weapon_skill}") if $debug_mode_ct
  1004.  
  1005. @theurgy_supply_container = settings.theurgy_supply_container
  1006. echo(" @theurgy_supply_container: #{@theurgy_supply_container}") if $debug_mode_ct
  1007.  
  1008. @water_holder = settings.water_holder
  1009. echo(" @water_holder: #{@water_holder}") if $debug_mode_ct
  1010.  
  1011. @flint_lighter = settings.flint_lighter
  1012. echo(" @flint_lighter: #{@flint_lighter}") if $debug_mode_ct
  1013. end
  1014.  
  1015. def execute(game_state)
  1016. return if game_state.danger
  1017.  
  1018. case select_ability(game_state)
  1019. when 'PercMana'
  1020. moon_mage_perc(game_state)
  1021. when 'Perc'
  1022. bput('perc', 'You reach out') unless game_state.retreating?
  1023. when 'Perc Health'
  1024. bput('perc heal', 'You close your eyes')
  1025. when 'Astro'
  1026. astrology(game_state)
  1027. when 'App'
  1028. appraise(game_state, '')
  1029. when 'App Quick'
  1030. appraise(game_state, 'quick')
  1031. when 'App Careful'
  1032. appraise(game_state, 'careful')
  1033. when 'Tactics'
  1034. 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?
  1035. when 'Hunt'
  1036. bput('hunt', 'You take note of ', 'You find yourself unable to hunt in this area') unless game_state.retreating?
  1037. when 'Pray'
  1038. bput('pray meraud', 'You glance')
  1039. when 'Scream'
  1040. 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?
  1041. when 'Khri Prowess'
  1042. 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?
  1043. when 'Stealth'
  1044. fput('stalk') if hide? && !@dont_stalk && !game_state.npcs.empty?
  1045. bput('unhide', 'You come out of hiding', 'But you are not') if game_state.npcs.empty?
  1046. when 'Ambush Stun'
  1047. return ambush_stun(game_state)
  1048. when 'Favor Orb'
  1049. fput("rub my #{@favor_god} orb")
  1050. when 'Charged Maneuver'
  1051. game_state.use_charged_maneuvers = true
  1052. when 'Meraud'
  1053. meraud_commune(game_state)
  1054. end
  1055. waitrt?
  1056. false
  1057. end
  1058.  
  1059. private
  1060.  
  1061. def meraud_commune(game_state)
  1062. unless (DRSkill.getrank('Theurgy') >= 300 || game_state.npcs.empty?) && !game_state.aimed_skill?
  1063. reset_ability(game_state, 'Meraud')
  1064. return
  1065. end
  1066. waitrt?
  1067. EquipmentManager.instance.stow_weapon(game_state.weapon_name)
  1068. fput "get #{@water_holder}"
  1069. if /that/i =~ bput("sprinkle #{@water_holder} on #{checkname}", 'You sprinkle', 'Sprinkle that')
  1070. fput "stow #{@water_holder}"
  1071. EquipmentManager.instance.wield_weapon(game_state.weapon_name, game_state.weapon_skill)
  1072. @training_abilities.delete('Meraud')
  1073. return
  1074. end
  1075. bput "put #{@water_holder} in my #{@theurgy_supply_container}", 'You put', 'What were you referring to'
  1076. fput "get #{@flint_lighter}", 'You get a', 'You are already'
  1077. if 'referring to' == bput('get incense', 'You get', 'You are already', 'referring to')
  1078. fput "stow #{@flint_lighter}", 'You put your', 'Stow what'
  1079. EquipmentManager.instance.wield_weapon(game_state.weapon_name, game_state.weapon_skill)
  1080. @training_abilities.delete('Meraud')
  1081. return
  1082. end
  1083. fput 'light my incense with flint' # get messaging
  1084. pause
  1085. waitrt?
  1086. fput "wave incense at #{checkname}"
  1087. fput 'snuff incense'
  1088. bput("put incense in my #{@theurgy_supply_container}", 'You put', 'What were you referring to')
  1089. fput "stow #{@flint_lighter}", 'You put your', 'Stow what'
  1090. pause 1
  1091. EquipmentManager.instance.wield_weapon(game_state.weapon_name, game_state.weapon_skill)
  1092. 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')
  1093. pause
  1094. waitrt?
  1095. fix_standing
  1096. end
  1097.  
  1098. def ambush_stun(game_state)
  1099. return false unless game_state.can_ambush_stun?
  1100. dead_count = DRRoom.dead_npcs.size
  1101.  
  1102. EquipmentManager.instance.stow_weapon(game_state.weapon_name)
  1103. EquipmentManager.instance.wield_weapon(@stun_weapon, @stun_weapon_skill)
  1104.  
  1105. if hide?
  1106. 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')
  1107. pause
  1108. waitrt?
  1109. end
  1110.  
  1111. EquipmentManager.instance.stow_weapon(@stun_weapon)
  1112. EquipmentManager.instance.wield_weapon(game_state.weapon_name, game_state.weapon_skill)
  1113. DRRoom.dead_npcs.size > dead_count
  1114. end
  1115.  
  1116. def appraise(game_state, modifier)
  1117. return if game_state.retreating?
  1118. return if game_state.npcs.empty?
  1119. target = (game_state.npcs - @no_app).first
  1120. return unless target
  1121. 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')
  1122. @no_app << target
  1123. end
  1124. end
  1125.  
  1126. def moon_mage_perc(game_state)
  1127. return if game_state.retreating?
  1128.  
  1129. retreat
  1130. bput('perc mana', 'You reach out')
  1131. end
  1132.  
  1133. def astrology(game_state)
  1134. return if game_state.retreating?
  1135. retreat
  1136. bput('predict weather', 'You predict that', 'You are far too', 'you lack the skill to grasp them fully')
  1137. waitrt?
  1138. fput('eng')
  1139. end
  1140.  
  1141. def reset_ability(game_state, ability_name)
  1142. ability_info = @training_abilities.find { |name, _| name == ability_name }.last
  1143. cooldown = ability_info.is_a?(Hash) ? ability_info[:cooldown] : ability_info.to_i
  1144. game_state.cooldown_timers[ability_name] = Time.now - cooldown
  1145. end
  1146.  
  1147. def select_ability(game_state)
  1148. ability = @training_abilities.find { |name, ability_info| check_ability(name, ability_info, game_state) }.first
  1149. echo("Selected: #{ability}") if ability && $debug_mode_ct
  1150. game_state.cooldown_timers[ability] = Time.now
  1151. ability
  1152. end
  1153.  
  1154. def check_ability(name, ability_info, game_state)
  1155. if game_state.casting
  1156. return false if ['PercMana', 'App Careful'].include?(name)
  1157. end
  1158. check = ability_info.is_a?(Hash) ? ability_info[:check] : @skill_map[name]
  1159. check = [check].flatten
  1160. cooldown = ability_info.is_a?(Hash) ? ability_info[:cooldown] : ability_info.to_i
  1161. expcheck = check.nil? || check.any? { |skill_to_check| DRSkill.getxp(skill_to_check) < 32 }
  1162. return expcheck unless game_state.cooldown_timers[name]
  1163. Time.now - game_state.cooldown_timers[name] >= cooldown ? expcheck : false
  1164. end
  1165. end
  1166.  
  1167. class AttackProcess
  1168. include DRC
  1169.  
  1170. def initialize(settings)
  1171. echo('New AttackProcess') if $debug_mode_ct
  1172.  
  1173. @fatigue_regen_action = settings.fatigue_regen_action
  1174. echo(" @fatigue_regen_action: #{@fatigue_regen_action}") if $debug_mode_ct
  1175.  
  1176. @is_empath = DRStats.empath? && !settings.construct(false)
  1177. echo(" @is_empath: #{@is_empath}") if $debug_mode_ct
  1178.  
  1179. @undead = DRStats.empath? && settings.undead
  1180. echo(" @undead: #{@undead}") if $debug_mode_ct
  1181.  
  1182. @stealth_attack_aimed_action = settings.stealth_attack_aimed_action
  1183. echo(" @stealth_attack_aimed_action: #{@stealth_attack_aimed_action}") if $debug_mode_ct
  1184.  
  1185. Flags.add('ct-ranged-ready', 'You think you have your best shot possible now')
  1186. Flags.add('ct-face-what', 'Face what')
  1187. end
  1188.  
  1189. def execute(game_state)
  1190. check_face(game_state)
  1191. if game_state.npcs.uniq.length == 1 && !game_state.stabbable?(game_state.npcs.uniq.first)
  1192. game_state.no_stab_current_mob = true
  1193. elsif game_state.mob_died && game_state.no_stab_current_mob
  1194. game_state.no_stab_current_mob = false
  1195. end
  1196.  
  1197. if game_state.dancing? || (@is_empath && !@undead && !DRSpells.active_spells['Absolution'])
  1198. if game_state.finish_killing?
  1199. echo('AttackProcess::clean_up') if $debug_mode_ct
  1200. game_state.next_clean_up_step
  1201. else
  1202. dance(game_state)
  1203. end
  1204. return false
  1205. end
  1206.  
  1207. if game_state.fatigue_low?
  1208. fput(@fatigue_regen_action)
  1209. return false
  1210. end
  1211.  
  1212. charged_maneuver = check_charged_maneuver(game_state)
  1213.  
  1214. if game_state.thrown_skill?
  1215. game_state.loaded = false
  1216. attack_thrown(game_state)
  1217. elsif game_state.aimed_skill?
  1218. attack_aimed(charged_maneuver, game_state)
  1219. else
  1220. game_state.loaded = false
  1221. attack_melee(charged_maneuver, game_state)
  1222. end
  1223. false
  1224. end
  1225.  
  1226. private
  1227.  
  1228. def check_face(game_state)
  1229. if Flags['ct-face-what']
  1230. fput("eng #{game_state.npcs.first}")
  1231. Flags.reset('ct-face-what')
  1232. end
  1233. end
  1234.  
  1235. def attack_melee(charged_maneuver, game_state)
  1236. waitrt?
  1237. if charged_maneuver.empty?
  1238. if game_state.backstab? || game_state.use_stealth_attack? || game_state.ambush?
  1239. hide?
  1240. end
  1241.  
  1242. verb = game_state.melee_attack_verb
  1243.  
  1244. command = game_state.offhand? ? "#{verb} left" : verb
  1245.  
  1246. if (game_state.backstab? || game_state.ambush?) && hiding?
  1247. if (game_state.backstab? && game_state.no_stab_current_mob) || (game_state.ambush? && !game_state.backstab?)
  1248. command += ' back'
  1249. else
  1250. command.sub!(verb, 'backstab')
  1251. end
  1252. end
  1253.  
  1254. fput(command)
  1255. else
  1256. use_charged_maneuver(charged_maneuver, game_state)
  1257. end
  1258.  
  1259. pause
  1260. waitrt?
  1261.  
  1262. if reget(5, 'You can\'t backstab that')
  1263. if game_state.npcs.uniq.length == 1
  1264. game_state.unstabbable(game_state.npcs.first)
  1265. else
  1266. game_state.no_stab_current_mob = true
  1267. end
  1268. end
  1269.  
  1270. if reget(5, 'You aren\'t close enough to attack', 'It would help if you were closer')
  1271. fput('eng')
  1272. pause 6
  1273. else
  1274. game_state.action_taken
  1275. end
  1276.  
  1277. if reget(5, 'You need two hands')
  1278. fput('stow left') if left_hand && left_hand !~ /\b#{game_state.weapon_name}/i
  1279. fput('stow right') if right_hand && right_hand !~ /\b#{game_state.weapon_name}/i
  1280. end
  1281. end
  1282.  
  1283. def attack_thrown(game_state)
  1284. hurl = game_state.bound_weapon? && !game_state.use_weak_attacks?
  1285. attack_action = hurl ? 'hurl' : 'lob'
  1286. retrieve_action = hurl ? 'invoke' : "get my #{game_state.weapon_name}"
  1287.  
  1288. bput(attack_action, 'roundtime', 'What are you trying to')
  1289. waitrt?
  1290.  
  1291. if game_state.weapon_name == 'blades'
  1292. until /(Stow what|You put your)/ =~ bput('stow blade', 'Stow what', 'You pick up .*blade', 'You put your blades')
  1293. end
  1294. end
  1295.  
  1296. case bput(retrieve_action, 'You are already holding', 'You pick up', 'You get', 'You catch', 'What were you')
  1297. when 'What were you'
  1298. # Workaround for a game bug when you lob an unblessed weapon at a noncorporeal mob
  1299. # The weapon lands on the ground, not in the 'at feet' slot, and 'my' will not work
  1300. bput("get #{game_state.weapon_name}", 'You pick up', 'You get')
  1301. end
  1302.  
  1303. game_state.action_taken
  1304. end
  1305.  
  1306. def shoot_aimed(command, game_state)
  1307. 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')
  1308. when 'How can you poach if you are not hidden', 'notices your attempt to remain hidden'
  1309. shoot_aimed('shoot', game_state)
  1310. when 'you fire', 'you poach', 'your moving to fire went unobserved'
  1311. game_state.action_taken
  1312. when 'you don\'t feel like fighting right now', 'That weapon must be in your right hand to fire'
  1313. pause 1
  1314. shoot_aimed(command, game_state)
  1315. end
  1316. end
  1317.  
  1318. def attack_aimed(charged_maneuver, game_state)
  1319. game_state.selected_maneuver = charged_maneuver unless game_state.loaded
  1320. game_state.loaded = false if game_state.mob_died && !(game_state.casting_consume || game_state.prepare_consume)
  1321. game_state.clear_aim_queue if Flags['ct-ranged-ready']
  1322.  
  1323. if game_state.loaded && game_state.done_aiming?
  1324. if game_state.selected_maneuver.empty?
  1325. command = if game_state.use_stealth_attack? && hide?
  1326. @stealth_attack_aimed_action
  1327. else
  1328. 'shoot'
  1329. end
  1330. shoot_aimed(command, game_state)
  1331. else
  1332. use_charged_maneuver(game_state.selected_maneuver, game_state)
  1333. game_state.action_taken
  1334. end
  1335. game_state.loaded = false
  1336. waitrt?
  1337. elsif game_state.loaded
  1338. fput(game_state.next_aim_action)
  1339. waitrt?
  1340. else
  1341. if game_state.dual_load? && DRSpells.active_spells['See the Wind']
  1342. pause 0.5 until bput('load arrows', 'You reach into', 'already loaded', 'Such a feat would be impossible without the winds to guide')
  1343. else
  1344. pause 0.5 until bput('load', 'You reach into', 'You carefully load', 'already loaded')
  1345. end
  1346.  
  1347. waitrt?
  1348. game_state.loaded = true
  1349. if game_state.selected_maneuver.empty?
  1350. game_state.set_aim_queue
  1351. aim(game_state)
  1352. Flags.reset('ct-ranged-ready')
  1353. end
  1354. end
  1355. end
  1356.  
  1357. def aim(game_state)
  1358. 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')
  1359. when 'Your repeating crossbow'
  1360. case bput('push my cross', 'A rapid series of clicks', 'You attempt to ready your repeating crossbow')
  1361. when 'A rapid series of clicks'
  1362. aim(game_state)
  1363. when 'You attempt to ready your repeating crossbow'
  1364. game_state.loaded = false
  1365. end
  1366. when 'Face what?'
  1367. game_state.clear_aim_queue
  1368. when 'Strangely, you don\'t feel like fighting right now'
  1369. pause 1
  1370. aim(game_state)
  1371. end
  1372. end
  1373.  
  1374. def dance(game_state)
  1375. if game_state.npcs.empty?
  1376. pause 1
  1377. else
  1378. game_state.set_dance_queue
  1379. if /Face what/ =~ fput(game_state.next_dance_action)
  1380. fput("eng #{game_state.npcs.first}")
  1381. end
  1382. waitrt?
  1383. end
  1384. end
  1385.  
  1386. def check_charged_maneuver(game_state)
  1387. return '' unless game_state.use_charged_maneuvers
  1388. return '' unless game_state.charged_maneuver
  1389.  
  1390. timer = game_state.cooldown_timers[game_state.charged_maneuver]
  1391. return '' if timer && (Time.now - timer).to_i < 60
  1392.  
  1393. echo "***Ready to use charged maneuver: #{game_state.charged_maneuver}***" if $debug_mode_ct
  1394. game_state.charged_maneuver
  1395. end
  1396.  
  1397. def use_charged_maneuver(action, game_state)
  1398. game_state.cooldown_timers[action] = Time.now
  1399. 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')
  1400. return if attempt == 'rest a bit longer'
  1401.  
  1402. # Maneuvers have extra non-RT delays
  1403. pause 7
  1404. waitrt?
  1405. game_state.use_charged_maneuvers = false
  1406. end
  1407. end
  1408.  
  1409. class CombatTrainer
  1410. include DRC
  1411.  
  1412. attr_reader :running
  1413.  
  1414. def stop
  1415. echo 'Received stop signal' if $debug_mode_ct
  1416. @stop = true
  1417. end
  1418.  
  1419. def set_args
  1420. arg_definitions = [
  1421. [
  1422. { name: 'debug', regex: /debug/i, optional: true },
  1423. { name: 'construct', regex: /construct/i, optional: true, description: 'Construct setting to override empath no attack settings.' },
  1424. { name: 'undead', regex: /undead/i, optional: true, description: 'Allows hunting of undead by empaths when absolution is up.' },
  1425. { name: 'dance', display: 'd#', regex: /d\d+/i, optional: true, description: 'Dance threshold, d2 would keep two enemies alive.' },
  1426. { name: 'retreat', display: 'r#', regex: /r\d+/i, optional: true, description: 'Retreat threshold, r3 would stay at range with three or more enemies' }
  1427. ]
  1428. ]
  1429.  
  1430. args = parse_args(arg_definitions, true)
  1431.  
  1432. settings = get_settings(args.flex)
  1433.  
  1434. settings.construct = args.construct
  1435. settings.undead = args.undead
  1436.  
  1437. settings.debug_mode = args.debug
  1438. set_dance(args.dance, settings)
  1439. set_retreat(args.retreat, settings)
  1440.  
  1441. settings
  1442. end
  1443.  
  1444. def initialize
  1445. settings = set_args
  1446.  
  1447. setup(settings)
  1448. settings.storage_containers.each { |container| fput("open my #{container}") }
  1449. EquipmentManager.instance.refresh(settings)
  1450. EquipmentManager.instance.wear_equipment_set?('standard')
  1451. end
  1452.  
  1453. def set_dance(message, settings)
  1454. return unless message
  1455. message =~ /d(\d+)/
  1456. settings.dance_threshold = Regexp.last_match(1).to_i
  1457. end
  1458.  
  1459. def set_retreat(message, settings)
  1460. return unless message
  1461. message =~ /r(\d+)/
  1462. settings.retreat_threshold = Regexp.last_match(1).to_i
  1463. end
  1464.  
  1465. def setup(settings)
  1466. 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\.')
  1467.  
  1468. 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')
  1469.  
  1470. bput('stance set 100 40 40', 'Setting your')
  1471. pause 0.25 until Flags['last-stance']
  1472.  
  1473. @stop = false
  1474. @running = true
  1475. $debug_mode_ct = UserVars.combat_trainer_debug || settings.debug_mode
  1476. @game_state = GameState.new(settings)
  1477. @combat_processes = make_processes(settings)
  1478. end
  1479.  
  1480. def make_processes(settings)
  1481. [
  1482. SetupProcess.new(settings),
  1483. SpellProcess.new(settings),
  1484. AbilityProcess.new(settings),
  1485. LootProcess.new(settings),
  1486. SafetyProcess.new,
  1487. ManipulateProcess.new(settings),
  1488. TrainerProcess.new(settings),
  1489. AttackProcess.new(settings)
  1490. ]
  1491. end
  1492.  
  1493. def start_combat
  1494. EquipmentManager.instance.empty_hands
  1495. loop do
  1496. @combat_processes.each do |process|
  1497. break if process.execute(@game_state)
  1498. end
  1499. pause 0.1
  1500. if @game_state.done_cleaning_up?
  1501. echo('CombatTrainer::clean_up') if $debug_mode_ct
  1502. @running = false
  1503. stop_script('tendme') if Script.running?('tendme')
  1504. break
  1505. end
  1506. next unless @stop && !@game_state.cleaning_up?
  1507. @game_state.next_clean_up_step
  1508. @game_state.stop_weak_attacks
  1509. @game_state.stop_analyze_combo
  1510. end
  1511. end
  1512. end
  1513.  
  1514. class GameState
  1515. include DRCA
  1516. include DRCS
  1517. include DRC
  1518.  
  1519. $thrown_skills = ['Heavy Thrown', 'Light Thrown']
  1520. $aim_skills = %w(Bow Slings Crossbow)
  1521. $ranged_skills = $thrown_skills + $aim_skills
  1522.  
  1523. 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
  1524.  
  1525. def initialize(settings)
  1526. echo('New GameState') if $debug_mode_ct
  1527. # public
  1528. @mob_died = false
  1529. @last_weapon_skill = nil
  1530. @danger = false
  1531. @parrying = false
  1532. @casting = false
  1533. @need_bundle = true
  1534. @cooldown_timers = {}
  1535. @no_stab_current_mob = false
  1536. @loaded = false
  1537. @selected_maneuver = ''
  1538. @cast_timer = nil
  1539. @casting_moonblade = false
  1540. @casting_ignite = false
  1541. @use_charged_maneuvers = false
  1542. @casting_consume = false
  1543. @prepare_consume = false
  1544. @wounds = {}
  1545.  
  1546. # private
  1547. @clean_up_step = nil
  1548. @target_weapon_skill = -1
  1549. @no_skins = []
  1550. @constructs = []
  1551. @no_stab_mobs = []
  1552. @no_loot = []
  1553. @dancing = false
  1554. @retreating = false
  1555. @action_count = 0
  1556. @charges = nil
  1557. @aim_queue = []
  1558. @dance_queue = []
  1559. @analyze_combo_array = []
  1560.  
  1561. @dance_skill = settings.dance_skill
  1562. echo(" @dance_skill: #{@dance_skill}") if $debug_mode_ct
  1563.  
  1564. @target_action_count = settings.combat_trainer_action_count
  1565. echo(" @target_action_count: #{@target_action_count}") if $debug_mode_ct
  1566.  
  1567. @dance_threshold = settings.dance_threshold
  1568. echo(" @dance_threshold: #{@dance_threshold}") if $debug_mode_ct
  1569.  
  1570. @retreat_threshold = settings.retreat_threshold
  1571. echo(" @retreat_threshold: #{@retreat_threshold}") if $debug_mode_ct
  1572.  
  1573. @summoned_weapons = settings.summoned_weapons
  1574. echo(" @summoned_weapons: #{@summoned_weapons}") if $debug_mode_ct
  1575.  
  1576. @target_increment = settings.combat_trainer_target_increment
  1577. echo(" @target_increment: #{@target_increment}") if $debug_mode_ct
  1578.  
  1579. @stances = settings.stances
  1580. echo(" @stances: #{@stances}") if $debug_mode_ct
  1581.  
  1582. if @stances.find { |_key, stances| !(stances & %w(evasion parry shield)).empty? }
  1583. echo 'Please update to the latest version of stance: settings!'
  1584. @stances.keys do |key|
  1585. settings = @stances[key]
  1586. settings.map! { |x| { 'parry' => 'Parry Ability', 'shield' => 'Shield Usage', 'evasion' => 'Evasion' }[x] }
  1587. (['Parry Ability', 'Shield Usage', 'Evasion'] - settings).each { |x| settings << x }
  1588. @stances[key] = settings
  1589. end
  1590. echo "Modified stances: #{@stances}"
  1591. end
  1592.  
  1593. @weapons_to_train = settings.weapon_training
  1594. echo(" @weapons_to_train: #{@weapons_to_train}") if $debug_mode_ct
  1595.  
  1596. @use_stealth_attacks = settings.use_stealth_attacks
  1597. echo(" @use_stealth_attacks: #{@use_stealth_attacks}") if $debug_mode_ct
  1598.  
  1599. @ambush = settings.ambush
  1600. echo(" @ambush: #{@ambush}") if $debug_mode_ct
  1601.  
  1602. @backstab = settings.backstab
  1603. echo(" @backstab: #{@backstab}") if $debug_mode_ct
  1604.  
  1605. @charged_maneuvers = settings.charged_maneuvers
  1606. echo(" @charged_maneuvers: #{@charged_maneuvers}") if $debug_mode_ct
  1607.  
  1608. @fatigue_regen_threshold = settings.fatigue_regen_threshold
  1609. echo(" @fatigue_regen_threshold: #{@fatigue_regen_threshold}") if $debug_mode_ct
  1610.  
  1611. @aim_fillers = settings.aim_fillers
  1612. echo(" @aim_fillers: #{@aim_fillers}") if $debug_mode_ct
  1613.  
  1614. @aim_fillers_stealth = settings.aim_fillers_stealth
  1615. echo(" @aim_fillers_stealth: #{@aim_fillers_stealth}") if $debug_mode_ct
  1616.  
  1617. @dance_actions = settings.dance_actions
  1618. echo(" @dance_actions: #{@dance_actions}") if $debug_mode_ct
  1619.  
  1620. @dance_actions_stealth = settings.dance_actions_stealth
  1621. echo(" @dance_actions_stealth: #{@dance_actions_stealth}") if $debug_mode_ct
  1622.  
  1623. @ignored_npcs = settings.ignored_npcs
  1624. echo(" @ignored_npcs: #{@ignored_npcs}") if $debug_mode_ct
  1625.  
  1626. @dual_load = settings.dual_load
  1627. echo(" @dual_load: #{@dual_load}") if $debug_mode_ct
  1628.  
  1629. @summoned_weapons_element = settings.summoned_weapons_element
  1630. echo(" @summoned_weapons_element: #{@summoned_weapons_element}") if $debug_mode_ct
  1631.  
  1632. @summoned_weapons_ingot = settings.summoned_weapons_ingot
  1633. echo(" @summoned_weapons_ingot: #{@summoned_weapons_ingot}") if $debug_mode_ct
  1634.  
  1635. @stop_on_bleeding = settings.stop_hunting_if_bleeding
  1636. echo(" @stop_on_bleeding: #{@stop_on_bleeding}") if $debug_mode_ct
  1637.  
  1638. @cambrinth = settings.cambrinth
  1639. echo(" @cambrinth: #{@cambrinth}") if $debug_mode_ct
  1640.  
  1641. @stored_cambrinth = settings.stored_cambrinth
  1642. echo(" @stored_cambrinth: #{@stored_cambrinth}") if $debug_mode_ct
  1643.  
  1644. @cambrinth_cap = settings.cambrinth_cap
  1645. echo(" @cambrinth_cap: #{@cambrinth_cap}") if $debug_mode_ct
  1646.  
  1647. @use_weak_attacks = settings.use_weak_attacks
  1648. echo(" @use_weak_attacks: #{@use_weak_attacks}") if $debug_mode_ct
  1649.  
  1650. @analyze_combo_type = settings.analyze_combo_type
  1651. echo(" @analyze_combo_type: #{@analyze_combo_type}") if $debug_mode_ct
  1652. end
  1653.  
  1654. def next_clean_up_step
  1655. case @clean_up_step
  1656. when nil
  1657. @clean_up_step = if @stop_on_bleeding && bleeding?
  1658. 'clear_magic'
  1659. else
  1660. 'kill'
  1661. end
  1662. when 'kill'
  1663. @clean_up_step = 'clear_magic'
  1664. when 'clear_magic'
  1665. @clean_up_step = 'stow'
  1666. when 'stow'
  1667. @clean_up_step = 'done'
  1668. end
  1669. end
  1670.  
  1671. def cleaning_up?
  1672. !@clean_up_step.nil?
  1673. end
  1674.  
  1675. def finish_killing?
  1676. @clean_up_step == 'kill'
  1677. end
  1678.  
  1679. def finish_spell_casting?
  1680. @clean_up_step == 'clear_magic'
  1681. end
  1682.  
  1683. def stowing?
  1684. @clean_up_step == 'stow'
  1685. end
  1686.  
  1687. def done_cleaning_up?
  1688. @clean_up_step == 'done'
  1689. end
  1690.  
  1691. def update_weapon_info(weapon_skill)
  1692. @last_weapon_skill = @current_weapon_skill
  1693. @current_weapon_skill = weapon_skill
  1694. end
  1695.  
  1696. def weapon_skill
  1697. @current_weapon_skill
  1698. end
  1699.  
  1700. def dance
  1701. update_weapon_info(@dance_skill)
  1702. end
  1703.  
  1704. def skill_done?
  1705. current_exp = DRSkill.getxp(weapon_skill)
  1706. echo("action count: #{@action_count} vs #{@target_action_count}") if $debug_mode_ct
  1707. echo("skill exp: #{current_exp} vs #{@target_weapon_skill}") if $debug_mode_ct
  1708.  
  1709. @action_count >= @target_action_count || current_exp >= @target_weapon_skill
  1710. end
  1711.  
  1712. def update_room_npcs
  1713. @dancing = npcs.length <= @dance_threshold || npcs.empty?
  1714. @retreating = @retreat_threshold && npcs.length >= @retreat_threshold
  1715. end
  1716.  
  1717. def retreat_weapons
  1718. weapon_training.select { |skill, _| $ranged_skills.include?(skill) }
  1719. end
  1720.  
  1721. def summoned_info(weapon_skill)
  1722. @summoned_weapons.find { |summoned_skill| summoned_skill['name'] == weapon_skill }
  1723. end
  1724.  
  1725. def update_target_weapon_skill
  1726. @target_weapon_skill = [34, DRSkill.getxp(current_weapon_skill) + @target_increment].min
  1727. end
  1728.  
  1729. def current_weapon_stance
  1730. @stances[weapon_skill]
  1731. end
  1732.  
  1733. def skinnable?(mob_noun)
  1734. !@no_skins.include?(mob_noun)
  1735. end
  1736.  
  1737. def unskinnable(mob_noun)
  1738. echo("adding #{mob_noun} to no skin list: #{@no_skins}") if $debug_mode_ct
  1739. @no_skins.push(mob_noun)
  1740. end
  1741.  
  1742. def construct?(mob_noun)
  1743. @constructs.include?(mob_noun)
  1744. end
  1745.  
  1746. def construct(mob_noun)
  1747. @constructs.push(mob_noun)
  1748. end
  1749.  
  1750. def stabbable?(mob_noun)
  1751. !@no_stab_mobs.include?(mob_noun)
  1752. end
  1753.  
  1754. def unstabbable(mob_noun)
  1755. @no_stab_mobs.push(mob_noun)
  1756. end
  1757.  
  1758. def lootable?(item)
  1759. !@no_loot.include?(item.downcase)
  1760. end
  1761.  
  1762. def unlootable(item)
  1763. @no_loot.push(item.downcase)
  1764. end
  1765.  
  1766. def weapon_training
  1767. @weapons_to_train
  1768. end
  1769.  
  1770. def weapon_name
  1771. weapon_training[weapon_skill]
  1772. end
  1773.  
  1774. def last_weapon_name
  1775. weapon_training[@last_weapon_skill]
  1776. end
  1777.  
  1778. def thrown_skill?
  1779. $thrown_skills.include?(weapon_skill)
  1780. end
  1781.  
  1782. def aimed_skill?
  1783. $aim_skills.include?(weapon_skill)
  1784. end
  1785.  
  1786. def bound_weapon?
  1787. item = EquipmentManager.instance.item_by_desc(weapon_name)
  1788. item && item.bound
  1789. end
  1790.  
  1791. def offhand?
  1792. weapon_skill == 'Offhand Weapon'
  1793. end
  1794.  
  1795. def brawling?
  1796. weapon_skill == 'Brawling'
  1797. end
  1798.  
  1799. def use_stealth_attack?
  1800. @use_stealth_attacks && use_stealth?
  1801. end
  1802.  
  1803. def ambush?
  1804. @ambush && DRSkill.getxp('Backstab') < 34
  1805. end
  1806.  
  1807. def backstab?
  1808. @backstab.include?(weapon_skill)
  1809. end
  1810.  
  1811. def dancing?
  1812. @dancing
  1813. end
  1814.  
  1815. def retreating?
  1816. @retreating
  1817. end
  1818.  
  1819. def charged_maneuver
  1820. @charged_maneuvers[weapon_skill]
  1821. end
  1822.  
  1823. def fatigue_low?
  1824. echo("***Fatigue: #{DRStats.fatigue}***") if $debug_mode_ct
  1825. echo("***Target: #{@fatigue_regen_threshold}***") if $debug_mode_ct
  1826. DRStats.fatigue < @fatigue_regen_threshold
  1827. end
  1828.  
  1829. def reset_action_count
  1830. @action_count = 0
  1831. end
  1832.  
  1833. def action_taken
  1834. @action_count += 1
  1835. end
  1836.  
  1837. def set_aim_queue
  1838. echo("set_aim_queue #{@aim_fillers}:#{@aim_fillers_stealth}") if $debug_mode_ct
  1839.  
  1840. @aim_queue = aim_stealth? ? @aim_fillers_stealth[weapon_skill].dup : @aim_fillers[weapon_skill].dup
  1841. end
  1842.  
  1843. def clear_aim_queue
  1844. @aim_queue = []
  1845. end
  1846.  
  1847. def done_aiming?
  1848. @aim_queue.empty?
  1849. end
  1850.  
  1851. def next_aim_action
  1852. @aim_queue.shift
  1853. end
  1854.  
  1855. def set_dance_queue
  1856. return unless @dance_queue.empty?
  1857.  
  1858. echo("set_dance_queue #{@dance_actions}:#{@dance_actions_stealth}") if $debug_mode_ct
  1859.  
  1860. @dance_queue = dance_stealth? ? @dance_actions_stealth.dup : @dance_actions.dup
  1861. end
  1862.  
  1863. def next_dance_action
  1864. @dance_queue.shift
  1865. end
  1866.  
  1867. def cambrinth_charges(cambrinth)
  1868. @charges = cambrinth.nil? || cambrinth.empty? ? nil : cambrinth.dup
  1869. end
  1870.  
  1871. def check_charging?
  1872. return false if @charges.nil?
  1873.  
  1874. find_cambrinth(@cambrinth, @stored_cambrinth, @cambrinth_cap)
  1875. if @charges.empty?
  1876. echo('check_charging?: done') if $debug_mode_ct
  1877.  
  1878. cambrinth_charges(nil)
  1879. invoke(@cambrinth)
  1880. else
  1881. next_charge = @charges.pop
  1882. echo("check_charging?: #{next_charge}") if $debug_mode_ct
  1883.  
  1884. charge(@cambrinth, next_charge)
  1885. end
  1886. stow_cambrinth(@cambrinth, @stored_cambrinth, @cambrinth_cap)
  1887.  
  1888. true
  1889. end
  1890.  
  1891. def npcs
  1892. DRRoom.npcs - @ignored_npcs
  1893. end
  1894.  
  1895. def dual_load?
  1896. @dual_load && weapon_skill == 'Bow'
  1897. end
  1898.  
  1899. def prepare_summoned_weapon(weapon_already_summoned)
  1900. info = summoned_info(weapon_skill)
  1901.  
  1902. summon_weapon(UserVars.moons['visible'].first, @summoned_weapons_element, @summoned_weapons_ingot, weapon_skill) unless weapon_already_summoned
  1903. shape_summoned_weapon(weapon_skill, @summoned_weapons_ingot) if weapon_already_summoned || DRStats.moon_mage?
  1904. turn_summoned_weapon if info['turn']
  1905. push_summoned_weapon if info['push']
  1906. pull_summoned_weapon if info['pull']
  1907. end
  1908.  
  1909. def can_ambush_stun?
  1910. !npcs.empty? && !aimed_skill?
  1911. end
  1912.  
  1913. def use_weak_attacks?
  1914. @use_weak_attacks
  1915. end
  1916.  
  1917. def stop_weak_attacks
  1918. @use_weak_attacks = false
  1919. end
  1920.  
  1921. def stop_analyze_combo
  1922. @analyze_combo_type = nil
  1923. end
  1924.  
  1925. def melee_attack_verb
  1926. if $arena
  1927. arena_enemy = fput "watch #{game_state.npcs.first}"
  1928. echo arena_enemy
  1929. fput 'pedal' if arena_enemy.include? 'pedal'
  1930. fput 'duck' if arena_enemy.include? 'duck'
  1931. fput 'lean' if arena_enemy.include? 'lean'
  1932. fput 'bob' if arena_enemy.include? 'bob'
  1933. fput 'cower' if arena_enemy.include? 'cower'
  1934. fput 'jump' if arena_enemy.include? 'jump'
  1935. end
  1936. if use_weak_attacks?
  1937. brawling? ? 'punch' : 'jab'
  1938. elsif !@analyze_combo_type.nil? && !offhand? && !brawling?
  1939. update_analyze_array if @analyze_combo_array.empty?
  1940. @analyze_combo_array.shift
  1941. else
  1942. 'attack'
  1943. end
  1944. end
  1945.  
  1946. private
  1947.  
  1948. def update_analyze_array
  1949. result = bput("analyze #{@analyze_combo_type}", 'Analyze what\?', 'by landing a .*')
  1950. waitrt?
  1951.  
  1952. case result
  1953. when 'Analyze what?'
  1954. fput('face next')
  1955. return []
  1956. end
  1957.  
  1958. text = result.match(/by landing a (.*)\.$/).to_a[1]
  1959. @analyze_combo_array = list_to_nouns(text)
  1960. end
  1961.  
  1962. def dance_stealth?
  1963. @dance_actions_stealth && !@dance_actions_stealth.empty? && use_stealth?
  1964. end
  1965.  
  1966. def aim_stealth?
  1967. @aim_fillers_stealth && @aim_fillers_stealth[weapon_skill] && use_stealth?
  1968. end
  1969.  
  1970. def use_stealth?
  1971. DRSkill.getxp('Stealth') < 32
  1972. end
  1973.  
  1974. 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
  1975. 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
  1976. end
  1977.  
  1978. $COMBAT_TRAINER = CombatTrainer.new
  1979. $COMBAT_TRAINER.start_combat
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement