Tower Helper - info utility / wrapper for mafia's tower automation

zarqon

Well-known member
Tower Helper 1.0

NOTE: This script does not apply to the current tower and is obsolete. A script beginning with O handles this now.

Time to climb the tower! Swell! I think in my customary italics. I'll just type "tower" into the CLI because mafia handles it all automatically!

Round 1: zarqon casts RETURN!

What! Oh crap, I didn't have a <dinglehopper>.

So, I wrote this little utility to make it even more foolproof. Call this anytime during your run for a list of which tower items you definitely/might need. If you're out of Ronin, it will buy any possibly needed items which you lack. It's smart about which items you might need though -- if you have a fully (or almost fully) upgraded telescope, it won't waste time with unneeded tower items.

If you call this in the window between completing the Level 12 quest and freeing the King, it will also run mafia's built-in tower automation after checking -- unless you're lacking any definitely needed items, in which case it will abort.

Basically, using this script as a wrapper for mafia's tower handling guarantees no wasted turns for people a) in aftercore, and 2) with complete telescopes. It is also a way to make telescope information easily available during your run in the CLI.

To use it:
  • Download it.
  • Type "safetower" in the CLI.
That's it! It doesn't even need ZLib.

Thanks to: Bale for saving me time by making his relay override telescope script available for code theft!
 

Attachments

  • safetower.ash
    3.1 KB · Views: 77
Last edited:

matt.chugg

Moderator
This is the most awesome line of code i've ever seen!

Code:
print("You "+((v)?"DEFINITELY":"might")+" need a "+i+" (have: "+item_amount(i)+")",((item_amount(i) > 0)?"green":((v)?"red":"olive")));

I only have 5 upgrades on my telescope, so its setting everything to false on this line:

Code:
if (count(res) < 6) foreach s,i in t res[i] = false;

is this desired behaviour? I think it would be useful to know the 5 items I definatly require still?
 

zarqon

Well-known member
Aha. It used to say

if (res[i]) {}

which avoided that problem but didn't seem to work -- I'd assumed referencing the key would initialize it if it didn't exist, but somehow that didn't work. I fixed that problem on a telescope-but-no-upgrades character, and forgot the actual purpose of the line of code when I did. It tested alright. Ha.

Fixed.

PS: this.
 
Last edited:

Bale

Minion
I've got this little thing I've been working on. Would you care to finish it and integrate it with your script? It's got some odd bug I haven't pinned down where sometimes it won't zap a key for no discernible reason.

PHP:
// Zap if neccessary for the third key, but only if wand not used yet today
boolean zapkey(item missing_key) {
	boolean zapp(item whatsit) {
		if(item_amount(whatsit) == 0)
			return false;
		print("Zapping a "+whatsit+" into a "+missing_key+".", "blue");
		cli_execute("zap 1 "+whatsit);
		return true;
	}
	
	int whichwand = 0;
	for i from 1268 to 1272
		if(item_amount(to_item(i)) > 0) whichwand = i;
	switch {
	case whichwand == 0:
		print("You don't have a wand and you're one Daily Dungeon key short. Icky!", "red");
		return false;
	case contains_text(visit_url("wand.php?whichwand="+whichwand),"feels warm"):
		if(!user_confirm("You've already used your wand today. Are you willing to risk it to get your third DD Key?")) {
			print("Wand is warm and you're one Daily Dungeon key short. Icky!", "red");
			return false;
		}
	case zapp($item[Boris key]):
	case zapp($item[Sneaky Pete key]):
	case zapp($item[Jarlsberg key]):
	}
	if(item_amount(missing_key) < 1) {
		print("You can't seem to get the Daily Dungeon key you need. Icky!", "red");
		return false;
	} else print("Zap successful!", "green");
}

void balloon_monkey() {
	if(item_amount($item[balloon monkey]) > 0)
		visit_url("lair2.php?preaction=key&whichkey=436&pwd");
}

