sekai-calculator 0.1.1 → 0.1.2

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
@@ -27,35 +27,60 @@ function duplicateObj(obj, times) {
27
27
  ret.push(obj);
28
28
  return ret;
29
29
  }
30
- function mapOrUndefined(arr, fun) {
31
- if (arr === undefined)
32
- return undefined;
33
- return arr.map(fun);
34
- }
35
30
 
36
31
  class DeckService {
37
32
  dataProvider;
38
33
  constructor(dataProvider) {
39
34
  this.dataProvider = dataProvider;
40
35
  }
36
+ async getUserCard(cardId) {
37
+ const userCards = await this.dataProvider.getUserData('userCards');
38
+ return findOrThrow(userCards, it => it.cardId === cardId);
39
+ }
41
40
  async getDeck(deckId) {
42
41
  const userDecks = await this.dataProvider.getUserData('userDecks');
43
42
  return findOrThrow(userDecks, it => it.deckId === deckId);
44
43
  }
45
44
  async getDeckCards(userDeck) {
46
- const userCards = await this.dataProvider.getUserData('userCards');
47
45
  const cardIds = [userDeck.member1, userDeck.member2, userDeck.member3, userDeck.member4, userDeck.member5];
48
- return cardIds.map(id => findOrThrow(userCards, it => it.cardId === id));
46
+ return await Promise.all(cardIds.map(async (id) => await this.getUserCard(id)));
47
+ }
48
+ static toUserDeck(userCards, deckId = 1, name = 'ユニット01') {
49
+ if (userCards.length !== 5)
50
+ throw new Error('deck card should be 5');
51
+ return {
52
+ userId: userCards[0].userId,
53
+ deckId,
54
+ name,
55
+ leader: userCards[0].cardId,
56
+ subLeader: userCards[1].cardId,
57
+ member1: userCards[0].cardId,
58
+ member2: userCards[1].cardId,
59
+ member3: userCards[2].cardId,
60
+ member4: userCards[3].cardId,
61
+ member5: userCards[4].cardId
62
+ };
49
63
  }
50
64
  async getChallengeLiveSoloDeck(characterId) {
51
65
  const userChallengeLiveSoloDecks = await this.dataProvider.getUserData('userChallengeLiveSoloDecks');
52
66
  return findOrThrow(userChallengeLiveSoloDecks, it => it.characterId === characterId);
53
67
  }
54
68
  async getChallengeLiveSoloDeckCards(deck) {
55
- const userCards = await this.dataProvider.getUserData('userCards');
56
69
  const cardIds = [deck.leader, deck.support1, deck.support2, deck.support3, deck.support4];
57
- return cardIds.filter(it => it !== undefined && it !== null)
58
- .map(id => findOrThrow(userCards, it => it.cardId === id));
70
+ return await Promise.all(cardIds.filter(it => it !== undefined && it !== null)
71
+ .map(async (id) => await this.getUserCard(id === null ? 0 : id)));
72
+ }
73
+ static toUserChallengeLiveSoloDeck(userCards, characterId) {
74
+ if (userCards.length !== 5)
75
+ throw new Error('deck card should be 5');
76
+ return {
77
+ characterId,
78
+ leader: userCards[0].cardId,
79
+ support1: userCards[1].cardId,
80
+ support2: userCards[2].cardId,
81
+ support3: userCards[3].cardId,
82
+ support4: userCards[4].cardId
83
+ };
59
84
  }
60
85
  }
61
86
 
