sekai-calculator 0.4.4 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +80 -13
- package/dist/index.d.ts +41 -5
- package/dist/index.mjs +80 -14
- package/package.json +12 -12
package/dist/index.cjs
CHANGED
|
@@ -35,6 +35,45 @@ function containsAny(collection, contains) {
|
|
|
35
35
|
return false;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
class CachedDataProvider {
|
|
39
|
+
dataProvider;
|
|
40
|
+
constructor(dataProvider) {
|
|
41
|
+
this.dataProvider = dataProvider;
|
|
42
|
+
}
|
|
43
|
+
static globalCache = new Map();
|
|
44
|
+
instanceCache = new Map();
|
|
45
|
+
static runningPromise = new Map();
|
|
46
|
+
async getData(cache, cacheKey, promise) {
|
|
47
|
+
if (cache.has(cacheKey))
|
|
48
|
+
return cache.get(cacheKey);
|
|
49
|
+
while (CachedDataProvider.runningPromise.has(cacheKey)) {
|
|
50
|
+
await CachedDataProvider.runningPromise.get(cacheKey);
|
|
51
|
+
}
|
|
52
|
+
if (cache.has(cacheKey))
|
|
53
|
+
return cache.get(cacheKey);
|
|
54
|
+
CachedDataProvider.runningPromise.set(cacheKey, promise());
|
|
55
|
+
const data = await getOrThrow(CachedDataProvider.runningPromise, cacheKey).then(data => {
|
|
56
|
+
cache.set(cacheKey, data);
|
|
57
|
+
return data;
|
|
58
|
+
});
|
|
59
|
+
CachedDataProvider.runningPromise.delete(cacheKey);
|
|
60
|
+
return data;
|
|
61
|
+
}
|
|
62
|
+
async getMasterData(key) {
|
|
63
|
+
return await this.getData(CachedDataProvider.globalCache, key, async () => await this.dataProvider.getMasterData(key));
|
|
64
|
+
}
|
|
65
|
+
async getMusicMeta() {
|
|
66
|
+
return await this.getData(CachedDataProvider.globalCache, 'musicMeta', async () => await this.dataProvider.getMusicMeta());
|
|
67
|
+
}
|
|
68
|
+
async getUserData(key) {
|
|
69
|
+
const allData = await this.getUserDataAll();
|
|
70
|
+
return allData[key];
|
|
71
|
+
}
|
|
72
|
+
async getUserDataAll() {
|
|
73
|
+
return await this.getData(this.instanceCache, 'userData', async () => await this.dataProvider.getUserDataAll());
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
38
77
|
class DeckService {
|
|
39
78
|
dataProvider;
|
|
40
79
|
constructor(dataProvider) {
|
|
@@ -300,13 +339,40 @@ class CardCalculator {
|
|
|
300
339
|
units.push(findOrThrow(gameCharacters, it => it.id === card.characterId).unit);
|
|
301
340
|
return units;
|
|
302
341
|
}
|
|
303
|
-
async
|
|
342
|
+
async applyCardConfig(userCard, card, { rankMax = false, episodeRead = false, masterMax = false, skillMax = false }) {
|
|
343
|
+
if (!rankMax && !episodeRead && !masterMax && !skillMax)
|
|
344
|
+
return userCard;
|
|
345
|
+
const cardRarities = await this.dataProvider.getMasterData('cardRarities');
|
|
346
|
+
const cardRarity = findOrThrow(cardRarities, it => it.cardRarityType === card.cardRarityType);
|
|
347
|
+
const ret = JSON.parse(JSON.stringify(userCard));
|
|
348
|
+
if (rankMax) {
|
|
349
|
+
if (cardRarity.trainingMaxLevel !== undefined) {
|
|
350
|
+
ret.level = cardRarity.trainingMaxLevel;
|
|
351
|
+
ret.specialTrainingStatus = 'done';
|
|
352
|
+
}
|
|
353
|
+
else {
|
|
354
|
+
ret.level = cardRarity.maxLevel;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
if (episodeRead) {
|
|
358
|
+
ret.episodes.forEach(it => { it.scenarioStatus = 'already_read'; });
|
|
359
|
+
}
|
|
360
|
+
if (masterMax) {
|
|
361
|
+
ret.masterRank = 5;
|
|
362
|
+
}
|
|
363
|
+
if (skillMax) {
|
|
364
|
+
ret.skillLevel = cardRarity.maxSkillLevel;
|
|
365
|
+
}
|
|
366
|
+
return ret;
|
|
367
|
+
}
|
|
368
|
+
async getCardDetail(userCard, userAreaItemLevels, config = {}, eventId = 0) {
|
|
304
369
|
const cards = await this.dataProvider.getMasterData('cards');
|
|
305
370
|
const card = findOrThrow(cards, it => it.id === userCard.cardId);
|
|
306
371
|
const units = await this.getCardUnits(card);
|
|
307
|
-
const
|
|
308
|
-
const
|
|
309
|
-
const
|
|
372
|
+
const userCard0 = await this.applyCardConfig(userCard, card, config);
|
|
373
|
+
const skill = await this.skillCalculator.getCardSkill(userCard0, card);
|
|
374
|
+
const power = await this.powerCalculator.getCardPower(userCard0, card, units, userAreaItemLevels);
|
|
375
|
+
const eventBonus = eventId === 0 ? undefined : await this.eventCalculator.getCardEventBonus(userCard0, eventId);
|
|
310
376
|
return {
|
|
311
377
|
cardId: card.id,
|
|
312
378
|
characterId: card.characterId,
|
|
@@ -318,11 +384,11 @@ class CardCalculator {
|
|
|
318
384
|
eventBonus
|
|
319
385
|
};
|
|
320
386
|
}
|
|
321
|
-
async batchGetCardDetail(userCards, eventId = 0) {
|
|
387
|
+
async batchGetCardDetail(userCards, config = {}, eventId = 0) {
|
|
322
388
|
const areaItemLevels = await this.dataProvider.getMasterData('areaItemLevels');
|
|
323
389
|
const userAreas = await this.dataProvider.getUserData('userAreas');
|
|
324
390
|
const userItemLevels = userAreas.flatMap(it => it.areaItems).map(areaItem => findOrThrow(areaItemLevels, it => it.areaItemId === areaItem.areaItemId && it.level === areaItem.level));
|
|
325
|
-
return await Promise.all(userCards.map(async (it) => await this.getCardDetail(it, userItemLevels, eventId)));
|
|
391
|
+
return await Promise.all(userCards.map(async (it) => await this.getCardDetail(it, userItemLevels, config, eventId)));
|
|
326
392
|
}
|
|
327
393
|
static isCertainlyLessThan(cardDetail0, cardDetail1) {
|
|
328
394
|
return cardDetail0.power.isCertainlyLessThen(cardDetail1.power) &&
|
|
@@ -545,7 +611,7 @@ class BaseDeckRecommend {
|
|
|
545
611
|
}
|
|
546
612
|
static filterCard(cardDetails) {
|
|
547
613
|
let afterFilter = cardDetails;
|
|
548
|
-
for (const minBonus of [
|
|
614
|
+
for (const minBonus of [55, 50, 45, 40, 30, 25, 15, 5, 0]) {
|
|
549
615
|
const bonusFilter = cardDetails.filter(cardDetail => !(cardDetail.eventBonus !== undefined && cardDetail.eventBonus < minBonus));
|
|
550
616
|
if (this.canMakeEventDeck(bonusFilter)) {
|
|
551
617
|
afterFilter = bonusFilter;
|
|
@@ -593,8 +659,8 @@ class BaseDeckRecommend {
|
|
|
593
659
|
throw new Error(`Cannot find deck in ${cardDetails.length} cards`);
|
|
594
660
|
return ans;
|
|
595
661
|
}
|
|
596
|
-
async recommendHighScoreDeck(userCards,
|
|
597
|
-
const cards = await this.cardCalculator.batchGetCardDetail(userCards, eventId);
|
|
662
|
+
async recommendHighScoreDeck(userCards, scoreFunc, { musicMeta, limit = 1, member = 5, cardConfig = {} }, eventId = 0, isChallengeLive = false) {
|
|
663
|
+
const cards = await this.cardCalculator.batchGetCardDetail(userCards, cardConfig, eventId);
|
|
598
664
|
let cardDetails = (isChallengeLive || eventId === 0) ? cards : BaseDeckRecommend.filterCard(cards);
|
|
599
665
|
cardDetails = cardDetails.sort((a, b) => a.cardId - b.cardId);
|
|
600
666
|
const honorBonus = await this.deckCalculator.getHonorBonusPower();
|
|
@@ -615,12 +681,12 @@ class ChallengeLiveDeckRecommend {
|
|
|
615
681
|
this.dataProvider = dataProvider;
|
|
616
682
|
this.baseRecommend = new BaseDeckRecommend(dataProvider);
|
|
617
683
|
}
|
|
618
|
-
async recommendChallengeLiveDeck(characterId,
|
|
684
|
+
async recommendChallengeLiveDeck(characterId, config) {
|
|
619
685
|
const userCards = await this.dataProvider.getUserData('userCards');
|
|
620
686
|
const cards = await this.dataProvider.getMasterData('cards');
|
|
621
687
|
const characterCards = userCards
|
|
622
688
|
.filter(userCard => findOrThrow(cards, it => it.id === userCard.cardId).characterId === characterId);
|
|
623
|
-
const recommend = await this.baseRecommend.recommendHighScoreDeck(characterCards,
|
|
689
|
+
const recommend = await this.baseRecommend.recommendHighScoreDeck(characterCards, BaseDeckRecommend.getLiveScoreFunction(exports.LiveType.SOLO), config, 0, true);
|
|
624
690
|
return recommend.map(it => {
|
|
625
691
|
return {
|
|
626
692
|
score: it.score,
|
|
@@ -638,9 +704,9 @@ class EventDeckRecommend {
|
|
|
638
704
|
this.dataProvider = dataProvider;
|
|
639
705
|
this.baseRecommend = new BaseDeckRecommend(dataProvider);
|
|
640
706
|
}
|
|
641
|
-
async recommendEventDeck(eventId,
|
|
707
|
+
async recommendEventDeck(eventId, liveType, config) {
|
|
642
708
|
const userCards = await this.dataProvider.getUserData('userCards');
|
|
643
|
-
const recommend = await this.baseRecommend.recommendHighScoreDeck(userCards,
|
|
709
|
+
const recommend = await this.baseRecommend.recommendHighScoreDeck(userCards, BaseDeckRecommend.getEventPointFunction(liveType), config, eventId);
|
|
644
710
|
return recommend.map(it => {
|
|
645
711
|
return {
|
|
646
712
|
point: it.score,
|
|
@@ -684,6 +750,7 @@ class MusicRecommend {
|
|
|
684
750
|
}
|
|
685
751
|
}
|
|
686
752
|
|
|
753
|
+
exports.CachedDataProvider = CachedDataProvider;
|
|
687
754
|
exports.CardCalculator = CardCalculator;
|
|
688
755
|
exports.CardEventCalculator = CardEventCalculator;
|
|
689
756
|
exports.CardPowerCalculator = CardPowerCalculator;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
interface DataProvider {
|
|
2
2
|
getMasterData: (key: string) => Promise<any>;
|
|
3
|
+
getUserDataAll: () => Promise<any>;
|
|
3
4
|
getUserData: (key: string) => Promise<any>;
|
|
4
5
|
getMusicMeta: () => Promise<any>;
|
|
5
6
|
}
|
|
6
7
|
|
|
8
|
+
declare class CachedDataProvider implements DataProvider {
|
|
9
|
+
private readonly dataProvider;
|
|
10
|
+
constructor(dataProvider: DataProvider);
|
|
11
|
+
private static readonly globalCache;
|
|
12
|
+
private readonly instanceCache;
|
|
13
|
+
private static readonly runningPromise;
|
|
14
|
+
private getData;
|
|
15
|
+
getMasterData(key: string): Promise<any>;
|
|
16
|
+
getMusicMeta(): Promise<any>;
|
|
17
|
+
getUserData(key: string): Promise<any>;
|
|
18
|
+
getUserDataAll(): Promise<any>;
|
|
19
|
+
}
|
|
20
|
+
|
|
7
21
|
interface UserDeck {
|
|
8
22
|
userId: number;
|
|
9
23
|
deckId: number;
|
|
@@ -81,8 +95,9 @@ declare class CardCalculator {
|
|
|
81
95
|
private readonly eventCalculator;
|
|
82
96
|
constructor(dataProvider: DataProvider);
|
|
83
97
|
private getCardUnits;
|
|
84
|
-
|
|
85
|
-
|
|
98
|
+
private applyCardConfig;
|
|
99
|
+
getCardDetail(userCard: UserCard, userAreaItemLevels: AreaItemLevel[], config?: CardConfig, eventId?: number): Promise<CardDetail>;
|
|
100
|
+
batchGetCardDetail(userCards: UserCard[], config?: CardConfig, eventId?: number): Promise<CardDetail[]>;
|
|
86
101
|
static isCertainlyLessThan(cardDetail0: CardDetail, cardDetail1: CardDetail): boolean;
|
|
87
102
|
}
|
|
88
103
|
interface CardDetail {
|
|
@@ -95,6 +110,12 @@ interface CardDetail {
|
|
|
95
110
|
lifeSkill: number;
|
|
96
111
|
eventBonus?: number;
|
|
97
112
|
}
|
|
113
|
+
interface CardConfig {
|
|
114
|
+
rankMax?: boolean;
|
|
115
|
+
episodeRead?: boolean;
|
|
116
|
+
masterMax?: boolean;
|
|
117
|
+
skillMax?: boolean;
|
|
118
|
+
}
|
|
98
119
|
|
|
99
120
|
declare class DeckService {
|
|
100
121
|
private readonly dataProvider;
|
|
@@ -250,11 +271,18 @@ declare class EventCalculator {
|
|
|
250
271
|
static getDeckEventPoint(deckCards: CardDetail[], honorBonus: number, musicMeta: MusicMeta, liveType: LiveType): number;
|
|
251
272
|
}
|
|
252
273
|
|
|
274
|
+
interface DeckRecommendConfig {
|
|
275
|
+
musicMeta: MusicMeta;
|
|
276
|
+
limit?: number;
|
|
277
|
+
member?: number;
|
|
278
|
+
cardConfig?: CardConfig;
|
|
279
|
+
}
|
|
280
|
+
|
|
253
281
|
declare class ChallengeLiveDeckRecommend {
|
|
254
282
|
private readonly dataProvider;
|
|
255
283
|
private readonly baseRecommend;
|
|
256
284
|
constructor(dataProvider: DataProvider);
|
|
257
|
-
recommendChallengeLiveDeck(characterId: number,
|
|
285
|
+
recommendChallengeLiveDeck(characterId: number, config: DeckRecommendConfig): Promise<Array<{
|
|
258
286
|
score: number;
|
|
259
287
|
power: number;
|
|
260
288
|
deck: UserChallengeLiveSoloDeck;
|
|
@@ -265,7 +293,7 @@ declare class EventDeckRecommend {
|
|
|
265
293
|
private readonly dataProvider;
|
|
266
294
|
private readonly baseRecommend;
|
|
267
295
|
constructor(dataProvider: DataProvider);
|
|
268
|
-
recommendEventDeck(eventId: number,
|
|
296
|
+
recommendEventDeck(eventId: number, liveType: LiveType, config: DeckRecommendConfig): Promise<Array<{
|
|
269
297
|
point: number;
|
|
270
298
|
power: number;
|
|
271
299
|
eventBonus?: number;
|
|
@@ -303,6 +331,14 @@ interface CardEpisode {
|
|
|
303
331
|
cardEpisodePartType: string;
|
|
304
332
|
}
|
|
305
333
|
|
|
334
|
+
interface CardRarity {
|
|
335
|
+
cardRarityType: string;
|
|
336
|
+
seq: number;
|
|
337
|
+
maxLevel: number;
|
|
338
|
+
trainingMaxLevel?: number;
|
|
339
|
+
maxSkillLevel: number;
|
|
340
|
+
}
|
|
341
|
+
|
|
306
342
|
interface CharacterRank {
|
|
307
343
|
id: number;
|
|
308
344
|
characterId: number;
|
|
@@ -492,4 +528,4 @@ interface UserHonor {
|
|
|
492
528
|
level: number;
|
|
493
529
|
}
|
|
494
530
|
|
|
495
|
-
export { AreaItemLevel, Card, CardCalculator, CardDetail, CardEpisode, CardEventCalculator, CardPowerCalculator, CardSkillCalculator, ChallengeLiveDeckRecommend, CharacterRank, DataProvider, DeckCalculator, DeckDetail, DeckService, EventCalculator, EventCard, EventDeckBonus, EventDeckRecommend, EventRarityBonusRate, GameCharacter, GameCharacterUnit, Honor, LiveCalculator, LiveDetail, LiveSkill, LiveType, MasterLesson, MusicMeta, MusicRecommend, Skill, SkillDetail, User, UserArea, UserCard, UserChallengeLiveSoloDeck, UserCharacter, UserDeck, UserHonor };
|
|
531
|
+
export { AreaItemLevel, CachedDataProvider, Card, CardCalculator, CardConfig, CardDetail, CardEpisode, CardEventCalculator, CardPowerCalculator, CardRarity, CardSkillCalculator, ChallengeLiveDeckRecommend, CharacterRank, DataProvider, DeckCalculator, DeckDetail, DeckService, EventCalculator, EventCard, EventDeckBonus, EventDeckRecommend, EventRarityBonusRate, GameCharacter, GameCharacterUnit, Honor, LiveCalculator, LiveDetail, LiveSkill, LiveType, MasterLesson, MusicMeta, MusicRecommend, Skill, SkillDetail, User, UserArea, UserCard, UserChallengeLiveSoloDeck, UserCharacter, UserDeck, UserHonor };
|
package/dist/index.mjs
CHANGED
|
@@ -33,6 +33,45 @@ function containsAny(collection, contains) {
|
|
|
33
33
|
return false;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
class CachedDataProvider {
|
|
37
|
+
dataProvider;
|
|
38
|
+
constructor(dataProvider) {
|
|
39
|
+
this.dataProvider = dataProvider;
|
|
40
|
+
}
|
|
41
|
+
static globalCache = new Map();
|
|
42
|
+
instanceCache = new Map();
|
|
43
|
+
static runningPromise = new Map();
|
|
44
|
+
async getData(cache, cacheKey, promise) {
|
|
45
|
+
if (cache.has(cacheKey))
|
|
46
|
+
return cache.get(cacheKey);
|
|
47
|
+
while (CachedDataProvider.runningPromise.has(cacheKey)) {
|
|
48
|
+
await CachedDataProvider.runningPromise.get(cacheKey);
|
|
49
|
+
}
|
|
50
|
+
if (cache.has(cacheKey))
|
|
51
|
+
return cache.get(cacheKey);
|
|
52
|
+
CachedDataProvider.runningPromise.set(cacheKey, promise());
|
|
53
|
+
const data = await getOrThrow(CachedDataProvider.runningPromise, cacheKey).then(data => {
|
|
54
|
+
cache.set(cacheKey, data);
|
|
55
|
+
return data;
|
|
56
|
+
});
|
|
57
|
+
CachedDataProvider.runningPromise.delete(cacheKey);
|
|
58
|
+
return data;
|
|
59
|
+
}
|
|
60
|
+
async getMasterData(key) {
|
|
61
|
+
return await this.getData(CachedDataProvider.globalCache, key, async () => await this.dataProvider.getMasterData(key));
|
|
62
|
+
}
|
|
63
|
+
async getMusicMeta() {
|
|
64
|
+
return await this.getData(CachedDataProvider.globalCache, 'musicMeta', async () => await this.dataProvider.getMusicMeta());
|
|
65
|
+
}
|
|
66
|
+
async getUserData(key) {
|
|
67
|
+
const allData = await this.getUserDataAll();
|
|
68
|
+
return allData[key];
|
|
69
|
+
}
|
|
70
|
+
async getUserDataAll() {
|
|
71
|
+
return await this.getData(this.instanceCache, 'userData', async () => await this.dataProvider.getUserDataAll());
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
36
75
|
class DeckService {
|
|
37
76
|
dataProvider;
|
|
38
77
|
constructor(dataProvider) {
|
|
@@ -298,13 +337,40 @@ class CardCalculator {
|
|
|
298
337
|
units.push(findOrThrow(gameCharacters, it => it.id === card.characterId).unit);
|
|
299
338
|
return units;
|
|
300
339
|
}
|
|
301
|
-
async
|
|
340
|
+
async applyCardConfig(userCard, card, { rankMax = false, episodeRead = false, masterMax = false, skillMax = false }) {
|
|
341
|
+
if (!rankMax && !episodeRead && !masterMax && !skillMax)
|
|
342
|
+
return userCard;
|
|
343
|
+
const cardRarities = await this.dataProvider.getMasterData('cardRarities');
|
|
344
|
+
const cardRarity = findOrThrow(cardRarities, it => it.cardRarityType === card.cardRarityType);
|
|
345
|
+
const ret = JSON.parse(JSON.stringify(userCard));
|
|
346
|
+
if (rankMax) {
|
|
347
|
+
if (cardRarity.trainingMaxLevel !== undefined) {
|
|
348
|
+
ret.level = cardRarity.trainingMaxLevel;
|
|
349
|
+
ret.specialTrainingStatus = 'done';
|
|
350
|
+
}
|
|
351
|
+
else {
|
|
352
|
+
ret.level = cardRarity.maxLevel;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
if (episodeRead) {
|
|
356
|
+
ret.episodes.forEach(it => { it.scenarioStatus = 'already_read'; });
|
|
357
|
+
}
|
|
358
|
+
if (masterMax) {
|
|
359
|
+
ret.masterRank = 5;
|
|
360
|
+
}
|
|
361
|
+
if (skillMax) {
|
|
362
|
+
ret.skillLevel = cardRarity.maxSkillLevel;
|
|
363
|
+
}
|
|
364
|
+
return ret;
|
|
365
|
+
}
|
|
366
|
+
async getCardDetail(userCard, userAreaItemLevels, config = {}, eventId = 0) {
|
|
302
367
|
const cards = await this.dataProvider.getMasterData('cards');
|
|
303
368
|
const card = findOrThrow(cards, it => it.id === userCard.cardId);
|
|
304
369
|
const units = await this.getCardUnits(card);
|
|
305
|
-
const
|
|
306
|
-
const
|
|
307
|
-
const
|
|
370
|
+
const userCard0 = await this.applyCardConfig(userCard, card, config);
|
|
371
|
+
const skill = await this.skillCalculator.getCardSkill(userCard0, card);
|
|
372
|
+
const power = await this.powerCalculator.getCardPower(userCard0, card, units, userAreaItemLevels);
|
|
373
|
+
const eventBonus = eventId === 0 ? undefined : await this.eventCalculator.getCardEventBonus(userCard0, eventId);
|
|
308
374
|
return {
|
|
309
375
|
cardId: card.id,
|
|
310
376
|
characterId: card.characterId,
|
|
@@ -316,11 +382,11 @@ class CardCalculator {
|
|
|
316
382
|
eventBonus
|
|
317
383
|
};
|
|
318
384
|
}
|
|
319
|
-
async batchGetCardDetail(userCards, eventId = 0) {
|
|
385
|
+
async batchGetCardDetail(userCards, config = {}, eventId = 0) {
|
|
320
386
|
const areaItemLevels = await this.dataProvider.getMasterData('areaItemLevels');
|
|
321
387
|
const userAreas = await this.dataProvider.getUserData('userAreas');
|
|
322
388
|
const userItemLevels = userAreas.flatMap(it => it.areaItems).map(areaItem => findOrThrow(areaItemLevels, it => it.areaItemId === areaItem.areaItemId && it.level === areaItem.level));
|
|
323
|
-
return await Promise.all(userCards.map(async (it) => await this.getCardDetail(it, userItemLevels, eventId)));
|
|
389
|
+
return await Promise.all(userCards.map(async (it) => await this.getCardDetail(it, userItemLevels, config, eventId)));
|
|
324
390
|
}
|
|
325
391
|
static isCertainlyLessThan(cardDetail0, cardDetail1) {
|
|
326
392
|
return cardDetail0.power.isCertainlyLessThen(cardDetail1.power) &&
|
|
@@ -543,7 +609,7 @@ class BaseDeckRecommend {
|
|
|
543
609
|
}
|
|
544
610
|
static filterCard(cardDetails) {
|
|
545
611
|
let afterFilter = cardDetails;
|
|
546
|
-
for (const minBonus of [
|
|
612
|
+
for (const minBonus of [55, 50, 45, 40, 30, 25, 15, 5, 0]) {
|
|
547
613
|
const bonusFilter = cardDetails.filter(cardDetail => !(cardDetail.eventBonus !== undefined && cardDetail.eventBonus < minBonus));
|
|
548
614
|
if (this.canMakeEventDeck(bonusFilter)) {
|
|
549
615
|
afterFilter = bonusFilter;
|
|
@@ -591,8 +657,8 @@ class BaseDeckRecommend {
|
|
|
591
657
|
throw new Error(`Cannot find deck in ${cardDetails.length} cards`);
|
|
592
658
|
return ans;
|
|
593
659
|
}
|
|
594
|
-
async recommendHighScoreDeck(userCards,
|
|
595
|
-
const cards = await this.cardCalculator.batchGetCardDetail(userCards, eventId);
|
|
660
|
+
async recommendHighScoreDeck(userCards, scoreFunc, { musicMeta, limit = 1, member = 5, cardConfig = {} }, eventId = 0, isChallengeLive = false) {
|
|
661
|
+
const cards = await this.cardCalculator.batchGetCardDetail(userCards, cardConfig, eventId);
|
|
596
662
|
let cardDetails = (isChallengeLive || eventId === 0) ? cards : BaseDeckRecommend.filterCard(cards);
|
|
597
663
|
cardDetails = cardDetails.sort((a, b) => a.cardId - b.cardId);
|
|
598
664
|
const honorBonus = await this.deckCalculator.getHonorBonusPower();
|
|
@@ -613,12 +679,12 @@ class ChallengeLiveDeckRecommend {
|
|
|
613
679
|
this.dataProvider = dataProvider;
|
|
614
680
|
this.baseRecommend = new BaseDeckRecommend(dataProvider);
|
|
615
681
|
}
|
|
616
|
-
async recommendChallengeLiveDeck(characterId,
|
|
682
|
+
async recommendChallengeLiveDeck(characterId, config) {
|
|
617
683
|
const userCards = await this.dataProvider.getUserData('userCards');
|
|
618
684
|
const cards = await this.dataProvider.getMasterData('cards');
|
|
619
685
|
const characterCards = userCards
|
|
620
686
|
.filter(userCard => findOrThrow(cards, it => it.id === userCard.cardId).characterId === characterId);
|
|
621
|
-
const recommend = await this.baseRecommend.recommendHighScoreDeck(characterCards,
|
|
687
|
+
const recommend = await this.baseRecommend.recommendHighScoreDeck(characterCards, BaseDeckRecommend.getLiveScoreFunction(LiveType.SOLO), config, 0, true);
|
|
622
688
|
return recommend.map(it => {
|
|
623
689
|
return {
|
|
624
690
|
score: it.score,
|
|
@@ -636,9 +702,9 @@ class EventDeckRecommend {
|
|
|
636
702
|
this.dataProvider = dataProvider;
|
|
637
703
|
this.baseRecommend = new BaseDeckRecommend(dataProvider);
|
|
638
704
|
}
|
|
639
|
-
async recommendEventDeck(eventId,
|
|
705
|
+
async recommendEventDeck(eventId, liveType, config) {
|
|
640
706
|
const userCards = await this.dataProvider.getUserData('userCards');
|
|
641
|
-
const recommend = await this.baseRecommend.recommendHighScoreDeck(userCards,
|
|
707
|
+
const recommend = await this.baseRecommend.recommendHighScoreDeck(userCards, BaseDeckRecommend.getEventPointFunction(liveType), config, eventId);
|
|
642
708
|
return recommend.map(it => {
|
|
643
709
|
return {
|
|
644
710
|
point: it.score,
|
|
@@ -682,4 +748,4 @@ class MusicRecommend {
|
|
|
682
748
|
}
|
|
683
749
|
}
|
|
684
750
|
|
|
685
|
-
export { CardCalculator, CardEventCalculator, CardPowerCalculator, CardSkillCalculator, ChallengeLiveDeckRecommend, DeckCalculator, DeckService, EventCalculator, EventDeckRecommend, LiveCalculator, LiveType, MusicRecommend };
|
|
751
|
+
export { CachedDataProvider, CardCalculator, CardEventCalculator, CardPowerCalculator, CardSkillCalculator, ChallengeLiveDeckRecommend, DeckCalculator, DeckService, EventCalculator, EventDeckRecommend, LiveCalculator, LiveType, MusicRecommend };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sekai-calculator",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Project SEKAI Calculator for deck power, live score, event point and more.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -30,22 +30,22 @@
|
|
|
30
30
|
},
|
|
31
31
|
"license": "LGPL-2.1-or-later",
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@rollup/plugin-typescript": "^11.
|
|
34
|
-
"@types/jest": "^29.
|
|
35
|
-
"@types/node": "^18.15.
|
|
36
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
37
|
-
"eslint": "^8.
|
|
38
|
-
"eslint-config-standard-with-typescript": "^34.0.
|
|
33
|
+
"@rollup/plugin-typescript": "^11.1.0",
|
|
34
|
+
"@types/jest": "^29.5.0",
|
|
35
|
+
"@types/node": "^18.15.11",
|
|
36
|
+
"@typescript-eslint/eslint-plugin": "^5.57.1",
|
|
37
|
+
"eslint": "^8.37.0",
|
|
38
|
+
"eslint-config-standard-with-typescript": "^34.0.1",
|
|
39
39
|
"eslint-plugin-import": "^2.27.5",
|
|
40
|
-
"eslint-plugin-n": "^15.
|
|
40
|
+
"eslint-plugin-n": "^15.7.0",
|
|
41
41
|
"eslint-plugin-promise": "^6.1.1",
|
|
42
42
|
"jest": "^29.5.0",
|
|
43
|
-
"rollup": "^3.
|
|
44
|
-
"rollup-plugin-dts": "^5.
|
|
45
|
-
"ts-jest": "^29.0
|
|
43
|
+
"rollup": "^3.20.2",
|
|
44
|
+
"rollup-plugin-dts": "^5.3.0",
|
|
45
|
+
"ts-jest": "^29.1.0",
|
|
46
46
|
"ts-node": "^10.9.1",
|
|
47
47
|
"tslib": "^2.5.0",
|
|
48
|
-
"typescript": "^
|
|
48
|
+
"typescript": "^5.0.3"
|
|
49
49
|
},
|
|
50
50
|
"scripts": {
|
|
51
51
|
"build": "rollup -c --configPlugin typescript",
|