volleyballsimtypes 0.0.447 → 0.0.449

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 (31) hide show
  1. package/dist/cjs/src/data/transformers/rally-event.js +5 -10
  2. package/dist/cjs/src/data/transformers/rally.js +5 -5
  3. package/dist/cjs/src/service/event/schemas/block.z.d.ts +2 -2
  4. package/dist/cjs/src/service/event/schemas/block.z.js +1 -1
  5. package/dist/cjs/src/service/event/schemas/reception.z.d.ts +2 -2
  6. package/dist/cjs/src/service/event/schemas/reception.z.js +1 -1
  7. package/dist/cjs/src/service/event/schemas/serve.z.d.ts +2 -2
  8. package/dist/cjs/src/service/event/schemas/serve.z.js +1 -1
  9. package/dist/cjs/src/service/event/schemas/set.z.d.ts +2 -2
  10. package/dist/cjs/src/service/event/schemas/set.z.js +1 -1
  11. package/dist/cjs/src/service/event/schemas/spike.z.d.ts +2 -2
  12. package/dist/cjs/src/service/event/schemas/spike.z.js +1 -1
  13. package/dist/cjs/src/service/player/player-generator.js +1 -1
  14. package/dist/cjs/src/service/player/role.d.ts +1 -1
  15. package/dist/cjs/src/service/player/role.js +7 -1
  16. package/dist/esm/src/data/transformers/rally-event.js +5 -10
  17. package/dist/esm/src/data/transformers/rally.js +5 -5
  18. package/dist/esm/src/service/event/schemas/block.z.d.ts +2 -2
  19. package/dist/esm/src/service/event/schemas/block.z.js +1 -1
  20. package/dist/esm/src/service/event/schemas/reception.z.d.ts +2 -2
  21. package/dist/esm/src/service/event/schemas/reception.z.js +1 -1
  22. package/dist/esm/src/service/event/schemas/serve.z.d.ts +2 -2
  23. package/dist/esm/src/service/event/schemas/serve.z.js +1 -1
  24. package/dist/esm/src/service/event/schemas/set.z.d.ts +2 -2
  25. package/dist/esm/src/service/event/schemas/set.z.js +1 -1
  26. package/dist/esm/src/service/event/schemas/spike.z.d.ts +2 -2
  27. package/dist/esm/src/service/event/schemas/spike.z.js +1 -1
  28. package/dist/esm/src/service/player/player-generator.js +1 -1
  29. package/dist/esm/src/service/player/role.d.ts +1 -1
  30. package/dist/esm/src/service/player/role.js +7 -1
  31. package/package.json +1 -1
@@ -39,8 +39,7 @@ function transformToBlock(event, roster) {
39
39
  playerId: roster[event.p],
40
40
  target: event.a,
41
41
  blockers: (event.b ?? []).map(i => roster[i]),
42
- score: event.s,
43
- activeTraits: []
42
+ score: event.s
44
43
  });
45
44
  }
46
45
  function transformToLiberoReplacement(event, roster) {
@@ -56,8 +55,7 @@ function transformToReception(event, roster) {
56
55
  type: event.t,
57
56
  playerId: roster[event.p],
58
57
  target: event.a,
59
- score: event.s,
60
- activeTraits: []
58
+ score: event.s
61
59
  });
62
60
  }
63
61
  function transformToServe(event, roster) {
@@ -66,8 +64,7 @@ function transformToServe(event, roster) {
66
64
  type: event.t,
67
65
  playerId: roster[event.p],
68
66
  target: event.a,
69
- score: event.s,
70
- activeTraits: []
67
+ score: event.s
71
68
  });
72
69
  }
73
70
  function transformToSet(event, roster) {
@@ -76,8 +73,7 @@ function transformToSet(event, roster) {
76
73
  type: event.t,
77
74
  playerId: roster[event.p],
78
75
  target: event.a,
79
- score: event.s,
80
- activeTraits: []
76
+ score: event.s
81
77
  });
82
78
  }
83
79
  function transformToSpike(event, roster) {
@@ -86,8 +82,7 @@ function transformToSpike(event, roster) {
86
82
  type: event.t,
87
83
  playerId: roster[event.p],
88
84
  target: event.a,
89
- score: event.s,
90
- activeTraits: []
85
+ score: event.s
91
86
  });
92
87
  }