@@ -333,7 +358,31 @@ class EventCalculator {
333
358
  async getDeckEventBonus(deckCards, eventId) {
334
359
  return await deckCards.reduce(async (v, it) => await v + await this.cardEventCalculator.getCardEventBonus(it, eventId), Promise.resolve(0));
335
360
  }
361
+ static getEventPoint(type, selfScore, musicRate = 100, deckBonus = 0, boostRate = 1, otherScore = 0, life = 1000) {
362
+ const musicRate0 = musicRate / 100;
363
+ const deckRate = deckBonus / 100 + 1;
364
+ switch (type) {
365
+ case exports.EventLiveType.SOLO:
366
+ return Math.floor((100 + Math.floor(selfScore / 20000)) * musicRate0 * deckRate) * boostRate;
367
+ case exports.EventLiveType.CHALLENGE:
368
+ return (100 + Math.floor(selfScore / 20000)) * 120;
369
+ case exports.EventLiveType.MULTI:
370
+ return Math.floor((110 + Math.floor(selfScore / 17000) +
371
+ Math.floor(Math.min(otherScore, 5200000) / 400000)) * musicRate0 * deckRate) * boostRate;
372
+ case exports.EventLiveType.CHEERFUL:
373
+ return Math.floor((114 + Math.floor(selfScore / 12500) +
374
+ Math.floor(Math.min(otherScore, 4400000) / 400000) + Math.floor(Math.min(life, 1000) / 25)) *
375
+ musicRate0 * deckRate) * boostRate;
376
+ }
377
+ }
336
378
  }
379
+ exports.EventLiveType = void 0;
380
+ (function (EventLiveType) {
381
+ EventLiveType["SOLO"] = "solo";
382
+ EventLiveType["CHALLENGE"] = "challenge";
383
+ EventLiveType["MULTI"] = "multi";
384
+ EventLiveType["CHEERFUL"] = "cheerful";
385
+ })(exports.EventLiveType || (exports.EventLiveType = {}));
337
386
 
338
387
  class LiveCalculator {
339
388
  dataProvider;
@@ -382,18 +431,38 @@ class LiveCalculator {
382
431
  tap: musicMeta.tap_count
383
432
  };
384
433
  }
385
- getMultiLiveSkill(deckDetail) {
434
+ static getMultiLiveSkill(deckDetail) {
386
435
  const scoreUp = deckDetail.skill.reduce((v, it, i) => v + (i === 0 ? it.scoreUp : (it.scoreUp / 5)), 0);
387
436
  const lifeRecovery = deckDetail.skill[0].lifeRecovery;
388
- return { scoreUp, lifeRecovery };
437
+ return {
438
+ scoreUp,
439
+ lifeRecovery
440
+ };
441
+ }
442
+ static getSoloLiveSkill(liveSkills, skillDetails) {
443
+ if (liveSkills === undefined)
444
+ return undefined;
445
+ const skills = liveSkills.map(liveSkill => findOrThrow(skillDetails, it => it.cardId === liveSkill.cardId));
446
+ const ret = [];
447
+ for (let i = 0; i < 6; ++i) {
448
+ ret.push({
449
+ scoreUp: 0,
450
+ lifeRecovery: 0
451
+ });
452
+ }
453
+ for (let i = 0; i < skills.length - 1; ++i) {
454
+ ret[i] = skills[i];
455
+ }
456
+ ret[5] = skills[skills.length - 1];
457
+ return ret;
389
458
  }
390
459
  async getLiveDetail(deckCards, musicId, musicDiff, liveType, liveSkills = undefined) {
391
460
  const musicMetas = await this.dataProvider.getMusicMeta();
392
461
  const musicMeta = findOrThrow(musicMetas, it => it.music_id === musicId && it.difficulty === musicDiff);
393
462
  const deckDetail = await this.deckCalculator.getDeckDetail(deckCards);
394
463
  const skills = liveType === exports.LiveType.MULTI
395
- ? duplicateObj(this.getMultiLiveSkill(deckDetail), 6)
396
- : (mapOrUndefined(liveSkills, liveSkill => findOrThrow(deckDetail.skill, it => it.cardId === liveSkill.cardId)));
464
+ ? duplicateObj(LiveCalculator.getMultiLiveSkill(deckDetail), 6)
465
+ : LiveCalculator.getSoloLiveSkill(liveSkills, deckDetail.skill);
397
466
  return await this.getLiveDetailByDeck(deckDetail, musicMeta, liveType, skills);
398
467
  }
399
468
  }
package/dist/index.d.ts CHANGED
@@ -5,7 +5,11 @@ interface DataProvider {
5
5
  }
6
6
 
