How to automate combat with tentacles from Dr. Stuart's tent or Evoke Eldritch Horror

I can start a fight with an eldritch tentacle at Dr. Stuart's tent with
Code:
visit_url("place.php?whichplace=forestvillage&action=fv_scientist");
run_choice(2);
or with
Code:
use_skill($skill[Evoke Eldritch Horror]);

But how can I automate those fights once they're started? I expected to be able to use run_combat(), but if the next line in my script is run_combat(), Mafia uses my Custom Combat settings, instead. Which is workable, but I'd rather not have a Custom Combat strategy set up just to deal with these once-a-day fights. I'm confused about why run_combat() doesn't get triggered here, even though it works when I start a fight with eg. a Witchess piece using visit_url().
 

fronobulax

Developer
Staff member
Veracity's VeracityMeatFarm.ash has code that will fight the tentacle so your "how to" is probably answered there.

I'm not sure I understand your point about not wanting to set up a CCS. Can't you just use your default or add a tentacle as a "case" and just autoattack?
 
Thanks for your reply. I'd actually referenced Veracity's meatfarming script, but it looks to me like it just does
Code:
visit_url( "place.php?whichplace=forestvillage&action=fv_scientist" );
and
Code:
use_skill( EVOKE_ELDRITCH_HORROR );
(exactly what I'm doing), and then performs the fights using CCS (which is what I'm trying to avoid doing). I'd prefer to use run_combat(), or some other means of defining a fight strategy in the same script where I'm starting the fights, only because I frequently select from my CCS list manually, and having a tentacle-only fight strategy in there is just one more thing I have to scroll past to find other strategies that I actually care about. This script is the only place I ever plan to fight tentacles (outside of world events), so there's no reason for my fight strategy to exist independently of the script.

Mostly, at this point, I'm wondering why I can do this:
Code:
visit_url("choice.php?option=1&pwd=" + my_hash() + "&whichchoice=1182&piece=1938", false); // fight the Witchess rook
run_combat("[COMBAT STRATEGY]");
but not this:
Code:
visit_url("place.php?whichplace=forestvillage&action=fv_scientist");
run_choice(2);
run_combat("[COMBAT STRATEGY]");

Is it the intervening run_choice() that screws things up?
 
Last edited:

Linknoid

Member
Have you tried doing this instead?

visit_url("place.php?whichplace=forestvillage&action=fv_scientist");
visit_url("choice.php?option=2&pwd=" + my_hash() + "&whichchoice=1201", false);
run_combat("[COMBAT STRATEGY]");
 

Pazleysox

Member
This script is the only place I ever plan to fight tentacles (outside of world events), so there's no reason for my fight strategy to exist independently of the script.

how about:
Code:
set_property("customCombatScript", "tentacle.ccs");
visit_url("place.php?whichplace=forestvillage&action=fv_scientist"); run_choice(2);
set_property("customCombatScript", "default.ccs");

visit_url("choice.php?option=2&pwd=" + my_hash() + "&whichchoice=1201", false);
I just recently learned you can put the code "run_choice(X);", instead of a whole separate visit_url.
 
Last edited:
Thanks for your replies, Linknoid and Pazleysocks. Getting through the choice adventure, and starting the fight, wasn't giving me any trouble. I was just struggling to figure out how to automate the fight itself (other than with run_combat).

Here's what I ended up doing:
Code:
visit_url("place.php?whichplace=forestvillage&action=fv_scientist");
run_choice(2);
adv1(my_location(), -1, "[I][my combat strategy][/I]");

That works well, for defining my strategy in the script.
 

Veracity

Developer
Staff member
You are fortunate that choice "2" works for you. It DOES vary. Here is my code from VeracityMeatFarm:

Code:
    // Dr. Gordon Stewart's tentacle
    if ( !tentacle ) {
	between_battle_checks();
	string page = visit_url( "place.php?whichplace=forestvillage&action=fv_scientist" );

	// The option can vary. Pick correct one
	int fight = 0;
	int great = 0;

	foreach n, text in available_choice_options() {
	    if ( text.starts_with( "Can I fight that tentacle" ) ) {
		fight = n;
	    } else if ( text.starts_with( "Great!" ) ) {
		great = n;
	    }
	}

	if ( fight != 0 ) {
	    run_choice( fight );
	} else if ( great != 0 ) {
	    run_choice( great );
	}

	// It is possible to have no choice options
    }
The code could be tightened up, but this was my initial attempt that does work for my two characters that have different choice options to get the fight.
 

Pazleysox

Member
Why would your characters have 2 options? I see 3 on my main actually, but it would appear that FIGHT, and GREAT are available on first visit, and FIGHT goes away after winning, leaving GREAT, and the dust choice.

Do your accounts attempt to visit twice? Sorry if this seems noobish

does the GREAT option always show for the same character?
 

Veracity

Developer
Staff member
I have multiple characters. Every character has one of the two options. No character has two options at the same time.

The code I posted works with all of my characters, as opposed to the code you posted, which works only for characters who have passed a certain point.
 
Specifically, you can have anywhere between 1 and 4 options, based on your free daily fight (completed or not), and if you have any dust bunnies/shovelfuls/granite and if you have any eldritch essence, and these will actually shift the numbers of the varying choices left. (As I found out when my own script broke right after halloween, because it got stuck in the 'which eldritch equipment (hat/hammer/pants) do you want to craft' followup choice).
 

Pazleysox

Member
I have multiple characters. Every character has one of the two options. No character has two options at the same time.

The code I posted works with all of my characters, as opposed to the code you posted, which works only for characters who have passed a certain point.

I understand. I didn't realize there were multiple options. I think your way is better, in the case of having items today, and not having them tomorrow.

