Advertisement
Guest User

Untitled

a guest
Dec 4th, 2015
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 61.93 KB | None | 0 0
  1. =begin
  2.  
  3. bigshot.lic: the new optimus prime
  4.  
  5. hunting script for hunting
  6.  
  7. author: Sheikhh
  8. contributers: SpiffyJr, Tillmen
  9. game: Gemstone
  10. tags: hunting
  11. version: 3.0
  12.  
  13. changelog:
  14. 3.0 (2015-05-30):
  15. stop trying to attack monsters that aren't in the room (wild guess, untested)
  16. bumped version up from 2.12052012 to 3.0, because 2.12052012 is a stupid version format
  17. added message to trust script
  18.  
  19. =end
  20.  
  21. # FIXME: Use new empty_hand(s)/fill_hand(s)
  22. # FIXME: Is poaching?() redundant?
  23. # FIXME: Instead of the head reiterating :ATTACK to tail every 15 seconds, have the tail loop upon :ATTACK until the room id changes
  24.  
  25. $bigshot_debug = false
  26.  
  27. if $SAFE > 0
  28. echo "error: This script needs to be trusted to work. (;trust #{script.name})"
  29. exit
  30. end
  31.  
  32. require 'drb'
  33.  
  34. # fixme: these constants and global variables could conflict with other scripts
  35. BIGSHOT_VERSION ||= '3.0'
  36. RALLY_TIME ||= 5
  37. REST_INTERVAL ||= 30
  38. $rest_reason = nil
  39. $not_hunting_reason = nil
  40. $bigshot_status = nil
  41. $bigshot_should_rest = false
  42.  
  43. def spam
  44. def waitcastrt?
  45. return if Spell[515].active?
  46. if (XMLData.cast_roundtime_end.to_f - Time.now.to_f + XMLData.server_time_offset.to_f) > 0
  47. sleep((XMLData.cast_roundtime_end.to_f - Time.now.to_f + XMLData.server_time_offset.to_f).abs)
  48. end
  49. end
  50.  
  51. def waitrt?
  52. if (XMLData.roundtime_end.to_f - Time.now.to_f + XMLData.server_time_offset.to_f) > 0
  53. sleep((XMLData.roundtime_end.to_f - Time.now.to_f + XMLData.server_time_offset.to_f).abs)
  54. end
  55. end
  56. end
  57.  
  58. def unspam
  59. def waitcastrt?
  60. if (XMLData.cast_roundtime_end.to_f - Time.now.to_f + XMLData.server_time_offset.to_f) > 0
  61. sleep((XMLData.cast_roundtime_end.to_f - Time.now.to_f + XMLData.server_time_offset.to_f + "0.6".to_f).abs)
  62. end
  63. end
  64.  
  65. def waitrt?
  66. if (XMLData.roundtime_end.to_f - Time.now.to_f + XMLData.server_time_offset.to_f) > 0
  67. sleep((XMLData.roundtime_end.to_f - Time.now.to_f + XMLData.server_time_offset.to_f + "0.6".to_f).abs)
  68. end
  69. end
  70. end
  71.  
  72. before_dying { unspam() }
  73. before_dying { $bigshot.gather_ammo }
  74.  
  75. class Event
  76. attr_accessor :type, :created_at, :room_id
  77. @@RECOGNIZED = [ :HUNTING_PREP_COMMANDS, :HUNTING_SCRIPTS_START, :CAST_SIGNS, :ATTACK,
  78. :HUNTING_SCRIPTS_STOP, :RESTING_SCRIPTS_START, :RESTING_PREP_COMMANDS, :DISPLAY_WATCH ]
  79.  
  80. def initialize( type, time_stamp, room_id )
  81. raise "Event type not recognized" unless @@RECOGNIZED.include?(type)
  82. @type = type
  83. @created_at = time_stamp
  84. @room_id = room_id
  85. end
  86.  
  87. def stale?
  88. if( Room.current.id != @room_id || Time.now.to_i - @created_at > 15 )
  89. return true
  90. else
  91. return false
  92. end
  93. end
  94.  
  95. def type
  96. return @type
  97. end
  98. end
  99.  
  100. class Group
  101. include DRbUndumped
  102. attr_accessor :leader, :members
  103.  
  104. def initialize()
  105. @members = Hash.new
  106. end
  107.  
  108. def set_leader(leader)
  109. @leader = leader
  110. end
  111.  
  112. def add_member(member)
  113. @members[member.name()] = member
  114. end
  115.  
  116. def size()
  117. return @members.size
  118. end
  119.  
  120. def get_names
  121. return @members.keys + [@leader.name]
  122. end
  123.  
  124. def room_id()
  125. return @leader.room_id()
  126. end
  127.  
  128. def add_event(type)
  129. @members.each_pair { |k,v|
  130. begin
  131. v.add_event( type, Time.now.to_i, Room.current.id )
  132. rescue
  133. @leader.message("Error adding #{type.to_s} event to members stack: #{$!}")
  134. @leader.message($!.backtrace.join("\n"))
  135. end
  136. }
  137. end
  138.  
  139. def add_leader_event(event)
  140. @leader.add_event( Event.new(event) ) unless @leader.event_stack.size > 5
  141. end
  142.  
  143. def roundtime?()
  144. @members.each_pair { |k,v|
  145. begin
  146. return true if v.rt? > 0
  147. rescue
  148. @leader.message("Error polling member for RT. Removing!")
  149. @members.delete(k)
  150. end
  151. }
  152. return false
  153. end
  154.  
  155. def should_hunt?()
  156. emergency = @leader.event_stack.size == 0 ? nil : @leader.event_stack.shift
  157. if(emergency)
  158. @leader.clear_events
  159. return false
  160. end
  161.  
  162. @members.each_pair { |k,v|
  163. begin
  164. return false if !v.should_hunt?
  165. rescue
  166. @leader.message("Error polling member. Removing!")
  167. @members.delete(k)
  168. end
  169. }
  170. $bigshot_status = :hunting
  171. return true
  172. end
  173.  
  174. def should_rest?()
  175. @members.each_pair { |k,v|
  176. begin
  177. return false if !v.should_rest?
  178. rescue
  179. @leader.message("Error polling member. Removing!")
  180. @members.delete(k)
  181. end
  182. }
  183. return true
  184. end
  185.  
  186. def emergency_rest?()
  187. @members.each_pair { |k,v|
  188. begin
  189. return true if v.wounded?
  190. rescue
  191. @leader.message("Error polling member. Removing!")
  192. @members.delete(k)
  193. end
  194. }
  195. return false
  196. end
  197. end
  198.  
  199. class Bigshot
  200. include DRbUndumped
  201. attr_accessor :BIRTH_TIME, :START_TIME, :STORED_TIMES, :FRIED, :OOM,
  202. :SIGNS, :TARGETS, :INVALID_TARGETS, :FLEE_COUNT, :ALWAYS_FLEE_FROM,
  203. :USE_WRACKING, :AMMO, :AMMO_CONTAINER, :HIDE_FOR_AMMO,
  204. :REST_TILL_EXP, :REST_TILL_MANA, :USE_HERBS, :DEAD_MAN_SWITCH,
  205. :RESTING_ROOM_ID, :RESTING_COMMANDS, :RESTING_SCRIPTS, :HUNTING_ROOM_ID,
  206. :HUNTING_BOUNDARIES, :HUNTING_SCRIPTS, :HUNTING_COMMANDS,
  207. :DISABLE_COMMANDS, :HUNTING_STANCE, :HUNTING_PREP_COMMANDS,
  208. :MONITOR_INTERACTION, :FLEE_CLOUDS, :WRACKING_SPIRIT,
  209. :REST_TILL_SPIRIT, :BOUNTY_MODE,
  210. :event_stack, :followers
  211.  
  212. PRONE = /sleeping|webbed|stunned|kneeling|sitting|^lying|prone/
  213.  
  214. def add_event( type, time_stamp, room_id )
  215. unless( @event_stack.size > 5 && type == :ATTACK )
  216. @event_stack.push( Event.new( type, time_stamp, room_id ) )
  217. end
  218. end
  219.  
  220. def grab_event()
  221. @event_stack.shift()
  222. end
  223.  
  224. def clear_events()
  225. @event_stack.clear
  226. end
  227.  
  228. def initialize(bounty_mode=nil)
  229. $bigshot = self
  230. if bounty_mode
  231. @BOUNTY_MODE = true
  232. end
  233.  
  234. UserVars.op ||= Hash.new
  235. CharSettings['targetable'] ||= Array.new
  236. CharSettings['untargetable'] ||= Array.new
  237. @BIRTH_TIME = Time.now.to_i
  238. @START_TIME = 1
  239. @STORED_TIMES = Array.new
  240.  
  241. @followers = nil
  242. @event_stack = Array.new
  243.  
  244. load_settings()
  245. dead_man_switch()
  246.  
  247. # this is mainly for azbounty:
  248. before_dying {
  249. @HUNTING_SCRIPTS.each { |i|
  250. echo "Cleaning up hunting scripts: #{i}."
  251. stop_script(i) if running?(i)
  252. }
  253. }
  254.  
  255. end
  256.  
  257. def load_settings()
  258. set_value_required( 'hunting_commands', 'split_xx' )
  259. set_value_required( 'fried', 'to_i' )
  260. set_value_required( 'oom', 'to_i' )
  261. set_value_required( 'rest_till_mana', 'to_i' )
  262. set_value_required( 'rest_till_exp', 'to_i' )
  263.  
  264. set_value( 'hunting_room_id', 'to_i', 4 )
  265. set_value( 'resting_room_id', 'to_i', 4 )
  266. set_value( 'hunting_boundaries', 'split', Array.new )
  267. set_value( 'hunting_commands_b', 'split_xx', Array.new )
  268. set_value( 'hunting_commands_c', 'split_xx', Array.new )
  269. set_value( 'disable_commands', 'split_xx', Array.new )
  270.  
  271. set_value( 'targets', 'targets', nil )
  272. set_value( 'dead_man_switch', '', false )
  273. set_value( 'monitor_interaction', '', false )
  274. set_value( 'depart_switch', '', false )
  275. set_value( 'encumbered', 'to_i', 200 )
  276. set_value( 'signs', 'split', Array.new )
  277. set_value( 'spam', '', true )
  278. set_value( 'flee_count', 'to_i', 10 )
  279. set_value( 'wracking_spirit', 'to_i', 0 )
  280. set_value( 'invalid_targets', 'split', Array.new )
  281. set_value( 'always_flee_from', 'split', Array.new )
  282. set_value( 'flee_clouds', '', false )
  283. set_value( 'use_wracking', '', false )
  284. set_value( 'lone_targets_only', '', false )
  285. set_value( 'rest_till_spirit', 'to_i', 0 )
  286. set_value( 'ammo', '', nil )
  287. set_value( 'ammo_container', '', nil )
  288. set_value( 'fresh_wand_container', '', nil )
  289. set_value( 'dead_wand_container', '', nil )
  290. set_value( 'wand', '', nil )
  291. set_value( 'wand_if_oom', '', false )
  292. set_value( 'hide_for_ammo', '', nil )
  293. set_value( 'wounded_eval', '', nil )
  294. set_value( 'resting_scripts', 'split', Array.new )
  295. set_value( 'hunting_scripts', 'split', Array.new )
  296. set_value( 'loot_script', '', nil )
  297. set_value( 'hunting_stance', '', 'defensive')
  298. set_value( 'resting_commands', 'split_xx', Array.new )
  299. set_value( 'hunting_prep_commands', 'split_xx', Array.new )
  300. end
  301.  
  302. def clean_value( clean, value )
  303. if( clean == 'to_i' )
  304. return value.to_i
  305. elsif( clean == 'split' )
  306. return value.split(/,\s*/)
  307. elsif( clean == 'split_xx' )
  308. cleaned = Array.new
  309. value.split(/,\s*/).each { |i|
  310. rep = 1
  311. cmd = ''
  312. if( i =~ /(.*)\(x(\d+)\)$/ )
  313. rep = $2.to_i
  314. cmd = $1
  315. elsif( i =~ /(.*)\(xx\)/ )
  316. rep = 5
  317. cmd = $1
  318. else
  319. cmd = i
  320. end
  321. and_tokens = cmd.split(/\sand\s/)
  322. cmd = and_tokens.size == 1 ? and_tokens[0] : and_tokens
  323. rep.times do cleaned.push(cmd) end
  324. }
  325. return cleaned
  326. elsif( clean == 'targets' )
  327. targets = Hash.new
  328. tokens = value.split(/,/)
  329. tokens.each do |i|
  330. if( i =~ /(.*)\(([a|b|c|A|B|C])\)/ )
  331. targets[$1.downcase.strip] = $2.downcase.strip
  332. else
  333. targets[i.downcase.strip] = 'a'
  334. end
  335. end
  336. return targets
  337. else
  338. return value
  339. end
  340. end
  341.  
  342. def set_value( key, clean, default )
  343. if( !UserVars.op[key].nil? && UserVars.op[key] !~ /^\s*$/ )
  344. cleaned = clean_value( clean, UserVars.op[key] )
  345. instance_variable_set( "@#{key.upcase}", cleaned )
  346. else
  347. instance_variable_set( "@#{key.upcase}", default )
  348. end
  349. end
  350.  
  351. def set_value_required( key, clean )
  352. if( !UserVars.op[key].nil? && UserVars.op[key] !~ /^\s*$/ )
  353. set_value( key, clean, nil )
  354. else
  355. message("ERROR: Missing required setting: #{key}")
  356. message("(fried? is percenthealth and oom is percentmana)")
  357. Script.self.kill
  358. end
  359. end
  360.  
  361. def cmd( command, npc = nil, stance_dance = true )
  362. command = command.dup
  363.  
  364. if( command.class.to_s == 'Array' )
  365. stance_dance = false if command.any? { |j| j =~ /stance/ }
  366. command.each do |i|
  367. echo i if $bigshot_debug
  368. cmd( i, npc, stance_dance )
  369. end
  370. return
  371. end
  372.  
  373. # check mana/stamina
  374. if( command =~ /(.*)\(([s|m])(\d+)\)$/ )
  375. if( $2 == 's' )
  376. return if !checkstamina($3.to_i)
  377. elsif( $2 == 'm' )
  378. return if !checkmana($3.to_i)
  379. end
  380. command = $1
  381. end
  382.  
  383. if( command =~ /force\s+(.*)\s+(?:till|until)\s+(\d+)/ )
  384. cmd_force( $1, $2.to_i, npc )
  385. return
  386. end
  387.  
  388. # sub id
  389. command.gsub!( /target/, "##{npc.id}" ) if !npc.nil?
  390.  
  391. # waitrt/waitcastrt
  392. unless( command =~ /^nudgeweapons?/ )
  393. waitrt?
  394. waitcastrt? if command =~ /^\d+|incant/
  395. end
  396.  
  397. # change_stance
  398. stand()
  399. unless( command =~ /^(?:\d+|wait|sleep|wand|berserk|script|hide|nudgeweapon)/ )
  400. change_stance(@HUNTING_STANCE) if stance_dance
  401. end
  402.  
  403. return if npc && !valid_target?(npc)
  404.  
  405. if( command =~ /^(\d+)(.*)$/ )
  406. cmd_spell( $1.to_i, $2.strip, npc )
  407. elsif( command =~ /^throw/i )
  408. cmd_throw( npc )
  409. elsif( command =~ /^k?weed/i )
  410. cmd_weed( command, npc )
  411. elsif( command =~ /^wand\s+(.*)/i )
  412. cmd_wand(npc)
  413. elsif( command =~ /^hide/i )
  414. cmd_hide()
  415. elsif( command =~ /^mstrike/i )
  416. cmd_mstrike( command, npc )
  417. elsif( command =~ /^fire/i )
  418. cmd_ranged(npc)
  419. elsif( command =~ /^berserk/i )
  420. cmd_berserk()
  421. elsif( command =~ /^script\s+(.*?)(\s|$)(.*)/i )
  422. cmd_run_script( $1, $3 )
  423. elsif( command =~ /^sleep\s+(\d+)/i )
  424. cmd_sleep( $1, npc )
  425. elsif( command =~ /^stance\s+(.*)/i )
  426. change_stance($1)
  427. elsif( command =~ /^wait\s+(\d+)/i )
  428. wait_for_swing( $1.to_i, npc )
  429. elsif( command =~ /^nudgeweapons?\s*/i )
  430. cmd_nudge_weapons
  431. else
  432. return if command =~ /1030/ && checkmana < 10
  433. return if $ambusher_here
  434. echo "inside cmd: #{command}" if $bigshot_debug
  435. bs_put command
  436. end
  437. end
  438.  
  439. def cmd_throw( npc )
  440. unless npc.status == 'lying down'
  441. empty_hands
  442. dothistimeout "throw ##{npc.id}", 1, /^You attempt to throw a .*\!$/
  443. waitrt?
  444. fill_hands
  445. end
  446. end
  447.  
  448. def cmd_force( force_this, goal, npc )
  449. start = Time.now
  450. loop {
  451. cmd( force_this, npc )
  452. buffer = reget(20)
  453. buffer.each_with_index { |line, i|
  454. if( line =~ /^You.*(#{checknpcs.join('|')})(\.|!)|^You feint (high|low|(to the (left|right)))/ )
  455. if buffer[i + 1] && buffer[i + 1] =~ /== \+(\d+)/
  456. return if $1.to_i >= goal # spell/swing
  457. elsif buffer[i - 1] && buffer[i - 1] =~ /^\[Roll result: (\d+)/
  458. return if $1.to_i >= goal # cman
  459. elsif buffer[i + 1] =~ /^As you focus on your magic, your vision swims with a swirling haze of crimson/
  460. return
  461. end
  462. elsif( line =~ /^You do not have enough stamina to attempt this maneuver\./ )
  463. return
  464. elsif( line =~ /^Your magic fizzles ineffectually\./ )
  465. return
  466. end
  467. }
  468. if ( force_this =~ /^(\d+) / && !Spell[$1.to_i].affordable? )
  469. message("Force ran out of mana. Giving up."); return;
  470. end
  471. return if GameObj.npcs.size.nil? || GameObj.npcs.size == 0
  472. return if should_flee?
  473. return if should_rest?
  474. return if npc.status =~ /dead|gone/
  475. return if ( Time.now - start ) > 30
  476. }
  477. end
  478.  
  479. def cmd_weed( command, target )
  480. return if target.status =~ /dead|gone/
  481. return if GameObj.loot.find { |loot| loot.name =~ /vine/ }
  482. return unless Spell[610].known? and Spell[610].affordable?
  483.  
  484. waitcastrt?
  485. change_stance('offensive') if command == 'kweed'
  486. Spell[610].cast("##{target.id}")
  487. change_stance('guarded') if command == 'kweed'
  488. waitcastrt?
  489. end
  490.  
  491. def cmd_spell( id, target_id, target )
  492. if ( checkprep != "None" and checkprep != Spell[id].name )
  493. fput 'release'
  494. end
  495.  
  496. return if id == 506 and Spell[506].active?
  497. return if id == 9605 and Spell[9606].active? # surge cooldown
  498. return if target.status =~ /dead|gone/
  499. unless( Spell[id].affordable? )
  500. if(@WAND_IF_OOM)
  501. cmd_wand(target); return;
  502. end
  503. if(@USE_WRACKING)
  504. wrack()
  505. end
  506. end
  507.  
  508. if ( !Spell[id].affordable? and id != 9605 and id != 506 )
  509. $bigshot_should_rest = true
  510. $rest_reason = "out of mana"
  511. end
  512. waitcastrt?
  513. Spell[id].cast(target_id)
  514. end
  515.  
  516. def cmd_wand(target)
  517. if(@FRESH_WAND_CONTAINER)
  518. hands = GameObj.right_hand.name.to_s + GameObj.left_hand.name.to_s
  519. wand = ( @WAND && @WAND !~ /^\s*$/ ) ? @WAND : 'wand'
  520. until( (GameObj.right_hand.name.to_s + GameObj.left_hand.name.to_s) =~ /#{wand}/i )
  521. result = dothistimeout( "get #{wand} from my #{@FRESH_WAND_CONTAINER}", 3, /You remove|You slip|Get what/ )
  522. if( result =~ /Get what/ )
  523. message("ERROR: Couldn't find fresh wand. Gonna rest."); $bigshot_should_rest = true; return;
  524. elsif(result.nil?)
  525. message("ERROR: Timed out looking for wand."); return;
  526. end
  527. end
  528.  
  529. change_stance('offensive')
  530. result = dothistimeout( "wave my wand at ##{target.id}", 2, /d100|You hurl|is already dead|You do not see that here|You are in no condition|I could not find|Wait/ )
  531. change_stance('defensive')
  532.  
  533. if( result =~ /You are in no condition/ )
  534. message("ERROR: Wounded. Gonna rest."); $bigshot_should_rest = true; return;
  535. elsif(result.nil?)
  536. if(@DEAD_WAND_CONTAINER)
  537. bs_put "put my wand in my #{@DEAD_WAND_CONTAINER}"
  538. else
  539. bs_put "drop my wand"
  540. end
  541. end
  542. else
  543. message("ERROR: Wand command called but fresh wand container not defined.")
  544. end
  545. end
  546.  
  547. def cmd_hide()
  548. tries = 0
  549. until(hiding?)
  550. break if tries > 3 || should_flee?
  551. change_stance('defensive')
  552. bs_put 'hide'; tries += 1;
  553. end
  554. end
  555.  
  556. def cmd_mstrike( command, target )
  557. if( !Spell[9005].active? && Skills.multiopponentcombat >= 30 && GameObj.npcs.all? { |i| i.noun !~ /nest/i } )
  558. if( GameObj.npcs.size > 1 and target.nil? )
  559. bs_put "mstrike"
  560. else
  561. bs_put "mstrike ##{target.id}"
  562. end
  563. else
  564. bs_put "kill ##{target.id}"
  565. end
  566. end
  567.  
  568. def cmd_ranged(npc)
  569. waitrt?
  570.  
  571. result = dothistimeout "get 1 my #{@AMMO.sub(/s$/, '')}", 2, /You remove|Get what\?|You already/
  572. if( result =~ /Get what\?/ )
  573. $bigshot_should_rest = true
  574. $rest_reason = "Out of ammo"
  575. return
  576. end
  577.  
  578. result = dothistimeout(
  579. "fire ##{npc.id}",
  580. 2,
  581. /You fire|You cannot|Could not find|seconds|Get what?/
  582. )
  583. if( result =~ /^Could not find/ )
  584. #$bigshot_should_rest = true
  585. #$rest_reason = "Out of ammo"
  586. gather_ammo
  587. elsif( result =~ /You cannot fire/ )
  588. unless GameObj.right_hand.id.nil?
  589. line = dothistimeout "stow ##{GameObj.right_hand.id}", 3, /put|closed/
  590. if line =~ /closed/
  591. fput "open my #{@AMMO_CONTAINER}"
  592. fput "put ##{GameObj.right_hand.id} in my ##{@AMMO_CONTAINER}"
  593. end
  594. end
  595. elsif( result =~ /but it has no effect/ )
  596. $bigshot_should_rest = true
  597. $rest_reason = "Ammo had no effect (need blessed or magical)"
  598. elsif ( result == false )
  599. $bigshot_should_rest = true
  600. $rest_reason = "Unknown result from fire routine: #{result}"
  601. end
  602. end
  603.  
  604. def cmd_berserk()
  605. if( checkstamina(20) )
  606. put 'stance def'
  607. until( get =~ /^Everything around you turns red|^You scream/ )
  608. bs_put 'berserk'
  609. end
  610. until( get =~ /^The redness fades from the world/ )
  611. break if checkmind(7)
  612. end
  613. else
  614. bs_put 'target random'; bs_put 'kill';
  615. end
  616. end
  617.  
  618. def cmd_run_script( name, args )
  619. if( args == nil || args =~ /^\s*$/ )
  620. run_script( name, true )
  621. else
  622. args = args.split(/ /)
  623. run_script( name, true, args )
  624. end
  625. end
  626.  
  627. def cmd_sleep( time, npc )
  628. change_stance('defensive')
  629. time.to_i.times do
  630. sleep 1
  631. break if should_rest?
  632. break if npc && npc.status =~ /dead|gone/
  633. end
  634. end
  635.  
  636. def cmd_nudge_weapons()
  637. return if checkpaths.size == 0
  638.  
  639. GameObj.loot.each { |i|
  640. next unless i.noun =~ /axe|scythe|pitchfork|falchion|sword|lance|sword|dagger|estoc|falchion|handaxe|katana|katar|gauche|rapier|scimitar|whip-blade|cudgel|crowbill|whip|mace|star|hammer|claidhmore|flail|flamberge|maul|pick|staff|mattock/
  641. change_stance('defensive')
  642.  
  643. sheathed = false
  644. unless( righthand.nil? || lefthand.nil? )
  645. sheathed = true
  646. fput 'sheath'
  647. unless( righthand.nil? || lefthand.nil? )
  648. message("Unable to empty hands via sheath.")
  649. return
  650. end
  651. end
  652.  
  653. dirs = checkpaths
  654. dir = checkpaths.shift
  655. fput "get ##{i.id}"
  656. put dir
  657. put "drop ##{i.id}"
  658. fput reverse_direction(dir)
  659. fput "gird" if sheathed
  660. }
  661. end
  662.  
  663. def message(text)
  664. string = ''
  665. if $fake_stormfront then string.concat("\034GSL\r\n ") else string.concat("<pushBold\/>") end
  666. if( text.index('\n') )
  667. text.split('\n').each { |line| string.concat("| #{line}") }
  668. else
  669. string.concat('| ' + text)
  670. end
  671. if $fake_stormfront then string.concat("\034GSM\r\n ") else string.concat("<popBold\/>") end
  672. puts string
  673. end
  674.  
  675. def dead_man_switch()
  676. if @DEAD_MAN_SWITCH
  677. Thread.new {
  678. while( running?('bigshot') )
  679. if( dead? || percenthealth < 40 )
  680. echo 'AUTOBOT ALERT: Your character is in trouble!'
  681. fput 'quit'
  682. end
  683. sleep 2
  684. end
  685. };
  686. elsif @DEPART_SWITCH
  687. start_exec_script( <<-EOF
  688. while( running?('bigshot') );
  689. if(dead?);
  690. stop_script('bigshot');
  691. fput 'depart'; fput 'depart';
  692. fput 'depart confirm'; fput 'depart confirm';
  693. start_script('waggle');
  694. 15.times { sleep 60; fput info; };
  695. sleep 1 until percentspirit == 100 && !running?('waggle');
  696. start_script( 'bigshot', ['solo'] );
  697. Script.self.kill;
  698. end;
  699. sleep 5;
  700. end;
  701. EOF
  702. );
  703. else
  704. Thread.new {
  705. loop { Script.self.kill if dead?; sleep 5; }
  706. }
  707. end
  708. end
  709.  
  710. def keep_awake()
  711. Thread.new {
  712. while( running?('bigshot') )
  713. sleep 150; put 'look';
  714. end
  715. }
  716. end
  717.  
  718. def monitor_interaction()
  719. if @MONITOR_INTERACTION
  720. start_exec_script( <<-eos
  721. def show_window(line);
  722. window_title = Char.name + ':' + line;
  723. Gtk.queue {
  724. $myWindow = Gtk::Window.new;
  725. $myWindow.title = "Autobot Alert!";
  726. $myWindow.set_size_request(450, 25);
  727. label = Gtk::Label.new window_title;
  728. $myWindow.add(label);
  729. $myWindow.show_all;
  730. };
  731. end;
  732. while(line = get);
  733. break unless running?('bigshot');
  734. if(line =~ /SEND|POLICY|[Rr](\s)*[Ee](\s)*[Pp](\s)*[Oo](\s)*[Rr](\s)*[Tt]|peaking to you|unresponsive|taps you|nods to you|lease respond|not in control|character|violation|lease speak|peak out loud|Y U SHOU D|whispers,|speaking to you|smiles at you|waves to you|grins at you|hugs you|takes hold your hand|grabs your hand|clasps your hand|trying to drag you/);
  735. unless(line =~ /LNet/);
  736. show_window(line);
  737. echo "AUTOBOT ALERT: " + line;
  738. end;
  739. end;
  740. end;
  741. eos
  742. )
  743. end
  744. end
  745.  
  746. def wrack()
  747. if Spell[9918].known? and not Spell[9012].active?
  748. Spell[9918].cast if checkspirit >= @WRACKING_SPIRIT
  749. elsif Spell[9718].known?
  750. ( checkstamina / 50 ).times { Spell[9718].cast }
  751. end
  752. end
  753.  
  754. def change_stance( new_stance, force = true )
  755. #return unless new_stance =~ /off/ # pookahs/bog
  756. return if Spell[1617].active? || Spell[216].active? || dead?
  757.  
  758. if( stance() =~ /#{new_stance}/ )
  759. return
  760. elsif( checkcastrt() > 0 && new_stance =~ /def/ )
  761. return if stance() == 'guarded'
  762. end
  763.  
  764. if(force)
  765. result = dothistimeout( "stance #{new_stance}", 3, /You are now in an?|Cast Round Time in effect|You are unable to change/ )
  766. else
  767. put "stance #{new_stance}"
  768. end
  769. end
  770.  
  771. def wait_for_swing( seconds, target = nil )
  772. status_tags
  773. start = Time.now
  774. swung = false
  775. while(1)
  776. change_stance( 'defensive', false ) unless target && target.status =~ PRONE
  777. stand()
  778.  
  779. pcs = checkpcs ? ' you(\.|!|r? )|' + checkpcs.join('|') : 'you(\.|!|r? )'
  780. break if clear.any? { |line| line =~ /#{target.id}.*(#{pcs})/ && line !~ /^<style id=""\/><style id="roomDesc"\/>|<component id='room objs'>|<compDef id='room objs'>/ }
  781. break if GameObj.npcs.size.nil? || GameObj.npcs.size == 0
  782. break if should_flee?
  783. break if target && target.status =~ PRONE
  784. break if ( Time.now - start ) > seconds
  785. sleep 0.50
  786. end
  787. status_tags
  788. end
  789.  
  790. def croak(message)
  791. message(message);
  792. croak_scripts( ['bigshot'] )
  793. end
  794.  
  795. def run_script( name, pause_bigshot = false, args = [] )
  796. if Script.running.find { |s| s.name.downcase == name.downcase }.paused or running? name
  797. stop_script name
  798. wait_while { running? name }
  799. end
  800.  
  801. start_script name, args
  802. if pause_bigshot
  803. wait_until { !running? name }
  804. end
  805. end
  806.  
  807. def run_scripts( scripts, pause_bigshot = false )
  808. scripts.each do |i|
  809. tokens = i.split(/\s+/)
  810. if( tokens.size > 1 )
  811. run_script( tokens[0], pause_bigshot, tokens[1..-1] )
  812. else
  813. run_script( tokens[0], pause_bigshot )
  814. end
  815. end
  816. end
  817.  
  818. def croak_script(name)
  819. kill_script(name) if running?(name)
  820. end
  821.  
  822. def croak_scripts(scripts)
  823. scripts.each { |i| croak_script(i) }
  824. end
  825.  
  826. def stand()
  827. until(standing?)
  828. change_stance('defensive')
  829. bs_put 'stand'
  830. end
  831. end
  832.  
  833. def lead( my_group = nil )
  834. monitor_interaction()
  835. @followers = my_group || Group.new()
  836.  
  837. if(should_rest?)
  838. rest()
  839. else
  840. hunt()
  841. end
  842. end
  843.  
  844. def find_routine(target)
  845. if( !solo? && fried? )
  846. return @DISABLE_COMMANDS
  847. else
  848. key = @TARGETS.keys.find { |k| target.name =~ /^#{k}$/ or target.noun =~ /^#{k}$/ }
  849. if key.nil?
  850. routine_letter = 'a'
  851. else
  852. routine_letter = @TARGETS[key]
  853. end
  854.  
  855. if routine_letter == 'c'
  856. return @HUNTING_COMMANDS_C unless @HUNTING_COMMANDS_C.size == 0
  857. elsif routine_letter == 'b'
  858. return @HUNTING_COMMANDS_B unless @HUNTING_COMMANDS_B.size == 0
  859. end
  860.  
  861. return @HUNTING_COMMANDS
  862. end
  863. end
  864.  
  865. def solo?
  866. # tails wont have followers
  867. if( @followers && @followers.size == 0 )
  868. return true
  869. else
  870. return false
  871. end
  872. end
  873.  
  874. def leading?
  875. return !following?
  876. end
  877.  
  878. def following?
  879. return @followers.nil?
  880. end
  881.  
  882. def no_players()
  883. return false if GameObj.loot.find { |obj| obj.noun == 'disk' and obj.name !~ /#{Char.name}/}
  884. return false if checkpcs or $ambusher_here
  885. return true
  886. end
  887.  
  888. def pre_hunt()
  889. # prep/go
  890. @followers.add_event(:HUNTING_PREP_COMMANDS)
  891. @HUNTING_PREP_COMMANDS.each { |i|
  892. if i =~ /^script\s+(.*?)(\s|$)(.*)/i
  893. cmd_run_script( $1, $3 )
  894. else
  895. fput(i)
  896. end
  897. }
  898.  
  899. @followers.add_event(:CAST_SIGNS)
  900. cast_signs()
  901.  
  902. @followers.add_event(:HUNTING_SCRIPTS_START)
  903. run_scripts( @HUNTING_SCRIPTS, false )
  904.  
  905. goto(@HUNTING_ROOM_ID)
  906. if( !solo? && @followers.get_names.any? { |i| !checkpcs.include?(i) } )
  907. @followers.add_event(:CAST_SIGNS) # trigger rubber band
  908. sleep 10 # wait for followers
  909. end
  910. end
  911.  
  912. def do_hunt()
  913. spam() if UserVars.op['spam']
  914.  
  915. start_watch()
  916. message('Bigshot hunting')
  917.  
  918. # loop
  919. target = nil
  920. just_arrived = true
  921. last_attack = 0
  922. $ambusher_here = false
  923.  
  924. start_exec_script( <<-eos
  925. while(line = get);
  926. break unless running?('bigshot');
  927. $ambusher_here = true if line =~ /^\w+ leaps from hiding to attack/;
  928. end;
  929. eos
  930. )
  931.  
  932.  
  933. while true
  934. while( (target = find_target(target, just_arrived)) && !should_rest? && no_players == true)
  935. echo target if $bigshot_debug
  936. if( (Time.now.to_i - last_attack > 15) || just_arrived )
  937. @followers.add_event(:ATTACK)
  938. last_attack = Time.now.to_i
  939. end
  940. attack(target)
  941. just_arrived = false
  942. loot() if $ambusher_here == false
  943. end
  944.  
  945. echo "Exiting attack loop" if $bigshot_debug
  946. gather_ammo()
  947.  
  948. if(should_rest?)
  949. break
  950. else
  951. prepare_for_movement()
  952. target = bs_wander()
  953. sleep 1
  954. just_arrived = true
  955. end
  956.  
  957. end
  958.  
  959. unspam()
  960. end
  961.  
  962. # this is a leader method
  963. def hunt()
  964. pre_hunt()
  965. do_hunt()
  966. rest()
  967. end
  968.  
  969. # this is a leader method
  970. def rest()
  971. message("Bigshot resting: #{$rest_reason}")
  972. $bigshot_should_rest = nil
  973. if @BOUNTY_MODE # bounty script should take over from here
  974. echo "Bounty mode. Killing self. Reason: #{$rest_reason}"
  975. Script.self.kill
  976. end
  977.  
  978. stop_watch()
  979.  
  980. # prep/go
  981. goto(@RESTING_ROOM_ID)
  982. @followers.add_event(:DISPLAY_WATCH)
  983.  
  984. @followers.add_event(:HUNTING_SCRIPTS_STOP)
  985. croak_scripts(@HUNTING_SCRIPTS)
  986.  
  987. @followers.add_event(:RESTING_PREP_COMMANDS)
  988. @RESTING_COMMANDS.each { |i| fput(i) }
  989.  
  990. @followers.add_event(:RESTING_SCRIPTS_START)
  991. run_scripts( @RESTING_SCRIPTS, true )
  992.  
  993. # loop
  994. until(should_hunt?)
  995. fput 'exp'
  996. display_watch_current()
  997. display_watch_average()
  998. display_watch_total()
  999. message( "Bigshot last rested because: #{$rest_reason}" ) if $rest_reason
  1000. message( "Bigshot isn't hunting because: #{$not_hunting_reason}" ) if $not_hunting_reason
  1001. sleep REST_INTERVAL
  1002. end
  1003.  
  1004. hunt()
  1005. end
  1006.  
  1007. def attack(target)
  1008. commands = find_routine(target)
  1009. echo commands if $bigshot_debug
  1010.  
  1011. commands.each do |i|
  1012. break unless valid_target?(target)
  1013. break if wounded? || $bigshot_should_rest
  1014. break if $ambusher_here
  1015. stand()
  1016. cast_signs()
  1017.  
  1018. cmd( i, target )
  1019. end
  1020. echo commands.size if $bigshot_debug
  1021. #sleep 1 if commands.size == 0
  1022. end
  1023.  
  1024. def goto(id)
  1025. prepare_for_movement()
  1026. until( Room.current.id == id )
  1027. run_script( 'go2', true, [ id, '_disable_confirm_' ] )
  1028. end
  1029. end
  1030.  
  1031. def start_watch()
  1032. @START_TIME = Time.now.to_i
  1033. end
  1034.  
  1035. def stop_watch()
  1036. if( @START_TIME > 100 )
  1037. @STORED_TIMES.push( Time.now.to_i - @START_TIME )
  1038. end
  1039. @START_TIME = 0
  1040. end
  1041.  
  1042. def display_watch_current()
  1043. if( @STORED_TIMES.size > 0 )
  1044. seconds = @STORED_TIMES[-1]
  1045. message( sprintf( "Bigshot: Last Hunt: %d min. %0.2f secs.",
  1046. seconds / 60, seconds % 60 ) )
  1047. end
  1048. end
  1049.  
  1050. def display_watch_average()
  1051. average = 0
  1052. if( @STORED_TIMES.size == 1 )
  1053. average = @STORED_TIMES[0]
  1054. elsif( @STORED_TIMES.size > 1 )
  1055. @STORED_TIMES.each { |i| average += i }
  1056. average /= @STORED_TIMES.size
  1057. else
  1058. return
  1059. end
  1060. message( sprintf( "Bigshot: Average Hunt: %d min. %0.2f secs.",
  1061. average / 60, average % 60 ) )
  1062. end
  1063.  
  1064. def display_watch_total()
  1065. total = Time.now.to_i - @BIRTH_TIME
  1066. message( sprintf( "Bigshot: Total Time Running: %d min. %0.2f secs.",
  1067. total / 60, total % 60 ) )
  1068. end
  1069.  
  1070. def room_id()
  1071. return Room.current.id()
  1072. end
  1073.  
  1074. def name()
  1075. return Char.name
  1076. end
  1077.  
  1078. def poaching?()
  1079. if(leading?)
  1080. checkpcs.each { |i| return true unless @followers.get_names.include?(i) }
  1081. return false
  1082. else
  1083. return false
  1084. end
  1085. end
  1086.  
  1087. def should_flee?( just_entered = false )
  1088. GameObj.loot.each { |i| return true if i.noun == 'cloud' } if @FLEE_CLOUDS
  1089. return true if GameObj.npcs.any? { |i| @ALWAYS_FLEE_FROM.include?(i.noun) }
  1090. return true if checkpcs.any? { |i| @ALWAYS_FLEE_FROM.include?(i) }
  1091. return true if !leading? && checkpcs.empty?
  1092.  
  1093. npcs = GameObj.npcs.find_all { |i| i.status !~ /dead|gone/ }
  1094. npcs.delete_if { |npc| (@INVALID_TARGETS.include?(npc.name) or @INVALID_TARGETS.include?(npc.noun)) }
  1095.  
  1096. flee_count = (just_entered && @LONE_TARGETS_ONLY) ? 1 : @FLEE_COUNT
  1097. if npcs.size > flee_count
  1098. return true
  1099. end
  1100. end
  1101.  
  1102. def valid_target?( target, just_entered = false )
  1103. return false if target == nil || target == false
  1104. return false if should_flee?(just_entered)
  1105. return false if just_entered && poaching?
  1106. return false if target.noun =~ /child|traveller|scribe|merchant|dignitary|official|magistrate/i
  1107.  
  1108. if( !CharSettings['targetable'].include?(target.noun) && !CharSettings['untargetable'].include?(target.name) )
  1109. result = dothistimeout( "target ##{target.id}", 3, /^You are now targeting|^You can't target/ )
  1110. if( result =~ /^You are now targeting/ )
  1111. CharSettings['targetable'].push(target.noun)
  1112. elsif( result =~ /^You can't target/ )
  1113. CharSettings['untargetable'].push(target.noun)
  1114. end
  1115. end
  1116. return false if CharSettings['untargetable'].include?(target.noun)
  1117. if (target.status !~ /dead|gone/) and GameObj.npcs.any? { |n| n.id == target.id } and (@TARGETS.nil? or @TARGETS.keys.any? { |i| target.name =~ /^#{i}$/i or target.noun =~ /^#{i}$/i })
  1118. return true
  1119. else
  1120. return false
  1121. end
  1122. end
  1123.  
  1124. def sort_npcs()
  1125. targets = @TARGETS
  1126.  
  1127. npcs = GameObj.npcs
  1128. sorted = Array.new
  1129.  
  1130. targets.keys.each { |target| sorted += npcs.find_all { |npc| (npc.name =~ /^#{target}$/i or npc.noun =~ /^#{target}$/i) }.to_a }
  1131. sorted.flatten
  1132. end
  1133.  
  1134. def find_target( target, just_entered = false )
  1135. return target if valid_target?(target, just_entered)
  1136.  
  1137. sort_npcs.each { |i| return i if valid_target?( i, just_entered ) }
  1138.  
  1139. # nothing valid
  1140. return nil
  1141. end
  1142.  
  1143. def rt?()
  1144. return checkrt()
  1145. end
  1146.  
  1147. def fried?()
  1148. if( percentmind() >= @FRIED )
  1149. return true
  1150. end
  1151. return false
  1152. end
  1153.  
  1154. def oom?()
  1155. if( percentmana() < @OOM )
  1156. return true
  1157. end
  1158. return false
  1159. end
  1160.  
  1161. def ammo_on_ground(ammo)
  1162. return GameObj.loot.find { |i| i.name =~ /^#{ammo}$/i or i.noun =~ /#{ammo}s?/i }
  1163. end
  1164.  
  1165. def gather_ammo()
  1166. ammo = @AMMO; container = @AMMO_CONTAINER; hide = @HIDE_FOR_AMMO;
  1167. return if ammo == nil || wounded?
  1168.  
  1169. while( ammo_on_ground(ammo) )
  1170. change_stance('defensive')
  1171.  
  1172. unless GameObj.right_hand.id.nil?
  1173. line = dothistimeout "stow ##{GameObj.right_hand.id}", 3, /put|closed/
  1174. if line =~ /closed/
  1175. fput "open my #{@AMMO_CONTAINER}"
  1176. fput "put ##{GameObj.right_hand.id} in my ##{@AMMO_CONTAINER}"
  1177. end
  1178. end
  1179.  
  1180. result = dothistimeout(
  1181. "gather #{ammo}",
  1182. 2,
  1183. /^You gather|^You pick up|^I could not|^What were you|^You may only|reach|on the ground/
  1184. )
  1185.  
  1186. if( result =~ /on the ground/)
  1187. result = dothistimeout "get arrows", 3, /^You gather|^You pick up|^I could not|^What were you|^You may only|reach|on the ground/
  1188. end
  1189.  
  1190. if( result =~ /^You gather|^You pick up/ )
  1191. dothistimeout(
  1192. "put my #{ammo} in my #{ammo} in my #{container}",
  1193. 2,
  1194. /^I could not find|^You can't seem to|^You add|^You bundle|You cannot bundle/
  1195. )
  1196. bs_put "put my #{ammo} in my #{container}" if righthand?
  1197. elsif( result =~ /You may only/ )
  1198. return
  1199. elsif( result == false || result =~ /^I could not find|^What were you/ )
  1200. return
  1201. elsif( result =~ /reach/ )
  1202. bs_put 'hide' if hide and not hidden?
  1203. sleep 4
  1204. end
  1205. end
  1206. end
  1207.  
  1208. def wounded?()
  1209. if(@WOUNDED_EVAL)
  1210. return eval @WOUNDED_EVAL
  1211. else
  1212. return false
  1213. end
  1214. end
  1215.  
  1216. def should_hunt?()
  1217. if(wounded?)
  1218. $not_hunting_reason = 'wounded.'
  1219. return false
  1220. end
  1221. if( percentencumbrance >= @ENCUMBERED )
  1222. $not_hunting_reason = 'encumbered.'
  1223. return false
  1224. end
  1225. if( @RESTING_SCRIPTS.any? { |i| running?(i) } )
  1226. $not_hunting_reason = 'resting scripts still running.'
  1227. return false
  1228. end
  1229.  
  1230. followers_should = (leading? && !solo?) ? @followers.should_hunt? : true
  1231. if(followers_should)
  1232. if( percentmind() > @REST_TILL_EXP )
  1233. $not_hunting_reason = 'mind still above threshold.'
  1234. return false
  1235. elsif( percentmana() < @REST_TILL_MANA )
  1236. $not_hunting_reason = 'mana still below threshold.'
  1237. return false
  1238. elsif( checkspirit() < @REST_TILL_SPIRIT )
  1239. $not_hunting_reason = 'spirit still below threshold.'
  1240. return false
  1241. end
  1242. else
  1243. $not_hunting_reason = 'followers still need rest.'
  1244. return false
  1245. end
  1246. $bigshot_status = :hunting
  1247. return true
  1248. end
  1249.  
  1250. def should_rest?()
  1251. if($bigshot_should_rest)
  1252. $rest_reason = "$bigshot_should_rest was set to true." unless $rest_reason
  1253. $bigshot_status = :resting
  1254. return true
  1255. elsif(wounded?)
  1256. $rest_reason = "wounded."
  1257. $bigshot_status = :resting
  1258. return true
  1259. elsif( percentencumbrance >= @ENCUMBERED )
  1260. $rest_reason = "encumbered."
  1261. $bigshot_status = :resting
  1262. return true
  1263. elsif( leading? && !solo? && @followers.emergency_rest? )
  1264. $rest_reason = "emergency rest."
  1265. $bigshot_status = :resting
  1266. return true
  1267. end
  1268.  
  1269. followers_fried = (leading? && !solo?) ? @followers.should_rest? : true
  1270.  
  1271. if(followers_fried)
  1272. if(fried?)
  1273. $rest_reason = "fried."
  1274. $bigshot_status = :resting
  1275. return true
  1276. elsif(oom?)
  1277. wrack() if @USE_WRACKING
  1278. return false if !oom?
  1279.  
  1280. $rest_reason = "out of mana."
  1281. $bigshot_status = :resting
  1282. return true
  1283. end
  1284. end
  1285.  
  1286. $rest_reason = "none."
  1287. return false
  1288. end
  1289.  
  1290. def cast_signs(single_cast = false)
  1291. @SIGNS.each do |i|
  1292. i = i.to_i
  1293. next if [ 9903,9904,9905,9906,9907,9908,9909,9910,9912,9913,9914,9918 ].include?(i) and Spell[9012].active?
  1294. next if i == 9918
  1295. next if i == 9603 && Spell[9604].active?
  1296. next if i == 9605 && Spell[9606].active?
  1297. sign = Spell[i]
  1298. next unless sign.known?
  1299.  
  1300. # wrack?
  1301. mana_cost = sign.mana_cost > 1 ? sign.mana_cost : 0 # Many erroneously return 1
  1302. wrack() if !sign.affordable? and mana_cost > checkmana and @USE_WRACKING
  1303.  
  1304. if( !sign.active? && sign.affordable? )
  1305. if( i == 9805 )
  1306. 2.times { sign.cast }
  1307. else
  1308. while(1)
  1309. result = sign.cast
  1310. break if result !~ /Spell Hindrance/ || !sign.affordable? || dead?
  1311. end
  1312. end
  1313.  
  1314. break if single_cast
  1315. end
  1316. end
  1317. end
  1318.  
  1319. def loot()
  1320. dead_npcs = GameObj.npcs.find_all { |i| i.status == 'dead' }
  1321. dead_npcs.each { |i|
  1322. change_stance('defensive')
  1323. if(@LOOT_SCRIPT)
  1324. run_script( @LOOT_SCRIPT, true )
  1325. break
  1326. else
  1327. bs_put 'loot'
  1328. end
  1329. }
  1330. end
  1331.  
  1332. def prepare_for_movement()
  1333. change_stance('defensive')
  1334. if( leading? && !solo? )
  1335. wait_while { @followers.roundtime? }
  1336. sleep 1
  1337. end
  1338. end
  1339.  
  1340. def bs_wander()
  1341. wander_last_room = nil
  1342.  
  1343. wander = proc {
  1344. room = Room.current
  1345. next_room_options = room.wayto.keys - @HUNTING_BOUNDARIES
  1346. if next_room_options.length > 1
  1347. next_room_options.delete_if { |option| option == wander_last_room }
  1348. end
  1349. next_room = next_room_options[rand(next_room_options.length)]
  1350. way = room.wayto[next_room]
  1351. if way.class == String
  1352. sleep 0.3
  1353. move(way)
  1354. else
  1355. way.call
  1356. end
  1357. cast_signs(true)
  1358. wander_last_room = room.id.to_s
  1359. }
  1360.  
  1361. while true # wander, check for players
  1362. echo "no_players: #{no_players}" if $bigshot_debug
  1363. npcs = GameObj.npcs
  1364. npcs.delete_if { |npc| (npc.status =~ /dead|gone/) }
  1365. sort_npcs.each { |i| return i if valid_target?( i, true ) and no_players == true and GameObj.npcs.size > 0 }
  1366. return if should_rest?
  1367. wander.call
  1368. sleep 0.1
  1369. $ambusher_here = false
  1370. end
  1371. end
  1372.  
  1373. def bs_put(message)
  1374. unless script = Script.self then respond('--- waitfor: Unable to identify calling script.'); return false; end
  1375. clear
  1376. put(message)
  1377.  
  1378. while string = get
  1379. if string =~ /(?:\.\.\.wait |Wait )[0-9]+/
  1380. hold_up = string.slice(/[0-9]+/).to_i
  1381. sleep(hold_up - 1) unless hold_up.nil? || hold_up == 1
  1382. clear
  1383. put(message)
  1384. next
  1385. elsif string =~ /struggle.+stand/
  1386. clear
  1387. bs_put("stand")
  1388. next
  1389. elsif string =~ /stunned|can't do that while|cannot seem|can't seem|don't seem|Sorry, you may only type ahead/
  1390. if dead?
  1391. echo("You're dead...! You can't do that!")
  1392. sleep 0.25
  1393. script.downstream_buffer.unshift(string)
  1394. return false
  1395. elsif checkstunned
  1396. while checkstunned
  1397. sleep("0.25".to_f)
  1398. end
  1399. elsif checkwebbed
  1400. while checkwebbed
  1401. sleep("0.25".to_f)
  1402. end
  1403. else
  1404. sleep(0.25)
  1405. end
  1406. clear
  1407. put(message)
  1408. next
  1409. else
  1410. script.downstream_buffer.unshift(string)
  1411. return string
  1412. end
  1413. end
  1414. end
  1415.  
  1416. # gui
  1417. def self.setup
  1418. Gtk.queue {
  1419. $OP_WINDOW = Gtk::Window.new
  1420. $OP_WINDOW.title = "Big Shot: v#{BIGSHOT_VERSION}"
  1421. $OP_WINDOW.set_border_width(10)
  1422. $OP_BOX = Gtk::VBox.new(false)
  1423. $OP_BOX.set_border_width(5)
  1424.  
  1425. $OP_VERTICAL_BOX1 = Gtk::VBox.new(false, 0)
  1426. $OP_VERTICAL_BOX2 = Gtk::VBox.new(false, 0)
  1427. $OP_VERTICAL_BOX3 = Gtk::VBox.new(false, 0)
  1428. $OP_VERTICAL_BOX4 = Gtk::VBox.new(false, 0)
  1429. $OP_VERTICAL_BOX5 = Gtk::VBox.new(false, 0)
  1430. $OP_VERTICAL_BOX6 = Gtk::VBox.new(false, 0)
  1431. $OP_VERTICAL_BOX7 = Gtk::VBox.new(false, 0)
  1432. $OP_VERTICAL_BOX8 = Gtk::VBox.new(false, 0)
  1433.  
  1434. $OP_WINDOW.add($OP_BOX)
  1435. $OP_NOTEBOOK = Gtk::Notebook.new
  1436. $OP_NOTEBOOK.set_show_border(true)
  1437. $OP_BOX.add($OP_NOTEBOOK)
  1438. $OP_NOTEBOOK.append_page($OP_VERTICAL_BOX1, Gtk::Label.new('General'))
  1439. $OP_NOTEBOOK.append_page($OP_VERTICAL_BOX2, Gtk::Label.new('Resting'))
  1440. $OP_NOTEBOOK.append_page($OP_VERTICAL_BOX3, Gtk::Label.new('Hunting Map'))
  1441. $OP_NOTEBOOK.append_page($OP_VERTICAL_BOX4, Gtk::Label.new('Hunting'))
  1442. $OP_NOTEBOOK.append_page($OP_VERTICAL_BOX5, Gtk::Label.new('Attacking'))
  1443. $OP_NOTEBOOK.append_page($OP_VERTICAL_BOX6, Gtk::Label.new('Should_hunt?'))
  1444. $OP_NOTEBOOK.append_page($OP_VERTICAL_BOX7, Gtk::Label.new('Should_rest?'))
  1445. $OP_NOTEBOOK.append_page($OP_VERTICAL_BOX8, Gtk::Label.new('Ammo/Wands'))
  1446.  
  1447. $OP_ENTRY = Hash.new # For mapping entries to variables
  1448. $OP_TABLE_SIZE = Hash.new # For mapping table sizes
  1449. }
  1450.  
  1451. Gtk.queue {
  1452. $OP_TABLE1 = Gtk::Table.new(6, 3, false)
  1453. $OP_TABLE1.row_spacings=3
  1454. $OP_TABLE1.column_spacings=3
  1455. $OP_VERTICAL_BOX1.pack_start($OP_TABLE1, false, false, 0)
  1456.  
  1457. $OP_TABLE2 = Gtk::Table.new(6, 3, false)
  1458. $OP_TABLE2.row_spacings=3
  1459. $OP_TABLE2.column_spacings=3
  1460. $OP_VERTICAL_BOX2.pack_start($OP_TABLE2, false, false, 0)
  1461.  
  1462. $OP_TABLE3 = Gtk::Table.new(6, 3, false)
  1463. $OP_TABLE3.row_spacings=3
  1464. $OP_TABLE3.column_spacings=3
  1465. $OP_VERTICAL_BOX3.pack_start($OP_TABLE3, false, false, 0)
  1466.  
  1467. $OP_TABLE4 = Gtk::Table.new(6, 3, false)
  1468. $OP_TABLE4.row_spacings=3
  1469. $OP_TABLE4.column_spacings=3
  1470. $OP_VERTICAL_BOX4.pack_start($OP_TABLE4, false, false, 0)
  1471.  
  1472. $OP_TABLE5 = Gtk::Table.new(6, 3, false)
  1473. $OP_TABLE5.row_spacings=3
  1474. $OP_TABLE5.column_spacings=3
  1475. $OP_VERTICAL_BOX5.pack_start($OP_TABLE5, false, false, 0)
  1476.  
  1477. $OP_TABLE6 = Gtk::Table.new(6, 3, false)
  1478. $OP_TABLE6.row_spacings=3
  1479. $OP_TABLE6.column_spacings=3
  1480. $OP_VERTICAL_BOX6.pack_start($OP_TABLE6, false, false, 0)
  1481.  
  1482. $OP_TABLE7 = Gtk::Table.new(6, 3, false)
  1483. $OP_TABLE7.row_spacings=3
  1484. $OP_TABLE7.column_spacings=3
  1485. $OP_VERTICAL_BOX7.pack_start($OP_TABLE7, false, false, 0)
  1486.  
  1487. $OP_TABLE8 = Gtk::Table.new(6, 3, false)
  1488. $OP_TABLE8.row_spacings=3
  1489. $OP_TABLE8.column_spacings=3
  1490. $OP_VERTICAL_BOX8.pack_start($OP_TABLE8, false, false, 0)
  1491. }
  1492.  
  1493. def self.add_label_entry(table, label, variable)
  1494. size = $OP_TABLE_SIZE[table] || 0
  1495.  
  1496. label = Gtk::Label.new(label)
  1497. align = Gtk::Alignment.new 1, 0, 0, 0
  1498. align.set_padding(4, 0, 3, 4)
  1499. align.add(label)
  1500. table.attach(align, 0, 1, size, size + 1)
  1501.  
  1502. entry = Gtk::Entry.new
  1503. entry.text = UserVars.op[variable].to_s
  1504. entry.set_width_request(157)
  1505. table.attach(entry, 1, 2, size, size + 1)
  1506.  
  1507. $OP_ENTRY[variable] = entry
  1508. $OP_TABLE_SIZE[table] += 1
  1509. end
  1510.  
  1511. Gtk.queue {
  1512. $OP_ENTRY = Hash.new
  1513. add_label_entry($OP_TABLE2, "*room id:", 'resting_room_id')
  1514. add_label_entry($OP_TABLE2, "pre-rest commands:", 'resting_commands')
  1515. add_label_entry($OP_TABLE2, "active resting scripts:", 'resting_scripts')
  1516. add_label_entry($OP_TABLE3, "*starting room ID:", 'hunting_room_id')
  1517. add_label_entry($OP_TABLE3, "*boundary rooms:", 'hunting_boundaries')
  1518. add_label_entry($OP_TABLE4, "valid targets:", 'targets')
  1519. add_label_entry($OP_TABLE4, "attack stance:", 'hunting_stance')
  1520. add_label_entry($OP_TABLE4, "pre-hunt commands:", 'hunting_prep_commands')
  1521. add_label_entry($OP_TABLE4, "active hunting scripts:", 'hunting_scripts')
  1522. add_label_entry($OP_TABLE4, "society abilities/spells/cmans:", 'signs')
  1523. add_label_entry($OP_TABLE4, "loot script:", 'loot_script')
  1524. add_label_entry($OP_TABLE4, "wracking spirit >=", 'wracking_spirit')
  1525. add_label_entry($OP_TABLE5, "*hunting commands:", 'hunting_commands')
  1526. add_label_entry($OP_TABLE5, "hunting commands(b):", 'hunting_commands_b')
  1527. add_label_entry($OP_TABLE5, "hunting commands(c):", 'hunting_commands_c')
  1528. add_label_entry($OP_TABLE5, "fried hunting commands:", 'disable_commands')
  1529. add_label_entry($OP_TABLE5, "flee if enemy count is >", 'flee_count')
  1530. add_label_entry($OP_TABLE5, "...but don't count these:", 'invalid_targets')
  1531. add_label_entry($OP_TABLE5, "...and always flee from:", 'always_flee_from')
  1532. add_label_entry($OP_TABLE6, "*when percentmind <=", 'rest_till_exp')
  1533. add_label_entry($OP_TABLE6, "...*and percentmana >=", 'rest_till_mana')
  1534. add_label_entry($OP_TABLE6, "...and CHECKspirit >=", 'rest_till_spirit')
  1535. add_label_entry($OP_TABLE7, "*when percentmind >=", 'fried')
  1536. add_label_entry($OP_TABLE7, "...*or percentmana <=", 'oom')
  1537. add_label_entry($OP_TABLE7, "...or percentencumbrance >=", 'encumbered')
  1538. add_label_entry($OP_TABLE7, "...or wounded eval:", 'wounded_eval')
  1539. add_label_entry($OP_TABLE8, "find ammo in this container:", 'ammo_container')
  1540. add_label_entry($OP_TABLE8, "use this ammo type:", 'ammo')
  1541. add_label_entry($OP_TABLE8, "fresh wand container:", 'fresh_wand_container')
  1542. add_label_entry($OP_TABLE8, "dead wand container:", 'dead_wand_container')
  1543. add_label_entry($OP_TABLE8, "use this wand type:", 'wand')
  1544. }
  1545.  
  1546. def self.add_checkbox(table, x_pos, label, variable, default = false)
  1547. size = $OP_TABLE_SIZE[table] || 0
  1548. checkbox = Gtk::CheckButton.new label
  1549. value = UserVars.op[variable].nil? ? default : UserVars.op[variable]
  1550. checkbox.set_active(value)
  1551. table.attach(checkbox, x_pos, x_pos + 1, size, size + 1)
  1552. $OP_ENTRY[variable] = checkbox
  1553. $OP_TABLE_SIZE[table] += 1 if x_pos == 1
  1554. end
  1555.  
  1556. Gtk.queue {
  1557. add_checkbox($OP_TABLE1, 0, "Engage deadmans switch", 'dead_man_switch')
  1558. add_checkbox($OP_TABLE1, 1, "Monitor interaction", 'monitor_interaction')
  1559. add_checkbox($OP_TABLE1, 0, "Depart/rerun if dead", 'depart_switch')
  1560. add_checkbox($OP_TABLE1, 1, "Flee from clouds", 'flee_clouds')
  1561. add_checkbox($OP_TABLE4, 1, "Use sign of wracking/sigil of power", 'use_wracking')
  1562. add_checkbox($OP_TABLE5, 1, "Spam attacks (recommended)", 'spam', true)
  1563. add_checkbox($OP_TABLE5, 1, "Approach lone targets only", 'lone_targets_only', false)
  1564. add_checkbox($OP_TABLE8, 1, "Hide while waiting to pick up ammo", 'hide_for_ammo')
  1565. add_checkbox($OP_TABLE8, 1, "Use wands when out of mana", 'wand_if_oom')
  1566. }
  1567.  
  1568. Gtk.queue {
  1569. $OP_WINDOW.signal_connect("delete_event") {
  1570. $OP_SETUP_COMPLETED = true
  1571. }
  1572. }
  1573.  
  1574. Gtk.queue {
  1575. $OP_TOOLTIPS = Gtk::Tooltips.new
  1576. $OP_TOOLTIPS.enable
  1577.  
  1578. label = Gtk::Label.new
  1579. label.set_markup("<i>Bigshot is the leader of the Battle Patrol.\nHe comes equipped with a gun as long as his entire superstructure.\nTakes the edge off.\n\n\n***Settings with * are required.***</i>")
  1580. align = Gtk::Alignment.new(1, 0, 0, 0)
  1581. align.set_padding(50, 0, 0, 40)
  1582. align.add(label)
  1583. $OP_TABLE1.attach(align, 1, 2, 8, 9)
  1584.  
  1585. commands_tip = "Example 1: 413 target, 903 target\nExample 2: 903 target(x2)\nExample 3: 903 target(xx)\nExample 4: 910 target(m50), 903 target\n\nExample 1 will cast 413 then 903 on the target. Example 2 will cast 903 on the target twice. Example 3 will cast 903 on the target until the fight is over. Example 4 will cast 910 if mana is at least 50, otherwise it will cast 903. Separate all commands with commas.\n\nNew feature: 'and'.\nFor example: stance def and 1615 target, kill target(xx)"
  1586. $OP_TOOLTIPS.set_tip($OP_ENTRY['hunting_commands'], commands_tip, "")
  1587. $OP_TOOLTIPS.set_tip($OP_ENTRY['g_hunting_commands'], commands_tip, "")
  1588. $OP_TOOLTIPS.set_tip($OP_ENTRY['g_disable_commands'], commands_tip, "")
  1589.  
  1590. signs_tip = "Combat Movement - 9601\nCombat Focus - 9602\nShadow Mastery - 9603\nSurge of Strength - 9605\n\nSigil of Contact - 9703\nSigil of Resolve - 9704\nSigil of Minor Bane - 9705\nSigil of Defense - 9707\nSigil of Offense - 9708\nSigil of Minor Protection - 9710\nSigil of Focus - 9711\nSigil of Mending - 9713\nSigil of Concentration - 9714\nSigil of Major Bane - 9715\nSigil of Major Determination - 9716\nSigil of Major Protection - 9719\n\nSign of Warding - 9903\nSign of Striking - 9904\nSign of Thought - 9906\nSign of Defending - 9907\nSign of Smiting - 9908\nSign of Staunching - 9909\nSign of Deflection - 9910\nSign of Swords - 9912\nSign of Shields - 9913\nSign of Dissipation - 9914\nSign of Madness - 9916\n\nSymbol of Courage - 9805\nSymbol of Protection - 9806"
  1591. $OP_TOOLTIPS.set_tip($OP_ENTRY['signs'], signs_tip, "")
  1592.  
  1593. size = $OP_TABLE_SIZE[$OP_TABLE3]
  1594. label = Gtk::Label.new
  1595. label.set_markup("<i>Note: Big Shot will not enter boundary rooms. The goal is to pin yourself into a hunting area.</i>")
  1596. align = Gtk::Alignment.new(1, 0, 0, 0)
  1597. align.set_padding(75, 0, 0, 4)
  1598. align.add(label)
  1599. $OP_TABLE3.attach(align, 1, 2, size, size + 1)
  1600.  
  1601. size = $OP_TABLE_SIZE[$OP_TABLE4]
  1602. label = Gtk::Label.new
  1603. label.set_markup("<i>Note: Use nouns for targets. Mouse over society abilities field for more info.</i>")
  1604. align = Gtk::Alignment.new(1, 0, 0, 0)
  1605. align.set_padding(0, 0, 0, 4)
  1606. align.add(label)
  1607. $OP_TABLE4.attach(align, 1, 2, size, size + 1)
  1608.  
  1609. size = $OP_TABLE_SIZE[$OP_TABLE5]
  1610. label = Gtk::Label.new
  1611. label.set_markup("<i>Note: Use nouns for flee info. Mouse over some hunting commands field for more info.</i>")
  1612. align = Gtk::Alignment.new(1, 0, 0, 0)
  1613. align.set_padding(0, 0, 0, 4)
  1614. align.add(label)
  1615. $OP_TABLE5.attach(align, 1, 2, size, size + 1)
  1616.  
  1617. $OP_WINDOW.show_all
  1618. }
  1619.  
  1620. $OP_SETUP_COMPLETED = false
  1621. until($OP_SETUP_COMPLETED)
  1622. sleep 1
  1623. end
  1624.  
  1625. UserVars.op ||= Hash.new
  1626. $OP_ENTRY.keys.each { |key|
  1627. if( $OP_ENTRY[key].class.to_s =~ /CheckButton/ )
  1628. value = $OP_ENTRY[key].active?
  1629. UserVars.op[key] = $OP_ENTRY[key].active?
  1630. else
  1631. if(key == 'wounded_eval')
  1632. UserVars.op[key] = $OP_ENTRY[key].text
  1633. else
  1634. UserVars.op[key] = $OP_ENTRY[key].text.strip.downcase
  1635. end
  1636. end
  1637. }
  1638. UserVars.save()
  1639.  
  1640. Gtk.queue {
  1641. $OP_WINDOW.destroy
  1642. }
  1643. end
  1644. end
  1645.  
  1646. if( script.vars[1].nil? || script.vars[1] =~ /solo|(bounty)/i )
  1647. bounty_mode = $1
  1648.  
  1649. bs = Bigshot.new(bounty_mode)
  1650. bs.croak('Requires Lich V4') unless defined?(Gtk.queue)
  1651. bs.croak('Requires a mapped room.') if( Room.current.id.nil? || Room.current.id == 4 )
  1652. bs.lead()
  1653.  
  1654. elsif( script.vars[1] =~ /setup/i )
  1655. Bigshot.setup()
  1656.  
  1657. elsif( script.vars[1] =~ /display/i )
  1658. echo "Version: #{BIGSHOT_VERSION}"
  1659. UserVars.op.each_pair { |k, v|
  1660. echo "#{k}: #{v}" unless v.nil? || v.class.to_s == 'Array' || v =~ /^\s*$/
  1661. }
  1662.  
  1663. elsif( script.vars[1] =~ /head/i )
  1664. # launch DRb server
  1665. DRb.start_service( nil, Group.new )
  1666. uri = DRb.uri
  1667. Thread.new { DRb.thread.join }
  1668.  
  1669. # launch DRb client
  1670. DRb.start_service()
  1671. bs = Bigshot.new()
  1672.  
  1673. # set leader
  1674. my_group = DRbObject.new( nil, uri )
  1675. my_group.set_leader(bs)
  1676.  
  1677. # announce/go
  1678. (1..RALLY_TIME).each { |i| fput "whisper group Bigshot rallying at #{uri}"; sleep 1; }
  1679. bs.lead(my_group)
  1680.  
  1681. elsif( script.vars[1] =~ /tail/i )
  1682. # Watch for rally
  1683. group = nil
  1684. bs = nil
  1685. while( group.nil? && bs.nil? )
  1686. if( get =~ /rallying at (.*)\."$/ )
  1687.  
  1688. # create group
  1689. DRb.start_service()
  1690. group = DRbObject.new( nil, $1 )
  1691.  
  1692. # create Bigshot
  1693. bs = Bigshot.new()
  1694. group.add_member(bs)
  1695. bs.keep_awake()
  1696. end
  1697. end
  1698.  
  1699. # Participate
  1700. bs.message("Joined group")
  1701. leader = group.leader.name
  1702.  
  1703. while(!dead?)
  1704. begin
  1705. bs.change_stance('defensive')
  1706. bs.stand()
  1707. sleep 0.25
  1708.  
  1709. # grab event
  1710. event = bs.event_stack.size == 0 ? nil : bs.grab_event
  1711. next if event.nil?
  1712.  
  1713. # kertwang!
  1714. until( checkpcs.include?(leader) )
  1715. start_script( 'go2', [ group.room_id, '_disable_confirm_' ] )
  1716. wait_while { running?('go2') }
  1717. fput "join #{leader}"
  1718. sleep 1
  1719. end
  1720.  
  1721. # process event
  1722. bs.message("event: " + event.type.to_s)
  1723. if( event.type == :HUNTING_PREP_COMMANDS )
  1724. bs.HUNTING_PREP_COMMANDS.each { |i| fput(i) }
  1725.  
  1726. elsif( event.type == :CAST_SIGNS )
  1727. bs.cast_signs()
  1728.  
  1729. elsif( event.type == :HUNTING_SCRIPTS_START )
  1730. bs.run_scripts( bs.HUNTING_SCRIPTS, false )
  1731.  
  1732. elsif( event.type == :ATTACK )
  1733. if( event.stale? ) # consider timestamp and room_id
  1734. bs.message("skipping attack because it's stale")
  1735. next
  1736. end
  1737.  
  1738. target = nil
  1739. while( target = bs.find_target(target) )
  1740. total_pcs = GameObj.pcs.count
  1741. break if total_pcs > 0
  1742. break if event.room_id != Room.current.id # only consider room_id
  1743. bs.attack(target)
  1744. end
  1745.  
  1746. elsif( event.type == :HUNTING_SCRIPTS_STOP )
  1747. bs.croak_scripts(bs.HUNTING_SCRIPTS)
  1748.  
  1749. elsif( event.type == :RESTING_PREP_COMMANDS )
  1750. $bigshot_should_rest = nil # need to reset this
  1751. bs.RESTING_COMMANDS.each { |i| fput(i) }
  1752.  
  1753. elsif( event.type == :RESTING_SCRIPTS_START )
  1754. bs.run_scripts( bs.RESTING_SCRIPTS, true )
  1755.  
  1756. elsif( event.type == :DISPLAY_WATCH )
  1757. if( event.stale? )
  1758. bs.message("skipping display_watch because it's stale")
  1759. next
  1760. end
  1761. bs.message( "Bigshot last rested because: #{$rest_reason}" ) if $rest_reason
  1762. bs.message( "Bigshot isn't hunting because: #{$not_hunting_reason}" ) if $not_hunting_reason
  1763. sleep( REST_INTERVAL / 10 )
  1764. end
  1765.  
  1766. rescue
  1767. fput 'leave group'
  1768. if( bs.RESTING_ROOM_ID && bs.RESTING_ROOM_ID != 4 )
  1769. start_script( 'go2', [ bs.RESTING_ROOM_ID, '_disable_confirm_' ] )
  1770. wait_while { running?('go2') }
  1771. end
  1772. echo "Fatal exception!"
  1773. echo $!.to_s
  1774. echo $!.backtrace.join("\n")
  1775. Script.self.kill
  1776. end
  1777. end
  1778. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement