New Content - Implemented Rethinking Candy

heeheehee

Developer
Staff member
I might want a "unrestricted" checkbox, checked by default if you are in a Standard-style run. But it would be more useful to not even have unusable candies in the list, if you are in such a run.

Are candies unusable in this context if they're too old? I'd be surprised if TPTB bothered (or remembered) to add an exception; the main source of said candies is... Cheeng's spectacles and related items? Or pulls, I guess, but I don't think they'd be concerned about people pulling old candies to synthesize.
 

Veracity

Developer
Staff member
Revision 17624 maintains selected candies when you filter and unfilter. It works well if both Candy A and Candy B pass the filter.

If Candy B is filtered out, we unselect it, but leave Candy B set in the right panel
If Candy A is filtered out, we leave the Candy A set in the right panel and leave the Candy B list visible.

I will fix those bugs tomorrow.
 

heeheehee

Developer
Staff member
For a second there, I thought you meant you'd added a filter input field (as we have in the item manager), which would be interesting. I don't know that there's all that much you could do with it that'd be useful (e.g. #>1, if you wanted to save at least one of each candy for... something).

I noticed the frame may get out of sync with inventory (since there's no listener attached), but it detects changes when you click on a different effect (I think; other things may also trigger this).
 

Veracity

Developer
Staff member
There is a listener attached. It just doesn't do anything yet. :)
Notice this in ResultProcessor.java:

Code:
		if ( ItemDatabase.isCandyItem( itemId ) )
		{
			NamedListenerRegistry.fireChange( "(candy)" );
		}
and this in SynthesizePanel.java:

Code:
		NamedListenerRegistry.registerNamedListener( "(candy)", this );
...
	// called when (candy) fires
	public void update()
	{
	}
I'm going to be hooking that up and doing some refactoring, once I get the selection handling sorted out when you filter out your selection.

Regarding filters, I didn't want a text field for the reason you mentioned; you are really not interested in candy names. Just count & cost & legality. A text field would have been easy: AutoFilter TextField has the functionality. Now, figuring out exactly how that widget was attached to the display model and methods so that I could use it for my own purpose was hard (for me).

This frame has been a Swing learning experience.

(I notice that AutoFilterTextField doesn't do a good job of preserving the selected item(s) after filtering:

Code:
			if ( AutoFilterTextField.this.list != null )
			{
				JList list = AutoFilterTextField.this.list; 
				if ( AutoFilterTextField.this.model.getSize() == 1 )
				{
					list.setSelectedIndex( 0 );
				}
				else if ( list.getSelectedIndices().length == 1 )
				{
					list.ensureIndexIsVisible( list.getSelectedIndex() );
				}
				else
				{
					list.clearSelection();
				}
			}
It is prone to just throw up its hands and give up. Perhaps I will look at this, with my hard-earned new knowledge, when I am done with this project.)
 

Veracity

Developer
Staff member
Revision 17625 refactors all the classes. The code is simpler, more understandable, and, more to the point, correct.

Selecting/deselecting while filtering works now.

I also hooked up the "(candy)" listener and all GUI elements should update when candy enters or leaves inventory. Note that if a candy table is sorted by "have", it will not re-sort; the candy's count field will increment or decrement, but the candy will not move in the list.

I also made the effect buttons explicitly use Color.BLACK for the background and Color.WHITE for the forground when they are selected, rather than inverting the original foreground and background colors - although when you deselect a button, it restores the originals. Hopefully this will work around Frono's Windows 10 bug.
 

Veracity

Developer
Staff member
Revision 17626 adds a "Total" section to the Candy Data panel in the right that shows total "mall cost" for the two candies and the cost/turn of the resulting effect.

It also refilters the candy lists when you gain or lose candy, since it may affect what is displayed if you are filtering on available quantity.
 

Veracity

Developer
Staff member
Revision 17629 does this:

1) If a synthesis combo requires two of the same candy and you are filtering on "available" candy and only have one of it, don't show the candy in the Candy B column, since you can't actually make it.

(Note that if you submit a request to synthesize A and B and they are the same candy, it will "acquire" 2. Using "available" candy, if you don't have 2, it will fail.)

2) If you issue a SynthesizeRequest (via ASH synthesize(), for example) and are under Standard restrictions, it will check that the candies are allowed and give you an error if not. You shouldn't be able to have such candies in inventory, but who knows what various item-dropping equipment will give you?

3) Previous ASH functions:

item [int] candy_for_tier( int )
item [int] sweet_synthesis_pairing( effect, item )

There are now new versions of both of those:

item [int] candy_for_tier( int, flags )
item [int] sweet_synthesis_pairing( effect, item, flags )

flags = 0: no filtering
flags = 1: "available" candies only
flags = 2: "allowed" (in Standard) candies only
flags = 3: both

Yes, it's a bit mask.

If you use the version with no flags, it uses default flags for your situation:

Ronin or Hardcore in a Standard-restricted run: 3
Ronin or Hardcore otherwise: 1
Otherwise (including not logged in): 0

The GUI always uses flags = 0 and lets you filter using the checkboxes - which are initially set to agree with the defaults as above - but you can uncheck them if you want to look more widely.
 
I haven't tried the new Candy panel in action yet, but I just wanted to say two things:

  1. It looks awesome, and I'm looking forward to using it.
  2. It's available much sooner, and is much fuller-featured, than I would've expected.

Thanks for all the hard work, Veracity (and others)!
 

Veracity

Developer
Staff member
Revision 17630 has a couple of tweaks to the Sweet Synthesis frame:

- I renamed the "unrestricted" checkbox to "allowed" - i.e., check it to see only things are "allowed" in your current run (or in Standard, if you are not otherwise restricted).
- I added tooltips to the checkboxes and effect buttons.

I think that's it for the GUI until Phase 5, although bug fixes and user-suggested tweaks are always possible.
 

Veracity

Developer
Staff member
I noticed the following in Ezandora's script:

Code:
int synthesis_price(item it)
{
    if (!it.tradeable)
        return 999999999;
    int price = it.historical_price();
    if (it.historical_age() > 60.0) //initiate re-search of everything if their knowledge is too old
    	return it.mall_price();
    if (price <= 0)
        return 999999999;
    return price;
}
It's a good idea, even if incorrectly coded: if the historical price is "too old", fetch a new price.

