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

Bale

Minion
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...

Huh?! You're saying it eats a cookie before getting the semi-rare?! I cannot imagine this script doing that. I don't have time to investigate BBB for the problem, so zarqon can you see if your script is doing this?

Theraze, I'm not using that canadv patch of yours, so you're on your own checking it out. I think this is not MY bug.
 

Theraze

Active member
Yeah... I got tired of the script sending me to the harem before I'd unlocked it. :D I tend to lazily run up to level 7-8 in the hidden temple, then finish all the level quests below in a simple rush. Helps because I'm doing BM, else I'd make it more optimal. Anyways, as my unlocking of those zones is really not guaranteed, the CC script was wasting more semirares than it actually would get, as it would fail to get the semirare, eat a cookie, and decide that it had done its job.

I'll keep tweaking it around, but for now, I suppose my best solution is to just keep the eatcookie part out of my CC, and just let BBB handle things.
 

zarqon

Well-known member
I don't think this is Bale's bug either. I'm using a cut-up version of CC with lots of stuff removed (including fortune cookie handling), and I've noticed that BBB needs a little tweaking; when CC sends you to get the semirare, the counter that triggered the script is evidently no longer active, but the new window counters have not yet been set, so basically you're in a completely unknown state. Need to bump a number on one of the get_counters() calls.
 

Theraze

Active member
Yeah... here's a log of the way it's running now.
Using 1 dance card...
Finished using 1 dance card.
Checking counters now.
Checking resistance to stench...
Searching items for stench resistance...
Resistance-granting item found: Knob Goblin harem veil
Getting a Dogsgotnonoz pills which is currently selling in the mall for 18,600 meat.
Internal checkpoint created.
Since you are not in a Mysticality sign, you may not visit the restaurant.
Searching for "fortune cookie"...
Purchasing fortune cookie (1 @ 40)...
You acquire an item: fortune cookie
You spent 40 Meat
Purchases complete.
Eating 1 fortune cookie...
You gain 1 Adventure
Lucky numbers: 79, 148, 168
Finished eating 1 fortune cookie.
Visit to BatHole: Batrat and Ratbat Burrow in progress...
[1689] Batrat and Ratbat Burrow
Encounter: How Does He Smell?
You acquire an item: Dogsgotnonoz pills
[1690] Haunted Ballroom
Encounter: floating platter of hors d'oeuvres
Strategy: C:\Program Files (x86)\KoLMafia\ccs\default.ccs [default]
Round 0: Theraze wins initiative!
(unable to macrofy due to action: consult SmartStasis.ash)
Round 1: Theraze executes a macro!
Round 1: Theraze attacks!
Round 2: floating platter of hors d'oeuvres takes 99 damage.
Round 2: Theraze attacks!
Round 3: floating platter of hors d'oeuvres takes 99 damage.
You acquire an item: desiccated apricot
You gain 15 Strongness
You gain 6 Enchantedness
You gain 9 Smarm
Since you are not in a Mysticality sign, you may not visit the restaurant.
Searching for "fortune cookie"...
Purchasing fortune cookie (1 @ 40)...
You acquire an item: fortune cookie
You spent 40 Meat
Purchases complete.
Eating 1 fortune cookie...
You gain 1 Adventure
Lucky numbers: 48, 237, 182
Lucky number 48 ignored - too soon to be a semirare.
Lucky number 237 ignored - too large to be a semirare.
Finished eating 1 fortune cookie.
 

zarqon

Well-known member
Yeah, just needs to disregard cookies when you actually have a counter expiring. Just have to change a 1 to a 0, or a 0 to a -1 or something. I'll look into it soon. Either way, it's not CC's doing and this discussion can be finished in the CC thread. In the meantime, may I recommend "timely" as a superior fortune cookie setting?
 

Theraze

Active member
Timely just eats (currently) the single cookie before the adventure, then never eats another when it's actually time. Sort of aggravated me until I figured that out.
 

Theraze

