Superhuman Cocktailcrafting script

Fluxxdog

Active member
Superdrinks for Fun and Profit!

Superdrinks 717
Code:
svn checkout https://svn.code.sf.net/p/fluxxdog-coding/code/trunk/superdrinks
I've got a little script here for whipping up Superhuman drinks. Couldn't find another one I liked. This one requires ZLib and is listed as a dependency. This is intended to be run as part of a beforeBattleScript. If you have a custom one, or use someone else's, you can basically add to the bBS:
Code:
import <superdrinks.ash>;
if(stills_available()>0) make_superdrinks();
When run as part of a beforeBattleScript, if you don't have all the ingredients right away but pick them up later, it'll start making drinks right away.

It can also be run as a standalone script. Just type "superdrinks" in the CLI.

There are several zlib settings that should be set to properly make drinks how you like. Without setting variables, it will make drinks by making what you have the least of. However, for a more personal selection, set these zlib vars:

superdrink_preferred:
none: default behavior, makes drinks that you have the least of
drink: Only make that specified drink, such as Mae West
garnish: makes drinks using only that kind of garnish, such as coconut shells
most: makes drinks using the garnish you have the most of
stat: makes drinks that give only the single stat you specify, such as moxie
single: only makes drinks that provide one kind of stat bonus
day: if today is a stat bonus day, make those single stat drinks, otherwise, treat as 'single' setting
refine: only makes single stat drinks using the garnish you have the most of <=excellent one to use
sake: only makes infused sake drinks
salty: makes as many salacious cocktails as it can before switching to the 'single' setting
ooze-o: only makes bottles of ooze-o

superdrink_only_preferred:
true/false: When true, the script will stop when you cannot make any more of your preferred drink, otherwise it will loosen restrictions to make more drinks until you're out of still uses.

superdrink_use_sake:
superdrink_use_salty:
superdrink_use_ooze-o:

true/false: if true, include these kinds of drinks in calculation. If your preferred drink is either of these, these will register as true.

superdrink_tempmall:
true/false: If true, will temporarily override your setting "autoSatisfyWithMall" to purchase ingredients from the mall and will set it back to false at the end. If you already have it as true, it will leave it alone.

superdrink_accuracy:
float: Determines the accuracy of prices used. The lower the number, the higher the accuracy, but this will require more frequent server hits. As SHC drinks tend to be somewhat stable, this shouldn't need to be changed.

superdrink_profit:
yes/true: Makes drinks that you can make the most profit off of.
no/false: doesn't factor in costs and just makes drinks
auto/mall: Makes most profitable drinks, puts them in your mall store**, and sets a competitive price (95% as reported by historical value). If you use this feature, it is advised that you use either 'single', 'refine', or 'none' as your preferred drink setting. If you have no shop, it will simply act as if you had set this to 'true'.
clan/stash: Makes drinks and puts them in your clan's stash**, you altruistic person you! If you are not currently part of a clan, it will simply act as if you had set this to 'false'.
**In the case of mall selling or clan stashing, if you are in Ronin or Hardcore, it will not transfer drinks. This way, you don't have to worry about forgetting to change the value and accidentally lose all your drinks for the day.

v706: Added check_version, flag check to keep Supershake() from false positives, added zLib var for preferred drink
v707: Fixed bug that would cause nothing to ever be made if you didn't have 0 of a drink.
v708: Fixed a bug that mixed up drink recipes. (Not so much a bug as a misunderstanding of the sort explanation.) Added ability to buy from mall. Reworked recipe records (ha!) into a datafile.
v709: Eliminated data file and now uses a more dynamic recipe system. Laid groundwork for making profitable drinks.
v710: Refined recipe creation, can now be used to calculate how profitable drinks are to make AND make them accordingly. Set your zlib verbosity to 6 to get heavy details. This has been tested on 3 accounts and seems to be working well. However, none of the accounts have easy access to sea items and no access to Salacious Cocktailcrafting. Please read through the script to understand the settings. All error reporting would be appreciated.
v711: Fixed 'return' error that was causing recipes to be made at Mafia's whim and expanded creation plans.
v712: Tidied up some code and added make_superdrinks() for importing. Fixed error where having a preferred drink and mall buying enabled couldn't properly execute the script.
v713: Tidied up the code and added debug info (verbosity 10) should it be needed as well as a host of improvements, including vastly simplifying mall selling. And let me tell ya, mall selling works great! Safety is gone!
v714: Added Ooze-O processing, fixed bug where suddenly being unable to make drinks would not mall/stash your drinks.
v715: Cleaned and tweaked code.
v716: Reworked code to not need separate library. You still need zlib, but that shouldn't be much of an issue.
v717: Moved to SVN. Reformat code. Added try..finally to allow drinks made to always show.
 
