-Request- Breakfast functionality/collecting "free" items

Vandire

New member
Hi,

I'm not sure if this is the right section for this, but there are four things that I'd really like scripted or included in KoLMafia.

1) Shake tea tree on login/breakfast. Or ideally have a breakfast preference for shaking/picking a tea.
2) Select my three aftercore clip-art summons during breakfast.
3) Collect my three free gene tonics during breakfast.
4) Select my 3 favoured deck of every card cards on login/breakfast.

If anyone can script this (or include it in KoLMafia) I'll pay 5 million meat per thing. (I realise this isn't much, but I'm quite meat-light right now. If need be I'm sure I can sort out a better reward!)

Thanks in advance, and apologies if this is inappropriate for this forum.
 

heeheehee

Developer
Staff member
Save the following as a .txt in your scripts folder (modifying individual parts as needed), where Mafia is located (assuming Windows; Linux and OS X "install" to specific directories):
Code:
teatree shake
create borrowed time, potion of the field gar, potion of punctual companionship
camp dnapotion 3
cheat spades
cheat laboratory
cheat wands
Then set it as your loginScript: General -> Preferences -> Automation -> On Login: whateverTheScriptIsCalled.txt
(Mafia will look for said script in its search path)

edit: if you instead wanted to pick a specific tea, you could use "teatree royal". If you wanted to do anything fancier than this, you'd probably want to switch over to an ASH script, but there's typically no need when you simply need to perform a sequence of actions.
 

fronobulax

Developer
Staff member
2) and 4) will probably never be mafia options. They require some kind of user choice - your favored choices might not be mine, and my choices may differ based on path, for example - so just hardwiring something is not going to work. Making the choices configurable is a lot harder than creating a script as the obvious choice for a Dev is to let a script do it. I think there are ash commands for 1, 2 & 4 so scripting should not be too hard. Bale wrote a script that decided what to summon based upon mall prices. That could be adapted.
 

Vandire

New member
Save the following as a .txt in your scripts folder (modifying individual parts as needed), where Mafia is located (assuming Windows; Linux and OS X "install" to specific directories):
Code:
teatree shake
create borrowed time, potion of the field gar, potion of punctual companionship
camp dnapotion 3
cheat spades
cheat laboratory
cheat wands
Then set it as your loginScript: General -> Preferences -> Automation -> On Login: whateverTheScriptIsCalled.txt
(Mafia will look for said script in its search path)

edit: if you instead wanted to pick a specific tea, you could use "teatree royal". If you wanted to do anything fancier than this, you'd probably want to switch over to an ASH script, but there's typically no need when you simply need to perform a sequence of actions.

Hey, thanks a lot!

I'll give this a try. Is your in-game name the same as your forum name?
 

Bale

Minion
Hi,

I'm not sure if this is the right section for this, but there are four things that I'd really like scripted or included in KoLMafia.

1) Shake tea tree on login/breakfast. Or ideally have a breakfast preference for shaking/picking a tea.
2) Select my three aftercore clip-art summons during breakfast.
3) Collect my three free gene tonics during breakfast.
4) Select my 3 favoured deck of every card cards on login/breakfast.

If anyone can script this (or include it in KoLMafia) I'll pay 5 million meat per thing. (I realise this isn't much, but I'm quite meat-light right now. If need be I'm sure I can sort out a better reward!)

Thanks in advance, and apologies if this is inappropriate for this forum.

Or if you want it to select your teatree, and clip-art summons based on current mall prices, I've already got code for that in my own logoutScript. Here's some sharing:

Code:
int price(item it) { return historical_age(it) > .8? mall_price(it): historical_price(it); }

