ZLib -- Zarqon's useful function library

Bale

Minion
Oh. I was under the impression that to_boolean(.9) was true since it was not 0. Ah well, small addition.
 

zarqon

Well-known member
Yes, for non-strings, to_boolean() first converts using to_int() and then returns true unless the result is 0. And to_int(float) is the same as truncate(), not round().
 

Bale

Minion
S'okay. So I'll have to use has_goals().ceil().to_boolean()

That is a little annoying, but quite do-able.
 

zarqon

Well-known member
No, that's redundant, since to_boolean(float) first converts using to_int(). You should instead use (has_goals() > 0). Or whatever threshold you prefer.
 

zarqon

Well-known member
OK, I'm fixing/revamping has_goal() right now, and I thought others may find this interesting. Here's my testing for circular items, foreaching over every monster's drops:

Code:
wad of dough is circular! Dropped by: Bread Golem
wad of dough is circular! Dropped by: Doughbat
Orcish meat locker is circular! Dropped by: Gelatinous Cube
wad of dough is circular! Dropped by: Gnollish Piebaker
wad of dough is circular! Dropped by: Knob Goblin Chef
wad of dough is circular! Dropped by: Yeast Beast

Hmmmm, thought I, looks like I could just make exceptions for a couple items.

Then I ran the same test on all items and got the following not-so-tiny list:

Code:
MSG
Orcish meat locker
ancient cursed foot locker
ballast turtle
bottlecap turtle
box turtle
boxcar turtle
briefcase
cursed black pearl onion
cursed bottle of black-label rum
cursed bottle of rum
cursed cannonball
cursed dirty joke scroll
cursed piece of thirteen
cursed sea biscuit
cursed voodoo skull
decorative fountain
disassembled clover
dueling turtle
fat stacks of cash
flat dough
furry green turtle
gilded ancient cursed chest
gilded ancient cursed key
grinning turtle
hedgeturtle
hobo nickel
ice-cold Sir Schlitz
ice-cold six-pack
knobby helmet turtle
ornate ancient cursed chest
ornate ancient cursed key
padded tortoise
painted turtle
rusty metal key
samurai turtle
sewer turtle
simple ancient cursed key
skeletortoise
sleeping wereturtle
snorkel
soup turtle
spices
stuffed Baron von Ratsworth
stuffed Meat
stuffed crazy bastard sword
stuffed key
stuffed martini
stuffed mink
stuffed monocle
stuffed teddy butler
stuffed tin of caviar
stuffed treasure chest
syncopated turtle
taco shell
ten-leaf clover
torquoise
tortoboggan
turtle wax greaves
turtle wax helmet
turtle wax shield
wad of dough
wooden figurine

So, rather than code exceptions, I just added a recursion limiter like I used in my test script -- there, I disallowed recursion more than 30 levels deep. Just to be absolutely sure, upping the recursion limit to 1000 did not decrease the number of items that were limited. In fact, I could actually lower the limit as far as 3 without increasing the number of limit-cutoff items. I'll go with 5 to be fast yet safe -- I'm pretty sure we won't ever see that limit reached unless TPTB implement a babushka doll.

Perhaps the most interesting result of my testing is this:

> conditions clear

Conditions list cleared.

> call test

pack of chewing gum is/has a goal.
pack of KWE trading card is/has a goal.
boxcar turtle is/has a goal.
medium slimy cyst is/has a goal.

What? Despite having no goals, has_goal() returns true for these items?? It's not a mafia issue -- I checked and is_goal() returns false for these items.

After a little investigation, it turns out that for some reason all of these items have a chance of getting $item[none] listed in use_for_items.txt. Evidently there's a chance of using the item and getting nothing? Anyway, this meant that one of the possible result items ($item[none]) matched my current bounty hunt (none), so it returned 1.0 for those items. I made a special case to skip $item[none], so regardless of what that means in use_for_items, it's now a more robust function.

Heads-Up:

For float has_goal(monster), it will return the sum chance of getting a goal from a monster à la the use_for_items data file. In other words, if a monster drops 1 goal at 100% and another at 50%, it will return 1.5, not 1.0.

I opted for the sum over the highest since a) it's easy to min(1.0, result) whatever you get if you need a strict percentage, and 2) you can compare the goal-getting efficacy of monsters that drop multiple goals, as in this test:

> call test

white pixel is 1.0 of a goal.
Blooper: 2.9358573
Buzzy Beetle: 0.7798809
Goomba: 0.7798809
Koopa Troopa: 0.7798809
Tektite: 0.7798809
finished!

The same will apply to the upcoming has_goal(location), although these percentages will invariably be smaller.

Update should be up tonight or tomorrow.