Active member
Just got the new version of BBB, which sets the FC check to -1 instead of 0 as its minimum. If it actually properly makes itself/CC eat cookies when it should, I'll post my tweaked version here for perusal. If it's still odd, I'll delay until I've figured out what's screwing it up. :) Did also set CC to use -1 as its minimum, like BBB.
 

Theraze

Active member
Because while BBB was set before to look for 0 to 200 counters, as was CC, it was triggering before the adventure. zarqon changed his check to -1 to 200, and it made sense... if the counter is at -1, it's still not time to eat a cookie. When mafia finds a semirare, it sets the counter to 160-200, so finding a -1 counter shouldn't ever cause it to eat a cookie. When I run adventures tonight, I'll check if it works as it should (one cookie eaten, AFTER the semirare) using both at -1 min. If it does, I'll try BBB at -1, CC at 0 and see if it still works. I'll try to remember to report back either way. :)
 

Theraze

Active member
Unfortunate...
PHP:
Request 4 of 24 (Knob: Knob Goblin Treasury) in progress...
Checking     for updates (running CounterChecker ver. 1.4)...
_version_BaleCC     => 1.4
You have a current version of     CounterChecker.
Checking counters now.
Checking     resistance to stench...
Searching items for     stench resistance...
Resistance-granting     item found: Knob Goblin harem veil
unlockedLocations => 5--     Haunted Kitchen Haunted Billiards Room
unlockedLocations => 5-- Haunted     Kitchen Haunted Billiards Room Knob Goblin Harem
Getting a Knob Goblin     lunchbox which is currently selling in the mall for 22,888 meat.
Internal     checkpoint created.
Since you are not in a Mysticality sign, you     may not visit the restaurant.
Searching for "fortune cookie"...
Purchasing     fortune cookie (1 @ 40)...
You acquire an item: fortune cookie
You     spent 40 Meat
Purchases complete.
Eating 1 fortune cookie...
You     gain 1 Adventure
Lucky numbers: 145, 29, 282
Lucky number 282     ignored - too large to be a semirare.
Finished eating 1 fortune cookie.
Visit     to Knob: Outskirts of The Knob in progress...
[263] Outskirts of     The Knob
Encounter: Lunchboxing
You acquire an item: Knob Goblin     lunchbox
Conditions not satisfied after 1     adventure.
[264] Knob Goblin Treasury
Encounter: Knob     Goblin Bean Counter
Strategy: C:\Program Files     (x86)\KoLMafia\ccs\default.ccs [default]
Round 0: Theraze loses     initiative!
(unable to macrofy due to action: consult SmartStasis.ash)
1/4     monsters drop goals here.
Round 1: Theraze executes a macro!
Round 1:     Theraze attacks!
Round 2: knob goblin bean counter takes 12 damage.
Round     2: Theraze attacks!
Round 3: knob goblin bean counter takes 11 damage.
You     gain 61 Meat
You acquire an item: hill of beans
You gain 5 Strongness
You     gain 1 Mysteriousness
Since you are not in a Mysticality sign, you     may not visit the restaurant.
Searching for "fortune cookie"...
Purchasing     fortune cookie (1 @ 40)...
You acquire an item: fortune cookie
You     spent 40 Meat
Purchases complete.
Eating 1 fortune cookie...
You     gain 1 Adventure
Lucky numbers: 174, 96, 147
Lucky number 96 ignored     - too soon to be a semirare.
Lucky number 147 ignored - too soon to be     a semirare.
Finished eating 1 fortune cookie.

So, not quite happy yet. I need to make it display whose eat_cookie it's doing...
 

Theraze

Active member
Okay, so managed to get BBB and CC to play nicely together by doing the following. I'll post the solutions in both threads, as both need some tweaking. This version does post updates, since it uses a mafia variable, but it could be converted to use a zlib variable for silence if preferred.

To CC, where it sets the locale, like so:
PHP:
 string last_rare = get_property("semirareLocation");
 location locale = expensive_semi(last_rare);
 string billiard = "2";