// Original version by darkcodelagsniper at http://kolmafia.us/showthread.php?19211-potted-tea-tree&p=128971&viewfull=1#post128971
void mallcuppa() {
	if(get_property("_pottedTeaTreeUsed") == "false" && get_campground() contains $item[potted tea tree]) {
		string cup;
		item [int] cuppas;
		float pricetotal;
		for i from 8601 to 8637 {
			cuppas[ count(cuppas) ] = to_item(i);
			pricetotal += price(to_item(i));
		}
		sort cuppas by -price(value);
		int shaketree = pricetotal / 37 * 3;
		print("Average value from shaking the tea tree is " + shaketree + " meat","blue");
		print("Single most expensive cuppa tea is " + cuppas[0] + " at " + historical_price(cuppas[0]) + " meat","blue");
		if(shaketree > historical_price(cuppas[0]))
			cup = "shake";
		else cup = cuppas[0].to_string();
		cli_execute("teatree " + cup);
		# if(cup != "shake")
		#	put_shop(mall_price(to_item(cup)), 0,  to_item(cup));
	}
}

void clip_mall() {
	int tomeLeft = 3- get_property("_clipartSummons").to_int();
	if(!have_skill($skill[Summon Clip Art]) || tomeLeft < 1 || !can_interact()) return;
	item [int] clip;
	for i from 5224 to 5283
		clip[count(clip)] = to_item(i);
	sort clip by -(price(value));print(clip[0]);
	create(tomeLeft, clip[0]);
	print("Sell "+tomeLeft+" "+(tomeLeft > 1? to_plural(clip[0]):clip[0])+" @ "+historical_price(clip[0]), "blue");
	# put_shop(historical_price(clip[0]), 0, tomeLeft,  clip[0]);
}

// This is a much less sophisticated function because I simply assumed that blue mana and the 1952 Mickey Mantle card will always be best
// Some day I should rewrite this to always check the mall
void cheating() {
	string picks = visit_url("inv_use.php?cheat=1&whichitem=8382&pwd="+my_hash());
	run_choice(2);
	foreach card in $strings[Island, Ancestral Recall, 1952 Mickey Mantle]
		if(get_property("_deckCardsDrawn").to_int() < 11 && picks.contains_text(card + "</option>"))
			cli_execute("cheat " + card);
}

void main() {
	if(can_interact()) {
		mallcuppa();
		clip_mall();
		cheating();
		cli_execute("camp dnapotion 3");
	}
}

Save it with the extension .ash and otherwise follow the previous directions to make it your loginScript...
General -> Preferences -> Automation -> On Login: whateverTheScriptIsCalled.ash
 

VladYvhuce

Member
I just put each of the things that Mafia doesn't handle in breakfast as Daily Deeds custom buttons. To do this for whatever cards you want: Go to Preferences and then select Daily Deeds. Next, select Add Custom. For cards and stuff like soaking in the mayo vat, you can use the Simple setup. Add a button name, set the max uses (1 for cards and single-use skills), and then type in the command. For a 1952 Mickey Mantle card, you'll want to use "play 1952 mickey mantle", without the quotes, of course. For variable cards, you'll want something like "play X of diamonds" or whatever variable card you want. Personally, I prefer this method over scripted automation, because it lets me choose something from Mafia's deck of every card selector, if I'm doing alright on meat and want some other benefit. For items, you can do the same basic thing, but use the Item setup.
 

Bale

Minion
For cards and stuff like soaking in the mayo vat, you can use the Simple setup. Add a button name, set the max uses (1 for cards and single-use skills), and then type in the command. For a 1952 Mickey Mantle card, you'll want to use "play 1952 mickey mantle", without the quotes, of course. For variable cards, you'll want something like "play X of diamonds" or whatever variable card you want.

Hate to mention this, but "Deck of Every Card" is a Built-In Deed. If you add that to your list you get a drop-down menu with all the cards and a hover tool-tip for each to explain what they do.
 

VladYvhuce

Member
Hate to mention this, but "Deck of Every Card" is a Built-In Deed. If you add that to your list you get a drop-down menu with all the cards and a hover tool-tip for each to explain what they do.
Yes, but you have to wait for Mafia to process the card request each time you pick a card to cheat with. You have to select your card, hit "draw", wait, then repeat the process. Most typically, I just want the 1952 card, the diamonds card, and the coins card. So, I made buttons for those. It's just a little convenient shortcut. Just click, click, click and then wait.
 

