Bug - Fixed Speculate/whatif command and familiar weight

Ezandora

Member
Tested on r15193.

If a familiar has an intrinsic weight over one pound, the whatif command will not speculate correctly when using the "familiar" command.

To reproduce, bring along a familiar that's over one pound and has modifiers, (a fairy, for instance) then run the command "whatif familiar [familiar name]"
The result will have modifiers less than what they should be, when it should be identical. This also affects changing to a different familiar.

Examples:
Five-pound base weight gelatinous cubeling as familiar, with a +5 to familiar weight from Amphibian Sympathy (ten pound total):

Code:
> whatif familiar Gelatinous Cubeling
Item Drop 21.17 (-9.29)

A six-pound fairy is +21.1659% item. The speculate command is treating the cubeling as (1 + 5) pounds, not (5 + 5) as it is.

With no familiar active:
Code:
> whatif familiar Gelatinous Cubeling
Item Drop 21.17 (+21.17)
Switching to it for real results in a +item of 30.45%.

Twenty-pound hound dog as familiar, with five pounds from Amphibian Sympathy and quartet set (-5% combat):
Code:
> whatif familiar Jumpsuited Hound Dog
Combat Rate -4.00 (-3.00)
Item Drop 24.81 (-44.90)

One-pound, zero-experience Grouper Groupie as familiar, with five pounds from Amphibian Sympathy:
Code:
> whatif familiar grouper groupie
No modifiers changed.
No change - it's already one pound.

I believe the bug happens in Speculation.java:
Code:
else if ( cmd.equals( "familiar" ) )
{
	int id = FamiliarDatabase.getFamiliarId( params );
	if ( id == -1 && !params.equals( "none" ) )
	{
		KoLmafia.updateDisplay( MafiaState.ERROR,
			"Unknown familiar: " + params );
		return true;
	}
	FamiliarData fam = new FamiliarData( id );
	this.setFamiliar( fam );
}

"new FamiliarData()" sets the familiar weight to one by default.

Maybe replace it with something like:
Code:
else if ( cmd.equals( "familiar" ) )
{
	int id = FamiliarDatabase.getFamiliarId( params );
	if ( id == -1 && !params.equals( "none" ) )
	{
		KoLmafia.updateDisplay( MafiaState.ERROR,
			"Unknown familiar: " + params );
		return true;
	}
	FamiliarData fam = KoLCharacter.findFamiliar( id );
	if ( fam != null && fam.getId() == -1 ) // NO_FAMILIAR
		fam = null;
	if ( fam == null )
		fam = new FamiliarData( id ); // don't have this one, create a blank familiar with this ID
	this.setFamiliar( fam );
}
(so it retains compatibility with commands such as "whatif familiar hand turkey" when you do not own a hand turkey.)
That code is probably not ideal or even correct, I am not familiar enough with mafia's internals.

"enthrone" and "bjornify" in Speculation.java also use new FamiliarData( id ) and ignore the weight. But I don't think the familiar weight in those can practically affect a modifier?

I found this because my script was disco dancing for more +item than it needed. This bug promotes excessive dancing.
 
Top