Last edited:

oly0015

Member
Nice job, I made one also last week, you might want to think about putting the drink recipe's into a structured array. If you feel creative beyond just going by what you have least of its only a couple more lines to sort by the cheapest to make and most profit.
 

slyz

Developer
I think he meant something like:
PHP:
record recipee {
    item improved_booze;
    item base_booze;
    item booze_ingredient;
    boolean hippy_store_sells;
    item improved_mixer;
    item base_mixer;
    item garnish;
}
recipee [ item ] Superdrink;
instead of
PHP:
item [ item,item,item,boolean,item,item,item ] Superdrink;
 

Fluxxdog

Active member
I tried looking over the Records explanation in the wiki, but I think that's confusing me more. How exactly would I replace those 13 lines that define the map and recipes?
 

heeheehee

Developer
Staff member
PHP:
record recipee {
    item improved_booze;
    item base_booze;
    item booze_ingredient;
    boolean hippy_store_sells;
    item improved_mixer;
    item base_mixer;
    item garnish;
}
recipee [ item ] Superdrink;

Just like that, except there should be a ; after the closing } of the record. You'd then call it via Superdrink[$item[gimlet]].garnish, for instance.
 

slyz

Developer
How exactly would I replace those 13 lines that define the map and recipes?
You would need a line to define each field:
PHP:
record recipee {
    item improved_booze;
    item base_booze;
    item booze_ingredient;
    boolean hippy_store_sells;
    item improved_mixer;
    item base_mixer;
    item garnish;
};
recipee [ item ] Superdrink; 
Superdrink[ $item[ Neuromancer ] ].improved_booze = $item[ bottle of Calcutta Emerald ];
Superdrink[ $item[ Neuromancer ] ].base_booze = $item[ bottle of gin ];
...
This way you could simply pass a record to Supershake(), canI_Superbooze() and canI_Superfruit(), which would become, for example:
PHP:
boolean canI_Superbooze( recipee rec )
{
	//Do I have the Superbooze?
	if ( possess_item( rec.improved_booze ) ) return true;
	//Can I use the still?
	else if (stills_available() > 0) 
	{
		//Do I have the base_booze?
		if ( possess_item( rec.base_booze ) ) return true;
		//Do I have the ingredient to make the base_booze?
		else if ( possess_item( rec.booze_ingredient ) ) return true;
		//Do the frat boys own the produce stand?
		//Can it sell the ingredient?
		else if ( get_property( "currentHippyStore") == "fratboy" && rec.hippy_store_sells )
			return true;
		else return false;
	}
	else return false;
}

It doesn't really change the way the script works, just the way data is stored. It's more readable by humans, but that's about the only advantage I can see.

You can also, for example, add a "price" field, where you store the cost of making the cocktail.

Regarding your script: why not have it go through all the supercocktails and check if creatable_amount() gives something other than 0?
 
Last edited:

oly0015

Member
Slyz right, more readable by humans / store extra data

On mine I actually hold the data in three arrays of record parts separated by still cost. That way i can specify a drink code to tell the script what mix of drinks to make beyond just the top SHC drinks. The other advantage is that if theres an odd number of still uses i can call back the script from itself at the end to use the remainder based off a modulus of the still.

to save ya a bit of typing:

PHP:
		record parts
		{
		item p1;
		item p2;
		item p3;
		item p4;
		int profit;
		int stillcost;
		};
		parts[item] recipe3;
		recipe3 [$item[Neuromancer]].p1 = $item[Bottle of Gin];
		recipe3 [$item[Neuromancer]].p2 = $item[Olive];
		recipe3 [$item[Neuromancer]].p3 = $item[Coconut Shell];
		recipe3 [$item[Vodka Stratocaster]].p1 = $item[Bottle of Vodka];
		recipe3 [$item[Vodka Stratocaster]].p2 = $item[Olive];
		recipe3 [$item[Vodka Stratocaster]].p3 = $item[Coconut Shell];
		recipe3 [$item[Mon Tiki]].p1 = $item[Bottle of Rum];
		recipe3 [$item[Mon Tiki]].p2 = $item[Lemon];
		recipe3 [$item[Mon Tiki]].p3 = $item[Coconut Shell];
		recipe3 [$item[Teqiwila Slammer]].p1 = $item[Bottle of Tequila];
		recipe3 [$item[Teqiwila Slammer]].p2 = $item[Lemon];
		recipe3 [$item[Teqiwila Slammer]].p3 = $item[Coconut Shell];
		recipe3 [$item[Divine]].p1 = $item[Bottle of Whiskey];
		recipe3 [$item[Divine]].p2 = $item[Orange];
		recipe3 [$item[Divine]].p3 = $item[Little Paper Umbrella];
		recipe3 [$item[Gordon Bennett]].p1 = $item[Boxed Wine];
		recipe3 [$item[Gordon Bennett]].p2 = $item[Orange];
		recipe3 [$item[Gordon Bennett]].p3 = $item[Little Paper Umbrella];
		recipe3 [$item[Gimlet]].p1 = $item[Bottle of Gin];
		recipe3 [$item[Gimlet]].p2 = $item[Soda Water];
		recipe3 [$item[Gimlet]].p3 = $item[Little Paper Umbrella];
		recipe3 [$item[Yellow Brick Road]].p1 = $item[Bottle of Vodka];
		recipe3 [$item[Yellow Brick Road]].p2 = $item[Soda Water];
		recipe3 [$item[Yellow Brick Road]].p3 = $item[Little Paper Umbrella];
		recipe3 [$item[Mandarina Colada]].p1 = $item[Bottle of Rum];
		recipe3 [$item[Mandarina Colada]].p2 = $item[Grapefruit];
		recipe3 [$item[Mandarina Colada]].p3 = $item[Magical Ice Cubes];
		recipe3 [$item[Tangarita]].p1 = $item[Bottle of Tequila];
		recipe3 [$item[Tangarita]].p2 = $item[Grapefruit];
		recipe3 [$item[Tangarita]].p3 = $item[Magical Ice Cubes];
		recipe3 [$item[Mae West]].p1 = $item[Bottle of Whiskey];
		recipe3 [$item[Mae West]].p2 = $item[Strawberry];
		recipe3 [$item[Mae West]].p3 = $item[Magical Ice Cubes];
		recipe3 [$item[Prussian Cathouse]].p1 = $item[Boxed Wine];
		recipe3 [$item[Prussian Cathouse]].p2 = $item[Strawberry];
		recipe3 [$item[Prussian Cathouse]].p3 = $item[Magical Ice Cubes];
 
Last edited:

Bale

Minion
In case you care, this works also...

PHP:
recipe3 [$item[Neuromancer]] = new parts($item[Bottle of Gin], $item[Olive], $item[Coconut Shell]);
recipe3 [$item[Vodka Stratocaster]] = new parts($item[Bottle of Vodka], $item[Olive], $item[Coconut Shell]);
recipe3 [$item[Mon Tiki]] = new parts($item[Bottle of Rum], $item[Lemon], $item[Coconut Shell]);
recipe3 [$item[Teqiwila Slammer]] = new parts($item[Bottle of Tequila], $item[Lemon], $item[Coconut Shell]);
recipe3 [$item[Divine]] = new parts($item[Bottle of Whiskey], $item[Orange], $item[Little Paper Umbrella]);
recipe3 [$item[Gordon Bennett]] = $item[Boxed Wine], $item[Orange], $item[Little Paper Umbrella]);
recipe3 [$item[Gimlet]] = new parts($item[Bottle of Gin], $item[Soda Water], $item[Little Paper Umbrella]);
recipe3 [$item[Yellow Brick Road]] = new parts($item[Bottle of Vodka], $item[Soda Water], $item[Little Paper Umbrella]);
recipe3 [$item[Mandarina Colada]]. = new parts($item[Bottle of Rum], $item[Grapefruit], $item[Magical Ice Cubes]);
recipe3 [$item[Tangarita]] = new parts($item[Bottle of Tequila], $item[Grapefruit], $item[Magical Ice Cubes]);
recipe3 [$item[Mae West]] = new parts($item[Bottle of Whiskey], $item[Strawberry], $item[Magical Ice Cubes]);
recipe3 [$item[Prussian Cathouse]] = new parts($item[Boxed Wine], $item[Strawberry], $item[Magical Ice Cubes]);

I prefer that method of defining record values.
 

Fluxxdog