Bale

Minion
Gotcha! Did you consider making one button that does all three cards? "cheat mickey; cheat diamond; cheat coins;" Then you'll only have to click once before you wait.
 

Bale

Minion
Yup! You can string together any number of CLI commands as long as you put semi-colons between them.

Note that there are a couple of commands that cannot be followed by another. Alias for instance, for very obvious reasons. There might be another few somewhere that I never use.
 

VladYvhuce

Member
But, if I wanted to use a number of items, I could tell it "use item1; use item2;" and so on? I have a number of single-use items that Mafia won't use during breakfast.
 

Bale

Minion
Yup!

Though for stuff you want during breakfast I'd suggest writing a loginScript. That way the item can check its preference to see if it has been used yet that day and use itself automatically if not. You won't have to remember a thing. At least, that's how I do it.
 

VladYvhuce

Member
For now, I'll stick to just consolidating most of my items to a button. Sometimes, I want to wait for a while, then load up on my bonuses. Not waste the good stuff on some small-fry baddies. Then, go forth and kick tougher baddies' butts with said bonuses. No sense in jacking my stats up, just to fight some badguys I could kill with a stern look. No, those bonuses come in more handy when I'm done goofing around and ready to get to some serious fighting. But, I'm considering making a script that would handle these items that I could just select from the script list when I'm ready for them.
 

Bale

Minion
I'm glad you're thinking about what you want for yourself. This is just me informing you about some of the options you might not know.
 

VladYvhuce

Member
And I thank you for that. Now that I've pulled a proverbial thorn out of my side, and worked up a between battle frankenscript, it's nice to have some suggestions on where to go from here.
 

VladYvhuce

Member
Alright. I've worked up a basic little script for handling my "second breakfast" by overhauling my familiar script to handle items, instead. I've left out card cheating and mayosoaking on purpose. I haven't been able to figure out yet how to check if items have already been used. But, Mafia's nice enough to just say "(usable quantity of [item name] is limited to 0 by daily limit)", instead of breaking the script.

Code:
print("Reticulating Splines!", "Green");

void main() {
	Item it;
		foreach it in $items[red face paint, green face paint, jackass plumber home game, all-year sucker, heart of dark chocolate, eternal car battery, stabonic scroll, circle drum, red and green rain stick]
		if (it.item_amount() > 0)
			use(1, it);
			print("Splines Reticulated!", "Green"); 
	}
 

Bale

Minion
I haven't been able to figure out yet how to check if items have already been used.

Every item has its own preference to determine the answer to that. Unfortunately there isn't a rule for attributing a preference to an item, so it needs to be done on a case-by-case basis. Your way is brute force, but it does work quite well. You might not want to do it my way, but if anyone is curious there is a portion of my loginScript that looks like this...


Code:
void gyrocopter() {
	if(get_property("_warbearGyrocopterUsed") == "false" && can_interact() &&  price($item[warbear gyrocopter]) * .3 < price($item[broken warbear gyrocopter]) + price($item[warbear gyro])) {
		int max_price = 225000;
		if(item_amount($item[warbear gyrocopter]) > 0 || (price($item[warbear gyrocopter]) <= max_price && buy(1, $item[warbear gyrocopter], min(max_price, my_meat() * .75 )) > 0)) {
			print("Sending myself a Gyro!", "blue");
			#visit_url("curse.php?action=use&pwd&whichitem=7038&targetplayer="+my_name()+"&curse=0");
			cli_execute("throw warbear gyrocopter at " + my_name());
			cli_execute("refresh inventory");
			put_shop(mall_price($item[warbear gyro]), 0,  $item[warbear gyro]);
		}
	}
}

