sekai-calculator 0.8.4 → 0.9.0

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 CHANGED
@@ -170,9 +170,9 @@ class CardDetailMap {
170
170
  min = Number.MAX_SAFE_INTEGER;
171
171
  max = Number.MIN_SAFE_INTEGER;
172
172
  values = new Map();
173
- set(unit, unitMember, attrMember, value) {
174
- this.min = Math.min(this.min, value);
175
- this.max = Math.max(this.max, value);
173
+ set(unit, unitMember, attrMember, cmpValue, value) {
174
+ this.min = Math.min(this.min, cmpValue);
175
+ this.max = Math.max(this.max, cmpValue);
176
176
  this.values.set(CardDetailMap.getKey(unit, unitMember, attrMember), value);
177
177
  }
178
178
  get(unit, unitMember, attrMember) {
@@ -209,15 +209,26 @@ class CardPowerCalculator {
209
209
  const basePower = await this.getCardBasePowers(userCard, card);
210
210
  const characterBonus = await this.getCharacterBonusPower(basePower, card.characterId);
211
211
  for (const unit of cardUnits) {
212
- ret.set(unit, 5, 5, await this.getPower(card, basePower, characterBonus, userAreaItemLevels, unit, true, true));
213
- ret.set(unit, 5, 1, await this.getPower(card, basePower, characterBonus, userAreaItemLevels, unit, true, false));
214
- ret.set(unit, 1, 5, await this.getPower(card, basePower, characterBonus, userAreaItemLevels, unit, false, true));
215
- ret.set(unit, 1, 1, await this.getPower(card, basePower, characterBonus, userAreaItemLevels, unit, false, false));
212
+ let power = await this.getPower(card, basePower, characterBonus, userAreaItemLevels, unit, true, true);
213
+ ret.set(unit, 5, 5, power.total, power);
214
+ power = await this.getPower(card, basePower, characterBonus, userAreaItemLevels, unit, true, false);
215
+ ret.set(unit, 5, 1, power.total, power);
216
+ power = await this.getPower(card, basePower, characterBonus, userAreaItemLevels, unit, false, true);
217
+ ret.set(unit, 1, 5, power.total, power);
218
+ power = await this.getPower(card, basePower, characterBonus, userAreaItemLevels, unit, false, false);
219
+ ret.set(unit, 1, 1, power.total, power);
216
220
  }
217
221
  return ret;
218
222
  }
219
223
  async getPower(card, basePower, characterBonus, userAreaItemLevels, unit, sameUnit, sameAttr) {
220
- return basePower.reduce((v, it) => v + it, 0) + characterBonus + await this.getAreaItemBonusPower(userAreaItemLevels, basePower, card.characterId, unit, sameUnit, card.attr, sameAttr);
224
+ const base = basePower.reduce((v, it) => v + it, 0);
225
+ const areaItemBonus = await this.getAreaItemBonusPower(userAreaItemLevels, basePower, card.characterId, unit, sameUnit, card.attr, sameAttr);
226
+ return {
227
+ base,
228
+ areaItemBonus,
229
+ characterBonus,
230
+ total: base + characterBonus + areaItemBonus
231
+ };
221
232
  }
222
233
  async getCardBasePowers(userCard, card) {
223
234
  const p = await Promise.all([
@@ -272,7 +283,7 @@ class CardPowerCalculator {
272
283
  Math.fround(allMatch ? areaItem.power3AllMatchBonusRate : areaItem.power3BonusRate));
273
284
  }
274
285
  return basePower
275
- .reduce((v, it, i) => v + Math.floor(Math.fround(it * areaItemBonus[i] / 100)), 0);
286
+ .reduce((v, it, i) => v + Math.floor(Math.fround(it * Math.fround(areaItemBonus[i] / 100))), 0);
276
287
  }
277
288
  async getCharacterBonusPower(basePower, characterId) {
278
289
  const characterRanks = await this.dataProvider.getMasterData('characterRanks');
@@ -296,16 +307,22 @@ class CardSkillCalculator {
296
307
  this.dataProvider = dataProvider;
297
308
  }
298
309
  async getCardSkill(userCard, card) {
299
- const scoreUpMap = new CardDetailMap();
310
+ const skillMap = new CardDetailMap();
300
311
  const detail = await this.getSkillDetail(userCard, card);
301
312
  if (detail.scoreUpEnhance !== undefined) {
302
313
  for (let i = 1; i <= 5; ++i) {
303
314
  const scoreUp = detail.scoreUp + (i === 5 ? 5 : (i - 1)) * detail.scoreUpEnhance.value;
304
- scoreUpMap.set(detail.scoreUpEnhance.unit, i, 1, scoreUp);
315
+ skillMap.set(detail.scoreUpEnhance.unit, i, 1, scoreUp, {
316
+ scoreUp,
317
+ lifeRecovery: detail.lifeRecovery
318
+ });
305
319
  }
306
320
  }
307
- scoreUpMap.set('any', 1, 1, detail.scoreUp);
308
- return { scoreUp: scoreUpMap, lifeRecovery: detail.lifeRecovery };
321
+ skillMap.set('any', 1, 1, detail.scoreUp, {
322
+ scoreUp: detail.scoreUp,
323
+ lifeRecovery: detail.lifeRecovery
324
+ });
325
+ return skillMap;
309
326
  }
310
327
  async getSkillDetail(userCard, card) {
311
328
  const skills = await this.dataProvider.getMasterData('skills');
@@ -439,8 +456,7 @@ class CardCalculator {
439
456
  units,
440
457
  attr: card.attr,
441
458
  power,
442
- scoreSkill: skill.scoreUp,
443
- lifeSkill: skill.lifeRecovery,
459
+ skill,
444
460
  eventBonus
445
461
  };
446
462
  }
@@ -452,7 +468,7 @@ class CardCalculator {
452
468
  }
453
469
  static isCertainlyLessThan(cardDetail0, cardDetail1) {
454
470
  return cardDetail0.power.isCertainlyLessThen(cardDetail1.power) &&
455
- cardDetail0.scoreSkill.isCertainlyLessThen(cardDetail1.scoreSkill) &&
471
+ cardDetail0.skill.isCertainlyLessThen(cardDetail1.skill) &&
456
472
  (cardDetail0.eventBonus === undefined || cardDetail1.eventBonus === undefined ||
457
473
  cardDetail0.eventBonus <= cardDetail1.eventBonus);
458
474
  }
@@ -534,10 +550,10 @@ class LiveCalculator {
534
550
  const rate = baseRate + skills.details
535
551
  .reduce((v, it, i) => v + it.scoreUp * skillRate[i] / 100, 0);
536
552
  const life = skills.details.reduce((v, it) => v + it.lifeRecovery, 0);
537
- const powerSum = multiPowerSum === 0 ? 5 * deckDetail.power : multiPowerSum;
553
+ const powerSum = multiPowerSum === 0 ? 5 * deckDetail.power.total : multiPowerSum;
538
554
  const activeBonus = liveType === exports.LiveType.MULTI ? 5 * 0.015 * powerSum : 0;
539
555
  return {
540
- score: Math.floor(rate * deckDetail.power * 4 + activeBonus),
556
+ score: Math.floor(rate * deckDetail.power.total * 4 + activeBonus),
541
557
  time: musicMeta.music_time,
542
558
  life: Math.min(2000, life + 1000),
543
559
  tap: musicMeta.tap_count
@@ -664,11 +680,27 @@ class DeckCalculator {
664
680
  }
665
681
  const cardPower = new Map();
666
682
  cardDetails.forEach(cardDetail => {
667
- cardPower.set(cardDetail.cardId, cardDetail.units.reduce((vv, unit) => Math.max(vv, cardDetail.power.get(unit, getOrThrow(map, unit), getOrThrow(map, cardDetail.attr))), 0));
683
+ cardPower.set(cardDetail.cardId, cardDetail.units.reduce((vv, unit) => {
684
+ const current = cardDetail.power.get(unit, getOrThrow(map, unit), getOrThrow(map, cardDetail.attr));
685
+ return current.total > vv.total ? current : vv;
686
+ }, cardDetail.power.get(cardDetail.units[0], getOrThrow(map, cardDetail.units[0]), getOrThrow(map, cardDetail.attr))));
668
687
  });
669
- const power = cardDetails.reduce((v, cardDetail) => v + getOrThrow(cardPower, cardDetail.cardId), 0) + honorBonus;
688
+ const base = cardDetails.reduce((v, cardDetail) => v + getOrThrow(cardPower, cardDetail.cardId).base, 0);
689
+ const areaItemBonus = cardDetails.reduce((v, cardDetail) => v + getOrThrow(cardPower, cardDetail.cardId).areaItemBonus, 0);
690
+ const characterBonus = cardDetails.reduce((v, cardDetail) => v + getOrThrow(cardPower, cardDetail.cardId).characterBonus, 0);
691
+ const total = base + areaItemBonus + characterBonus + honorBonus;
692
+ const power = {
693
+ base,
694
+ areaItemBonus,
695
+ characterBonus,
696
+ honorBonus,
697
+ total
698
+ };
670
699
  const cards = cardDetails.map(cardDetail => {
671
- const scoreUp = cardDetail.units.reduce((vv, unit) => Math.max(vv, cardDetail.scoreSkill.get(unit, getOrThrow(map, unit), 1)), 0);
700
+ const skill = cardDetail.units.reduce((vv, unit) => {
701
+ const current = cardDetail.skill.get(unit, getOrThrow(map, unit), 1);
702
+ return current.scoreUp > vv.scoreUp ? current : vv;
703
+ }, cardDetail.skill.get(cardDetail.units[0], getOrThrow(map, cardDetail.units[0]), 1));
672
704
  return {
673
705
  cardId: cardDetail.cardId,
674
706
  level: cardDetail.level,
@@ -676,10 +708,7 @@ class DeckCalculator {
676
708
  masterRank: cardDetail.masterRank,
677
709
  power: getOrThrow(cardPower, cardDetail.cardId),
678
710
  eventBonus: cardDetail.eventBonus,
679
- skill: {
680
- scoreUp,
681
- lifeRecovery: cardDetail.lifeSkill
682
- }
711
+ skill
683
712
  };
684
713
  });
685
714
  const eventBonus = EventCalculator.getDeckBonus(cardDetails);
@@ -735,7 +764,7 @@ class AreaItemRecommend {
735
764
  ...currentAreaItemLevels.filter(it => it.areaItemId !== areaItem.id), newAreaItemLevel
736
765
  ];
737
766
  const { power: newPower } = await this.deckCalculator.getDeckDetail(userCards, 0, newAreaItemLevels);
738
- return await this.getRecommendAreaItem(areaItem, newAreaItemLevel, newPower - currentPower);
767
+ return await this.getRecommendAreaItem(areaItem, newAreaItemLevel, newPower.total - currentPower.total);
739
768
  }));
740
769
  return recommend.filter(it => it.power > 0)
741
770
  .sort((a, b) => b.power / b.cost.coin - a.power / a.cost.coin);
@@ -865,7 +894,7 @@ function compareDeck(deck1, deck2) {
865
894
  if (deck1.score !== deck2.score)
866
895
  return deck2.score - deck1.score;
867
896
  if (deck1.power !== deck2.power)
868
- return deck2.power - deck1.power;
897
+ return deck2.power.total - deck1.power.total;
869
898
  return deck1.deckCards[0].cardId - deck2.deckCards[0].cardId;
870
899
  }
871
900
  function removeSameDeck(it, i, arr) {
@@ -929,7 +958,7 @@ class BaseDeckRecommend {
929
958
  continue;
930
959
  if (!isChallengeLive && deckCharacters.includes(card.characterId))
931
960
  continue;
932
- if (deckCards.length >= 1 && deckCards[0].scoreSkill.isCertainlyLessThen(card.scoreSkill))
961
+ if (deckCards.length >= 1 && deckCards[0].skill.isCertainlyLessThen(card.skill))
933
962
  continue;
934
963
  if (deckCards.length >= 1 && card.attr !== deckCards[0].attr && !containsAny(deckCards[0].units, card.units)) {
935
964
  continue;
package/dist/index.d.ts CHANGED
@@ -131,15 +131,15 @@ interface UserChallengeLiveSoloDeck {
131
131
  support4: number | null;
132
132
  }
133
133
 
134
- declare class CardDetailMap {
134
+ declare class CardDetailMap<T> {
135
135
  min: number;
136
136
  max: number;
137
- values: Map<string, number>;
138
- set(unit: string, unitMember: number, attrMember: number, value: number): void;
139
- get(unit: string, unitMember: number, attrMember: number): number;
137
+ values: Map<string, T>;
138
+ set(unit: string, unitMember: number, attrMember: number, cmpValue: number, value: T): void;
139
+ get(unit: string, unitMember: number, attrMember: number): T;
140
140
  private getInternal;
141
141
  static getKey(unit: string, unitMember: number, attrMember: number): string;
142
- isCertainlyLessThen(another: CardDetailMap): boolean;
142
+ isCertainlyLessThen(another: CardDetailMap<T>): boolean;
143
143
  }
144
144
 
145
145
  declare class CardCalculator {
@@ -164,9 +164,8 @@ interface CardDetail {
164
164
  characterId: number;
165
165
  units: string[];
166
166
  attr: string;
167
- power: CardDetailMap;
168
- scoreSkill: CardDetailMap;
169
- lifeSkill: number;
167
+ power: CardDetailMap<DeckCardPowerDetail>;
168
+ skill: CardDetailMap<DeckCardSkillDetail>;
170
169
  eventBonus?: number;
171
170
  }
172
171
  interface CardConfig {
@@ -185,7 +184,7 @@ declare class DeckCalculator {
185
184
  getDeckDetail(deckCards: UserCard[], eventId?: number, areaItemLevels?: AreaItemLevel[]): Promise<DeckDetail>;
186
185
  }
187
186
  interface DeckDetail {
188
- power: number;
187
+ power: DeckPowerDetail;
189
188
  eventBonus?: number;
190
189
  cards: DeckCardDetail[];
191
190
  }
@@ -194,10 +193,23 @@ interface DeckCardDetail {
194
193
  level: number;
195
194
  skillLevel: number;
196
195
  masterRank: number;
197
- power: number;
196
+ power: DeckCardPowerDetail;
198
197
  eventBonus?: number;
199
198
  skill: DeckCardSkillDetail;
200
199
  }
200
+ interface DeckPowerDetail {
201
+ base: number;
202
+ areaItemBonus: number;
203
+ characterBonus: number;
204
+ honorBonus: number;
205
+ total: number;
206
+ }
207
+ interface DeckCardPowerDetail {
208
+ base: number;
209
+ areaItemBonus: number;
210
+ characterBonus: number;
211
+ total: number;
212
+ }
201
213
  interface DeckCardSkillDetail {
202
214
  scoreUp: number;
203
215
  lifeRecovery: number;
@@ -251,7 +263,7 @@ interface Card {
251
263
  declare class CardPowerCalculator {
252
264
  private readonly dataProvider;
253
265
  constructor(dataProvider: DataProvider);
254
- getCardPower(userCard: UserCard, card: Card, cardUnits: string[], userAreaItemLevels: AreaItemLevel[]): Promise<CardDetailMap>;
266
+ getCardPower(userCard: UserCard, card: Card, cardUnits: string[], userAreaItemLevels: AreaItemLevel[]): Promise<CardDetailMap<DeckCardPowerDetail>>;
255
267
  private getPower;
256
268
  private getCardBasePowers;
257
269
  private getAreaItemBonusPower;
@@ -261,10 +273,7 @@ declare class CardPowerCalculator {
261
273
  declare class CardSkillCalculator {
262
274
  private readonly dataProvider;
263
275
  constructor(dataProvider: DataProvider);
264
- getCardSkill(userCard: UserCard, card: Card): Promise<{
265
- scoreUp: CardDetailMap;
266
- lifeRecovery: number;
267
- }>;
276
+ getCardSkill(userCard: UserCard, card: Card): Promise<CardDetailMap<DeckCardSkillDetail>>;
268
277
  private getSkillDetail;
269
278
  }
270
279
 
@@ -363,7 +372,7 @@ declare class BaseDeckRecommend {
363
372
  type ScoreFunction = (musicMeta: MusicMeta, honorBonus: number, deckCards: CardDetail[]) => number;
364
373
  interface RecommendDeck {
365
374
  score: number;
366
- power: number;
375
+ power: DeckPowerDetail;
367
376
  eventBonus?: number;
368
377
  deckCards: DeckCardDetail[];
369
378
  }
@@ -702,4 +711,4 @@ interface UserHonor {
702
711
  level: number;
703
712
  }
704
713
 
705
- export { Area, AreaItem, AreaItemLevel, AreaItemRecommend, AreaItemService, BaseDeckRecommend, CachedDataProvider, Card, CardCalculator, CardConfig, CardDetail, CardEpisode, CardEventCalculator, CardPowerCalculator, CardRarity, CardSkillCalculator, ChallengeLiveDeckRecommend, CharacterRank, DataProvider, DeckCalculator, DeckCardDetail, DeckCardSkillDetail, DeckDetail, DeckRecommendConfig, DeckService, Event, EventCalculator, EventCard, EventDeckBonus, EventDeckRecommend, EventExchange, EventRarityBonusRate, GameCharacter, GameCharacterUnit, Honor, LiveCalculator, LiveDetail, LiveSkill, LiveType, MasterLesson, Music, MusicDifficulty, MusicMeta, MusicRecommend, MusicVocal, RecommendAreaItem, RecommendDeck, ScoreFunction, ShopItem, Skill, User, UserArea, UserCard, UserChallengeLiveSoloDeck, UserCharacter, UserDeck, UserHonor };
714
+ export { Area, AreaItem, AreaItemLevel, AreaItemRecommend, AreaItemService, BaseDeckRecommend, CachedDataProvider, Card, CardCalculator, CardConfig, CardDetail, CardEpisode, CardEventCalculator, CardPowerCalculator, CardRarity, CardSkillCalculator, ChallengeLiveDeckRecommend, CharacterRank, DataProvider, DeckCalculator, DeckCardDetail, DeckCardPowerDetail, DeckCardSkillDetail, DeckDetail, DeckPowerDetail, DeckRecommendConfig, DeckService, Event, EventCalculator, EventCard, EventDeckBonus, EventDeckRecommend, EventExchange, EventRarityBonusRate, GameCharacter, GameCharacterUnit, Honor, LiveCalculator, LiveDetail, LiveSkill, LiveType, MasterLesson, Music, MusicDifficulty, MusicMeta, MusicRecommend, MusicVocal, RecommendAreaItem, RecommendDeck, ScoreFunction, ShopItem, Skill, User, UserArea, UserCard, UserChallengeLiveSoloDeck, UserCharacter, UserDeck, UserHonor };
package/dist/index.mjs CHANGED
@@ -168,9 +168,9 @@ class CardDetailMap {
168
168
  min = Number.MAX_SAFE_INTEGER;
169
169
  max = Number.MIN_SAFE_INTEGER;
170
170
  values = new Map();
171
- set(unit, unitMember, attrMember, value) {
172
- this.min = Math.min(this.min, value);
173
- this.max = Math.max(this.max, value);
171
+ set(unit, unitMember, attrMember, cmpValue, value) {
172
+ this.min = Math.min(this.min, cmpValue);
173
+ this.max = Math.max(this.max, cmpValue);
174
174
  this.values.set(CardDetailMap.getKey(unit, unitMember, attrMember), value);
175
175
  }
176
176
  get(unit, unitMember, attrMember) {
@@ -207,15 +207,26 @@ class CardPowerCalculator {
207
207
  const basePower = await this.getCardBasePowers(userCard, card);
208
208
  const characterBonus = await this.getCharacterBonusPower(basePower, card.characterId);
209
209
  for (const unit of cardUnits) {
210
- ret.set(unit, 5, 5, await this.getPower(card, basePower, characterBonus, userAreaItemLevels, unit, true, true));
211
- ret.set(unit, 5, 1, await this.getPower(card, basePower, characterBonus, userAreaItemLevels, unit, true, false));
212
- ret.set(unit, 1, 5, await this.getPower(card, basePower, characterBonus, userAreaItemLevels, unit, false, true));
213
- ret.set(unit, 1, 1, await this.getPower(card, basePower, characterBonus, userAreaItemLevels, unit, false, false));
210
+ let power = await this.getPower(card, basePower, characterBonus, userAreaItemLevels, unit, true, true);
211
+ ret.set(unit, 5, 5, power.total, power);
212
+ power = await this.getPower(card, basePower, characterBonus, userAreaItemLevels, unit, true, false);
213
+ ret.set(unit, 5, 1, power.total, power);
214
+ power = await this.getPower(card, basePower, characterBonus, userAreaItemLevels, unit, false, true);
215
+ ret.set(unit, 1, 5, power.total, power);
216
+ power = await this.getPower(card, basePower, characterBonus, userAreaItemLevels, unit, false, false);
217
+ ret.set(unit, 1, 1, power.total, power);
214
218
  }
215
219
  return ret;
216
220
  }
217
221
  async getPower(card, basePower, characterBonus, userAreaItemLevels, unit, sameUnit, sameAttr) {
218
- return basePower.reduce((v, it) => v + it, 0) + characterBonus + await this.getAreaItemBonusPower(userAreaItemLevels, basePower, card.characterId, unit, sameUnit, card.attr, sameAttr);
222
+ const base = basePower.reduce((v, it) => v + it, 0);
223
+ const areaItemBonus = await this.getAreaItemBonusPower(userAreaItemLevels, basePower, card.characterId, unit, sameUnit, card.attr, sameAttr);
224
+ return {
225
+ base,
226
+ areaItemBonus,
227
+ characterBonus,
228
+ total: base + characterBonus + areaItemBonus
229
+ };
219
230
  }
220
231
  async getCardBasePowers(userCard, card) {
221
232
  const p = await Promise.all([
@@ -270,7 +281,7 @@ class CardPowerCalculator {
270
281
  Math.fround(allMatch ? areaItem.power3AllMatchBonusRate : areaItem.power3BonusRate));
271
282
  }
272
283
  return basePower
273
- .reduce((v, it, i) => v + Math.floor(Math.fround(it * areaItemBonus[i] / 100)), 0);
284
+ .reduce((v, it, i) => v + Math.floor(Math.fround(it * Math.fround(areaItemBonus[i] / 100))), 0);
274
285
  }
275
286
  async getCharacterBonusPower(basePower, characterId) {
276
287
  const characterRanks = await this.dataProvider.getMasterData('characterRanks');
@@ -294,16 +305,22 @@ class CardSkillCalculator {
294
305
  this.dataProvider = dataProvider;
295
306
  }
296
307
  async getCardSkill(userCard, card) {
297
- const scoreUpMap = new CardDetailMap();
308
+ const skillMap = new CardDetailMap();
298
309
  const detail = await this.getSkillDetail(userCard, card);
299
310
  if (detail.scoreUpEnhance !== undefined) {
300
311
  for (let i = 1; i <= 5; ++i) {
301
312
  const scoreUp = detail.scoreUp + (i === 5 ? 5 : (i - 1)) * detail.scoreUpEnhance.value;
302
- scoreUpMap.set(detail.scoreUpEnhance.unit, i, 1, scoreUp);
313
+ skillMap.set(detail.scoreUpEnhance.unit, i, 1, scoreUp, {
314
+ scoreUp,
315
+ lifeRecovery: detail.lifeRecovery
316
+ });
303
317
  }
304
318
  }
305
- scoreUpMap.set('any', 1, 1, detail.scoreUp);
306
- return { scoreUp: scoreUpMap, lifeRecovery: detail.lifeRecovery };
319
+ skillMap.set('any', 1, 1, detail.scoreUp, {
320
+ scoreUp: detail.scoreUp,
321
+ lifeRecovery: detail.lifeRecovery
322
+ });
323
+ return skillMap;
307
324
  }
308
325
  async getSkillDetail(userCard, card) {
309
326
  const skills = await this.dataProvider.getMasterData('skills');
@@ -437,8 +454,7 @@ class CardCalculator {
437
454
  units,
438
455
  attr: card.attr,
439
456
  power,
440
- scoreSkill: skill.scoreUp,
441
- lifeSkill: skill.lifeRecovery,
457
+ skill,
442
458
  eventBonus
443
459
  };
444
460
  }
@@ -450,7 +466,7 @@ class CardCalculator {
450
466
  }
451
467
  static isCertainlyLessThan(cardDetail0, cardDetail1) {
452
468
  return cardDetail0.power.isCertainlyLessThen(cardDetail1.power) &&
453
- cardDetail0.scoreSkill.isCertainlyLessThen(cardDetail1.scoreSkill) &&
469
+ cardDetail0.skill.isCertainlyLessThen(cardDetail1.skill) &&
454
470
  (cardDetail0.eventBonus === undefined || cardDetail1.eventBonus === undefined ||
455
471
  cardDetail0.eventBonus <= cardDetail1.eventBonus);
456
472
  }
@@ -532,10 +548,10 @@ class LiveCalculator {
532
548
  const rate = baseRate + skills.details
533
549
  .reduce((v, it, i) => v + it.scoreUp * skillRate[i] / 100, 0);
534
550
  const life = skills.details.reduce((v, it) => v + it.lifeRecovery, 0);
535
- const powerSum = multiPowerSum === 0 ? 5 * deckDetail.power : multiPowerSum;
551
+ const powerSum = multiPowerSum === 0 ? 5 * deckDetail.power.total : multiPowerSum;
536
552
  const activeBonus = liveType === LiveType.MULTI ? 5 * 0.015 * powerSum : 0;
537
553
  return {
538
- score: Math.floor(rate * deckDetail.power * 4 + activeBonus),
554
+ score: Math.floor(rate * deckDetail.power.total * 4 + activeBonus),
539
555
  time: musicMeta.music_time,
540
556
  life: Math.min(2000, life + 1000),
541
557
  tap: musicMeta.tap_count
@@ -662,11 +678,27 @@ class DeckCalculator {
662
678
  }
663
679
  const cardPower = new Map();
664
680
  cardDetails.forEach(cardDetail => {
665
- cardPower.set(cardDetail.cardId, cardDetail.units.reduce((vv, unit) => Math.max(vv, cardDetail.power.get(unit, getOrThrow(map, unit), getOrThrow(map, cardDetail.attr))), 0));
681
+ cardPower.set(cardDetail.cardId, cardDetail.units.reduce((vv, unit) => {
682
+ const current = cardDetail.power.get(unit, getOrThrow(map, unit), getOrThrow(map, cardDetail.attr));
683
+ return current.total > vv.total ? current : vv;
684
+ }, cardDetail.power.get(cardDetail.units[0], getOrThrow(map, cardDetail.units[0]), getOrThrow(map, cardDetail.attr))));
666
685
  });
667
- const power = cardDetails.reduce((v, cardDetail) => v + getOrThrow(cardPower, cardDetail.cardId), 0) + honorBonus;
686
+ const base = cardDetails.reduce((v, cardDetail) => v + getOrThrow(cardPower, cardDetail.cardId).base, 0);
687
+ const areaItemBonus = cardDetails.reduce((v, cardDetail) => v + getOrThrow(cardPower, cardDetail.cardId).areaItemBonus, 0);
688
+ const characterBonus = cardDetails.reduce((v, cardDetail) => v + getOrThrow(cardPower, cardDetail.cardId).characterBonus, 0);
689
+ const total = base + areaItemBonus + characterBonus + honorBonus;
690
+ const power = {
691
+ base,
692
+ areaItemBonus,
693
+ characterBonus,
694
+ honorBonus,
695
+ total
696
+ };
668
697
  const cards = cardDetails.map(cardDetail => {
669
- const scoreUp = cardDetail.units.reduce((vv, unit) => Math.max(vv, cardDetail.scoreSkill.get(unit, getOrThrow(map, unit), 1)), 0);
698
+ const skill = cardDetail.units.reduce((vv, unit) => {
699
+ const current = cardDetail.skill.get(unit, getOrThrow(map, unit), 1);
700
+ return current.scoreUp > vv.scoreUp ? current : vv;
701
+ }, cardDetail.skill.get(cardDetail.units[0], getOrThrow(map, cardDetail.units[0]), 1));
670
702
  return {
671
703
  cardId: cardDetail.cardId,
672
704
  level: cardDetail.level,
@@ -674,10 +706,7 @@ class DeckCalculator {
674
706
  masterRank: cardDetail.masterRank,
675
707
  power: getOrThrow(cardPower, cardDetail.cardId),
676
708
  eventBonus: cardDetail.eventBonus,
677
- skill: {
678
- scoreUp,
679
- lifeRecovery: cardDetail.lifeSkill
680
- }
709
+ skill
681
710
  };
682
711
  });
683
712
  const eventBonus = EventCalculator.getDeckBonus(cardDetails);
@@ -733,7 +762,7 @@ class AreaItemRecommend {
733
762
  ...currentAreaItemLevels.filter(it => it.areaItemId !== areaItem.id), newAreaItemLevel
734
763
  ];
735
764
  const { power: newPower } = await this.deckCalculator.getDeckDetail(userCards, 0, newAreaItemLevels);
736
- return await this.getRecommendAreaItem(areaItem, newAreaItemLevel, newPower - currentPower);
765
+ return await this.getRecommendAreaItem(areaItem, newAreaItemLevel, newPower.total - currentPower.total);
737
766
  }));
738
767
  return recommend.filter(it => it.power > 0)
739
768
  .sort((a, b) => b.power / b.cost.coin - a.power / a.cost.coin);
@@ -863,7 +892,7 @@ function compareDeck(deck1, deck2) {
863
892
  if (deck1.score !== deck2.score)
864
893
  return deck2.score - deck1.score;
865
894
  if (deck1.power !== deck2.power)
866
- return deck2.power - deck1.power;
895
+ return deck2.power.total - deck1.power.total;
867
896
  return deck1.deckCards[0].cardId - deck2.deckCards[0].cardId;
868
897
  }
869
898
  function removeSameDeck(it, i, arr) {
@@ -927,7 +956,7 @@ class BaseDeckRecommend {
927
956
  continue;
928
957
  if (!isChallengeLive && deckCharacters.includes(card.characterId))
929
958
  continue;
930
- if (deckCards.length >= 1 && deckCards[0].scoreSkill.isCertainlyLessThen(card.scoreSkill))
959
+ if (deckCards.length >= 1 && deckCards[0].skill.isCertainlyLessThen(card.skill))
931
960
  continue;
932
961
  if (deckCards.length >= 1 && card.attr !== deckCards[0].attr && !containsAny(deckCards[0].units, card.units)) {
933
962
  continue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sekai-calculator",
3
- "version": "0.8.4",
3
+ "version": "0.9.0",
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",