I can't quite do it On Demand like that, since every action you do on the Sweet Synthesis frame happens in the Swing (i.e., GUI updating) thread and we can't (don't want to) freeze the GUI while making requests of KoL. But buttons can execute their action in a different thread, so ...

Revision 17632 adds a Check Prices button which will update the saved mall price of every candy whose current price is more than an hour old. And I made the "cost" of an untradeable item be 999,999,999, rather than Integer.MAX_INT.

(Ezandora's function is incorrectly coded because historical_age() returns the age as a fractional day. Therefore, that function will refresh the price if the saved value is more than 60 days old. That is certainly not what was intended.)
 

lostcalpolydude

Developer
Staff member
Since mall_price() won't actually do a new search if you already ran it once in the current session, I think 60 days is actually more likely than 60 minutes.
 

Veracity

Developer
Staff member
Considering I updated prices for all candies yesterday - and, as is the default, shared mall prices - nobody has a mall price more than a day old.
 

PeKaJe

Member
Hmm, don't the prices only update when you log in? Then wouldn't this search everything if it's been more than an hour since you logged in? Allowing day-old prices seems like it wouldn't make all that much difference in displayed prices and reduce the number of searches for most people.
 

Veracity

Developer
Staff member
Revision 17637:

Code:
[color=green]> synthesize? box of Dweebs, PEEZ dispenser[/color]

Searching for "box of Dweebs"...
Search complete.
Searching for "PEEZ dispenser"...
Search complete.
Item 'box of Dweebs is a complex candy. You have 248 of it available to you without using the mall, where it costs 100 Meat.
Item 'PEEZ dispenser is a complex candy. You have 5 of it available to you without using the mall, where it costs 135 Meat.
Synthesizing those two candies will give you 30 turns of Synthesis: Greed

[color=green]> synthesize? bag of W&Ws, bag of W&Ws[/color]

Searching for "bag of W&Ws"...
Search complete.
Item 'bag of W&Ws is a complex candy. You have 236 of it available to you without using the mall, where it costs 100 Meat.
Item 'bag of W&Ws is a complex candy. You have 236 of it available to you without using the mall, where it costs 100 Meat.
Synthesizing those two candies will give you 30 turns of Synthesis: Greed

[color=green]> inv W&W[/color]

bag of W&Ws (236)

[color=green]> synthesize bag of W&Ws, bag of W&Ws[/color]

Encounter: Sweet Synthesis
You acquire an effect: Synthesis: Greed (30)
Done!

[color=green]> inv W&W[/color]

bag of W&Ws (234)
I think this completes Phases 1-4.

Phase 5 is "advanced" features; we have the infrastructure, but they involve writing (an) algorithm(s) to decide candy combos which are possible and/or cheap.

CLI:

synthesize EFFECT
synthesize? EFFECT

ASH:

boolean sweet_synthesis( effect )

GUI:

"Automatic" button to load and select a minimum cost pairing for a particular effect. You like it? Press "Synthesize!".

When filtering on "available" candy (i.e., in-run):

Pre-analyze candy combos and filter out candies which will not combine with things you have to get the selected effect.

The above and grey-out effects you can't currently get at all.

I'm going to take a break before thinking about the above. This has been non-stop work for a week. I have learned a whole lot about Java Swing widgets, but I am tired.
 

Veracity

Developer
Staff member
Well, I wanted my script to let KoLmafia make intelligent choices for it, so revision 17644 has the following:

GUI:

There is now an Automatic button which will select an appropriate pair of candies to get the desired effect.

If you are in-run, it will use only "available" candy and will prefer candies that you have more of.
If you are post-run, it will consider all candies and will choose the pair with the lowest total mall price.

If you want to force "available" candies post-run, check the "available" checkbox.

ASH:

item [int] sweet_synthesis_pair( effect )
item [int] sweet_synthesis_pair( effect, flags )

For the desired effect, pick a suitable pair of candies.

If you are in-run, it will use only "available" candy and will prefer candies that you have more of.
If you are post-run, it will consider all candies and will choose the pair with the lowest total mall price.

If you want to force "available" candies post-run, use flags = 1.

boolean sweet_synthesis( effect )
boolean sweet_synthesis( effect, flags )

The same, but it will actually perform Sweet Synthesis to get the effect.

Note that although you can specify flags when actually requesting the effect, it will always use at least the flags imposed by your run; you can be more restrictive post-run, but you cannot be less restrictive in-run.

Code:
[color=green]> ash sweet_synthesis_pair( $effect[ Synthesis: Greed ] )[/color]

Returned: aggregate item [2]
0 => box of Dweebs
1 => PEEZ dispenser

[color=green]> ash sweet_synthesis( $effect[ Synthesis: Greed ] )[/color]

Encounter: Sweet Synthesis
You acquire an effect: Synthesis: Greed (30)
Returned: true

[color=green]> ash sweet_synthesis_pair( $effect[ Synthesis: Greed ], 1 )[/color]

Returned: aggregate item [2]
0 => Crimbo fudge
1 => sugar sheet

[color=green]> ash sweet_synthesis( $effect[ Synthesis: Greed ], 1 )[/color]

Encounter: Sweet Synthesis
You acquire an effect: Synthesis: Greed (30)
Returned: true
session log:

Code:
cast 1 Sweet Synthesis
Encounter: Sweet Synthesis

synthesize box of Dweebs, PEEZ dispenser
You acquire an effect: Synthesis: Greed (30)

cast 1 Sweet Synthesis
Encounter: Sweet Synthesis

synthesize Crimbo fudge, sugar sheet
You acquire an effect: Synthesis: Greed (30)
Still need to add the "synthesize EFFECT" and "synthesize? EFFECT" CLI commands, and play more games with the GUI.
Later.
 

Veracity

Developer
Staff member
Revision 17645 allows this:

Code:
[color=green]> synthesize? Synthesis: Greed[/color]

Item 'box of Dweebs' is a complex candy. You have 247 available to you without using the mall, where it costs 100 Meat.
Item 'PEEZ dispenser' is a complex candy. You have 51 available to you without using the mall, where it costs 135 Meat.
Synthesizing those two candies will give you 30 turns of Synthesis: Greed

[color=green]> synthesize Synthesis: Greed[/color]

[color=red]Your spleen has been abused enough today[/color]
I suppose one last tweak to that would be to allow keywords, rather than fuzzy matched effect names.

I may do that. If not, I am done until I ascend, by and by, since heeheehee's suggested GUI tweaks are for the benefit of in-run Sweet Synthesis and it will be a lot easier to test once I am in-run. I may even get candies from the Gingerbread Train Station in order to test.
 

Bale

Minion
I am incredibly impressed by the level of support you have added for ash scripts to have complete control over this skill.

It is quite safe to say that no single skill has ever prompted this much effort. Well done.
 
Top