I was thinking before this, that you might be able to use
if (my_name() == "PazSox") ... choice1
if (my_name() == "Veracity") ... choice2

But this wouldn't work either... It would still force the particular choice number, which as I know now, CAN change based on items/equipment.

I'm still learning. A little bit each day. :)
 

Veracity

Developer
Staff member
Thanks for your replies, Linknoid and Pazleysocks. Getting through the choice adventure, and starting the fight, wasn't giving me any trouble. I was just struggling to figure out how to automate the fight itself (other than with run_combat).

Here's what I ended up doing:
Code:
visit_url("place.php?whichplace=forestvillage&action=fv_scientist");
run_choice(2);
adv1(my_location(), -1, "[I][my combat strategy][/I]");

That works well, for defining my strategy in the script.
Sorry that I ignored this; I plead my new job (six months now, so is it still new?) which sucks away all my attention during the week - and I'm less inclined to dive into coding on the weekend. My brain is full. ;)

This thread is full of interesting things. Some observations:

1) visit_url() will follow a redirect for you. So, when you visit_url() to fight a Witchess Piece or to follow a choice in the Science Tent, KoL redirects to fight.php and visit_url() itself will follow that redirect, which will set up KoLmafia to know that you are inside a fight. At that point, you can use run_combat() and it will carry on as directed. In particular, if you give it a combat filter, it will use it.

2) I don't think run_choice follows a redirect. Given an option > 0, I see this:

Code:
		else if ( option > 0 )
		{
			// Submit the option chosen
			String message = "Submitting option " + option + " for choice " + ChoiceManager.getLastChoice();
			RequestLogger.printLine( message );
			response = ChoiceManager.processChoiceAdventure( option, false );
		}
processChoiceAdventure with "false" means "do not try to automate".

Code:
	public static final String processChoiceAdventure( final int decision, final boolean tryToAutomate )
	{
		GenericRequest request = ChoiceManager.CHOICE_HANDLER;

		request.constructURLString( "choice.php" );
		request.addFormField( "whichchoice", String.valueOf( ChoiceManager.lastChoice ) );
		request.addFormField( "option", String.valueOf( decision ) );
		request.addFormField( "pwd", GenericRequest.passwordHash );
		request.run();

		if ( tryToAutomate )
		{
			ChoiceManager.processChoiceAdventure( request, "choice.php", request.responseText );
			return "";
		}
		
		return request.responseText;
	}
Which is to say, it should simply submit the choice.php URL and return the page text. However, choice.php redirected to fight.php. So, what does it return?

I'm wondering where - if ever - it follows the redirect to fight.php to let KoLmafia know you are in a fight. Apparently, it does not (although I have not finished tracing the code in GenericRequest to understand that, yet) in which case, run_combat() would not know you are already in a combat.

3) run_combat() when called and we think you are not in a fight will return "" (if given a filter function) or whatever the last combat round returns. I'm not sure why the difference.

4) adv1 will try to adventure, will get redirected to a fight, and will do it. That is why your solution is working - at the expense of an extra server hit.

5) VeracityMeatFarm does this for Witchess pieces:

Code:
	    visit_url( "campground.php?action=witchess" );
	    run_choice( 1 );
	    visit_url( "choice.php?whichchoice=1182&option=1&piece=" + fight.id + "&pwd=" + my_hash(), false );
	    combat_filter_setup( NO_LOCATION );
	    run_combat( "hobo_monkey_filter" );
It does visit_url to choose the monster - because you need to specify the "piece" parameter in addition to the option - which redirects to the fight, and run_combat() works well.

6) VeracityMeatFarm does this for the Science Tent:

Code:
	string page = visit_url( "place.php?whichplace=forestvillage&action=fv_scientist" );
	...
	    run_choice( fight );
and I see the following in my session log:

Code:
> Fighting Eldritch Tentacles

Visiting a Science Tent
Encounter: Dr. Gordon Stuart, a Scientist
Took choice 1201/1: Can I fight that tentacle you saved for science?
choice.php?whichchoice=1201&option=1&pwd

[20795] Dr. Gordon Stuart's Science Tent
Encounter: Eldritch Tentacle named Shhhhhblrgglblllrrgggh
Round 0: Veracity wins initiative!
...
And I'm not sure where the fighting happens! It used my CCS, as you commented.

I need to track down how GenericRequest processes a choice.php -> fight.php.
For me, it seems to automate the fight, in this case.
For you, it seems to leave the fight un-started.
 

Veracity

Developer
Staff member
I think I get it.

- GenericRequesthandleServerRedirect WILL follow the redirect if the base class is a GenericRequest
- visit_url uses a GenericRequest -> which means it will follow the redirect and start the fight.
- visit_choice calls ChoiceManager.processChoiceAdventure, which uses ChoiceManager.CHOICE_HANDLER (which is a GenericRequest, so it would follow the redirect) - except it is also a "special" request which does not follow the redirect and automatically runs the fight.

I am considering making another version of run_choice which will let you say to craft a new GenericRequest rather than using CHOICE_HANDLER, which will allow you take over the combat, as you desire.
 

Veracity

Developer
Staff member
Try revision 18246.

string run_choice( int option, boolean handle_fights )

If "handle_fights" is false, will follow the redirect to set up for the fight and return. run_combat() should work.
If it is true - the backward compatible default for run_choice( option) - we will run the fight using your CCS.

Untested, since I am out of turns for the day.
 
A million years later, I can confirm that the two-parameter run_choice() works well for my purposes. Thanks very much for implementing it!
 

apologue

New member
I didn't notice the skill part being answered yet (I might have missed it though), so:
instead of
use_skill($skill[Evoke Eldritch Horror])
casting the skill through chat:
cli_execute("/cast 1 Evoke Eldritch Horror")
followed by run_combat seems to work.
 
Top