93
88
  function transformToSubstitution(event, roster) {
@@ -68,11 +68,11 @@ function decodeLegacyEvent(event) {
68
68
  switch (event.e) {
69
69
  case 0: return service_1.LiberoReplacement.create({ playerId: event.p, libero: event.l, type: event.t });
70
70
  case 1: return service_1.Substitution.create({ playerId: event.p, playerOut: event.o });
71
- case 2: return service_1.Serve.create({ failure: event.f, type: event.t, playerId: event.p, target: event.a, score: event.s, activeTraits: [] });
72
- case 3: return service_1.Reception.create({ failure: event.f, type: event.t, playerId: event.p, target: event.a, score: event.s, activeTraits: [] });
73
- case 4: return service_1.Set.create({ failure: event.f, type: event.t, playerId: event.p, target: event.a, score: event.s, activeTraits: [] });
74
- case 5: return service_1.Spike.create({ failure: event.f, type: event.t, playerId: event.p, target: event.a, score: event.s, activeTraits: [] });
75
- case 6: return service_1.Block.create({ failure: event.f, type: event.t, playerId: event.p, target: event.a, blockers: event.b ?? [], score: event.s, activeTraits: [] });
71
+ case 2: return service_1.Serve.create({ failure: event.f, type: event.t, playerId: event.p, target: event.a, score: event.s });
72
+ case 3: return service_1.Reception.create({ failure: event.f, type: event.t, playerId: event.p, target: event.a, score: event.s });
73
+ case 4: return service_1.Set.create({ failure: event.f, type: event.t, playerId: event.p, target: event.a, score: event.s });
74
+ case 5: return service_1.Spike.create({ failure: event.f, type: event.t, playerId: event.p, target: event.a, score: event.s });
75
+ case 6: return service_1.Block.create({ failure: event.f, type: event.t, playerId: event.p, target: event.a, blockers: event.b ?? [], score: event.s });
76
76
  default: throw new Error(`UNKNOWN_EVENT_TYPE: ${String(event.e)}`);
77
77
  }
78
78
  }
@@ -4,7 +4,7 @@ export declare const BlockInputSchema: z.ZodObject<{
4
4
  playerId: z.ZodUUID;
5
5
  score: z.ZodNumber;
6
6
  target: z.ZodNumber;
7
- activeTraits: z.ZodArray<z.ZodEnum<{
7
+ activeTraits: z.ZodDefault<z.ZodArray<z.ZodEnum<{
8
8
  MASTER_MIND: TraitEnum.MASTER_MIND;
9
9
  MOVING_WALL: TraitEnum.MOVING_WALL;
10
10
  SURPRISE_ATTACK: TraitEnum.SURPRISE_ATTACK;
@@ -14,7 +14,7 @@ export declare const BlockInputSchema: z.ZodObject<{
14
14
  GUARDIAN: TraitEnum.GUARDIAN;
15
15
  FLOAT_SERVE: TraitEnum.FLOAT_SERVE;
16
16
  DEFENSIVE_SPECIALIST: TraitEnum.DEFENSIVE_SPECIALIST;
17
- }>>;
17
+ }>>>;
18
18
  failure: z.ZodNumber;
19
19
  type: z.ZodNumber;
20
20
  blockers: z.ZodArray<z.ZodUUID>;
@@ -10,7 +10,7 @@ exports.BlockInputSchema = zod_1.z.object({
10
10
  playerId: zod_1.z.uuid(),
11
11
  score: zod_1.z.number().finite(),
12
12
  target: zod_1.z.number().int().refine((v) => courtTargetValues.includes(v), { message: 'INVALID_COURT_TARGET' }),
13
- activeTraits: zod_1.z.array(zod_1.z.enum(Object.values(player_1.TraitEnum))),
13
+ activeTraits: zod_1.z.array(zod_1.z.enum(Object.values(player_1.TraitEnum))).default([]),
14
14
  failure: zod_1.z.number().int().refine((v) => blockFailureValues.includes(v), { message: 'INVALID_BLOCK_FAILURE' }),
15
15
  type: zod_1.z.number().int().refine((v) => blockTypeValues.includes(v), { message: 'INVALID_BLOCK_TYPE' }),
16
16
  blockers: zod_1.z.array(zod_1.z.uuid())
@@ -4,7 +4,7 @@ export declare const ReceptionInputSchema: z.ZodObject<{
4
4
  playerId: z.ZodUUID;
5
5
  score: z.ZodNumber;
6
6
  target: z.ZodNumber;
7
- activeTraits: z.ZodArray<z.ZodEnum<{
7
+ activeTraits: z.ZodDefault<z.ZodArray<z.ZodEnum<{
8
8
  MASTER_MIND: TraitEnum.MASTER_MIND;
9
9
  MOVING_WALL: TraitEnum.MOVING_WALL;
10
10
  SURPRISE_ATTACK: TraitEnum.SURPRISE_ATTACK;
@@ -14,7 +14,7 @@ export declare const ReceptionInputSchema: z.ZodObject<{
14
14
  GUARDIAN: TraitEnum.GUARDIAN;
15
15
  FLOAT_SERVE: TraitEnum.FLOAT_SERVE;
16
16
  DEFENSIVE_SPECIALIST: TraitEnum.DEFENSIVE_SPECIALIST;
17
- }>>;
17
+ }>>>;
18
18
  failure: z.ZodNumber;
19
19
  type: z.ZodNumber;
20
20
  }, z.core.$strip>;
@@ -10,7 +10,7 @@ exports.ReceptionInputSchema = zod_1.z.object({
10
10
  playerId: zod_1.z.uuid(),
11
11
  score: zod_1.z.number().finite(),
12
12
  target: zod_1.z.number().int().refine((v) => courtTargetValues.includes(v), { message: 'INVALID_COURT_TARGET' }),
13
- activeTraits: zod_1.z.array(zod_1.z.enum(Object.values(player_1.TraitEnum))),
13
+ activeTraits: zod_1.z.array(zod_1.z.enum(Object.values(player_1.TraitEnum))).default([]),
14
14
  failure: zod_1.z.number().int().refine((v) => receptionFailureValues.includes(v), { message: 'INVALID_RECEPTION_FAILURE' }),
15
15
  type: zod_1.z.number().int().refine((v) => receptionTypeValues.includes(v), { message: 'INVALID_RECEPTION_TYPE' })
16
16
  });
@@ -4,7 +4,7 @@ export declare const ServeInputSchema: z.ZodObject<{
4
4
  playerId: z.ZodUUID;
5
5
  score: z.ZodNumber;
6
6
  target: z.ZodNumber;
7
- activeTraits: z.ZodArray<z.ZodEnum<{
7
+ activeTraits: z.ZodDefault<z.ZodArray<z.ZodEnum<{
8
8
  MASTER_MIND: TraitEnum.MASTER_MIND;
9
9
  MOVING_WALL: TraitEnum.MOVING_WALL;
10
10
  SURPRISE_ATTACK: TraitEnum.SURPRISE_ATTACK;
@@ -14,7 +14,7 @@ export declare const ServeInputSchema: z.ZodObject<{
14
14
  GUARDIAN: TraitEnum.GUARDIAN;
15
15
  FLOAT_SERVE: TraitEnum.FLOAT_SERVE;
16
16
  DEFENSIVE_SPECIALIST: TraitEnum.DEFENSIVE_SPECIALIST;
17
- }>>;
17
+ }>>>;
18
18
  failure: z.ZodNumber;
19
19
  type: z.ZodNumber;
20
20
  }, z.core.$strip>;
@@ -10,7 +10,7 @@ exports.ServeInputSchema = zod_1.z.object({
10
10
  playerId: zod_1.z.uuid(),
11
11
  score: zod_1.z.number().finite(),
12
12
  target: zod_1.z.number().int().refine((v) => courtTargetValues.includes(v), { message: 'INVALID_COURT_TARGET' }),
13
- activeTraits: zod_1.z.array(zod_1.z.enum(Object.values(player_1.TraitEnum))),
13
+ activeTraits: zod_1.z.array(zod_1.z.enum(Object.values(player_1.TraitEnum))).default([]),
14
14
  failure: zod_1.z.number().int().refine((v) => serveFailureValues.includes(v), { message: 'INVALID_SERVE_FAILURE' }),
15
15
  type: zod_1.z.number().int().refine((v) => serveTypeValues.includes(v), { message: 'INVALID_SERVE_TYPE' })
16
16
  });
@@ -4,7 +4,7 @@ export declare const SetInputSchema: z.ZodObject<{
4
4
  playerId: z.ZodUUID;
5
5
  score: z.ZodNumber;
6
6
  target: z.ZodNumber;
7
- activeTraits: z.ZodArray<z.ZodEnum<{
7
+ activeTraits: z.ZodDefault<z.ZodArray<z.ZodEnum<{
8
8
  MASTER_MIND: TraitEnum.MASTER_MIND;
9
9
  MOVING_WALL: TraitEnum.MOVING_WALL;
10
10
  SURPRISE_ATTACK: TraitEnum.SURPRISE_ATTACK;
@@ -14,7 +14,7 @@ export declare const SetInputSchema: z.ZodObject<{
14
14
  GUARDIAN: TraitEnum.GUARDIAN;
15
15
  FLOAT_SERVE: TraitEnum.FLOAT_SERVE;
16
16
  DEFENSIVE_SPECIALIST: TraitEnum.DEFENSIVE_SPECIALIST;
17
- }>>;
17
+ }>>>;
18
18
  failure: z.ZodNumber;
19
19
  type: z.ZodNumber;
20
20
  }, z.core.$strip>;
@@ -10,7 +10,7 @@ exports.SetInputSchema = zod_1.z.object({
10
10
  playerId: zod_1.z.uuid(),
11
11
  score: zod_1.z.number().finite(),
12
12
  target: zod_1.z.number().int().refine((v) => courtTargetValues.includes(v), { message: 'INVALID_COURT_TARGET' }),
13
- activeTraits: zod_1.z.array(zod_1.z.enum(Object.values(player_1.TraitEnum))),
13
+ activeTraits: zod_1.z.array(zod_1.z.enum(Object.values(player_1.TraitEnum))).default([]),
14
14
  failure: zod_1.z.number().int().refine((v) => setFailureValues.includes(v), { message: 'INVALID_SET_FAILURE' }),
15
15
  type: zod_1.z.number().int().refine((v) => setTypeValues.includes(v), { message: 'INVALID_SET_TYPE' })
16
16
  });
@@ -4,7 +4,7 @@ export declare const SpikeInputSchema: z.ZodObject<{
4
4
  playerId: z.ZodUUID;
5
5
  score: z.ZodNumber;
6
6
  target: z.ZodNumber;
7
- activeTraits: z.ZodArray<z.ZodEnum<{
7
+ activeTraits: z.ZodDefault<z.ZodArray<z.ZodEnum<{
8
8
  MASTER_MIND: TraitEnum.MASTER_MIND;
9
9
  MOVING_WALL: TraitEnum.MOVING_WALL;
10
10
  SURPRISE_ATTACK: TraitEnum.SURPRISE_ATTACK;
@@ -14,7 +14,7 @@ export declare const SpikeInputSchema: z.ZodObject<{
14
14
  GUARDIAN: TraitEnum.GUARDIAN;
15
15
  FLOAT_SERVE: TraitEnum.FLOAT_SERVE;
16
16
  DEFENSIVE_SPECIALIST: TraitEnum.DEFENSIVE_SPECIALIST;
17
- }>>;
17
+ }>>>;
18
18
  failure: z.ZodNumber;
19
19
  type: z.ZodNumber;
20
20
  }, z.core.$strip>;
@@ -10,7 +10,7 @@ exports.SpikeInputSchema = zod_1.z.object({
10
10
  playerId: zod_1.z.uuid(),
11
11
  score: zod_1.z.number().finite(),
12
12
  target: zod_1.z.number().int().refine((v) => courtTargetValues.includes(v), { message: 'INVALID_COURT_TARGET' }),
13
- activeTraits: zod_1.z.array(zod_1.z.enum(Object.values(player_1.TraitEnum))),
13
+ activeTraits: zod_1.z.array(zod_1.z.enum(Object.values(player_1.TraitEnum))).default([]),
14
14
  failure: zod_1.z.number().int().refine((v) => spikeFailureValues.includes(v), { message: 'INVALID_SPIKE_FAILURE' }),
15
15
  type: zod_1.z.number().int().refine((v) => spikeTypeValues.includes(v), { message: 'INVALID_SPIKE_TYPE' })
16
16
  });
@@ -304,7 +304,7 @@ class PlayerGenerator {
304
304
  const rarity = _rarity ?? rollRarity({ legendaryPity: 0, mythicPity: 0, specialPity: 0 }).rarity;
305
305
  const name = (0, utils_1.generatePlayerName)(country.locales, 1)[0];
306
306
  const stats = PlayerGenerator.generatePerformance(rarity, role);
307
- const roles = (0, role_1.assignRoles)(stats, rarity);
307
+ const roles = (0, role_1.assignRoles)(stats, rarity, role);
308
308
  const traits = (0, trait_1.assignTraits)(roles, rarity, maxTraits);
309
309
  const birthAge = (0, node_crypto_1.randomInt)(15, 21);
310
310
  const declineProfile = decline_1.declineProfiles[(0, node_crypto_1.randomInt)(0, decline_1.declineProfiles.length)];
@@ -14,7 +14,7 @@ export interface RolesFormula {
14
14
  weight: PerformanceStatsParams;
15
15
  }
16
16
  export declare function calculateRoleScore(stats: PerformanceStats, role: Role): number;
17
- export declare function assignRoles(stats: PerformanceStats, rarity: Rarity): Role[];
17
+ export declare function assignRoles(stats: PerformanceStats, rarity: Rarity, forcedRole?: Role): Role[];
18
18
  /**
19
19
  * Returns the role-based multiplier for a player performing a given action.
20
20
  * When the player holds multiple roles, the least-penalising role wins.
@@ -43,7 +43,7 @@ function getRoleCountRange(rarity) {
43
43
  default: return [1, 1];
44
44
  }
45
45
  }
46
- function assignRoles(stats, rarity) {
46
+ function assignRoles(stats, rarity, forcedRole) {
47
47
  const scores = Object.values(RoleEnum)
48
48
  .map((role) => ({
49
49
  role,
@@ -52,6 +52,12 @@ function assignRoles(stats, rarity) {
52
52
  .sort((x, y) => y.score - x.score);
53
53
  const [min, max] = getRoleCountRange(rarity);
54
54
  const count = min + Math.floor(Math.random() * (max - min + 1));
55
+ // A forced role (role pick, wishlist proc, team seeding) must be the player's primary role.
56
+ // Remaining slots fill with the top-scoring other roles so multi-role rarity flavour is kept.
57
+ if (forcedRole != null) {
58
+ const others = scores.map(s => s.role).filter(r => r !== forcedRole);
59
+ return [forcedRole, ...others].slice(0, count);
60
+ }
55
61
  return scores.slice(0, count).map(s => s.role);
56
62
  }
57
63
  // ─── Role event penalties ─────────────────────────────────────────────────────
@@ -29,8 +29,7 @@ export function transformToBlock(event, roster) {
29
29
  playerId: roster[event.p],
30
30
  target: event.a,
31
31
  blockers: (event.b ?? []).map(i => roster[i]),
32
- score: event.s,
33
- activeTraits: []
32
+ score: event.s
34
33
  });
35
34
  }
36
35
  export function transformToLiberoReplacement(event, roster) {
@@ -46,8 +45,7 @@ export function transformToReception(event, roster) {
46
45
  type: event.t,
47
46
  playerId: roster[event.p],
48
47
  target: event.a,
49
- score: event.s,
50
- activeTraits: []
48
+ score: event.s
51
49
  });
52
50
  }
53
51
  export function transformToServe(event, roster) {
@@ -56,8 +54,7 @@ export function transformToServe(event, roster) {
56
54
  type: event.t,
57
55
  playerId: roster[event.p],
58
56
  target: event.a,
59
- score: event.s,
60
- activeTraits: []
57
+ score: event.s
61
58
  });
62
59
  }
63
60
  export function transformToSet(event, roster) {
@@ -66,8 +63,7 @@ export function transformToSet(event, roster) {
66
63
  type: event.t,
67
64
  playerId: roster[event.p],
68
65
  target: event.a,
69
- score: event.s,
70
- activeTraits: []
66
+ score: event.s
71
67
  });
72
68
  }
73
69
  export function transformToSpike(event, roster) {
@@ -76,8 +72,7 @@ export function transformToSpike(event, roster) {
76
72
  type: event.t,
77
73
  playerId: roster[event.p],
78
74
  target: event.a,
79
- score: event.s,
80
- activeTraits: []
75
+ score: event.s
81
76
  });
82
77
  }
83
78
  export function transformToSubstitution(event, roster) {
@@ -64,11 +64,11 @@ function decodeLegacyEvent(event) {
64
64
  switch (event.e) {
65
65
  case 0: return LiberoReplacement.create({ playerId: event.p, libero: event.l, type: event.t });
66
66
  case 1: return Substitution.create({ playerId: event.p, playerOut: event.o });
67
- case 2: return Serve.create({ failure: event.f, type: event.t, playerId: event.p, target: event.a, score: event.s, activeTraits: [] });
68
- case 3: return Reception.create({ failure: event.f, type: event.t, playerId: event.p, target: event.a, score: event.s, activeTraits: [] });
69
- case 4: return VolleySet.create({ failure: event.f, type: event.t, playerId: event.p, target: event.a, score: event.s, activeTraits: [] });
70
- case 5: return Spike.create({ failure: event.f, type: event.t, playerId: event.p, target: event.a, score: event.s, activeTraits: [] });
71
- case 6: return Block.create({ failure: event.f, type: event.t, playerId: event.p, target: event.a, blockers: event.b ?? [], score: event.s, activeTraits: [] });
67
+ case 2: return Serve.create({ failure: event.f, type: event.t, playerId: event.p, target: event.a, score: event.s });
68
+ case 3: return Reception.create({ failure: event.f, type: event.t, playerId: event.p, target: event.a, score: event.s });
69
+ case 4: return VolleySet.create({ failure: event.f, type: event.t, playerId: event.p, target: event.a, score: event.s });
70
+ case 5: return Spike.create({ failure: event.f, type: event.t, playerId: event.p, target: event.a, score: event.s });
71
+ case 6: return Block.create({ failure: event.f, type: event.t, playerId: event.p, target: event.a, blockers: event.b ?? [], score: event.s });
72
72
  default: throw new Error(`UNKNOWN_EVENT_TYPE: ${String(event.e)}`);
73
73
  }
74
74
  }
@@ -4,7 +4,7 @@ export declare const BlockInputSchema: z.ZodObject<{
4
4
  playerId: z.ZodUUID;
5
5
  score: z.ZodNumber;
6
6
  target: z.ZodNumber;
7
- activeTraits: z.ZodArray<z.ZodEnum<{
7
+ activeTraits: z.ZodDefault<z.ZodArray<z.ZodEnum<{
8
8
  MASTER_MIND: TraitEnum.MASTER_MIND;
9
9
  MOVING_WALL: TraitEnum.MOVING_WALL;
10
10
  SURPRISE_ATTACK: TraitEnum.SURPRISE_ATTACK;
@@ -14,7 +14,7 @@ export declare const BlockInputSchema: z.ZodObject<{
14
14
  GUARDIAN: TraitEnum.GUARDIAN;
15
15
  FLOAT_SERVE: TraitEnum.FLOAT_SERVE;
16
16
  DEFENSIVE_SPECIALIST: TraitEnum.DEFENSIVE_SPECIALIST;
17
- }>>;
17
+ }>>>;
18
18
  failure: z.ZodNumber;
19
19
  type: z.ZodNumber;
20
20
  blockers: z.ZodArray<z.ZodUUID>;
@@ -7,7 +7,7 @@ export const BlockInputSchema = z.object({
7
7
  playerId: z.uuid(),
8
8
  score: z.number().finite(),
9
9
  target: z.number().int().refine((v) => courtTargetValues.includes(v), { message: 'INVALID_COURT_TARGET' }),
10
- activeTraits: z.array(z.enum(Object.values(TraitEnum))),
10
+ activeTraits: z.array(z.enum(Object.values(TraitEnum))).default([]),
11
11
  failure: z.number().int().refine((v) => blockFailureValues.includes(v), { message: 'INVALID_BLOCK_FAILURE' }),
12
12
  type: z.number().int().refine((v) => blockTypeValues.includes(v), { message: 'INVALID_BLOCK_TYPE' }),
13
13
  blockers: z.array(z.uuid())
@@ -4,7 +4,7 @@ export declare const ReceptionInputSchema: z.ZodObject<{
4
4
  playerId: z.ZodUUID;
5
5
  score: z.ZodNumber;
6
6
  target: z.ZodNumber;
7
- activeTraits: z.ZodArray<z.ZodEnum<{
7
+ activeTraits: z.ZodDefault<z.ZodArray<z.ZodEnum<{
8
8
  MASTER_MIND: TraitEnum.MASTER_MIND;
9
9
  MOVING_WALL: TraitEnum.MOVING_WALL;
10
10
  SURPRISE_ATTACK: TraitEnum.SURPRISE_ATTACK;
@@ -14,7 +14,7 @@ export declare const ReceptionInputSchema: z.ZodObject<{
14
14
  GUARDIAN: TraitEnum.GUARDIAN;
15
15
  FLOAT_SERVE: TraitEnum.FLOAT_SERVE;
16
16
  DEFENSIVE_SPECIALIST: TraitEnum.DEFENSIVE_SPECIALIST;
17
- }>>;
17
+ }>>>;
18
18
  failure: z.ZodNumber;
19
19
  type: z.ZodNumber;
20
20
  }, z.core.$strip>;
@@ -7,7 +7,7 @@ export const ReceptionInputSchema = z.object({
7
7
  playerId: z.uuid(),
8
8
  score: z.number().finite(),
9
9
  target: z.number().int().refine((v) => courtTargetValues.includes(v), { message: 'INVALID_COURT_TARGET' }),
10
- activeTraits: z.array(z.enum(Object.values(TraitEnum))),
10
+ activeTraits: z.array(z.enum(Object.values(TraitEnum))).default([]),
11
11
  failure: z.number().int().refine((v) => receptionFailureValues.includes(v), { message: 'INVALID_RECEPTION_FAILURE' }),
12
12
  type: z.number().int().refine((v) => receptionTypeValues.includes(v), { message: 'INVALID_RECEPTION_TYPE' })
13
13
  });
@@ -4,7 +4,7 @@ export declare const ServeInputSchema: z.ZodObject<{
4
4
  playerId: z.ZodUUID;
5
5
  score: z.ZodNumber;
6
6
  target: z.ZodNumber;
7
- activeTraits: z.ZodArray<z.ZodEnum<{
7
+ activeTraits: z.ZodDefault<z.ZodArray<z.ZodEnum<{
8
8
  MASTER_MIND: TraitEnum.MASTER_MIND;
9
9
  MOVING_WALL: TraitEnum.MOVING_WALL;
10
10
  SURPRISE_ATTACK: TraitEnum.SURPRISE_ATTACK;
@@ -14,7 +14,7 @@ export declare const ServeInputSchema: z.ZodObject<{
14
14
  GUARDIAN: TraitEnum.GUARDIAN;
15
15
  FLOAT_SERVE: TraitEnum.FLOAT_SERVE;
16
16
  DEFENSIVE_SPECIALIST: TraitEnum.DEFENSIVE_SPECIALIST;
17
- }>>;
17
+ }>>>;
18
18
  failure: z.ZodNumber;
19
19
  type: z.ZodNumber;
20
20
  }, z.core.$strip>;
@@ -7,7 +7,7 @@ export const ServeInputSchema = z.object({
7
7
  playerId: z.uuid(),
8
8
  score: z.number().finite(),
9
9
  target: z.number().int().refine((v) => courtTargetValues.includes(v), { message: 'INVALID_COURT_TARGET' }),
10
- activeTraits: z.array(z.enum(Object.values(TraitEnum))),
10
+ activeTraits: z.array(z.enum(Object.values(TraitEnum))).default([]),
11
11
  failure: z.number().int().refine((v) => serveFailureValues.includes(v), { message: 'INVALID_SERVE_FAILURE' }),
12
12
  type: z.number().int().refine((v) => serveTypeValues.includes(v), { message: 'INVALID_SERVE_TYPE' })
13
13
  });
@@ -4,7 +4,7 @@ export declare const SetInputSchema: z.ZodObject<{
4
4
  playerId: z.ZodUUID;
5
5
  score: z.ZodNumber;
6
6
  target: z.ZodNumber;
7
- activeTraits: z.ZodArray<z.ZodEnum<{
7
+ activeTraits: z.ZodDefault<z.ZodArray<z.ZodEnum<{
8
8
  MASTER_MIND: TraitEnum.MASTER_MIND;
9
9
  MOVING_WALL: TraitEnum.MOVING_WALL;
10
10
  SURPRISE_ATTACK: TraitEnum.SURPRISE_ATTACK;
@@ -14,7 +14,7 @@ export declare const SetInputSchema: z.ZodObject<{
14
14
  GUARDIAN: TraitEnum.GUARDIAN;
15
15
  FLOAT_SERVE: TraitEnum.FLOAT_SERVE;
16
16
  DEFENSIVE_SPECIALIST: TraitEnum.DEFENSIVE_SPECIALIST;
17
- }>>;
17
+ }>>>;
18
18
  failure: z.ZodNumber;
19
19
  type: z.ZodNumber;
20
20
  }, z.core.$strip>;
@@ -7,7 +7,7 @@ export const SetInputSchema = z.object({
7
7
  playerId: z.uuid(),
8
8
  score: z.number().finite(),
9
9
  target: z.number().int().refine((v) => courtTargetValues.includes(v), { message: 'INVALID_COURT_TARGET' }),
10
- activeTraits: z.array(z.enum(Object.values(TraitEnum))),
10
+ activeTraits: z.array(z.enum(Object.values(TraitEnum))).default([]),
11
11
  failure: z.number().int().refine((v) => setFailureValues.includes(v), { message: 'INVALID_SET_FAILURE' }),
12
12
  type: z.number().int().refine((v) => setTypeValues.includes(v), { message: 'INVALID_SET_TYPE' })
13
13
  });
@@ -4,7 +4,7 @@ export declare const SpikeInputSchema: z.ZodObject<{
4
4
  playerId: z.ZodUUID;
5
5
  score: z.ZodNumber;
6
6
  target: z.ZodNumber;
7
- activeTraits: z.ZodArray<z.ZodEnum<{
7
+ activeTraits: z.ZodDefault<z.ZodArray<z.ZodEnum<{
8
8
  MASTER_MIND: TraitEnum.MASTER_MIND;
9
9
  MOVING_WALL: TraitEnum.MOVING_WALL;
10
10
  SURPRISE_ATTACK: TraitEnum.SURPRISE_ATTACK;
@@ -14,7 +14,7 @@ export declare const SpikeInputSchema: z.ZodObject<{
14
14
  GUARDIAN: TraitEnum.GUARDIAN;
15
15
  FLOAT_SERVE: TraitEnum.FLOAT_SERVE;
16
16
  DEFENSIVE_SPECIALIST: TraitEnum.DEFENSIVE_SPECIALIST;
17
- }>>;
17
+ }>>>;
18
18
  failure: z.ZodNumber;
19
19
  type: z.ZodNumber;
20
20
  }, z.core.$strip>;
@@ -7,7 +7,7 @@ export const SpikeInputSchema = z.object({
7
7
  playerId: z.uuid(),
8
8
  score: z.number().finite(),
9
9
  target: z.number().int().refine((v) => courtTargetValues.includes(v), { message: 'INVALID_COURT_TARGET' }),
10
- activeTraits: z.array(z.enum(Object.values(TraitEnum))),
10
+ activeTraits: z.array(z.enum(Object.values(TraitEnum))).default([]),
11
11
  failure: z.number().int().refine((v) => spikeFailureValues.includes(v), { message: 'INVALID_SPIKE_FAILURE' }),
12
12
  type: z.number().int().refine((v) => spikeTypeValues.includes(v), { message: 'INVALID_SPIKE_TYPE' })
13
13
  });
@@ -298,7 +298,7 @@ export class PlayerGenerator {
298
298
  const rarity = _rarity ?? rollRarity({ legendaryPity: 0, mythicPity: 0, specialPity: 0 }).rarity;
299
299
  const name = generatePlayerName(country.locales, 1)[0];
300
300
  const stats = PlayerGenerator.generatePerformance(rarity, role);
301
- const roles = assignRoles(stats, rarity);
301
+ const roles = assignRoles(stats, rarity, role);
302
302
  const traits = assignTraits(roles, rarity, maxTraits);
303
303
  const birthAge = randomInt(15, 21);
304
304
  const declineProfile = declineProfiles[randomInt(0, declineProfiles.length)];
@@ -14,7 +14,7 @@ export interface RolesFormula {
14
14
  weight: PerformanceStatsParams;
15
15
  }
16
16
  export declare function calculateRoleScore(stats: PerformanceStats, role: Role): number;
17
- export declare function assignRoles(stats: PerformanceStats, rarity: Rarity): Role[];
17
+ export declare function assignRoles(stats: PerformanceStats, rarity: Rarity, forcedRole?: Role): Role[];
18
18
  /**
19
19
  * Returns the role-based multiplier for a player performing a given action.
20
20
  * When the player holds multiple roles, the least-penalising role wins.
@@ -33,7 +33,7 @@ function getRoleCountRange(rarity) {
33
33
  default: return [1, 1];
34
34
  }
35
35
  }
36
- export function assignRoles(stats, rarity) {
36
+ export function assignRoles(stats, rarity, forcedRole) {
37
37
  const scores = Object.values(RoleEnum)
38
38
  .map((role) => ({
39
39
  role,
@@ -42,6 +42,12 @@ export function assignRoles(stats, rarity) {
42
42
  .sort((x, y) => y.score - x.score);
43
43
  const [min, max] = getRoleCountRange(rarity);
44
44
  const count = min + Math.floor(Math.random() * (max - min + 1));
45
+ // A forced role (role pick, wishlist proc, team seeding) must be the player's primary role.
46
+ // Remaining slots fill with the top-scoring other roles so multi-role rarity flavour is kept.
47
+ if (forcedRole != null) {
48
+ const others = scores.map(s => s.role).filter(r => r !== forcedRole);
49
+ return [forcedRole, ...others].slice(0, count);
50
+ }
45
51
  return scores.slice(0, count).map(s => s.role);
46
52
  }
47
53
  // ─── Role event penalties ─────────────────────────────────────────────────────
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "volleyballsimtypes",
3
- "version": "0.0.447",
3
+ "version": "0.0.449",
4
4
  "description": "vbsim types",
5
5
  "main": "./dist/cjs/src/index.js",
6
6
  "module": "./dist/esm/src/index.js",