1515 */
1616/**
1717 * @typedef {Object } Building
18- * @property {number } price
1918 * @property {DocumentFragment } l
19+ * @property {number } price
20+ * @property {number } timeToTargetCookie
2021 */
2122/**
2223 * @typedef {Object } Upgrade
2324 * @property {function } getPrice
2425 * @property {number } bought
26+ * @property {number } timeToTargetCookie
2527 */
2628/**
2729 * @typedef {Object } Game
@@ -61,11 +63,7 @@ let BestDealHelper = {
6163 sortbuildings : 0 ,
6264 } ,
6365
64- isLoaded : false ,
65- load_chroma : false ,
66- loopCount : 0 ,
67-
68- register : function ( ) {
66+ isLoaded : false , load_chroma : false , loopCount : 0 , register : function ( ) {
6967 Game . registerMod ( this . name , this ) ;
7068 } ,
7169
@@ -114,34 +112,75 @@ let BestDealHelper = {
114112
115113 logicLoop : function ( ) {
116114 MOD . loopCount ++ ;
117- if (
118- MOD . loopCount >= 5
119- || MOD . last_cps !== Game . cookiesPs
120- || MOD . config . sortbuildings !== MOD . last_config_sortbuildings
121- || ! document . querySelector ( "#productAcc0" )
122- || ( document . querySelector ( "#upgrade0" ) && ! document . querySelector ( "#upgradeAcc0" ) )
123- ) {
115+ if ( MOD . loopCount >= 5 || MOD . last_cps !== Game . cookiesPs || MOD . config . sortbuildings !== MOD . last_config_sortbuildings || ! document . querySelector ( "#productAcc0" ) || ( document . querySelector ( "#upgrade0" ) && ! document . querySelector ( "#upgradeAcc0" ) ) ) {
124116 MOD . sortDeals ( ) ;
125117 MOD . loopCount = 0 ;
126118 MOD . last_config_sortbuildings = MOD . config . sortbuildings ;
127119 MOD . last_cps = Game . cookiesPs ;
128120 }
129121 } ,
130- median : function ( values ) {
131- if ( values . length === 0 ) return 0 ;
132122
133- values . sort ( function ( a , b ) {
134- return a - b ;
135- } ) ;
123+ insertAfter : function ( newNode , referenceNode ) {
124+ referenceNode . parentNode . insertBefore ( newNode , referenceNode . nextSibling ) ;
125+ } ,
136126
137- const half = Math . floor ( values . length / 2 ) ;
127+ getCpsAcceleration : function ( me ) {
128+ // Treat Grandmapocalypse upgrade as 0% temporary
129+ if ( [ "One mind" , "Communal brainsweep" , "Elder pact" ] . includes ( me . name ) ) return 0 ;
138130
139- if ( values . length % 2 ) return values [ half ] ;
131+ // Backup
132+ Game . Logic_ = Game . Logic ;
133+ Game . Logic = function ( ) {
134+ } ;
135+ let oldCookiesPsRawHighest = Game . cookiesPsRawHighest ;
136+
137+ if ( me . type === "upgrade" ) me . bought ++ ; else me . amount ++ ;
138+ Game . CalculateGains ( ) ;
139+ me . newCookiesPs = Game . cookiesPs ;
140+ if ( me . type === "upgrade" ) me . bought -- ; else me . amount -- ;
141+ Game . CalculateGains ( ) ;
142+
143+ // Restore
144+ Game . cookiesPsRawHighest = oldCookiesPsRawHighest ;
145+ Game . Logic = Game . Logic_ ;
146+
147+ let deltaTime ;
148+ if ( me . type === "upgrade" ) me . price = me . getPrice ( ) ;
149+ if ( me . price > Game . cookies ) {
150+ deltaTime = ( me . price - Game . cookies ) / Game . cookiesPs + me . price / me . newCookiesPs ;
151+ } else {
152+ deltaTime = me . price / me . newCookiesPs ;
153+ }
140154
141- return ( values [ half - 1 ] + values [ half ] ) / 2.0 ;
155+ let deltaCps = me . newCookiesPs - Game . cookiesPs ;
156+ return deltaCps / deltaTime ;
142157 } ,
143- insertAfter : function ( newNode , referenceNode ) {
144- referenceNode . parentNode . insertBefore ( newNode , referenceNode . nextSibling ) ;
158+
159+ /**
160+ * @param {(Building|Upgrade)[] } all
161+ */
162+ findHelper : function ( all ) {
163+ all . forEach ( e => e . isBestHelper = false ) ;
164+
165+ const target = all [ 0 ] ;
166+ if ( target . price <= Game . cookies ) return ;
167+
168+ target . timeToTargetCookie = ( target . price - Game . cookies ) / Game . cookiesPs ;
169+ let helpers = all . filter ( me => me !== target && me . price < target . price ) ;
170+ if ( ! helpers . length ) return ;
171+
172+ helpers . forEach ( function ( me ) {
173+ if ( me . price > Game . cookies ) {
174+ me . timeToTargetCookie = ( me . price - Game . cookies ) / Game . cookiesPs + target . price / me . newCookiesPs ;
175+ } else {
176+ me . timeToTargetCookie = ( target . price - ( Game . cookies - me . price ) ) / me . newCookiesPs ;
177+ }
178+ } ) ;
179+ helpers . sort ( ( a , b ) => a . timeToTargetCookie - b . timeToTargetCookie ) ;
180+ if ( helpers [ 0 ] . timeToTargetCookie < target . timeToTargetCookie ) {
181+ helpers [ 0 ] . isBestHelper = true ;
182+ }
183+
145184 } ,
146185
147186 sortDeals : function ( ) {
@@ -151,54 +190,37 @@ let BestDealHelper = {
151190 let all = [ ...buildings , ...upgrades ] ;
152191
153192 // Calculate cpsAcceleration
154- all . forEach ( function ( me ) {
155- Game . Logic_ = Game . Logic ;
156- Game . Logic = function ( ) {
157- } ;
158- if ( me . type === "upgrade" ) me . bought ++ ; else me . amount ++ ;
159- Game . CalculateGains ( ) ;
160- let newCookiesPs = Game . cookiesPs ;
161- if ( me . type === "upgrade" ) me . bought -- ; else me . amount -- ;
162- Game . CalculateGains ( ) ;
163- Game . Logic = Game . Logic_ ;
164-
165- let deltaTime ;
166- if ( me . type === "upgrade" ) me . price = me . getPrice ( ) ;
167- if ( me . price > Game . cookies ) {
168- deltaTime = ( me . price - Game . cookies ) / Game . cookiesPs + me . price / newCookiesPs ;
169- } else {
170- deltaTime = me . price / newCookiesPs ;
171- }
193+ all . forEach ( me => me . cpsAcceleration = MOD . getCpsAcceleration ( me ) ) ;
194+ // Sorting by cpsAcceleration
195+ all . sort ( ( a , b ) => b . cpsAcceleration - a . cpsAcceleration ) ;
172196
173- let deltaCps = newCookiesPs - Game . cookiesPs ;
174- return me . cpsAcceleration = deltaCps / deltaTime ;
175- } ) ;
197+ // If the best cpsAcceleration is not affordable, try to find a pre-deal help us to get the best deal quicker.
198+ MOD . findHelper ( all ) ;
176199
177- // determine colors
178- all . sort ( ( a , b ) => a . cpsAcceleration - b . cpsAcceleration ) ;
200+ // Determine colors
179201 all . forEach ( ( e , index ) => e . accRank = index ) ;
180202 let palette = [ "#00ffff" ] ;
181- let rank = all . length - 1 ;
203+ let rank = 0 ;
182204 let domain = [ all [ rank ] . cpsAcceleration ] ;
183- rank -- ;
184- if ( rank >= 0 ) {
205+ rank ++ ;
206+ if ( rank < all . length ) {
185207 palette . unshift ( "#00ff00" ) ;
186208 domain . unshift ( all [ rank ] . cpsAcceleration ) ;
187209 }
188- rank - = 6 ;
189- if ( rank >= 0 ) {
210+ rank + = 6 ;
211+ if ( rank < all . length ) {
190212 palette . unshift ( "#ffd939" ) ;
191213 domain . unshift ( all [ rank ] . cpsAcceleration ) ;
192214 }
193- rank - = 8 ;
194- if ( rank >= 0 ) {
215+ rank + = 8 ;
216+ if ( rank < all . length ) {
195217 palette . unshift ( "#ff0000" ) ;
196218 domain . unshift ( all [ rank ] . cpsAcceleration ) ;
197219 }
198- rank -- ;
199- if ( rank >= 0 ) {
220+ rank ++ ;
221+ if ( rank < all . length ) {
200222 palette . unshift ( "#64007c" ) ;
201- domain . unshift ( all [ 0 ] . cpsAcceleration ) ;
223+ domain . unshift ( all [ all . length - 1 ] . cpsAcceleration ) ;
202224 }
203225
204226 let color = chroma . scale ( palette ) . mode ( "lab" ) . domain ( domain ) ;
@@ -223,20 +245,19 @@ let BestDealHelper = {
223245 l ( "upgrade" + i ) . appendChild ( span ) ;
224246 }
225247 span . textContent = Beautify ( me . cpsAcceleration * 100 / avg , 1 ) + "%" ;
226- span . style . color = color ( me . cpsAcceleration ) ;
227- }
228- // Sort upgrades (or leave them as default)
229- upgrades . sort ( ( a , b ) => b . cpsAcceleration - a . cpsAcceleration ) ;
230- // Only sort when the order is different
231- let upgrades_order = upgrades . map ( e => e . l . id ) ;
232- let current_upgrades_order = [ ... document . querySelector ( "#upgrades" ) . children ] . map ( e => e . id ) ;
233- if ( ! upgrades_order . every ( ( value , index ) => value === current_upgrades_order [ index ] ) ) {
234- let store = document . querySelector ( "#upgrades" ) ;
235- for ( let i = 0 ; i < upgrades . length ; ++ i ) {
236- store . appendChild ( upgrades [ i ] . l ) ;
248+ if ( me . isBestHelper ) {
249+ let text = span . innerText ;
250+ span . innerHTML = "" ;
251+ for ( let i = 0 ; i < text . length ; i ++ ) {
252+ let charElem = document . createElement ( "span" ) ;
253+ charElem . style . color = "hsl(" + ( 360 * i / text . length ) + ",80%,50%)" ;
254+ charElem . innerHTML = text [ i ] ;
255+ span . appendChild ( charElem ) ;
256+ }
257+ } else {
258+ span . style . color = color ( me . cpsAcceleration ) ;
237259 }
238260 }
239-
240261 // Notation for buildings
241262 for ( const i in buildings ) {
242263 let me = buildings [ i ] ;
@@ -249,10 +270,32 @@ let BestDealHelper = {
249270 MOD . insertAfter ( span , l ( "productPrice" + me . id ) ) ;
250271 }
251272 span . textContent = " 💹" + Beautify ( me . cpsAcceleration * 100 / avg , 2 ) + "%" ;
252- span . style . color = color ( me . cpsAcceleration ) ;
253-
273+ if ( me . isBestHelper ) {
274+ let text = span . innerText ;
275+ span . innerHTML = "" ;
276+ for ( let i = 0 ; i < text . length ; i ++ ) {
277+ let charElem = document . createElement ( "span" ) ;
278+ charElem . style . color = "hsl(" + ( 360 * i / text . length ) + ",80%,50%)" ;
279+ charElem . innerHTML = text [ i ] ;
280+ span . appendChild ( charElem ) ;
281+ }
282+ } else {
283+ span . style . color = color ( me . cpsAcceleration ) ;
284+ }
254285 }
255286
287+
288+ // Sort upgrades (or leave them as default)
289+ upgrades . sort ( ( a , b ) => b . cpsAcceleration - a . cpsAcceleration ) ;
290+ // Only sort when the order is different
291+ let upgrades_order = upgrades . map ( e => e . l . id ) ;
292+ let current_upgrades_order = [ ...document . querySelector ( "#upgrades" ) . children ] . map ( e => e . id ) ;
293+ if ( ! upgrades_order . every ( ( value , index ) => value === current_upgrades_order [ index ] ) ) {
294+ let store = document . querySelector ( "#upgrades" ) ;
295+ for ( let i = 0 ; i < upgrades . length ; ++ i ) {
296+ store . appendChild ( upgrades [ i ] . l ) ;
297+ }
298+ }
256299 // Sort buildings (or leave them as default)
257300 if ( MOD . config . sortbuildings ) {
258301 buildings . sort ( ( a , b ) => b . cpsAcceleration - a . cpsAcceleration ) ;
0 commit comments