CounterChecker: Wormwood, Semi-rares, Dance Cards and more

You can do wonders with an ASH command in a mood. For example, create a Mafia setting that will be cleared every day to indicate that you have not farmed your !pipes yet:

Code:
[B]Trigger On:[/B] When an effect is lost
[B]Check For:[/B] Absinthe-Minded
[B]Command:[/B] ashq int n=get_property("_pipesFarmed").to_int(); if(n<3){use(1,$item[tiny bottle of absinthe]);set_property("_pipesFarmed",to_string(n+1));}
(this is untested)
 
Don't, actually. The _ before the preference name means that KoLmafia automatically resets it each day.

Edit: Ninja-ed while reading another post!
 
EVERY logout/login, or just when it's a new day? Either way, it's probably a bug, though with the first it's a higher severity.
 
Still curious about if it's bugged/not clearing properly. Did have a new issue though... it appears that CC doesn't use CanAdv to check if you can actually go to the zone, or maybe the CanAdv check failed miserably. Got the following:
You have a current version of CounterChecker.
Checking counters now.
Getting a irradiated pet snacks which is currently selling in the mall for 15,500 meat.

You need 1 more turtle pheromones to continue.
Unable to acquire the effect 'Eau de Tortue'.

Visit to Lab: Menagerie 2 in progress...
You can't get to that area.
 
I don't use canadv for this. You're right that I should add a check for the knob lab key. I'll have to take care of that later, when I have a little time.
 
Trying this to see if it works... hoping it does, as it appears to be the right code for things. :)

Added
Code:
import <canadv.ash>
under the zlib import, and added
Code:
                if (!can_adv(locale,false))
                        continue;
into the foreach locale bit. So that whole section changes to this:
Code:
 foreach locale, rare in semi_rare {
  if (!can_adv(locale,false))
   continue;
  if(historical_age(rare) > 1 || historical_price(rare) == 0)
   mall_price(rare);
  if(semi_rare_multiplier contains rare) 
   rare_price = semi_rare_multiplier[rare] * historical_price(rare) ;
  else rare_price = historical_price(rare) ;
  if( rare_price > expensive) {
   best = locale;
   expensive = rare_price;
  }
 }

Hadn't gotten to actually try it, but just had my semirare trigger, and got the following:
Request 12 of 44 (Mountain: Barrel full of Barrels) in progress...
Checking for updates (running CounterChecker ver. 1.4)...
_version_BaleCC => 1.4
You have a current version of CounterChecker.
Checking counters now.
unlockedLocations => 5-- Haunted Billiards Room
Searching for "distilled fortified wine"...
Getting 3 bottles of distilled fortified wine which are currently selling in the mall for 5000 meat each.

Visit to Town: Sleazy Back Alley in progress...

[424] Sleazy Back Alley
Encounter: In the Still of the Alley
You acquire distilled fortified wine (3)

Should hopefully work fine out in general and not do anything weird. If I'm understanding properly, the 'false' on can_adv just means to not heal up as you're parsing through areas. I suppose since it's a semi-rare, you may actually want to heal up, but unless you actually hit the ultra-rare, I think they're all non-combats, so... doesn't really matter if you heal, right?

Anyways, I won't really know if it works until I hit a semi-rare right after ascension again, but hopefully this should reduce chaos for others. :)
 
Two small things:

1) You don't need to import both canadv and zlib -- canadv imports zlib, so you can just import canadv.
2) The second parameter (prep) should be true if you want to actually adventure somewhere afterwards, otherwise false. In other words, true means that it will prepare (equip gear or use items to get effects or open zones), whereas false means that it will only tell you whether adventuring there is possible. You correctly used false in the loop for eliminating impossible zones, but depending on whether or not any of the zones have necessary preparations, you may also want to call it again with prep true before actually adventuring there.
 
Useful. :) I suppose that the prepped version would be called in the get_semirare() function, immediately after the location locale = expensive_semi(last_rare); line. One question... is this a time to force a checkpoint before and restore it after the adventure is done? I don't want to screw up people (like me) whose adventuring might be more scattered and have requirements of its own.

Edit: Also, due to boredom, added in ALL the semi-rares... well, except the Filthy Crown. Made the Purple Light District check also remove the other Hobo zones. Did do the checkpoint before/outfit checkpoint after. Will see how well it works next semi-rare I get... :)

