volleyballsimtypes 0.0.491 → 0.0.493

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.
Files changed (135) hide show
  1. package/dist/cjs/src/api/index.d.ts +2 -1
  2. package/dist/cjs/src/api/index.js +15 -0
  3. package/dist/cjs/src/api/tactics-player-refs.d.ts +13 -0
  4. package/dist/cjs/src/api/tactics-player-refs.js +43 -0
  5. package/dist/cjs/src/data/event-purge.d.ts +14 -0
  6. package/dist/cjs/src/data/event-purge.js +116 -0
  7. package/dist/cjs/src/data/index.d.ts +1 -0
  8. package/dist/cjs/src/data/index.js +1 -0
  9. package/dist/cjs/src/data/init-models.js +41 -0
  10. package/dist/cjs/src/data/models/competition.d.ts +1 -1
  11. package/dist/cjs/src/data/models/competition.js +1 -1
  12. package/dist/cjs/src/data/models/event-bot-team.d.ts +21 -0
  13. package/dist/cjs/src/data/models/event-bot-team.js +44 -0
  14. package/dist/cjs/src/data/models/event-competition.d.ts +29 -0
  15. package/dist/cjs/src/data/models/event-competition.js +52 -0
  16. package/dist/cjs/src/data/models/event-pack-player.d.ts +22 -0
  17. package/dist/cjs/src/data/models/event-pack-player.js +31 -0
  18. package/dist/cjs/src/data/models/event-pack.d.ts +37 -0
  19. package/dist/cjs/src/data/models/event-pack.js +55 -0
  20. package/dist/cjs/src/data/models/event-result.d.ts +34 -0
  21. package/dist/cjs/src/data/models/event-result.js +48 -0
  22. package/dist/cjs/src/data/models/event-squad.d.ts +30 -0
  23. package/dist/cjs/src/data/models/event-squad.js +46 -0
  24. package/dist/cjs/src/data/models/event.d.ts +51 -0
  25. package/dist/cjs/src/data/models/event.js +82 -0
  26. package/dist/cjs/src/data/models/index.d.ts +7 -0
  27. package/dist/cjs/src/data/models/index.js +7 -0
  28. package/dist/cjs/src/data/models/lineup-preset.d.ts +3 -1
  29. package/dist/cjs/src/data/models/lineup-preset.js +53 -0
  30. package/dist/cjs/src/index.d.ts +1 -0
  31. package/dist/cjs/src/index.js +6 -0
  32. package/dist/cjs/src/service/competition/event-draft.d.ts +40 -0
  33. package/dist/cjs/src/service/competition/event-draft.js +68 -0
  34. package/dist/cjs/src/service/competition/event-draft.test.d.ts +1 -0
  35. package/dist/cjs/src/service/competition/event-draft.test.js +118 -0
  36. package/dist/cjs/src/service/competition/event-rewards.d.ts +26 -0
  37. package/dist/cjs/src/service/competition/event-rewards.js +49 -0
  38. package/dist/cjs/src/service/competition/event-rewards.test.d.ts +1 -0
  39. package/dist/cjs/src/service/competition/event-rewards.test.js +58 -0
  40. package/dist/cjs/src/service/competition/event-schedule.d.ts +126 -0
  41. package/dist/cjs/src/service/competition/event-schedule.js +141 -0
  42. package/dist/cjs/src/service/competition/event-schedule.test.d.ts +1 -0
  43. package/dist/cjs/src/service/competition/event-schedule.test.js +138 -0
  44. package/dist/cjs/src/service/competition/index.d.ts +3 -0
  45. package/dist/cjs/src/service/competition/index.js +3 -0
  46. package/dist/cjs/src/service/match/index.d.ts +1 -0
  47. package/dist/cjs/src/service/match/index.js +1 -0
  48. package/dist/cjs/src/service/match/match-generator.js +25 -48
  49. package/dist/cjs/src/service/match/match-generator.test.d.ts +1 -0
  50. package/dist/cjs/src/service/match/match-generator.test.js +48 -0
  51. package/dist/cjs/src/service/match/round-robin.d.ts +11 -0
  52. package/dist/cjs/src/service/match/round-robin.js +44 -0
  53. package/dist/cjs/src/service/match/round-robin.test.d.ts +1 -0
  54. package/dist/cjs/src/service/match/round-robin.test.js +71 -0
  55. package/dist/cjs/src/service/notification/catalog/en.json +21 -0
  56. package/dist/cjs/src/service/notification/catalog/es.json +21 -0
  57. package/dist/cjs/src/service/notification/catalog/fr.json +21 -0
  58. package/dist/cjs/src/service/notification/catalog/it.json +21 -0
  59. package/dist/cjs/src/service/notification/catalog/pl.json +21 -0
  60. package/dist/cjs/src/service/notification/catalog/pt-BR.json +21 -0
  61. package/dist/cjs/src/service/notification/catalog/tr.json +21 -0
  62. package/dist/cjs/src/service/notification/notification-type.d.ts +1 -1
  63. package/dist/cjs/src/service/notification/notification-type.js +6 -1
  64. package/dist/cjs/src/service/notification/notification.test.js +3 -1
  65. package/dist/cjs/src/service/notification/registry.js +52 -0
  66. package/dist/cjs/src/service/player/player-generator.d.ts +2 -1
  67. package/dist/cjs/src/service/player/player-generator.js +37 -5
  68. package/dist/esm/src/api/index.d.ts +2 -1
  69. package/dist/esm/src/api/index.js +1 -0
  70. package/dist/esm/src/api/tactics-player-refs.d.ts +13 -0
  71. package/dist/esm/src/api/tactics-player-refs.js +40 -0
  72. package/dist/esm/src/data/event-purge.d.ts +14 -0
  73. package/dist/esm/src/data/event-purge.js +110 -0
  74. package/dist/esm/src/data/index.d.ts +1 -0
  75. package/dist/esm/src/data/index.js +1 -0
  76. package/dist/esm/src/data/init-models.js +42 -1
  77. package/dist/esm/src/data/models/competition.d.ts +1 -1
  78. package/dist/esm/src/data/models/competition.js +1 -1
  79. package/dist/esm/src/data/models/event-bot-team.d.ts +21 -0
  80. package/dist/esm/src/data/models/event-bot-team.js +40 -0
  81. package/dist/esm/src/data/models/event-competition.d.ts +29 -0
  82. package/dist/esm/src/data/models/event-competition.js +48 -0
  83. package/dist/esm/src/data/models/event-pack-player.d.ts +22 -0
  84. package/dist/esm/src/data/models/event-pack-player.js +27 -0
  85. package/dist/esm/src/data/models/event-pack.d.ts +37 -0
  86. package/dist/esm/src/data/models/event-pack.js +51 -0
  87. package/dist/esm/src/data/models/event-result.d.ts +34 -0
  88. package/dist/esm/src/data/models/event-result.js +44 -0
  89. package/dist/esm/src/data/models/event-squad.d.ts +30 -0
  90. package/dist/esm/src/data/models/event-squad.js +42 -0
  91. package/dist/esm/src/data/models/event.d.ts +51 -0
  92. package/dist/esm/src/data/models/event.js +78 -0
  93. package/dist/esm/src/data/models/index.d.ts +7 -0
  94. package/dist/esm/src/data/models/index.js +7 -0
  95. package/dist/esm/src/data/models/lineup-preset.d.ts +3 -1
  96. package/dist/esm/src/data/models/lineup-preset.js +20 -0
  97. package/dist/esm/src/index.d.ts +1 -0
  98. package/dist/esm/src/index.js +4 -0
  99. package/dist/esm/src/service/competition/event-draft.d.ts +40 -0
  100. package/dist/esm/src/service/competition/event-draft.js +62 -0
  101. package/dist/esm/src/service/competition/event-draft.test.d.ts +1 -0
  102. package/dist/esm/src/service/competition/event-draft.test.js +116 -0
  103. package/dist/esm/src/service/competition/event-rewards.d.ts +26 -0
  104. package/dist/esm/src/service/competition/event-rewards.js +44 -0
  105. package/dist/esm/src/service/competition/event-rewards.test.d.ts +1 -0
  106. package/dist/esm/src/service/competition/event-rewards.test.js +56 -0
  107. package/dist/esm/src/service/competition/event-schedule.d.ts +126 -0
  108. package/dist/esm/src/service/competition/event-schedule.js +129 -0
  109. package/dist/esm/src/service/competition/event-schedule.test.d.ts +1 -0
  110. package/dist/esm/src/service/competition/event-schedule.test.js +136 -0
  111. package/dist/esm/src/service/competition/index.d.ts +3 -0
  112. package/dist/esm/src/service/competition/index.js +3 -0
  113. package/dist/esm/src/service/match/index.d.ts +1 -0
  114. package/dist/esm/src/service/match/index.js +1 -0
  115. package/dist/esm/src/service/match/match-generator.js +25 -48
  116. package/dist/esm/src/service/match/match-generator.test.d.ts +1 -0
  117. package/dist/esm/src/service/match/match-generator.test.js +43 -0
  118. package/dist/esm/src/service/match/round-robin.d.ts +11 -0
  119. package/dist/esm/src/service/match/round-robin.js +41 -0
  120. package/dist/esm/src/service/match/round-robin.test.d.ts +1 -0
  121. package/dist/esm/src/service/match/round-robin.test.js +69 -0
  122. package/dist/esm/src/service/notification/catalog/en.json +21 -0
  123. package/dist/esm/src/service/notification/catalog/es.json +21 -0
  124. package/dist/esm/src/service/notification/catalog/fr.json +21 -0
  125. package/dist/esm/src/service/notification/catalog/it.json +21 -0
  126. package/dist/esm/src/service/notification/catalog/pl.json +21 -0
  127. package/dist/esm/src/service/notification/catalog/pt-BR.json +21 -0
  128. package/dist/esm/src/service/notification/catalog/tr.json +21 -0
  129. package/dist/esm/src/service/notification/notification-type.d.ts +1 -1
  130. package/dist/esm/src/service/notification/notification-type.js +6 -1
  131. package/dist/esm/src/service/notification/notification.test.js +3 -1
  132. package/dist/esm/src/service/notification/registry.js +52 -0
  133. package/dist/esm/src/service/player/player-generator.d.ts +2 -1
  134. package/dist/esm/src/service/player/player-generator.js +36 -4
  135. package/package.json +6 -1