7
7
  interface UserDeck {
8
+ userId: number;
8
9
  deckId: number;
10
+ name: string;
11
+ leader: number;
12
+ subLeader: number;
9
13
  member1: number;
10
14
  member2: number;
11
15
  member3: number;
@@ -14,14 +18,24 @@ interface UserDeck {
14
18
  }
15
19
 
16
20
  interface UserCard {
21
+ userId: number;
17
22
  cardId: number;
18
23
  level: number;
24
+ exp?: number;
25
+ totalExp: number;
19
26
  skillLevel: number;
27
+ skillExp: number;
28
+ totalSkillExp: number;
20
29
  masterRank: number;
21
- specialTrainingStatus?: string;
30
+ specialTrainingStatus: string;
31
+ defaultImage: string;
32
+ duplicateCount: number;
33
+ createdAt: number;
22
34
  episodes: Array<{
23
35
  cardEpisodeId: number;
24
36
  scenarioStatus: string;
37
+ scenarioStatusReasons: string[];
38
+ isNotSkipped: boolean;
25
39
  }>;
26
40
  }
27
41
 
@@ -37,10 +51,13 @@ interface UserChallengeLiveSoloDeck {
37
51
  declare class DeckService {
38
52
  private readonly dataProvider;
39
53
  constructor(dataProvider: DataProvider);
54
+ getUserCard(cardId: number): Promise<UserCard>;
40
55
  getDeck(deckId: number): Promise<UserDeck>;
41
56
  getDeckCards(userDeck: UserDeck): Promise<UserCard[]>;
57
+ static toUserDeck(userCards: UserCard[], deckId?: number, name?: string): UserDeck;
42
58
  getChallengeLiveSoloDeck(characterId: number): Promise<UserChallengeLiveSoloDeck>;
43
59
  getChallengeLiveSoloDeckCards(deck: UserChallengeLiveSoloDeck): Promise<UserCard[]>;
60
+ static toUserChallengeLiveSoloDeck(userCards: UserCard[], characterId: number): UserChallengeLiveSoloDeck;
44
61
  }
45
62
 
46
63
  interface AreaItemLevel {
@@ -176,6 +193,13 @@ declare class EventCalculator {
176
193
  private readonly cardEventCalculator;
177
194
  constructor(dataProvider: DataProvider);
178
195
  getDeckEventBonus(deckCards: UserCard[], eventId: number): Promise<number>;
196
+ static getEventPoint(type: EventLiveType, selfScore: number, musicRate?: number, deckBonus?: number, boostRate?: number, otherScore?: number, life?: number): number;
197
+ }
198
+ declare enum EventLiveType {
199
+ SOLO = "solo",
200
+ CHALLENGE = "challenge",
201
+ MULTI = "multi",
202
+ CHEERFUL = "cheerful"
179
203
  }
180
204
 
181
205
  interface MusicMeta {
@@ -200,7 +224,8 @@ declare class LiveCalculator {
200
224
  private getBaseScore;
201
225
  private getSkillScore;
202
226
  getLiveDetailByDeck(deckDetail: DeckDetail, musicMeta: MusicMeta, liveType: LiveType, skillDetails?: SkillDetail[] | undefined, multiPowerSum?: number): Promise<LiveDetail>;
203
- private getMultiLiveSkill;
227
+ private static getMultiLiveSkill;
228
+ private static getSoloLiveSkill;
204
229
  getLiveDetail(deckCards: UserCard[], musicId: number, musicDiff: string, liveType: LiveType, liveSkills?: LiveSkill[] | undefined): Promise<LiveDetail>;
205
230
  }
206
231
  interface LiveDetail {
@@ -219,4 +244,4 @@ declare enum LiveType {
219
244
  AUTO = "auto"
220
245
  }
221
246
 
222
- export { CardCalculator, CardDetail, CardDetailMap, CardEventCalculator, CardPowerCalculator, CardSkillCalculator, DataProvider, DeckCalculator, DeckDetail, DeckService, EventCalculator, LiveCalculator, LiveDetail, LiveSkill, LiveType, SkillDetail };
247
+ export { CardCalculator, CardDetail, CardDetailMap, CardEventCalculator, CardPowerCalculator, CardSkillCalculator, DataProvider, DeckCalculator, DeckDetail, DeckService, EventCalculator, EventLiveType, LiveCalculator, LiveDetail, LiveSkill, LiveType, SkillDetail };
package/dist/index.mjs CHANGED
@@ -25,35 +25,60 @@ function duplicateObj(obj, times) {
25
25
  ret.push(obj);
26
26
  return ret;
27
27
  }
28
- function mapOrUndefined(arr, fun) {
29
- if (arr === undefined)
30
- return undefined;
31
- return arr.map(fun);
32
- }
33
28
 
34
29
  class DeckService {
35
30
  dataProvider;
36
31
  constructor(dataProvider) {
37
32
  this.dataProvider = dataProvider;
38
33
  }
34
+ async getUserCard(cardId) {
35
+ const userCards = await this.dataProvider.getUserData('userCards');
36
+ return findOrThrow(userCards, it => it.cardId === cardId);
37
+ }
39
38
  async getDeck(deckId) {
40
39
  const userDecks = await this.dataProvider.getUserData('userDecks');
41
40
  return findOrThrow(userDecks, it => it.deckId === deckId);
42
41
  }
43
42
  async getDeckCards(userDeck) {
44
- const userCards = await this.dataProvider.getUserData('userCards');
45
43
  const cardIds = [userDeck.member1, userDeck.member2, userDeck.member3, userDeck.member4, userDeck.member5];
46
- return cardIds.map(id => findOrThrow(userCards, it => it.cardId === id));
44
+ return await Promise.all(cardIds.map(async (id) => await this.getUserCard(id)));
45
+ }
46
+ static toUserDeck(userCards, deckId = 1, name = 'ユニット01') {
47
+ if (userCards.length !== 5)
48
+ throw new Error('deck card should be 5');
49
+ return {
50
+ userId: userCards[0].userId,
51
+ deckId,
52
+ name,
53
+ leader: userCards[0].cardId,
54
+ subLeader: userCards[1].cardId,
55
+ member1: userCards[0].cardId,
56
+ member2: userCards[1].cardId,
57
+ member3: userCards[2].cardId,
58
+ member4: userCards[3].cardId,
59
+ member5: userCards[4].cardId
60
+ };
47
61
  }
48
62
  async getChallengeLiveSoloDeck(characterId) {
49
63
  const userChallengeLiveSoloDecks = await this.dataProvider.getUserData('userChallengeLiveSoloDecks');
50
64
  return findOrThrow(userChallengeLiveSoloDecks, it => it.characterId === characterId);
51
65
  }
52
66
  async getChallengeLiveSoloDeckCards(deck) {
53
- const userCards = await this.dataProvider.getUserData('userCards');
54
67
  const cardIds = [deck.leader, deck.support1, deck.support2, deck.support3, deck.support4];
55
- return cardIds.filter(it => it !== undefined && it !== null)
56
- .map(id => findOrThrow(userCards, it => it.cardId === id));
68
+ return await Promise.all(cardIds.filter(it => it !== undefined && it !== null)
69
+ .map(async (id) => await this.getUserCard(id === null ? 0 : id)));
70
+ }
71
+ static toUserChallengeLiveSoloDeck(userCards, characterId) {
72
+ if (userCards.length !== 5)
73
+ throw new Error('deck card should be 5');
74
+ return {
75
+ characterId,
76
+ leader: userCards[0].cardId,
77
+ support1: userCards[1].cardId,
78
+ support2: userCards[2].cardId,
79
+ support3: userCards[3].cardId,
80
+ support4: userCards[4].cardId
81
+ };
57
82
  }
58
83
  }
59
84
 
@@ -331,7 +356,31 @@ class EventCalculator {
331
356
  async getDeckEventBonus(deckCards, eventId) {
332
357
  return await deckCards.reduce(async (v, it) => await v + await this.cardEventCalculator.getCardEventBonus(it, eventId), Promise.resolve(0));
333
358
  }
359
+ static getEventPoint(type, selfScore, musicRate = 100, deckBonus = 0, boostRate = 1, otherScore = 0, life = 1000) {
360
+ const musicRate0 = musicRate / 100;
361
+ const deckRate = deckBonus / 100 + 1;
362
+ switch (type) {
363
+ case EventLiveType.SOLO:
364
+ return Math.floor((100 + Math.floor(selfScore / 20000)) * musicRate0 * deckRate) * boostRate;
365
+ case EventLiveType.CHALLENGE:
366
+ return (100 + Math.floor(selfScore / 20000)) * 120;
367
+ case EventLiveType.MULTI:
368
+ return Math.floor((110 + Math.floor(selfScore / 17000) +
369
+ Math.floor(Math.min(otherScore, 5200000) / 400000)) * musicRate0 * deckRate) * boostRate;
370
+ case EventLiveType.CHEERFUL:
371
+ return Math.floor((114 + Math.floor(selfScore / 12500) +
372
+ Math.floor(Math.min(otherScore, 4400000) / 400000) + Math.floor(Math.min(life, 1000) / 25)) *
373
+ musicRate0 * deckRate) * boostRate;
374
+ }
375
+ }
334
376
  }
377
+ var EventLiveType;
378
+ (function (EventLiveType) {
379
+ EventLiveType["SOLO"] = "solo";
380
+ EventLiveType["CHALLENGE"] = "challenge";
381
+ EventLiveType["MULTI"] = "multi";
382
+ EventLiveType["CHEERFUL"] = "cheerful";
383
+ })(EventLiveType || (EventLiveType = {}));
335
384
 
336
385
  class LiveCalculator {
337
386
  dataProvider;
@@ -380,18 +429,38 @@ class LiveCalculator {
380
429
  tap: musicMeta.tap_count
381
430
  };
382
431
  }
383
- getMultiLiveSkill(deckDetail) {
432
+ static getMultiLiveSkill(deckDetail) {
384
433
  const scoreUp = deckDetail.skill.reduce((v, it, i) => v + (i === 0 ? it.scoreUp : (it.scoreUp / 5)), 0);
385
434
  const lifeRecovery = deckDetail.skill[0].lifeRecovery;
386
- return { scoreUp, lifeRecovery };
435
+ return {
436
+ scoreUp,
437
+ lifeRecovery
438
+ };
439
+ }
440
+ static getSoloLiveSkill(liveSkills, skillDetails) {
441
+ if (liveSkills === undefined)
442
+ return undefined;
443
+ const skills = liveSkills.map(liveSkill => findOrThrow(skillDetails, it => it.cardId === liveSkill.cardId));
444
+ const ret = [];
445
+ for (let i = 0; i < 6; ++i) {
446
+ ret.push({
447
+ scoreUp: 0,
448
+ lifeRecovery: 0
449
+ });
450
+ }
451
+ for (let i = 0; i < skills.length - 1; ++i) {
452
+ ret[i] = skills[i];
453
+ }
454
+ ret[5] = skills[skills.length - 1];
455
+ return ret;
387
456
  }
388
457
  async getLiveDetail(deckCards, musicId, musicDiff, liveType, liveSkills = undefined) {
389
458
  const musicMetas = await this.dataProvider.getMusicMeta();
390
459
  const musicMeta = findOrThrow(musicMetas, it => it.music_id === musicId && it.difficulty === musicDiff);
391
460
  const deckDetail = await this.deckCalculator.getDeckDetail(deckCards);
392
461
  const skills = liveType === LiveType.MULTI
393
- ? duplicateObj(this.getMultiLiveSkill(deckDetail), 6)
394
- : (mapOrUndefined(liveSkills, liveSkill => findOrThrow(deckDetail.skill, it => it.cardId === liveSkill.cardId)));
462
+ ? duplicateObj(LiveCalculator.getMultiLiveSkill(deckDetail), 6)
463
+ : LiveCalculator.getSoloLiveSkill(liveSkills, deckDetail.skill);
395
464
  return await this.getLiveDetailByDeck(deckDetail, musicMeta, liveType, skills);
396
465
  }
397
466
  }
@@ -402,4 +471,4 @@ var LiveType;
402
471
  LiveType["AUTO"] = "auto";
403
472
  })(LiveType || (LiveType = {}));
404
473
 
405
- export { CardCalculator, CardDetailMap, CardEventCalculator, CardPowerCalculator, CardSkillCalculator, DeckCalculator, DeckService, EventCalculator, LiveCalculator, LiveType };
474
+ export { CardCalculator, CardDetailMap, CardEventCalculator, CardPowerCalculator, CardSkillCalculator, DeckCalculator, DeckService, EventCalculator, EventLiveType, LiveCalculator, LiveType };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sekai-calculator",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
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",