Edit2: Just got this on my level 8... Turtle Tamer, obviously. :D
Checking for updates (running CounterChecker ver. 1.4)...
_version_BaleCC => 1.4
You have a current version of CounterChecker.
Checking counters now.
unlockedLocations => 5-- Batrat and Ratbat Burrow
Checking resistance to stench...
Searching items for stench resistance...
Resistance-granting item found: Knob Goblin harem veil
unlockedLocations => 5-- Batrat and Ratbat Burrow Haunted Billiards Room
Searching for "cube of billiard chalk"...
unlockedLocations => 5-- Batrat and Ratbat Burrow Haunted Billiards Room Haunted Kitchen
Searching for "tasty tart"...
You gain 1,000 Meat
Getting a Knob Goblin lunchbox which is currently selling in the mall for 20,800 meat.
Internal checkpoint created.

Preparing to tame a knobby helmet turtle...

Visit to Knob: Outskirts of The Knob in progress...

[621] Outskirts of The Knob
Encounter: Lunchboxing
You acquire an item: Knob Goblin lunchbox
Edit3: And on a different level 8:
Checking for updates (running CounterChecker ver. 1.4)...
_version_BaleCC => 1.4
You have a current version of CounterChecker.
Checking counters now.
unlockedLocations => 5-- Batrat and Ratbat Burrow
Checking resistance to stench...
Searching items for stench resistance...
Resistance-granting item found: Knob Goblin harem veil
unlockedLocations => 5-- Batrat and Ratbat Burrow Haunted Billiards Room
Getting a Dogsgotnonoz pills which is currently selling in the mall for 17,400 meat.
Internal checkpoint created.

Visit to BatHole: Batrat and Ratbat Burrow in progress...

[820] Batrat and Ratbat Burrow
Encounter: How Does He Smell?
You acquire an item: Dogsgotnonoz pills
 
Last edited:
Very minor feature request (I could probably fork this into my local version if you're unwilling, but I think others would benefit from this) -- can you add some code to check valueOfAdventure and use that (presumably in conjunction with autoSatisfyWithMall or something like that) to figure out whether munchies pill / milk of magnesium would be worth using before consuming a fortune cookie?

(notes: munchies pill adds 3 adv per cookie, milk adds 1 adv per cookie.)
 
Question... after pulling a semirare, don't you have to do another adventure following the acquisition to restart the counters? Or am I just too tired to think right now? My checks are running a bit odd currently, so, I figured I'd check if there was a good reason for it to hate me. :)

Also, would it be possible to have it check (possibly another variable) if there's a range of either exactly 40, or no counter at all? Since it reinitializes at a range of 40, that could be a check if you've acquired a semirare and not had it considered. It just really likes to trigger immediately before/after the semi-rare and force me to collect another after the session finishes.
 
Very minor feature request (I could probably fork this into my local version if you're unwilling, but I think others would benefit from this) -- can you add some code to check valueOfAdventure and use that (presumably in conjunction with autoSatisfyWithMall or something like that) to figure out whether munchies pill / milk of magnesium would be worth using before consuming a fortune cookie?

(notes: munchies pill adds 3 adv per cookie, milk adds 1 adv per cookie.)

I'm not really interested in writing the code to add the feature, but if you write the code for it I'll probably add it into this script for the sake of all. Link it to a zlib variable since it will annoy some people and I want to leave it off by default.

Question... after pulling a semirare, don't you have to do another adventure following the acquisition to restart the counters? Or am I just too tired to think right now? My checks are running a bit odd currently, so, I figured I'd check if there was a good reason for it to hate me. :)

Getting the semi-rare hits adventure.php and restarts the counters. It's not an issue. For a while I was under the impression that the hidden city semi-rare wouldn't restart the counter since it doesn't hit adventure.php, but it turns out that the semi-rare redirects to adventure.php so it's good also.

Also, would it be possible to have it check (possibly another variable) if there's a range of either exactly 40, or no counter at all? Since it reinitializes at a range of 40, that could be a check if you've acquired a semirare and not had it considered. It just really likes to trigger immediately before/after the semi-rare and force me to collect another after the session finishes.

I'm afraid I have no idea what you're asking.
 
I'm afraid I have no idea what you're asking.