boolean check_keys() {
	boolean have_key = true;
	foreach key in $items[skeleton key, digital key, Richard star key]
		if(item_amount(key) < 1) {
			print("You don't have a "+key+".", "red");
			have_key = false;
		}
	if(!have_key) return false;
	item [int] lost;
	foreach key in $items[Boris key, Jarlsberg key, Sneaky Pete key]
		if(item_amount(key) < 1) {
			lost[count(lost)] = key;
			print("You don't have a "+key+".", "red");
		}
	if(count(lost) == 0) return true;
	if(count(lost) == 1) {
		if(zapkey(lost[0]))
			return entryway();
	}
	return false;
}

boolean hedging() {
    boolean success = false;
	int maze_trips = 0;

	while(my_adventures() > 0 && !success) {
		if(item_amount($item[hedge maze puzzle]) == 0) {
			adventure(1, $location[hedge maze]);
			maze_trips = maze_trips + 1;
			if(maze_trips > 1)
				print("Entered the Hedge Maze "+ maze_trips + " times.");
			else 
				print("Entered the Hedge Maze once.");
		}
		if(item_amount($item[hedge maze puzzle]) > 0)
			success = hedgemaze();
	}
	return success;
}

item [slot] save_outfit() {
	item [slot] save;
	foreach slt in $slots[hat, weapon, pants, acc1, acc2, acc3, familiar]
		save[slt] = equipped_item(slt);
	if(weapon_hands(save[$slot[weapon]]) < 2)
		save[$slot[off-hand]] = equipped_item($slot[off-hand]);
	if(have_skill($skill[torso awaregness]))
		save[$slot[shirt]] = equipped_item($slot[shirt]);
	return save;
}

void restore_outfit(familiar start_familiar, item [slot] start_outfit) {
	use_familiar(start_familiar);
	foreach slt in start_outfit
		equip(slt, start_outfit[slt]);
}

boolean use_sombrero() {
	foreach key in $familiars[Baby Sandworm, Hovering Sombrero]
		if(have_familiar(key)) return use_familiar(key);
	return false;
}

// Inside the entrance to the Lair, you've encountered three strange gates. An inscription provides a clue on how you might pass through them...
// Having made it through the three gates, you've encountered a giant mirror that blocks your way deeper into the Lair.
// You've come to an odd junction in the cave leading to the Sorceress' Lair. It seems that in order to proceed, you'll need to solve a really convoluted and contrived puzzle involving a cloud of gas, a locked door, and three statues of mariachis.
// The Council of Loathing has instructed you to make your way to the top of the Naughty Sorceress' Tower and defeat her. Currently, you're stuck in a hedge maze, Don't beat around the bush, get through it!
// You've passed through the gates, solved a fiendish puzzle, beat the hedge maze like a psychotic landscaper, and now you're facing a fiendish monster on the first level of the sorceress's tower.
// You've passed through the gates, solved a fiendish puzzle, beat the hedge maze like a psychotic landscaper, and now you're facing a fiendish monster on the second level of the sorceress's tower.
// You've passed through the gates, solved a fiendish puzzle, beat the hedge maze like a psychotic landscaper, and now you're facing a fiendish monster on the third level of the Sorceress's tower.
// You've passed through the gates, solved a fiendish puzzle, beat the hedge maze like a psychotic landscaper, and now you're facing a fiendish monster on the fourth level of the sorceress's tower.
// You've passed through the gates, solved a fiendish puzzle, beat the hedge maze like a psychotic landscaper, and now you're facing a fiendish monster on the fifth level of the sorceress's tower.
// You've passed through the gates, solved a fiendish puzzle, beat the hedge maze like a psychotic landscaper, and now you're facing a fiendish monster on the sixth level of the sorceress's tower.
// You've solved many puzzles, and now are confronted with the most frustrating puzzle yet. Can you figure out the code to get through the heavy door?
// You're almost to the final epic showdown battle countdown of fate and destiny and whatnot! Get in there and kick some tail!
// You thought you were finally going to fight the Sorceress, but you're still stuck battling her minions. This one seems to be a shadowy, evil version of you, except it doesn't have a goatee.
// You find yourself fighting one of the Sorceress's freakishly overgrown familiars. What is she feeding them, anyway?
// This is it, sparky -- the big showdown with the Naughty Sorceress. I just wanted to say, "good luck - we're all counting on you."
int test_lair() {
	string questlog = visit_url("questlog.php?which=1");
	if(questlog.contains_text("encountered three strange gates"))
		return 1;
	if(questlog.contains_text("encountered a giant mirror"))
		return 2;
	if(questlog.contains_text("three statues of mariachis"))
		return 3;
	if(questlog.contains_text("you're stuck in a hedge maze"))
		return 11;
	if(questlog.contains_text("fiendish monster on the first level"))
		return 21;
	if(questlog.contains_text("fiendish monster on the second level"))
		return 22;
	if(questlog.contains_text("fiendish monster on the third level"))
		return 23;
	if(questlog.contains_text("fiendish monster on the fourth level"))
		return 24;
	if(questlog.contains_text("fiendish monster on the fifth level"))
		return 25;
	if(questlog.contains_text("fiendish monster on the sixth level"))
		return 26;
	if(questlog.contains_text("figure out the code"))
		return 31;
	if(questlog.contains_text("almost to the final epic showdown"))
		return 32;   //  Need to use the huge mirror shard
	if(questlog.contains_text("shadowy, evil version of you"))
		return 33;
	if(questlog.contains_text("freakishly overgrown familiars"))
		return 34;
	if(questlog.contains_text("big showdown with the Naughty"))
		return 40;
	return 0;
}

