Familiar Switching

Hi, I'm new to scripting, but I was looking at making a scipt that detects if you have the Jack-in-the-Box, and if you do, it adventures for you.
I have searched through the FAQs, the wiki, etc. and I can't seem to find out the commands for detecting and switching familiars.

I expect it to be something similiar to:
Code:
if(have_familiar($familiar[Jack-in-the-Box]))
for detecting if you have the familiar, but I'm not sure how to script it so it switches familiars for you.
Thanks for your time!
 
Last edited:

StDoodle

Minion
Code:
if(have_familiar[$familiar[Jack-in-the-Box])) {
   use_familiar[$familiar[Jack-in-the-Box])
   // do stuff with familiar
}
 
It says
Code:
Unknown variable 'use_familiar' (test.ash, line 5)
Even though it registers 'have_familiar'
I did import zlib and I put it under a method, is something wrong?
 
Thanks, that fixed things.
Also, I know that I didn't ask this question earlier, but how do you code it so that it detects you went through a combat?
My dilema here is that zones offer noncombats, which don't charge the Jack-in-the-Box, so is there a way of programming it so that it goes through 2 combats regardless of noncombats or a way to figure out the 'Jack Charge' and retrieve the counter?
 

StDoodle

Minion
Argh, so much for trying to throw some code out when half-awake (will I ever learn?)...

Checking for combats vs. noncombats is a bit tricky; there isn't a "simple" way to do so in KoLmafia; you really need to trap & analyze each encounter, via one of several methods (such as matching the page text). Or possibly checking to see if lastEncounter is a valid monster. (Please somebody, point out a better method.)
 

slyz

Developer
This will set com to true if your last encounter was a monster:
PHP:
string last = get_property("lastEncounter");
boolean com = false;
foreach mon in $monsters[] {
   if ( last != mon.to_string() ) continue;
   com = true;
   break;
}

Unfortunately this wouldn't work in the Slimetube, a Hobopolis zone, or any zone where you have random monster names (see here).

EDIT: you can narrow it down actually:

PHP:
string last = get_property("lastEncounter");
boolean com = false;
foreach num, mon in get_monsters(my_location()) {
   if ( last != mon.to_string() ) continue;
   com = true;
   break;
}
 
Last edited:
So I fiddled with it a bit, and would this work?
Code:
if(have_familiar($familiar[Jack-in-the-Box])){
	int jNum = 0;
	use_familiar($familiar[Jack-in-the-Box]);
	while( jNum != 2 ){
		string last = get_property("lastEncounter");
		foreach num, mon in get_monsters(my_location()) {
		if ( last != mon.to_string() ) continue;
			jNum++;
			break;}
		if ( jNum == 1 ){
			print("Jack Charge at 1.");}
		else if ( jNum == 2 ){
			print("Jack Charge at 2.");}
		adventure(1, $location[random location]);
	}
	use_familiar($familiar[random familiar]);
}
else{
	print("No Jack-in-the-Box. Skipping charging step.");
}
While on the topic, is there a way to switch back to the previous familiar before you changed the Jack? Or should I just put in something safe like 'Mosquito' since everyone is bound to have one?
And I changed 'boolean com' to 'int jNum' to accomidate the fact that the Jack has a 0, 1, and 2 charge, or am I missing something here?
 
Last edited:

slyz

Developer
You have a logic problem in your loop - you should adventure before updating jNum. Try it like this (I also added Camber's advice):
PHP:
if(have_familiar($familiar[Jack-in-the-Box])){
	familiar startFam = my_familiar() ; 
	use_familiar($familiar[Jack-in-the-Box]);
	int jNum = 0 ;
	string last ;
	while( jNum != 2 ){
		adventure(1, $location[random location]);
		last = get_property("lastEncounter");
		foreach num, mon in get_monsters(my_location()) {
			if ( last != mon.to_string() ) continue ;
			jNum += 1 ; break;
		}
		print("Jack Charge at "+jNum+".");
	}
	use_familiar(startFam);
}
else{
	print("No Jack-in-the-Box. Skipping charging step.");
}
 

heeheehee

Developer
Staff member
Why use a foreach loop for checking if lastEncounter is a monster or not? Why not just use, in lieu of the whole foreach loop,
PHP:
if(get_property("lastEncounter").to_monster()!=$monster[none]) jNum +=1;
? At least this way, you won't skip over monsters that don't occur in the area normally (e.g. FoB monsters).
 

slyz

Developer
That's a lot better, Thou Who Hath A Name That Laughs.
PHP:
if(have_familiar($familiar[Jack-in-the-Box])){
    familiar startFam = my_familiar() ; 
    use_familiar($familiar[Jack-in-the-Box]);
    int jNum = 0 ;
    while( jNum != 2 ) {
        adventure(1, $location[random location]);
        if ( get_property("lastEncounter").to_monster() != $monster[none])
            jNum +=1;  
        print("Jack Charge at "+jNum+".");
    }
    use_familiar(startFam);
}
else{
    print("No Jack-in-the-Box. Skipping charging step.");
}
Now all we need is for Zarqon to write the same function with 3 lines of code and have it executed remotely.
 

zarqon

Well-known member
Hahaha. Four lines is the best I can manage, and it's kind of cheating. :)

PHP:
familiar prevfam = my_familiar();
if (!have_familiar($familiar[jack-in-the-box]) || !use_familiar($familiar[jack-in-the-box])) abort("No Jack!");
for i from 1 to 2 while (adventure(1,my_location()) && get_property("lastEncounter").to_monster() == $monster[none]) {}
use_familiar(prevfam);

Thanks for wasting some of my lunch break!
 
Top