And while I'm here, I would like to give a huge thanks to Jason for implementing item_drops_array() -- without which, much of this would be guesswork at best.
 
Last edited:

slyz

Developer
How did you determine if an item is circular? I don't see how most of these items can cause more recursion...
 

Bale

Minion
Good point. For instance, you can find a cursed bottle of rum from three different container types, but since you cannot do anything to it except consume, it cannot possibly be circular! And stuffed monocle? Seriously?
 

zarqon

Well-known member
Those were the items where has_goal() recursed more than 30 times. I'm not claiming to know why -- I haven't looked too closely at use_for_items.txt.
 

Bale

Minion
I took a look at use_for_items.txt and I still cannot figure it out. Could you post the algorithm that produced the list? These results seem fishy to me.
 

heeheehee

Developer
Staff member
I'm thinking it's caused by checking to see if item x is created by anything. If that's the case, then it uses the same loop to look at the container to see if that's "created" by anything, which, in this case, might even be something that's consumed (like a key, since it's including negative quantities). And that key loops back to the item that consumes it.

...

Yeah, I think I lost everyone.

Edit: That doesn't seem to explain the turtles. Hmm. Does it account for use of turtle pheromones? That might be it.

Double edit: Wait, no, got it. Boxcar turtle has a chance to yield boxcar turtle (as well as all other turtles listed). =P

Triple edit: Okay, here's that same list, split up so that you can see the groups more clearly.
Code:
boxcar turtle
   MSG
   ballast turtle
   bottlecap turtle
   box turtle
   boxcar turtle*
   briefcase
      fat stacks of cash
   decorative fountain
   disassembled clover
   dueling turtle
   furry green turtle
   grinning turtle
   hedgeturtle
   hobo nickel
   ice-cold six-pack
      ice-cold Sir Schlitz
   knobby helmet turtle
   padded tortoise
   painted turtle
   samurai turtle
   sewer turtle
   skeletortoise
   sleeping wereturtle
   snorkel
   soup turtle
   spices
   syncopated turtle
   taco shell
   ten-leaf clover
   torquoise
   tortoboggan
   wooden figurine

turtle wax greaves
   turtle wax helmet
      turtle wax shield*

stuffed treasure chest
   stuffed key*
   stuffed Baron von Ratsworth
   stuffed Meat
   stuffed crazy bastard sword
   stuffed martini
   stuffed mink
   stuffed monocle
   stuffed teddy butler
   stuffed tin of caviar

Orcish meat locker
   rusty metal key*


[gilded ancient cursed chest
   gilded ancient cursed key*
ornate ancient cursed chest
   ornate ancient cursed key*
ancient cursed foot locker
   simple ancient cursed key*]
   [cursed black pearl onion
   cursed bottle of black-label rum
   cursed bottle of rum
   cursed cannonball
   cursed dirty joke scroll
   cursed piece of thirteen
   cursed sea biscuit
   cursed voodoo skull]

flat dough
   wad of dough*

The brackets should be somewhat self-explanatory. The asterisk marks that the item, when used, returns the beginning item. Basically, item A looks for what produces it, item B. It then looks to see what produces item B, but does not take into account that use_for_items presents items (let's just say one item -- item C) required to use item B as negative quantities (for example, simple ancient cursed key is shown to create -1 ancient cursed foot locker). Item C requires item B to be "used" (technically, consumed), and that leads to recursion.

(Tell me if I lost everyone again. :( )
 
Last edited:

zarqon

Well-known member
Hahaha heeheehee, that was magnificent. I do believe you're exactly right.

Updates updates updates wtf why so many updates

The new has_goal() is up for items, monsters, and locations. Unfortunately, this screwed with my entire combat script family -- FTF, SS, and BBB were all affected. So, for your convenience I've attached updated versions of all of them here as a single zip. Otherwise, I'll be updating the rest of those threads with new versions in the next few minutes, and you can hunt down the specific ones that you use and update from the threads as usual.

I also recommend this alias:

Code:
alias goalinfo => ashq import <zlib.ash> foreach i in $items[] if (has_goal(i) > 0) print(i+" is "+rnum(has_goal(i))+" of a goal."); foreach m in $monsters[] if (has_goal(m) > 0) print("Encountering "+m+": "+rnum(has_goal(m)*100.0)+"%","#606060"); foreach l in $locations[] if (has_goal(l) > 0) print("Adventuring at "+l+": "+rnum(has_goal(l)*100.0)+"%"); print("finished!");

That will let you see nifty things like this:

> conditions add 1 wad of dough

Condition added: wad of dough
wad of dough

> goalinfo

wad of dough is 1 of a goal.
flat dough is 1 of a goal.
Knob Kitchen grab-bag is 1 of a goal.
all-purpose flower is 40 of a goal.
Encountering Bread Golem: 54.6%
Encountering Doughbat: 54.6%
Encountering Gnollish Piebaker: 90.99%
Encountering Knob Goblin Chef: 27.3%
Encountering Yeast Beast: 181.99%
Adventuring at Guano Junction: 9.1%
Adventuring at Degrassi Knoll: 7.66%
Adventuring at Fernswarthy's Ruins: 39.43%
Adventuring at Knob Goblin Kitchens: 18.2%
finished!

Presently has_goal() for locations uses the values given by appearance_rates(). On my to-do list: 1) account for combat frequency modifiers, and 2) specify an On the Trail target when calculating has_goal() for locations.

