Advertisement
intangibles

Untitled

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