@@ -11,7 +11,12 @@ export const NOTIFICATION_TYPES = [
11
11
  'PROMOTION',
12
12
  'DAILY_LOGIN',
13
13
  'WELCOME',
14
- 'COMPENSATION'
14
+ 'COMPENSATION',
15
+ 'EVENT_REGISTRATION_OPEN',
16
+ 'EVENT_REGISTRATION_CLOSING',
17
+ 'EVENT_STARTED',
18
+ 'EVENT_FINAL_ROUND',
19
+ 'EVENT_FINISHED'
15
20
  ];
16
21
  // The 7 supported locales. Must stay in sync with the API VALID_LOCALES set and the UI src/locales/*.json.
17
22
  export const NOTIFICATION_LOCALES = ['en', 'es', 'fr', 'it', 'pl', 'pt-BR', 'tr'];
@@ -130,7 +130,9 @@ describe('push preferences (PUSH_NOTIFICATION_TYPES + pushEnabledFor)', () => {
130
130
  .toEqual(NOTIFICATION_TYPES.filter((t) => NOTIFICATION_REGISTRY[t].emitsPush).sort((a, b) => a.localeCompare(b)));
131
131
  expect(PUSH_NOTIFICATION_TYPES).not.toContain('COMPENSATION');
132
132
  expect(PUSH_NOTIFICATION_TYPES).toContain('MATCH_RESULT');
133
- expect(PUSH_NOTIFICATION_TYPES).toHaveLength(8);
133
+ // COMPENSATION is the ONLY in-app-only type, so every other type pushes. Expressed as a relationship
134
+ // rather than a count, so adding a type does not need this number edited.
135
+ expect(PUSH_NOTIFICATION_TYPES).toHaveLength(NOTIFICATION_TYPES.length - 1);
134
136
  });