boolean enter_thelair() {
	familiar start_familiar = my_familiar();
	item [slot] start_outfit = save_outfit();
	
	repeat {
		switch(test_lair()) {
		case 0:
			print("You can't handle the lair", "red");
			return false;
		case 1:
		case 2:
		case 3:
			cli_execute("maximize hp, -tie, switch disembodied hand");
			boolean good = true;
			if(!entryway()) {
				good = false;
				switch(test_lair()) {
				case 1:
					print("You don't have the necessary items to pass the three gates!", "red");
					break;
				case 2:
					print("You couldn't pass teh mirror in the Lair? WTF?!!", "red");
					break;
				case 3:
					if(check_keys()) good = true;
					else print("You need more keys to enter the Lair!", "red");
				}
			}
			restore_outfit(start_familiar, start_outfit);
			if(!good) return false;
			balloon_monkey();
		
		case 11:
			if(!hedging()) {
				print("You can't make it through the Hedge Maze!", "red");
				return false;
			}
		
		case 21:
		case 22:
		case 23:
		case 24:
		case 25:
		case 26:
		case 31:
		case 32:
		case 33:
		case 34:
			#cli_execute("maximize hp, -tie, -familiar");
			use_sombrero();
			item pass = guardians();
			int lair = test_lair();
			if(lair < 30)
				print("You need a "+pass+" to defeat the guardian on level "+(lair - 20), "red");
			else if(lair == 33)
				print("You could not defeat your shadow", "red");
			else if(lair == 34)
				print("You're still fighting the Sorceress's freakishly overgrown familiars", "red");
			restore_outfit(start_familiar, start_outfit);
			if(lair < 40)
				return false;
		case 40:
			print("You are ready to fight her Naughtiness!", "green");
			return true;
		}
	} until(false);
	return false;
}

void main() {
	enter_thelair();
}
 

slyz

Developer
I think nothing happens when you have 3 keys. Maybe
PHP:
if(count(lost) == 0) return true; 
if(count(lost) == 1) { 
	if(zapkey(lost[0])) 
		return entryway(); 
} 
return false;
should be something like this:
PHP:
if(count(lost) > 1) return false; 
if(count(lost) == 1 && !zapkey(lost[0])) return false; 
return entryway();

I couldn't find any problem with zapkey() when you have 2/3 DD keys though.
 
Top