Active member
OK, I see now. 'record' is more useful for data that's expected to change or have unknown values. For calculating mall prices and profit, that would be handy. I think I'm pretty safe then since I'm not using this for direct profit. The basic aim of this now is to allow you to make as many Superhuman drinks as possible. Picture it more like a HC scenario where you have the still and obviously limited resources.
Regarding your script: why not have it go through all the supercocktails and check if creatable_amount() gives something other than 0?
One of the things I'm looking at for later versions is the option to hunt for your booze ingredients, for example if you need cactus fruit for tequila so you can make bottles of Jorge Sinsonte so you can make a preferred drink. This will allow (however unoptimal it might be) to automate a bit of farming for booze ingredients. There are only 3 items you would need to do this for: brown sugar cane, cactus fruit, and square grapes. Basically, consider this the start of something much grander in scope. Some of the later plans will process Pete's Sake, make underwater drinks, and go after Salacious cocktails. Futher work will automate regular Advanced Cocktails, check for preferences based on your mainstat, check for ungarnished drinks, calculating potential profit for making each item from mall selling (still might not need to use records), and other details I haven't even thought of yet.

This is but the core of bigger things yet to come. By the time I'm done, this script alone will have grown in size as well as the "aftercoretest.ash" personal library. (You can thank zarqon for that last idea.) Right now, I'm just getting the basics tested and stream lined. The first version I had was about 230 lines long, with different calls and checks for each individual recipe.

Some other things I need to learn is how to check for different options set in Mafia, like is buying from mall or NPCs enabled or can it automate pulls from the clan stash. This scripts uses an assumption of false, true, true right now. Not everyone is going to use those. I'm studying the ZLib Relay Manager scripts for that.
 

heeheehee

Developer
Staff member
Code:
alias prefref => ashq record r{string d ; }; r[string,string]m; file_to_map("defaults.txt",m); foreach t,p,d in m if(to_lower_case(p).contains_text(to_lower_case($string[%%]))) print(p+" ("+t+", now '"+get_property(p)+"', default '"+d.d+"')")

Use this to search more easily for Mafia's preferences.

Code:
> prefref satisfy

autoSatisfyWithCloset (global, now 'false', default 'false')
autoSatisfyWithMall (global, now 'true', default 'false')
autoSatisfyWithNPCs (global, now 'true', default 'false')
autoSatisfyWithStash (global, now 'false', default 'false')

Ooh, lookies, that's all of 'em!

Edit: Granted, you do need to have a rough idea of what the preference should look like. But I guess "prefref mall" is intuitive enough.
 
Last edited:

Fluxxdog

Active member
Huh, so it's as simple as a get_property(), eh? Well, that make things MUCH easier. I can easily expand the script to accommodate the different preferences. GLOBAL_prefs.txt and fluxxdog_prefs.txt can provide me with the rest of the answers for that then. Thanks!
 

Winterbay

Active member
Basically, consider this the start of something much grander in scope. Some of the later plans will process Pete's Sake, make underwater drinks, and go after Salacious cocktails. Futher work will automate regular Advanced Cocktails, check for preferences based on your mainstat, check for ungarnished drinks, calculating potential profit for making each item from mall selling (still might not need to use records), and other details I haven't even thought of yet.

Oh. I'd love that. My farming DB-multi would love to be able to automagically create sea-drinks :)
 

Fluxxdog

Active member
Hooray! Update with check_version(). Found a logic hole where if you have 1 still use left, if would return a false positive that it could make the drink if you needed to make the fruit AND the booze. Also added a var to allow a preference for making certain drinks.
 

Fluxxdog

Active member
New version up with a bug fix. Should have caught it sooner, but I was in the middle of an ascension. Fixed a bug that would only make drinks that you had 0 of and fixed that as a "preferred drink".
 

Winterbay

Active member
Seeing as the new in-a-boxes-system and mafia is not fully cooperating this script is also failing. In order to fix this temporarily I've commented out line 70-74. This means that if my bartender breaks I will risk using turns but I'll have to accept that for now I guess :)
 

fronobulax

Developer
Staff member
I cannot speak for this script, but EatDrink (which crafts and consumes) has worked since the Crafting Change provided that I have unchecked use in-a-boxen, manually made sure the appropriate items are in my kitchen, including the in-a-boxen and has at least one adventure. That seems to fake out mafia enough so that it uses the new features. This thread seems to be the largest repository of information about what doesn't work and how to work around it until mafia gets updated.
 

Winterbay

Active member
The offending line is
Code:
if (!have_bartender() && in_aftercore())

And since Mafia cannot detect that you have a Bartender any more it returns false and thus no drinks are made. With that if-statement commented out it works just fine (provided I have unchecked the boxes to require one).
 

Fluxxdog

Active member
With the newer updates, it works now. Had to have a bit of patience and make the drinks by hands until then, but it works now ^^
 
Top