135
137
  it('is opt-out: absent / null / empty / true all enable, only explicit false suppresses', () => {
136
138
  expect(pushEnabledFor(undefined, 'MATCH_RESULT')).toBe(true);
@@ -85,6 +85,58 @@ export const NOTIFICATION_REGISTRY = {
85
85
  inAppMessageKey: 'promotion.body',
86
86
  catalogKeys: ['promotion.title', 'promotion.body']
87
87
  },
88
+ // In-game events. All five deep-link to the Events section, which is where every phase of an event lives.
89
+ // eventName is the event's key; the UI resolves it to the translated name, so the catalog copy interpolates
90
+ // a key rather than a localised string the sender would have to translate.
91
+ EVENT_REGISTRATION_OPEN: {
92
+ emitsPush: true,
93
+ deepLink: () => '/events',
94
+ pushTitleKey: 'eventRegistrationOpen.title',
95
+ pushBodyKey: 'eventRegistrationOpen.body',
96
+ inAppMessageKey: 'eventRegistrationOpen.body',
97
+ catalogKeys: ['eventRegistrationOpen.title', 'eventRegistrationOpen.body']
98
+ },
99
+ EVENT_REGISTRATION_CLOSING: {
100
+ emitsPush: true,
101
+ deepLink: () => '/events',
102
+ pushTitleKey: 'eventRegistrationClosing.title',
103
+ pushBodyKey: 'eventRegistrationClosing.body',
104
+ inAppMessageKey: 'eventRegistrationClosing.body',
105
+ catalogKeys: ['eventRegistrationClosing.title', 'eventRegistrationClosing.body']
106
+ },
107
+ EVENT_STARTED: {
108
+ emitsPush: true,
109
+ deepLink: () => '/events',
110
+ pushTitleKey: 'eventStarted.title',
111
+ pushBodyKey: 'eventStarted.body',
112
+ inAppMessageKey: 'eventStarted.body',
113
+ catalogKeys: ['eventStarted.title', 'eventStarted.body']
114
+ },
115
+ EVENT_FINAL_ROUND: {
116
+ emitsPush: true,
117
+ deepLink: () => '/events',
118
+ pushTitleKey: 'eventFinalRound.title',
119
+ pushBodyKey: 'eventFinalRound.body',
120
+ inAppMessageKey: 'eventFinalRound.body',
121
+ catalogKeys: ['eventFinalRound.title', 'eventFinalRound.body']
122
+ },
123
+ EVENT_FINISHED: {
124
+ emitsPush: true,
125
+ deepLink: () => '/events',
126
+ pushTitleKey: 'eventFinished.title',
127
+ // Copy depends on whether we know where they finished; a missing position never renders "You finished th".
128
+ pushBodyKey: (p) => readString(p.position) != null || typeof p.position === 'number'
129
+ ? 'eventFinished.placed'
130
+ : 'eventFinished.body',
131
+ inAppMessageKey: (p) => readString(p.position) != null || typeof p.position === 'number'
132
+ ? 'eventFinished.placed'
133
+ : 'eventFinished.body',
134
+ params: (p) => ({
135
+ position: typeof p.position === 'number' ? String(p.position) : (readString(p.position) ?? ''),
136
+ entrants: typeof p.entrants === 'number' ? String(p.entrants) : (readString(p.entrants) ?? '')
137
+ }),
138
+ catalogKeys: ['eventFinished.title', 'eventFinished.body', 'eventFinished.placed']
139
+ },
88
140
  DAILY_LOGIN: {
89
141
  emitsPush: true,
90
142
  // Fires when the reward becomes claimable (00:00 UTC), so it opens the daily-login claim view.
@@ -35,13 +35,14 @@ export interface GachaPullConfig {
35
35
  }
36
36
  export declare const NORMAL_PULL_CONFIG: GachaPullConfig;
37
37
  export declare const QUALIFIER_PULL_CONFIG: GachaPullConfig;
38
+ export declare const EVENT_PULL_CONFIG: GachaPullConfig;
38
39
  export declare const TOURNAMENT_PULL_CONFIG: GachaPullConfig;
39
40
  export declare function scoutPullConfig(level: string): GachaPullConfig;
40
41
  export declare function rollRarity(pity: PityState, config?: GachaPullConfig): RollResult;
41
42
  export declare class PlayerGenerator {
42
43
  private constructor();
43
44
  private static generatePerformance;
44
- static generatePlayer(country: Country, _rarity?: Rarity, role?: Role, maxTraits?: boolean, birthIteration?: number): Player;
45
+ static generatePlayer(country: Country, _rarity?: Rarity, role?: Role, maxTraits?: boolean, birthIteration?: number, topSkew?: number): Player;
45
46
  static generatePlayers(count: number, countries: Country[]): Player[];
46
47
  }
47
48
  export declare function pickPlayerCountry(teamCountry: Country, allCountries: Country[]): Country;
@@ -63,6 +63,21 @@ export const QUALIFIER_PULL_CONFIG = {
63
63
  accumulateMythicPity: true,
64
64
  accumulateSpecialPity: true
65
65
  };
66
+ // Event Pack (x5): the NATIONAL pool and structure, with TRIPLE the legendary and mythic chance. Special is
67
+ // untouched and rare absorbs the difference, so it still sums to 1. Builds all three pities, like NATIONAL.
68
+ // Owner-defined 2026-07-23.
69
+ export const EVENT_PULL_CONFIG = {
70
+ special: 0.003,
71
+ mythic: 0.03,
72
+ legendary: 0.30,
73
+ rare: 0.667,
74
+ applyLegendaryPity: true,
75
+ applyMythicPity: true,
76
+ applySpecialPity: true,
77
+ accumulateLegendaryPity: true,
78
+ accumulateMythicPity: true,
79
+ accumulateSpecialPity: true
80
+ };
66
81
  // Tournament gacha (x5 per match): LEGENDARY–SPECIAL, no legendary pity (floor is legendary)
67
82
  export const TOURNAMENT_PULL_CONFIG = {
68
83
  special: 0.01,
@@ -188,7 +203,7 @@ export function rollRarity(pity, config = WORLD_PULL_CONFIG) {
188
203
  /* eslint-disable @typescript-eslint/no-extraneous-class */
189
204
  export class PlayerGenerator {
190
205
  constructor() { }
191
- static generatePerformance(rarity, role) {
206
+ static generatePerformance(rarity, role, topSkew = 0) {
192
207
  const ATTACK = getMultipliers(StatsEnum.ATTACK);
193
208
  const SET = getMultipliers(StatsEnum.SET);
194
209
  const RECEIVE = getMultipliers(StatsEnum.RECEIVE);
@@ -199,8 +214,10 @@ export class PlayerGenerator {
199
214
  // Stamina always uses its own per-rarity range (guaranteed floor), regardless of role weight.
200
215
  if (key === 'stamina')
201
216
  return [key, rollStamina(rarity)];
217
+ // On-role stats drive the role score, so a positive topSkew bends only these toward the top of the
218
+ // range; off-role stats stay uniform. topSkew defaults to 0 (the historic uniform draw).
202
219
  if (weights[key] > 0)
203
- return [key, randomInt(minValue, maxValue + 1)];
220
+ return [key, randomIntSkewed(minValue, maxValue, topSkew)];
204
221
  else
205
222
  return [key, randomInt(RarityRanges.COMMON[0], Math.max(minValue - 1, RarityRanges.COMMON[0] + 1))];
206
223
  })));
@@ -294,10 +311,10 @@ export class PlayerGenerator {
294
311
  }
295
312
  }
296
313
  }
297
- static generatePlayer(country, _rarity, role, maxTraits, birthIteration = 1) {
314
+ static generatePlayer(country, _rarity, role, maxTraits, birthIteration = 1, topSkew = 0) {
298
315
  const rarity = _rarity ?? rollRarity({ legendaryPity: 0, mythicPity: 0, specialPity: 0 }).rarity;
299
316
  const name = generatePlayerName(country.locales, 1)[0];
300
- const stats = PlayerGenerator.generatePerformance(rarity, role);
317
+ const stats = PlayerGenerator.generatePerformance(rarity, role, topSkew);
301
318
  const roles = assignRoles(stats, rarity, role);
302
319
  const traits = assignTraits(roles, rarity, maxTraits);
303
320
  const birthAge = randomInt(15, 21);
@@ -338,6 +355,21 @@ function rollStamina(rarity) {
338
355
  const [low, high] = StaminaRanges[rarity];
339
356
  return randomInt(low, high + 1);
340
357
  }
358
+ /**
359
+ * A crypto.randomInt draw over [min, max] inclusive, optionally skewed toward the top.
360
+ *
361
+ * skew = 0 is the plain uniform draw the generator has always used. A positive skew bends a uniform fraction
362
+ * upward with u^(1/(1+skew)), so higher values become progressively likelier while the maximum is never forced,
363
+ * which keeps the result random rather than a maxed stat. Event drafts use this to make the lower rarities'
364
+ * recruits cluster near the top of their range (see EVENT_DRAFT_TOP_SKEW).
365
+ */
366
+ function randomIntSkewed(min, max, skew) {
367
+ if (skew <= 0 || max <= min)
368
+ return randomInt(min, max + 1);
369
+ const u = randomInt(0, 1000001) / 1000000;
370
+ const frac = Math.pow(u, 1 / (1 + skew));
371
+ return min + Math.round(frac * (max - min));
372
+ }
341
373
  function assignValues(stat, low, high, performance) {
342
374
  performanceStatKeys.filter((key) => stat[key] != null && stat[key] > 0)
343
375
  .forEach((key) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "volleyballsimtypes",
3
- "version": "0.0.491",
3
+ "version": "0.0.493",
4
4
  "description": "vbsim types",
5
5
  "main": "./dist/cjs/src/index.js",
6
6
  "module": "./dist/esm/src/index.js",
@@ -42,6 +42,11 @@
42
42
  "import": "./dist/esm/src/service/notification/index.js",
43
43
  "require": "./dist/cjs/src/service/notification/index.js"
44
44
  },
45
+ "./api": {
46
+ "types": "./dist/esm/src/api/index.d.ts",
47
+ "import": "./dist/esm/src/api/index.js",
48
+ "require": "./dist/cjs/src/api/index.js"
49
+ },
45
50
  "./stat-config": {
46
51
  "types": "./dist/esm/src/stat-config/index.d.ts",
47
52
  "import": "./dist/esm/src/stat-config/index.js",