For some reason, it REALLY wants to run the eating of the cookie right before it does the adventuring, enough so that I actually completely removed the eatcookie function from my copy of CounterChecker. It may have to do with adding CanAdv to my copy, not sure.

What I was wondering is, if it's possible to have it check if the counter has been reset back to its range of 40... 159-199, 160-200, etc. As it does after actually finding the semi-rare.

The setup around how it was running was that it was set to timely (the default), using counterchecker as its counter script and zarqon's BBB as its between battle script. The behaviour was that it would start the CanAdv check (with prep as false), decide where to go, run CanAdv (with prep to true), eat a fortune cookie, THEN run the actual adventure. Because KoLmafia resets the cookie counter on semirare acquisition to 160-200, it would then decide that it didn't need to eat another cookie.

With the auto-recookie removed from CounterChecker and auto_semirare set to always, BBB still triggers eating a cookie BEFORE the semi-rare adventure, but will actually eat one the turn after as well. Not sure what's triggering the precookie-ing part. Guessing it's somehow tied into the new CanAdv checks though. On a positive note, using my copy of CanAdv that actually checks if the Knob is unlocked, haven't wasted a Semirare encounter since though...
 
Fairly simple bit of code, I think. Not tested extensively yet.
Code:
// Put this somewhere near the top.
setvar("BaleCC_useConsumptionHelpers", FALSE);

// Skip down to where the code would be added. Presumably in get_cookie(),
// in the while(toEat()) loop.
if(vars["BaleCC_useConsumptionHelpers"].to_boolean()) {
	item milk = $item[Milk of Magnesium];
	item pill = $item[munchies pill];
	int mpa = get_property("valueOfAdventure").to_int();
	if(have_effect($effect[Got Milk])==0 && mpa>historical_price(milk) && retrieve_item(1, milk)) use(1, milk);
	if(3*mpa>historical_price(pill) && retrieve_item(1, pill)) use(1, pill);
}

Or, if you want to be slightly more like Zarqon, you can rewrite the last two if statements as:
Code:
((!(have_effect($effect[Got Milk])==0 && mpa>historical_price(milk) && retrieve_item(1, milk) && use(1, milk)) && 0>1) || (3*mpa>historical_price(pill) && retrieve_item(1, pill) && use(1, pill)));

(I could've done the same thing for the whole snippet, but there'd be a lot of unnecessary repetition.)

Edit: Minor error in the code -- forgot that get_property() returns a string, which has to be converted to an int. Fixed.

Double edit: Changed the code to account for the possibility that the user already has Got Milk active.
Triple edit: Ack, forgot that if the first one returns true, the second won't be executed. Changed.
 
Last edited:
Haha, not quite -- use() has an unreliable return value and can't be included in otherwise delightfully uninterrupted condition chains. :)
 
Haha, not quite -- use() has an unreliable return value and can't be included in otherwise delightfully uninterrupted condition chains. :)
Uh huh.

Didn't I ask you to file bug reports for ASH functions with "unreliable" or otherwise not useful return values? Let's see:

Here is zarqon (quickly followed by Bale) complaining about return values of various functions. May 29, 2009.
Here is me asking for bug reports to be pinned for specific functions with useless return values, and zarqon saying he'd write reports after working up tests to demonstrate the problems. Jan 19, 2010.
Here is zarqon admitting that he'll get around to testing the "unreliable" functions and writing up bug reports - someday. Someday after Feb 10, 2010. ;)

I've seen no bug reports from you or Bale or anybody else, so the issue is not on my personal bug radar...
 
Zarqon -- even so, it's at the end of each mini-chain, so it should still execute, no?

(edit: wouldn't Mafia abort if use() returned a false value? So technically the second way's safer.)
 
Last edited:
@3hee: Yes, actually, that would work fine!

@Veracity: I don't think it's possible to make use() have a reliable return value -- there are too many varying results, it would be a detection madness! MADNESS! So I haven't reported it. I was mentioning it here not as a complaint -- just pointing out the way things are.

The problems I'd had with create() seem to have been caused by some inaccuracies in the data files, which have since been fixed. And hermit() has very limited application, so I didn't mind scripting around it -- and once I had, it fled from my otherwise occupied mind.

I apologize for making you waste your time (which we all value almost as much as we value our mothers!) putting together that forum post. Those issues fell off my radar a while back too. Probably not too long after Feb 10, 2010. :)
 
Back
Top