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.
- package/dist/cjs/src/data/transformers/rally-event.js +5 -10
- package/dist/cjs/src/data/transformers/rally.js +5 -5
- package/dist/cjs/src/service/event/schemas/block.z.d.ts +2 -2
- package/dist/cjs/src/service/event/schemas/block.z.js +1 -1
- package/dist/cjs/src/service/event/schemas/reception.z.d.ts +2 -2
- package/dist/cjs/src/service/event/schemas/reception.z.js +1 -1
- package/dist/cjs/src/service/event/schemas/serve.z.d.ts +2 -2
- package/dist/cjs/src/service/event/schemas/serve.z.js +1 -1
- package/dist/cjs/src/service/event/schemas/set.z.d.ts +2 -2
- package/dist/cjs/src/service/event/schemas/set.z.js +1 -1
- package/dist/cjs/src/service/event/schemas/spike.z.d.ts +2 -2
- package/dist/cjs/src/service/event/schemas/spike.z.js +1 -1
- package/dist/cjs/src/service/player/player-generator.js +1 -1
- package/dist/cjs/src/service/player/role.d.ts +1 -1
- package/dist/cjs/src/service/player/role.js +7 -1
- package/dist/esm/src/data/transformers/rally-event.js +5 -10
- package/dist/esm/src/data/transformers/rally.js +5 -5
- package/dist/esm/src/service/event/schemas/block.z.d.ts +2 -2
- package/dist/esm/src/service/event/schemas/block.z.js +1 -1
- package/dist/esm/src/service/event/schemas/reception.z.d.ts +2 -2
- package/dist/esm/src/service/event/schemas/reception.z.js +1 -1
- package/dist/esm/src/service/event/schemas/serve.z.d.ts +2 -2
- package/dist/esm/src/service/event/schemas/serve.z.js +1 -1
- package/dist/esm/src/service/event/schemas/set.z.d.ts +2 -2
- package/dist/esm/src/service/event/schemas/set.z.js +1 -1
- package/dist/esm/src/service/event/schemas/spike.z.d.ts +2 -2
- package/dist/esm/src/service/event/schemas/spike.z.js +1 -1
- package/dist/esm/src/service/player/player-generator.js +1 -1
- package/dist/esm/src/service/player/role.d.ts +1 -1
- package/dist/esm/src/service/player/role.js +7 -1
- 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
|
|
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
|
|
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
|
|
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
|
|
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 ─────────────────────────────────────────────────────
|