Advertisement
intangibles

Untitled

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