Enjoy!
 

Attachments

  • zarqonupdate.zip
    25.5 KB · Views: 58

heeheehee

Developer
Staff member
I do think that I will possibly love this new version of has_goal(). (Wait, erm, does it check Lemon Party Slots vs. Menagerie 2 vs. Sonofa Beach for a lime, say, in BM? Presumably not [yet?], since those are noncombats. Oh well.)

Edit: Zap groups would also be a nice addition, but that can wait until later, generally (all that mess with DD keys and whatnot...).
 
Last edited:

zarqon

Well-known member
Unfortunately, has_goal(location) does not consider items gained from noncombats. I noted a map in the Map Manager which may be usable for this, but haven't looked into it yet. It would be tricky, since getting a goal could also be dependent on choiceadv settings -- and even if you're using BBB to help you with that, you may call the function with the choiceadvs set defferently from how they would be when actually adventuring.

Someone should perhaps make a zap_for_items.txt map, following aqua's excellent format for the data files in PriceAdvisor. aqua could factor it in to PA, and BBB could use it to try zapping for goals (that would have to be opt-in, methinks).
 

zarqon

Well-known member
Yeah, I remember that now! Well then, I suppose I could add this to BBB -- perhaps try using your daily zap for a goal if your best chance of getting it by adventuring is under 10%. That percent would be a script setting, with a value of 0 to disable auto-zapping entirely.
 

Xenthes

Member
Hahaha heeheehee, that was magnificent. I do believe you're exactly right.

Updates updates updates wtf why so many updates


I also recommend this alias:

Code:
alias goalinfo => ashq import <zlib.ash> foreach i in $items[] if (has_goal(i) > 0) print(i+" is "+rnum(has_goal(i))+" of a goal."); foreach m in $monsters[] if (has_goal(m) > 0) print("Encountering "+m+": "+rnum(has_goal(m)*100.0)+"%","#606060"); foreach l in $locations[] if (has_goal(l) > 0) print("Adventuring at "+l+": "+rnum(has_goal(l)*100.0)+"%"); print("finished!");

That will let you see nifty things like this:



Presently has_goal() for locations uses the values given by appearance_rates(). On my to-do list: 1) account for combat frequency modifiers, and 2) specify an On the Trail target when calculating has_goal() for locations.

Enjoy!


Thanks for the continual updates to your excellent scripts.

Main question is will I need to add that alias (optional I know) to all of my toons, or just once and mafia will remember it?
 

heeheehee

Developer
Staff member
Of course I made it -- I ran into this same problem. But that only shows the items/meat that can be acquired from noncombats. I hadn't added in Lemon Party Slot, but I suppose I could rather easily. Now let's see the format, so that other people can update it (and not break my script)...
float skip -- number of skippable noncombats

float NC_count -- number of noncombats that can't be skipped

string it_gain -- a list of expected items dropped from encountering one of each noncombat (e.g. 1 bag of Cheat-Os;1 insanely spicy bean burrito;1 six pack of Mountain Stream;1 unrefined Mountain Stream syrup; for the Icy Peak).

string meat_gain -- Expected meat gained from encountering one of each noncombat (so Treasury would be 800).

string encounters -- Monsters that can be encountered as a result of noncombats (e.g. animated nightstand (Mahogany);remains of a jilted mistress;animated nightstand (White); for the Haunted Bedroom).

string it_expend -- Items expended in noncombats (e.g.1 glob of green slime;1 soggy seed packet; in An Octopus's Garden).


Edit: And because double-posting is bad, I present my hacked-together ZLib-variable-modifying relay-override script! Requires ZLib (duh) and htmlform.
Double edit: Slightly updated version attached; improved support for stuff like OCW.
 

Attachments

  • relay_zlib.ash
    2.3 KB · Views: 35
Last edited:

zezima

New member
> eatdrink_modified.ash

Function 'item_drops_array( monster )' undefined (zlib.ash, line 232)
what I get when I try to run eatdrink_modified on newest version
 
Top