@@ -16,6 +16,8 @@ declare global {
16
16
export type KittenAnalystsMessageId =
17
17
| "connected"
18
18
| "getBuildings"
19
+ | "getCalendar"
20
+ | "getRaces"
19
21
| "getResourcePool"
20
22
| "getStatistics"
21
23
| "getTechnologies"
@@ -24,17 +26,40 @@ export type KittenAnalystsMessageId =
24
26
| "reportSavegame" ;
25
27
26
28
export type PayloadBuildings = Array < {
29
+ group : string ;
27
30
label : string ;
28
31
name : string ;
29
32
on : number ;
30
33
tab : TabId ;
31
34
value : number ;
32
35
} > ;
36
+ export type PayloadCalendar = Array < {
37
+ cryptoPrice : number ;
38
+ cycle : number ;
39
+ cycleYear : number ;
40
+ day : number ;
41
+ eventChance : number ;
42
+ festivalDays : number ;
43
+ futureSeasonTemporalParadox : number ;
44
+ season : number ;
45
+ seasonsPerYear : number ;
46
+ year : number ;
47
+ yearsPerCycle : number ;
48
+ } > ;
49
+ export type PayloadRaces = Array < {
50
+ embassyLevel : number ;
51
+ energy : number ;
52
+ name : string ;
53
+ standing : number ;
54
+ title : string ;
55
+ unlocked : boolean ;
56
+ } > ;
33
57
export type PayloadResources = Array < {
34
58
craftable : boolean ;
35
59
label : string ;
36
60
maxValue : number ;
37
61
name : string ;
62
+ rate : number ;
38
63
value : number ;
39
64
} > ;
40
65
export type PayloadStatistics = Array < {
@@ -55,19 +80,23 @@ export interface KittenAnalystsMessage<
55
80
TMessage extends KittenAnalystsMessageId ,
56
81
TData = TMessage extends "getBuildings"
57
82
? PayloadBuildings
58
- : TMessage extends "getResourcePool"
59
- ? PayloadResources
60
- : TMessage extends "getStatistics"
61
- ? PayloadStatistics
62
- : TMessage extends "getTechnologies"
63
- ? PayloadTechnologies
64
- : TMessage extends "reportFrame"
65
- ? unknown
66
- : TMessage extends "reportSavegame"
67
- ? unknown
68
- : TMessage extends "injectSavegame"
69
- ? KGNetSavePersisted
70
- : never ,
83
+ : TMessage extends "getCalendar"
84
+ ? PayloadCalendar
85
+ : TMessage extends "getRaces"
86
+ ? PayloadRaces
87
+ : TMessage extends "getResourcePool"
88
+ ? PayloadResources
89
+ : TMessage extends "getStatistics"
90
+ ? PayloadStatistics
91
+ : TMessage extends "getTechnologies"
92
+ ? PayloadTechnologies
93
+ : TMessage extends "reportFrame"
94
+ ? unknown
95
+ : TMessage extends "reportSavegame"
96
+ ? unknown
97
+ : TMessage extends "injectSavegame"
98
+ ? KGNetSavePersisted
99
+ : never ,
71
100
> {
72
101
/**
73
102
* The payload of the message.
@@ -225,80 +254,180 @@ export class KittenAnalysts {
225
254
const bonfire : PayloadBuildings = game . bld . meta [ 0 ] . meta . flatMap ( building => {
226
255
if ( building . stages ) {
227
256
return building . stages . map ( ( stage , index ) => ( {
257
+ group : "upgrade" ,
258
+ label : stage . label ,
228
259
name : building . name ,
229
- value : index === building . stage ? building . val : 0 ,
230
260
on : index === building . stage ? building . on : 0 ,
231
- label : stage . label ,
232
261
tab : "Bonfire" ,
262
+ value : index === building . stage ? building . val : 0 ,
233
263
} ) ) ;
234
264
}
235
265
return {
266
+ group : "base" ,
267
+ label : building . label ?? building . name ,
236
268
name : building . name ,
237
- value : building . val ,
238
269
on : building . on ,
239
- label : building . label ?? building . name ,
240
270
tab : "Bonfire" ,
271
+ value : building . val ,
241
272
} ;
242
273
} ) ;
274
+
275
+ const religionGroups = [ "ziggurats" , "orderOfTheSun" , "cryptotheology" , "pacts" ] ;
276
+ const religion : PayloadBuildings = game . religion . meta . flatMap ( ( meta , index ) =>
277
+ meta . meta . map ( building => ( {
278
+ group : religionGroups [ index ] ,
279
+ label : building . label ,
280
+ name : building . name ,
281
+ on : 0 ,
282
+ tab : "Religion" ,
283
+ value : building . val ,
284
+ } ) ) ,
285
+ ) ;
286
+
287
+ const spaceGroups = [
288
+ "groundControl" ,
289
+ "cath" ,
290
+ "moon" ,
291
+ "dune" ,
292
+ "piscine" ,
293
+ "helios" ,
294
+ "terminus" ,
295
+ "kairo" ,
296
+ "yarn" ,
297
+ "umbra" ,
298
+ "charon" ,
299
+ "centaurusSystem" ,
300
+ "furthestRing" ,
301
+ ] ;
243
302
const space : PayloadBuildings = game . space . meta . flatMap ( ( meta , index ) =>
244
303
// index 0 is moon missions
245
304
index === 0
246
305
? [ ]
247
306
: meta . meta . map ( building => ( {
307
+ group : spaceGroups [ index ] ,
308
+ label : building . label ,
248
309
name : building . name ,
249
- value : building . val ,
250
310
on : building . on ,
251
- label : building . label ,
252
311
tab : "Space" ,
312
+ value : building . val ,
253
313
} ) ) ,
254
314
) ;
255
- const religion : PayloadBuildings = game . religion . meta . flatMap ( meta =>
256
- meta . meta . map ( building => ( {
257
- name : building . name ,
258
- value : building . val ,
259
- on : 0 ,
260
- label : building . label ,
261
- tab : "Religion" ,
315
+
316
+ const timeGroups = [ "chronoForge" , "voidSpace" ] ;
317
+ const time : PayloadBuildings = game . time . meta . flatMap ( ( meta , index ) =>
318
+ meta . meta . map ( item => ( {
319
+ group : timeGroups [ index ] ,
320
+ label : item . label ,
321
+ name : item . name ,
322
+ on : "on" in item ? ( item . on ?? 0 ) : 0 ,
323
+ tab : "Time" ,
324
+ value : item . val ,
262
325
} ) ) ,
263
326
) ;
264
327
265
328
return {
266
329
client_type : this . location . includes ( "headless.html" ) ? "headless" : "browser" ,
267
- data : [ ...bonfire , ...space , ...religion ] ,
330
+ data : [ ...bonfire , ...religion , ... space , ...time ] ,
268
331
guid : game . telemetry . guid ,
269
332
location : this . location ,
270
333
responseId : message . responseId ,
271
334
type : message . type ,
272
335
} ;
273
336
}
274
- case "getResourcePool" : {
275
- const resources : PayloadResources = game . resPool . resources . map ( resource => ( {
276
- name : resource . name ,
277
- value : resource . value ,
278
- maxValue : resource . maxValue ,
279
- label : resource . title ,
280
- craftable : resource . craftable ?? false ,
337
+
338
+ case "getCalendar" : {
339
+ const data : PayloadCalendar = [
340
+ {
341
+ cryptoPrice : game . calendar . cryptoPrice ,
342
+ cycle : game . calendar . cycle ,
343
+ cycleYear : game . calendar . cycleYear ,
344
+ day : game . calendar . day ,
345
+ eventChance : game . calendar . eventChance ,
346
+ festivalDays : game . calendar . festivalDays ,
347
+ futureSeasonTemporalParadox : game . calendar . futureSeasonTemporalParadox ,
348
+ season : game . calendar . season ,
349
+ seasonsPerYear : game . calendar . seasonsPerYear ,
350
+ year : game . calendar . year ,
351
+ yearsPerCycle : game . calendar . yearsPerCycle ,
352
+ } ,
353
+ ] ;
354
+ return {
355
+ client_type : this . location . includes ( "headless.html" ) ? "headless" : "browser" ,
356
+ data,
357
+ guid : game . telemetry . guid ,
358
+ location : this . location ,
359
+ responseId : message . responseId ,
360
+ type : message . type ,
361
+ } ;
362
+ }
363
+
364
+ case "getRaces" : {
365
+ const data : PayloadRaces = game . diplomacy . races . map ( race => ( {
366
+ embassyLevel : race . embassyLevel ,
367
+ energy : race . energy ,
368
+ name : race . name ,
369
+ standing : race . standing ,
370
+ title : race . title ,
371
+ unlocked : race . unlocked ,
281
372
} ) ) ;
373
+
374
+ return {
375
+ client_type : this . location . includes ( "headless.html" ) ? "headless" : "browser" ,
376
+ data,
377
+ guid : game . telemetry . guid ,
378
+ location : this . location ,
379
+ responseId : message . responseId ,
380
+ type : message . type ,
381
+ } ;
382
+ }
383
+ case "getResourcePool" : {
384
+ const isTimeParadox = this . game . calendar . day < 0 ;
385
+
386
+ const resources : PayloadResources = this . game . resPool . resources . map ( resource => {
387
+ let rate =
388
+ ( isTimeParadox ? 0 : this . game . getResourcePerTick ( resource . name , true ) ) *
389
+ this . game . getTicksPerSecondUI ( ) ;
390
+ if ( resource . calculatePerDay === true ) {
391
+ rate =
392
+ this . game . getResourcePerDay ( resource . name ) *
393
+ ( resource . name === "necrocorn" ? 1 + this . game . timeAccelerationRatio ( ) : 1 ) ;
394
+ } else if ( resource . calculatePerYear ) {
395
+ rate = this . game . getResourceOnYearProduction ( resource . name ) ;
396
+ }
397
+
398
+ return {
399
+ name : resource . name ,
400
+ value : resource . value ,
401
+ maxValue : resource . maxValue ,
402
+ label : resource . title ,
403
+ craftable : resource . craftable ?? false ,
404
+ rate : rate ,
405
+ } ;
406
+ } ) ;
407
+
282
408
const pseudoResources : PayloadResources = [
283
409
{
284
410
craftable : false ,
285
411
label : "Worship" ,
286
412
maxValue : Infinity ,
287
413
name : "worship" ,
414
+ rate : 0 ,
288
415
value : game . religion . faith ,
289
416
} ,
290
417
{
291
418
craftable : false ,
292
419
label : "Epiphany" ,
293
420
maxValue : Infinity ,
294
421
name : "epiphany" ,
422
+ rate : 0 ,
295
423
value : game . religion . faithRatio ,
296
424
} ,
297
425
{
298
426
craftable : false ,
299
427
label : "Necrocorn deficit" ,
300
428
maxValue : Infinity ,
301
429
name : "necrocornDeficit" ,
430
+ rate : 0 ,
302
431
value : game . religion . pactsManager . necrocornDeficit ,
303
432
} ,
304
433
] ;
0 commit comments