import { Item } from "../../items/types/Item" ; import { layout , LayoutResult } from "../layout" ; import { PlugyStash } from "../../plugy-stash/types" ; import { makeIndex } from "../../plugy-stash/makeIndex" ; import { UNIQUE_ITEMS , UniqueItem } from "../../../game-data" ; import { UNIQUES_ORDER , UniqueSection } from "../list/uniquesOrder" ; import { fillTemplate } from "./fillTemplate" ; import { getBase } from "../../items/getBase" ; import { groupUniquesBySection } from "../list/groupUniques" ; import { listGrailUniques } from "../list/listGrailUniques" ; import { canBeEthereal } from "../list/canBeEthereal" ; import { addPage } from "../../plugy-stash/addPage" ; import { moveItem } from "../../items/moving/safeMove" ; function createTemplates ( eth ) { const uniques = listGrailUniques ( eth ) ; const templates = new Map < UniqueSection , LayoutResult < UniqueItem > > ( ) ; for ( const [ section , items ] of uniques ) { templates . set ( section , layout ( section . layout ?? "tier-lines" , items ) ) ; } return templates ; } function extrasOrder ( a , b ) { const baseA = getBase ( a ) ; const baseB = getBase ( b ) ; return ( ( b . quality ?? 0 ) - ( a . quality ?? 0 ) || baseB . qlevel - baseA . qlevel || ( b . unique ? UNIQUE_ITEMS [ b . unique ] . qlevel : 0 ) - ( a . unique ? UNIQUE_ITEMS [ a . unique ] . qlevel : 0 ) ) ; } export function organizeUniques ( stash , items ) { const bySection = groupUniquesBySection ( items , false ) ; const normalTemplates = createTemplates ( false ) ; const ethTemplates = createTemplates ( true ) ; let offset = stash . pages . length ; for ( const category of UNIQUES_ORDER ) { category . forEach ( ( section , i ) => { const { name , shortName } = section ; const normalTemplate = normalTemplates . get ( section ) ! ; const ethTemplate = ethTemplates . get ( section ) ; if ( ! normalTemplate ) { throw new Error ( `No template for ${ name }` ) ; } for ( let j = 0 ; j < normalTemplate . nbPages ; j ++ ) { const page = addPage ( stash , name ) ; if ( j === 0 ) { makeIndex ( page , i === 0 ) ; } } for ( let j = 0 ; j < ( ethTemplate ?. nbPages ?? 0 ) ; j ++ ) { addPage ( stash , `Eth ${ shortName }` ) ; } const itemsInSection = bySection . get ( section ) ?. [ 0 ] ; if ( ! itemsInSection ) { offset += normalTemplate . nbPages + ( ethTemplate ?. nbPages ?? 0 ) ; return ; } itemsInSection ?. sort ( ( a , b ) => Number ( a . ethereal ) - Number ( b . ethereal ) ) ; let remaining = fillTemplate ( stash , itemsInSection , normalTemplate , offset ) ; offset += normalTemplate . nbPages ; if ( ethTemplate ) { const remainingAfterEth = remaining . filter ( ( item ) => ! item . ethereal || ! canBeEthereal ( item ) ) ; remainingAfterEth . push ( ... fillTemplate ( stash , remaining . filter ( ( item ) => item . ethereal && canBeEthereal ( item ) ) , ethTemplate , offset ) ) ; remaining = remainingAfterEth ; offset += ethTemplate . nbPages ; } if ( remaining . length > 0 ) { remaining . sort ( extrasOrder ) ; const byQuality = remaining . reduce < Item [ ] [ ] > ( ( groups , item ) => { let lastGroup = groups . length - 1 ; if ( groups [ lastGroup ] ?. [ 0 ] ?. quality !== item . quality ) { lastGroup = groups . push ( [ ] ) - 1 ; } groups [ lastGroup ] . push ( item ) ; return groups ; } , [ ] ) ; const { nbPages , positions } = layout ( "lines" , byQuality ) ; for ( let j = 0 ; j < nbPages ; j ++ ) { addPage ( stash , `Extra ${ shortName }` ) ; } for ( const [ item , { page , rows , cols } ] of positions . entries ( ) ) { moveItem ( stash , item , offset + page , rows [ 0 ] , cols [ 0 ] ) ; } offset += nbPages ; } } ) ; } }