@@ -487,18 +487,28 @@ export function availableMachines(machineNames: string[]): Set<string> {
487487 * items). See [[turd-planning-model]] for the buildableNow vs availableNow
488488 * split. */
489489export function unlockedItems ( names : string [ ] ) : Set < string > {
490- if ( ! names . length ) return new Set ( ) ;
490+ const uniq = [ ...new Set ( names ) ] . filter ( ( name ) => name ) ;
491+ if ( ! uniq . length ) return new Set ( ) ;
491492 const h = getResearchHorizon ( ) ;
492493 // FUTURE mode plans against the whole tech tree — anything producible is fair
493494 // game (availableNow would wrongly exclude not-yet-researched tiers).
494- if ( h . mode === "future" ) return obtainableGoods ( names ) ;
495+ if ( h . mode === "future" ) return obtainableGoods ( uniq ) ;
495496 const selections = getTurdSelections ( ) ;
496497 const now = h . mode === "now" ;
498+ const recipesByGood = recipesProducingByGoods ( uniq ) ;
499+ const recipeRows = [
500+ ...new Map ( [ ...recipesByGood . values ( ) ] . flat ( ) . map ( ( recipe ) => [ recipe . name , recipe ] ) ) . values ( ) ,
501+ ] ;
502+ const locks = recipeLockStatesByRecipe (
503+ recipeRows . map ( ( recipe ) => recipe . name ) ,
504+ new Set ( selections . values ( ) ) ,
505+ ) ;
506+ const availability = computeAvailByRecipe ( recipeRows , locks , h , selections ) ;
497507 const out = new Set < string > ( ) ;
498- for ( const name of new Set ( names ) ) {
499- const ok = recipesProducing ( name ) . some ( ( r ) => {
500- const a = computeAvail ( r . enabled , recipeLockState ( r . name ) , h , selections ) ;
501- return now ? a . buildableNow : a . availableNow ;
508+ for ( const name of uniq ) {
509+ const ok = ( recipesByGood . get ( name ) ?? [ ] ) . some ( ( recipe ) => {
510+ const a = availability . get ( recipe . name ) ;
511+ return a && ( now ? a . buildableNow : a . availableNow ) ;
502512 } ) ;
503513 if ( ok ) out . add ( name ) ;
504514 }
0 commit comments