// These are normally controlled by "once a day items" preference: useCrimboToysHardcore & useCrimboToysSoftcore
void useToys() {
	gyrocopter();
	
	boolean get(item toy) {
		return item_amount(toy) > 0 
			|| (closet_amount(toy) > 0 && take_closet(1, toy))
			|| (can_interact() && storage_amount(toy) > 0 && take_storage(1, toy))
			|| (available_amount(toy) > 0 && retrieve_item(1, toy))  // Stupid free pulls (pony keg and microwave) don't follow the same runes as other storage items.
			|| (can_interact() && historical_price(toy) > 0 && my_meat() > 1002003 && historical_price(toy) < to_int(get_property("autoBuyPriceLimit")) && retrieve_item(1, toy));
	}
	
	boolean playwith(item toy, string prop) {
		if(get(toy) && (get_property(prop) == "" || get_property(prop) == "false"))
			return use(1, toy);
		return false;
	}
	
	while(get($item[cheap toaster]) && get_property("_toastSummons").to_int() < 3)
		use(1, $item[cheap toaster]);
	
	foreach car in $items[BittyCar MeatCar, BittyCar SoulCar, BittyCar HotCar]
		if(playwith(car, "_bittycar")) break;
	playwith($item[handmade hobby horse], "_hobbyHorseUsed");
	playwith($item[ball-in-a-cup], "_ballInACupUsed");
	playwith($item[set of jacks], "_setOfJacksUsed");
	playwith($item[Chester's bag of candy], "_bagOfCandyUsed");
	playwith($item[Emblem of Ak'gyxoth], "_akgyxothUsed");
	playwith($item[Idol of Ak'gyxoth], "_akgyxothUsed");
	playwith($item[burrowgrub hive], "burrowgrubHiveUsed");
	playwith($item[glass gnoll eye], "_gnollEyeUsed");
	playwith($item[KoL Con Six Pack], "_kolConSixPackUsed");
	playwith($item[Trivial Avocations board game], "_trivialAvocationsGame");
	playwith($item[creepy voodoo doll], "_creepyVoodooDollUsed");
	playwith($item[Taco Dan's Taco Stand Flier], "_tacoFlierUsed");
	playwith($item[cursed microwave], "_cursedMicrowaveUsed");
	playwith($item[cursed pony keg], "_cursedKegUsed");
	playwith($item[warbear soda machine], "_warbearSodaMachineUsed");
	playwith($item[warbear breakfast machine], "_warbearBreakfastMachineUsed");
	playwith($item[festive warbear bank], "_warbearBankUsed");
	playwith($item[Chroner trigger], "_chronerTriggerUsed");
	playwith($item[Chroner cross], "_chronerCrossUsed");
	playwith($item[picky tweezers], "_pickyTweezersUsed");
	playwith($item[The Cocktail Shaker], "_cocktailShakerUsed");
	playwith($item[infinite BACON machine], "_baconMachineUsed");
}

I've got my own reasons for disabling those items in breakfast. It's not really important to get into though, just assume I'm not entirely crazy to do it.

For face paint, I have this interesting function that uses 0, 1 or both face paints once a day. It is set up to automatically adjust the number of items it might use if there is eventually another item of that class...

Code:
	if(get_property("_loginAvatarPaint") == "") {
		item [int] paint;
		foreach it in $items[green face paint, red face paint]
			if(available_amount(it) > 0)
				paint[ count(paint) ] = it;
		if(count(paint) > 0) {
			print("Randomly choosing face paint for color.", "blue");
			foreach x, it in paint
				if(random(max(count(paint), 2)) == 0)
					use(1, it);
			set_property("_loginAvatarPaint", "painted");
		}
	}
 
Last edited:

VladYvhuce

Member
Ah. I still have a copy of my original "check each familiar" BB script. If that would work better than the "elegant familiar BB script" format for items, then I'll just modify a copy of it for items. Do I check for "can_interact()" or "_itemnameUsed"? Or both? Or something else?
 
Top