PDA

View Full Version : Bigshot woe : why is this happening?



Shari
01-05-2015, 10:59 PM
I'm guessing because the description is "thin wand", but I don't know how to correct it.

[bigshot]>get thin wand from my case
You remove an acid-etched thin crystal wand from in your bronze filigree case.
>
[bigshot]>get thin wand from my case
You need a free hand to pick that up.
>
| ERROR: Timed out looking for wand.
[bigshot]>get thin wand from my case.

DaCapn
01-06-2015, 02:15 PM
Personally, I don't use any built-in attack functions. I have everything in an attack script. I've found this to be helpful in working around a number of curious bigshot behaviors that weren't a quick fix to the script itself. This is not so much a fix as an easy way forward.

Your guess is correct and unless "wand" alone is acceptable, you can't fix it with settings. Otherwise, you'll have to modify bigshot.

The problem is in this block (bolded for emphasis):

def cmd_wand(target)
if(@FRESH_WAND_CONTAINER)
hands = GameObj.right_hand.name.to_s + GameObj.left_hand.name.to_s
wand = ( @WAND && @WAND !~ /^\s*$/ ) ? @WAND : 'wand'
until( (GameObj.right_hand.name.to_s + GameObj.left_hand.name.to_s) =~ /#{wand}/i )
result = dothistimeout( "get #{wand} from my #{@FRESH_WAND_CONTAINER}", 3, /You remove|You slip|Get what/ )
if( result =~ /Get what/ )
message("ERROR: Couldn't find fresh wand. Gonna rest."); $bigshot_should_rest = true; return;
elsif(result.nil?)
message("ERROR: Timed out looking for wand."); return;
end
end


If you change it to the following, you can use "thin crystal wand" as your wand setting:

def cmd_wand(target)
if(@FRESH_WAND_CONTAINER)
hands = GameObj.right_hand.name.to_s + GameObj.left_hand.name.to_s
wand = ( @WAND && @WAND !~ /^\s*$/ ) ? @WAND : 'wand'
until( (GameObj.right_hand.name.to_s + GameObj.left_hand.name.to_s) =~ /#{wand}/i )
wandtoget = GameObj[@FRESH_WAND_CONTAINER].contents.find { |obj| obj.name =~ /#{wand}/i }
result = dothistimeout( "get ##{wandtoget.id}", 3, /You remove|You slip|Get what/ )
if( result =~ /Get what/ )
message("ERROR: Couldn't find fresh wand. Gonna rest."); $bigshot_should_rest = true; return;
elsif(result.nil?)
message("ERROR: Timed out looking for wand."); return;
end
end


At least... that's what my version looks like (around line 491). I've made a number of changes and may not have the same version you do so your mileage may vary.

Alternatively, you could just comment out the until statement and keep using "thin wand" as your setting. The root of the problem is the disagreement between what the until statement is checking for (that you have an object which has "thin wand" in the name in hand) and the function which retrieves the "thin wand" (which is why you got stuck in that until loop). Personally, I think it's best to keep the until statement because it may be useful in powering through combat situations (RT and the like).

Tillmen
01-06-2015, 07:49 PM
Judging by the log, the dothistimeout line doesn't need to be modified at all. In the log, it does successfully remove the wand. It doesn't fail until it tries to remove the wand a second time, which is expected because you already removed the wand. The problem is the until loop. It doesn't exit even though the wand is in your hand, because "thin crystal wand" !~ /thin wand/.

You could change the until line to:

until (GameObj.right_hand.noun == 'wand') or (GameObj.left_hand.noun == 'wand')

but that will break if you use a ranger rod or something like that.

However, the loop doesn't really serve much purpose. There's three possible outcomes. 1: You remove something. 2: You can't find the wand. 3: Anything else happens and it times out. In case of 2 or 3, the code already tells it to abort not only the loop but the whole method. In case of 1, you removed something, and it's going to try to remove something again if there doesn't appear to be the correct wand in your hand. That's a pretty small window of usefulness.

Here's the code without a loop:



def cmd_wand(target)
if(@FRESH_WAND_CONTAINER)
wand = ( @WAND && @WAND !~ /^\s*$/ ) ? @WAND : 'wand'
result = dothistimeout( "get #{wand} from my #{@FRESH_WAND_CONTAINER}", 3, /You remove|You slip|Get what/ )
if result =~ /Get what/
message("ERROR: Couldn't find fresh wand. Gonna rest.")
$bigshot_should_rest = true
return
elsif result.nil?
message("ERROR: Timed out looking for wand.")
return
end
change_stance('offensive')
...


So, that could theoretically fail, but isn't actually going to. If it does, you'll try to wave a wand you don't have, try to put away a wand you don't have, and then continue as normal.

Personally, the idea of doing a blind "get wand" without already knowing if there's a wand there to get annoys me. Also, everything else about the script annoys me.

Tillmen
01-06-2015, 07:55 PM
Looking slightly closer, DaCapn's solution is perfectly fine, so long as GameObj.right_hand.name returns at least "thin crystal wand" as the name. Objects in your hands have a sorter name in GameObj, and I just assumed the whole thing wouldn't be there. But, I don't have one of those wands and didn't check, so it very well could be there.

Also, you don't have to worry about breaking the script for ranger rods, because later in the code it uses a hard-coded "wand" and few times. It's already broken for ranger rods.