add a line for setting what that locale is:
PHP:
 string last_rare = get_property("semirareLocation");
 location locale = expensive_semi(last_rare);
 set_property("nextSemirareLocation", locale);
 string billiard = "2";

Then, after it's done with the turn, clean up the setting...
PHP:
 eat_cookie();
}
becomes
PHP:
 eat_cookie();
 set_property("nextSemirareLocation", "");
}


BBB then needs to be modified to respect that if nextSemirareLocation happens to be the place where we're going next, don't try to eat cookies, regardless of whether or not it's on the good cookie list. Change the following:
PHP:
      case "always": case "true":
         while (get_counters("Fortune Cookie",-1,200) == "" ||
                (to_int(cooks.group(2)) > 0 && count(split_string(get_counters("Fortune Cookie",0,200),"\t")) > to_int(cooks.group(2)))) {
to this:
PHP:
      case "always": case "true":
         while (my_location() != to_location(get_property("nextSemirareLocation")) && (get_counters("Fortune Cookie",-1,200) == "" ||
                (to_int(cooks.group(2)) > 0 && count(split_string(get_counters("Fortune Cookie",0,200),"\t")) > to_int(cooks.group(2))))) {

Basically, encapsulating the current check with a validation that we don't have a nextSemirareLocation active and that it isn't set to our current location. By doing it as a check instead of being a boolean, if something crashes out we don't completely break BBB's ability to re-cookie us, since CC will only cookie us if it's doing it in conjunction with one of the counters ticking off.
 

Theraze

Active member
And... worked fine tonight.
Request 10 of 45 (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.
You need a 'map to Vanya's Castle' to adventure here.
You need a 'dingy dinghy' to adventure here.
You need to be level 8 or higher to adventure at Goatlet.
Checking resistance to stench...
Searching items for stench resistance...
Unable to resist stench!
unlockedLocations => 6-- Haunted Kitchen Haunted Billiards Room
Searching for "cube of billiard chalk"...
You need a 'Spookyraven library key' to adventure here.
Searching for "tasty tart"...
You need to be level 11 or higher to adventure at Hidden City.
You need a 'dingy dinghy' to adventure here.
unlockedLocations => 6-- Haunted Kitchen Haunted Billiards Room Knob Goblin Harem
You need a 'Cobb's Knob lab key' to adventure here.
You need a 'Cobb's Knob lab key' to adventure here.
You need to be level 8 or higher to adventure at Ninja Snowmen.
You need to be level 9 or higher to adventure at Orc Chasm.
You need a 'dingy dinghy' to adventure here.
You need at least 40 Mysticality to adventure at Post-Cyrpt Cemetary.
Searching for "distilled fortified wine"...
You need to be level 7 or higher to adventure at Whitey's Grove.
Getting 3 bottles of distilled fortified wine which are currently selling in the mall for 5690 meat each.
New ZLib location setting: BaleCC_nextSemirareLocation => Sleazy Back Alley
Internal checkpoint created.

Restoring HP! Currently at 3 of 31 HP, 21 of 51 MP, current meat: 24 ... Target HP = 30.
Insufficient meat to fully restore HP without wasting restoratives!
Did not fully restore HP for some reason.

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

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

Visiting Hell's Kitchen...
Menu retrieved.
Since you are not in a Mysticality sign, you may not visit the restaurant.
You need 1 more fortune cookie to continue.
Fortune Cookie counter expired. Last semirare found 0 turns ago (on turn 244) in Sleazy Back Alley
Well, with the exception of not having enough meat to buy the cookie post-SR. Joys of lazy BM runs. Anyways, modified parts follow... and there are rather a few. :)
PHP:
script "CounterChecker.ash";
notify Bale;
import <canadv.ash>
check_version("CounterChecker", "BaleCC", "1.4", 2519);
PHP:
// This will return the location of the currently most expensive semi-rare
location expensive_semi(string last) {
 item [location] semi_rare;
 semi_rare[$location[The Purple Light District]] = $item[lewd playing card];
 semi_rare[$location[Haunted Billiards Room]] = $item[cube of billiard chalk];
 semi_rare[$location[Menagerie 2]] = $item[irradiated pet snacks];
 semi_rare[$location[Outskirts of The Knob]] = $item[Knob Goblin lunchbox];
 semi_rare[$location[Limerick Dungeon]] = $item[cyclops eyedrops];
 semi_rare[$location[Sleazy Back Alley]] = $item[distilled fortified wine];
 semi_rare[$location[Haunted Pantry]] = $item[tasty tart];
 semi_rare[$location[Harem]] = $item[scented massage oil];
 semi_rare[$location[Haunted Kitchen]] = $item[freezerburned ice cube];
 semi_rare[$location[Haunted Library]] = $item[black eyedrops];
 semi_rare[$location[Goatlet]] = $item[can of spinach];
 semi_rare[$location[Ninja Snowmen]] = $item[bottle of antifreeze];
 semi_rare[$location[Orc Chasm]] = $item[ASCII shirt];
 semi_rare[$location[Battlefield (No Uniform)]] = $item[six-pack of New Cloaca-Cola];
 semi_rare[$location[Batrat and Ratbat Burrow]] = $item[Dogsgotnonoz pills];
 semi_rare[$location[Giant's Castle]] = $item[Mick's IcyVapoHotness Inhaler];
 semi_rare[$location[Guano Junction]] = $item[Eau de Guaneau];
 semi_rare[$location[Laboratory]] = $item[bottle of Mystic Shell];
 semi_rare[$location[Pre-Cyrpt Cemetary]] = $item[poltergeist-in-the-jar-o];
 semi_rare[$location[Post-Cyrpt Cemetary]] = $item[poltergeist-in-the-jar-o];
 semi_rare[$location[South of The Border]] = $item[donkey flipbook];
 semi_rare[$location[Friars Gate]] = $item[SPF 451 lip balm];
 semi_rare[$location[Hidden City]] = $item[shrinking powder];
 semi_rare[$location[8-Bit Realm]] = $item[fire flower];
 semi_rare[$location[Spooky Forest]] = $item[fake blood];
 semi_rare[$location[Whitey's Grove]] = $item[bag of lard];
 semi_rare[$location[Hippy Camp]] = $item[teeny-tiny magic scroll];
 semi_rare[$location[Frat House]] = $item[bottle of rhinoceros hormones];
 semi_rare[$location[Pirate Cove]] = $item[bottle of pirate juice];
 semi_rare[$location[Burnbarrel Blvd]] = $item[jar of squeeze];
 semi_rare[$location[Exposure Esplanade]] = $item[bowl of fishysoisse];
 semi_rare[$location[The Heap]] = $item[concentrated garbage juice];
 semi_rare[$location[The Ancient Hobo Burial Ground]] = $item[deadly lampshade];
 semi_rare[$location[Chapel]] = $item[pixel stopwatch];
 remove semi_rare[last.to_location()];
 
 int[item] semi_rare_multiplier;
 semi_rare_multiplier[$item[distilled fortified wine]] = 3;
 semi_rare_multiplier[$item[tasty tart]] = 3;
 semi_rare_multiplier[$item[scented massage oil]] = 3;
 // This finds out if the PLD can be accessed for semi-rare usage.
 if(last != "The Purple Light District") {
  if(visit_url("town_clan.php").contains_text("clanbasement.gif") 
    && !visit_url("clan_basement.php?fromabove=1").contains_text("not allowed")) {
   buffer pld = visit_url("clan_hobopolis.php?place=8&pwd");
   if(!pld.contains_text("purplelightdistrict") || pld.contains_text("purplelightdistrict11.gif"))
    remove semi_rare[$location[The Purple Light District]];
   // purplelightdistrict11.gif == Chester defeated.
  } else
   remove semi_rare[$location[The Purple Light District]];
   remove semi_rare[$location[The Ancient Hobo Burial Ground]];
   remove semi_rare[$location[The Heap]];
   remove semi_rare[$location[Exposure Esplanade]];
   remove semi_rare[$location[Burnbarrel Blvd.]];
 }
 
 int [item] prices;
 int expensive = 0;
 int rare_price;
 location best = $location[none];
 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;
  }
 }
PHP:
void get_semirare() {
 int last = get_property("semirareCounter").to_int();
 void eat_cookie() {
  if(get_property("semirareCounter").to_int() != last) {
   // semi-rare acquired, let's do it again
   if(my_fullness() == fullness_limit())
    print("If I ate even a fortune cookie I'd burst! Remember to eat a fortune cookie when the tummy is emptier.", "red");
   else while(toEat())
    eatsilent(1, $item[fortune cookie]);
  } else
   print("Oops, that wasn't the right number!", "red");
 }
 
 string last_rare = get_property("semirareLocation");
 location locale = expensive_semi(last_rare);
 vars["BaleCC_nextSemirareLocation"] = locale;
 updatevars();
 cli_execute("checkpoint");
 can_adv(locale,true);
 string billiard = "2";
 // If ImprovePoolSkills, then play a game of pool at every opportunity!
 if(ImprovePoolSkills && last_rare != "Haunted Billiards Room") {
  locale = $location[Haunted Billiards Room];
  billiard = get_property("choiceAdventure330");
  if(billiard != "1")
   set_property("choiceAdventure330", "1");
 }
 else if(locale == $location[Haunted Billiards Room]) {
  billiard = get_property("choiceAdventure330");
  if(billiard != "2")
   set_property("choiceAdventure330", "2");
 }
 (!adventure(1, locale));
 if(locale == $location[Haunted Billiards Room] && billiard != get_property("choiceAdventure330"))
  set_property("choiceAdventure330", billiard);
 outfit("checkpoint");
 remove vars["BaleCC_nextSemirareLocation"];
 updatevars();
 eat_cookie();
}
 
Last edited:

Theraze

Active member
Updated the post above to have the vars[] and updatevars() instead of using setvar, since we're not just setting a default, we're wanting to change an existing value... Suppose it's time to ask for a removevar command or something similar. :)

Note: To just make this be less cruel to BBB, the fix is just the nextSemirareLocation being set and unset with its lines before and after the adventuring. I also streamlined the billiards handling to use the same adventure and exit as the normal bit.

CanAdv affects the first two patch locations... to skip implementing that, ignore those two codeblocks completely. The specific changes near the end that involve CanAdv are the checkpoint, can_adv(), and outfit("checkpoint") lines. Besides that, the rest of the get_semirare function should act exactly the same as the current one (except with setting the value so BBB doesn't try to eat its cookie too quickly).
 
Last edited:

Theraze

Active member
Applied slyz's tip on removing variables to the semirare bit. Should clean things up better now. Will note if it fails, but otherwise it should work.
 

Winterbay

Active member
Trying this out...

So, what does the
Code:
	(!adventure(1, locale));
part do? I mean what is the point of the parenthesis and the !-symbol since it isn't in a boolean check?
 

Winterbay

Active member
Right. I should've known there was some good reason :)
I've only done error catching sofar (ie putting the result into a variable and check for it, not an implicit use of the return value itself).
 

me259259

Member
Is there a way to get a specific semi-rare using counterchecker? Instead of it searching for the semi-rares with the best mallprice, can you switch it to a mode where it gets only a couple of user defined semi-rares?
 

Bale

Minion
You'd have to edit it. For instance, if you do this:

Code:
location expensive_semi(string last) {
[COLOR="#ff0000"]	if(last != "Elf Alley")
		return $location[Elf Alley];[/COLOR]
...

Then it will always go to Elf Alley if you weren't there last. Unfortunately that code doesn't include any checks to see if Elf Ally is actually available, so you'd best make sure of that yourself. Sadly I haven't updated this script for some time.
 

Theraze

Active member
me259, easiest thing to do is delete all but the 2-3 semirares you want it to harvest. It'll switch between the choices you allow it automatically. But nothing says you need to leave in all the choices that exist currently... or even says that you can't add in more. :)
 
Top