volleyballsimtypes 0.0.441 → 0.0.442
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/api/index.d.ts +0 -2
- package/dist/cjs/src/data/models/tactics.d.ts +1 -6
- package/dist/cjs/src/data/models/tactics.js +0 -10
- package/dist/cjs/src/data/transformers/tactics.js +0 -13
- package/dist/cjs/src/data/transformers/tactics.test.js +0 -4
- package/dist/cjs/src/service/team/schemas/tactics.z.d.ts +0 -2
- package/dist/cjs/src/service/team/schemas/tactics.z.js +0 -3
- package/dist/cjs/src/service/team/schemas/tactics.z.test.js +0 -2
- package/dist/cjs/src/service/team/schemas/team.z.d.ts +0 -2
- package/dist/cjs/src/service/team/tactics.d.ts +0 -4
- package/dist/cjs/src/service/team/tactics.js +1 -3
- package/dist/cjs/src/service/team/team-generator.js +0 -2
- package/dist/esm/src/api/index.d.ts +0 -2
- package/dist/esm/src/data/models/tactics.d.ts +1 -6
- package/dist/esm/src/data/models/tactics.js +0 -10
- package/dist/esm/src/data/transformers/tactics.js +0 -13
- package/dist/esm/src/data/transformers/tactics.test.js +0 -4
- package/dist/esm/src/service/team/schemas/tactics.z.d.ts +0 -2
- package/dist/esm/src/service/team/schemas/tactics.z.js +0 -3
- package/dist/esm/src/service/team/schemas/tactics.z.test.js +0 -2
- package/dist/esm/src/service/team/schemas/team.z.d.ts +0 -2
- package/dist/esm/src/service/team/tactics.d.ts +0 -4
- package/dist/esm/src/service/team/tactics.js +1 -3
- package/dist/esm/src/service/team/team-generator.js +1 -3
- package/package.json +1 -1
|
@@ -102,9 +102,7 @@ export interface ApiLiberoSubConfig extends ApiLiberoSetSubConfig {
|
|
|
102
102
|
}
|
|
103
103
|
export interface Tactics {
|
|
104
104
|
lineup: StartingLineup;
|
|
105
|
-
substitutionTolerance: number;
|
|
106
105
|
liberoReplacements: string[];
|
|
107
|
-
pinchServerSubs: Record<string, string>;
|
|
108
106
|
receiveRotationOffset: boolean;
|
|
109
107
|
designatedSubs: ApiDesignatedSub[];
|
|
110
108
|
substitutionBand: SubBand;
|
|
@@ -12,7 +12,6 @@ export interface TacticsLineupAttributes {
|
|
|
12
12
|
[CourtPosition.RIGHT_FRONT]: PlayerId;
|
|
13
13
|
bench: PlayerId[];
|
|
14
14
|
}
|
|
15
|
-
export type PinchServerSubsAttributes = Record<PlayerId, PlayerId>;
|
|
16
15
|
export interface SetSubConfigAttributes {
|
|
17
16
|
mode: SubMode;
|
|
18
17
|
benchId?: PlayerId;
|
|
@@ -45,10 +44,8 @@ export interface LiberoSubConfigAttributes extends LiberoSetSubConfigAttributes
|
|
|
45
44
|
}
|
|
46
45
|
export interface TacticsAttributes {
|
|
47
46
|
team_id: string;
|
|
48
|
-
substitution_tolerance: number;
|
|
49
47
|
lineup: TacticsLineupAttributes;
|
|
50
48
|
libero_replacements: PlayerId[];
|
|
51
|
-
pinch_server_subs: PinchServerSubsAttributes;
|
|
52
49
|
receive_rotation_offset: boolean;
|
|
53
50
|
designated_subs: DesignatedSubAttributes[];
|
|
54
51
|
substitution_band: SubBand;
|
|
@@ -61,14 +58,12 @@ export interface TacticsAttributes {
|
|
|
61
58
|
}
|
|
62
59
|
export type TacticsPk = 'team_id';
|
|
63
60
|
export type TacticsId = TacticsModel[TacticsPk];
|
|
64
|
-
export type TacticsOptionalAttributes = '
|
|
61
|
+
export type TacticsOptionalAttributes = 'lineup' | 'libero_replacements' | 'receive_rotation_offset' | 'designated_subs' | 'substitution_band' | 'second_libero' | 'libero_sub' | 'libero_replacement_sets' | 'rotation_system' | 'designated_setters' | 'offensive_preferences';
|
|
65
62
|
export type TacticsCreationAttributes = Optional<TacticsAttributes, TacticsOptionalAttributes>;
|
|
66
63
|
export declare class TacticsModel extends Model<TacticsAttributes, TacticsCreationAttributes> implements TacticsAttributes {
|
|
67
64
|
team_id: string;
|
|
68
|
-
substitution_tolerance: number;
|
|
69
65
|
lineup: TacticsLineupAttributes;
|
|
70
66
|
libero_replacements: PlayerId[];
|
|
71
|
-
pinch_server_subs: PinchServerSubsAttributes;
|
|
72
67
|
receive_rotation_offset: boolean;
|
|
73
68
|
designated_subs: DesignatedSubAttributes[];
|
|
74
69
|
substitution_band: SubBand;
|
|
@@ -15,11 +15,6 @@ class TacticsModel extends sequelize_1.Model {
|
|
|
15
15
|
key: 'team_id'
|
|
16
16
|
}
|
|
17
17
|
},
|
|
18
|
-
substitution_tolerance: {
|
|
19
|
-
type: sequelize_1.DataTypes.REAL,
|
|
20
|
-
allowNull: false,
|
|
21
|
-
defaultValue: 0
|
|
22
|
-
},
|
|
23
18
|
lineup: {
|
|
24
19
|
type: sequelize_1.DataTypes.JSONB,
|
|
25
20
|
allowNull: false,
|
|
@@ -30,11 +25,6 @@ class TacticsModel extends sequelize_1.Model {
|
|
|
30
25
|
allowNull: false,
|
|
31
26
|
defaultValue: []
|
|
32
27
|
},
|
|
33
|
-
pinch_server_subs: {
|
|
34
|
-
type: sequelize_1.DataTypes.JSONB,
|
|
35
|
-
allowNull: false,
|
|
36
|
-
defaultValue: {}
|
|
37
|
-
},
|
|
38
28
|
receive_rotation_offset: {
|
|
39
29
|
type: sequelize_1.DataTypes.BOOLEAN,
|
|
40
30
|
allowNull: false,
|
|
@@ -49,11 +49,9 @@ function transformToLineup(lineup, roster) {
|
|
|
49
49
|
function transformToAttributes(tactics, teamId) {
|
|
50
50
|
return {
|
|
51
51
|
team_id: teamId,
|
|
52
|
-
substitution_tolerance: tactics.substitutionTolerance ?? 0,
|
|
53
52
|
receive_rotation_offset: tactics.receiveRotationOffset ?? false,
|
|
54
53
|
lineup: transformFromLineup(tactics.lineup),
|
|
55
54
|
libero_replacements: tactics.liberoReplacements.map((lr) => lr.id),
|
|
56
|
-
pinch_server_subs: Object.fromEntries([...tactics.pinchServerSubs].map(([k, v]) => [k.id, v.id])),
|
|
57
55
|
substitution_band: tactics.substitutionBand,
|
|
58
56
|
second_libero: tactics.secondLibero?.id,
|
|
59
57
|
libero_sub: tactics.liberoSub,
|
|
@@ -83,13 +81,6 @@ function transformToAttributes(tactics, teamId) {
|
|
|
83
81
|
}))
|
|
84
82
|
};
|
|
85
83
|
}
|
|
86
|
-
function buildPinchServerSubs(pinchServerSubs, roster) {
|
|
87
|
-
const map = new Map();
|
|
88
|
-
for (const [key, value] of Object.entries(pinchServerSubs)) {
|
|
89
|
-
map.set(findPlayer(key, roster), findPlayer(value, roster));
|
|
90
|
-
}
|
|
91
|
-
return map;
|
|
92
|
-
}
|
|
93
84
|
function transformToObject(model, roster) {
|
|
94
85
|
const lineup = transformToLineup(model.lineup, roster);
|
|
95
86
|
// A second libero is only valid as a RESERVE: it needs a starting libero (LIBERO_ZONE), the L2 player must be
|
|
@@ -115,11 +106,9 @@ function transformToObject(model, roster) {
|
|
|
115
106
|
? roster.find((p) => p.id === model.second_libero)
|
|
116
107
|
: undefined;
|
|
117
108
|
return service_1.Tactics.create({
|
|
118
|
-
substitutionTolerance: model.substitution_tolerance,
|
|
119
109
|
receiveRotationOffset: model.receive_rotation_offset,
|
|
120
110
|
lineup,
|
|
121
111
|
liberoReplacements: model.libero_replacements.map((lr) => findPlayer(lr, roster)),
|
|
122
|
-
pinchServerSubs: buildPinchServerSubs(model.pinch_server_subs, roster),
|
|
123
112
|
substitutionBand: model.substitution_band,
|
|
124
113
|
secondLibero,
|
|
125
114
|
liberoSub: secondLibero != null ? (model.libero_sub ?? undefined) : undefined,
|
|
@@ -173,9 +162,7 @@ function tacticsColumnsToApiDto(model) {
|
|
|
173
162
|
: undefined;
|
|
174
163
|
return {
|
|
175
164
|
lineup: model.lineup,
|
|
176
|
-
substitutionTolerance: model.substitution_tolerance,
|
|
177
165
|
liberoReplacements: model.libero_replacements,
|
|
178
|
-
pinchServerSubs: model.pinch_server_subs,
|
|
179
166
|
receiveRotationOffset: model.receive_rotation_offset,
|
|
180
167
|
substitutionBand: model.substitution_band,
|
|
181
168
|
secondLibero: validSecondLibero,
|
|
@@ -7,7 +7,6 @@ const service_1 = require("../../service");
|
|
|
7
7
|
function makeTactics(designatedSubs) {
|
|
8
8
|
return {
|
|
9
9
|
team_id: 'team-1',
|
|
10
|
-
substitution_tolerance: 10,
|
|
11
10
|
lineup: {
|
|
12
11
|
[service_1.CourtPosition.LEFT_FRONT]: 'lf',
|
|
13
12
|
[service_1.CourtPosition.MIDDLE_FRONT]: 'mf',
|
|
@@ -18,7 +17,6 @@ function makeTactics(designatedSubs) {
|
|
|
18
17
|
bench: ['b1', 'b2']
|
|
19
18
|
},
|
|
20
19
|
libero_replacements: ['lf'],
|
|
21
|
-
pinch_server_subs: { starter1: 'server1' },
|
|
22
20
|
receive_rotation_offset: true,
|
|
23
21
|
designated_subs: designatedSubs,
|
|
24
22
|
substitution_band: service_1.EnergyBand.TIRED,
|
|
@@ -33,12 +31,10 @@ function makeTactics(designatedSubs) {
|
|
|
33
31
|
(0, globals_1.describe)('tacticsColumnsToApiDto()', () => {
|
|
34
32
|
(0, globals_1.it)('passes scalar/array columns through to the API DTO shape', () => {
|
|
35
33
|
const dto = (0, tactics_1.tacticsColumnsToApiDto)(makeTactics([]));
|
|
36
|
-
(0, globals_1.expect)(dto.substitutionTolerance).toBe(10);
|
|
37
34
|
(0, globals_1.expect)(dto.receiveRotationOffset).toBe(true);
|
|
38
35
|
(0, globals_1.expect)(dto.substitutionBand).toBe(service_1.EnergyBand.TIRED);
|
|
39
36
|
(0, globals_1.expect)(dto.rotationSystem).toBe('5-1');
|
|
40
37
|
(0, globals_1.expect)(dto.liberoReplacements).toEqual(['lf']);
|
|
41
|
-
(0, globals_1.expect)(dto.pinchServerSubs).toEqual({ starter1: 'server1' });
|
|
42
38
|
(0, globals_1.expect)(dto.lineup.bench).toEqual(['b1', 'b2']);
|
|
43
39
|
(0, globals_1.expect)(dto.offensivePreferences).toEqual([{ rotation: 1, order: ['lf', 'rf'] }]);
|
|
44
40
|
});
|
|
@@ -13,10 +13,8 @@ export declare const TacticsInputSchema: z.ZodObject<{
|
|
|
13
13
|
0: z.ZodOptional<z.ZodCustom<Player, Player>>;
|
|
14
14
|
bench: z.ZodArray<z.ZodCustom<Player, Player>>;
|
|
15
15
|
}, z.core.$strip>;
|
|
16
|
-
substitutionTolerance: z.ZodNumber;
|
|
17
16
|
liberoReplacements: z.ZodArray<z.ZodCustom<Player, Player>>;
|
|
18
17
|
receiveRotationOffset: z.ZodDefault<z.ZodBoolean>;
|
|
19
|
-
pinchServerSubs: z.ZodCustom<Map<Player, Player>, Map<Player, Player>>;
|
|
20
18
|
designatedSubs: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
21
19
|
sets: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
22
20
|
mode: z.ZodEnum<{
|
|
@@ -56,12 +56,9 @@ const offensivePreferenceSchema = zod_1.z.object({
|
|
|
56
56
|
});
|
|
57
57
|
exports.TacticsInputSchema = zod_1.z.object({
|
|
58
58
|
lineup: lineupSchema,
|
|
59
|
-
substitutionTolerance: zod_1.z.number().int().min(1).max(50),
|
|
60
59
|
liberoReplacements: zod_1.z.array(playerInstanceSchema),
|
|
61
60
|
// Default false keeps every existing Tactics.create({...}) call (that omits this) valid.
|
|
62
61
|
receiveRotationOffset: zod_1.z.boolean().default(false),
|
|
63
|
-
pinchServerSubs: zod_1.z.custom((v) => v instanceof Map &&
|
|
64
|
-
Array.from(v.entries()).every(([k, val]) => k instanceof player_1.Player && val instanceof player_1.Player), { message: 'INVALID_PINCH_SERVER_SUBS' }),
|
|
65
62
|
// New (designated-subs feature). Defaults keep every existing Tactics.create({...}) call valid.
|
|
66
63
|
designatedSubs: zod_1.z.array(designated_sub_z_1.DesignatedSubSchema).default([]),
|
|
67
64
|
substitutionBand: designated_sub_z_1.SubBandSchema.default(energy_band_1.EnergyBand.TIRED),
|
|
@@ -21,10 +21,8 @@ export declare const TeamInputSchema: z.ZodObject<{
|
|
|
21
21
|
0: z.ZodOptional<z.ZodCustom<Player, Player>>;
|
|
22
22
|
bench: z.ZodArray<z.ZodCustom<Player, Player>>;
|
|
23
23
|
}, z.core.$strip>;
|
|
24
|
-
substitutionTolerance: z.ZodNumber;
|
|
25
24
|
liberoReplacements: z.ZodArray<z.ZodCustom<Player, Player>>;
|
|
26
25
|
receiveRotationOffset: z.ZodDefault<z.ZodBoolean>;
|
|
27
|
-
pinchServerSubs: z.ZodCustom<Map<Player, Player>, Map<Player, Player>>;
|
|
28
26
|
designatedSubs: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
29
27
|
sets: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
30
28
|
mode: z.ZodEnum<{
|
|
@@ -17,9 +17,7 @@ export interface StartingLineup {
|
|
|
17
17
|
}
|
|
18
18
|
export interface TacticsOpts {
|
|
19
19
|
readonly lineup: StartingLineup;
|
|
20
|
-
readonly substitutionTolerance: number;
|
|
21
20
|
readonly liberoReplacements: Player[];
|
|
22
|
-
readonly pinchServerSubs: Map<Player, Player>;
|
|
23
21
|
readonly receiveRotationOffset: boolean;
|
|
24
22
|
readonly designatedSubs: DesignatedSub[];
|
|
25
23
|
readonly substitutionBand: SubBand;
|
|
@@ -32,9 +30,7 @@ export interface TacticsOpts {
|
|
|
32
30
|
}
|
|
33
31
|
export declare class Tactics {
|
|
34
32
|
readonly lineup: StartingLineup;
|
|
35
|
-
readonly substitutionTolerance: number;
|
|
36
33
|
readonly liberoReplacements: Player[];
|
|
37
|
-
readonly pinchServerSubs: Map<Player, Player>;
|
|
38
34
|
readonly receiveRotationOffset: boolean;
|
|
39
35
|
readonly designatedSubs: DesignatedSub[];
|
|
40
36
|
readonly substitutionBand: SubBand;
|
|
@@ -18,10 +18,8 @@ class Tactics {
|
|
|
18
18
|
}
|
|
19
19
|
return new Tactics(result.data);
|
|
20
20
|
}
|
|
21
|
-
constructor({ lineup,
|
|
21
|
+
constructor({ lineup, liberoReplacements, receiveRotationOffset = false, designatedSubs = [], substitutionBand = energy_band_1.EnergyBand.TIRED, secondLibero, liberoSub, liberoReplacementSets, rotationSystem = rotation_system_1.RotationSystemEnum.SIX_ZERO, designatedSetters = [], offensivePreferences = [] }) {
|
|
22
22
|
this.lineup = lineup;
|
|
23
|
-
this.substitutionTolerance = substitutionTolerance;
|
|
24
|
-
this.pinchServerSubs = pinchServerSubs;
|
|
25
23
|
this.liberoReplacements = liberoReplacements;
|
|
26
24
|
this.receiveRotationOffset = receiveRotationOffset;
|
|
27
25
|
this.designatedSubs = designatedSubs;
|
|
@@ -68,8 +68,6 @@ class TeamGenerator {
|
|
|
68
68
|
return tactics_1.Tactics.create({
|
|
69
69
|
lineup,
|
|
70
70
|
liberoReplacements: [lineup[3], lineup[6]],
|
|
71
|
-
pinchServerSubs: new Map(),
|
|
72
|
-
substitutionTolerance: Math.round((0, utils_1.randomNumber)(1, 50)),
|
|
73
71
|
substitutionBand: TeamGenerator.BOT_SUB_BANDS[Math.floor(Math.random() * TeamGenerator.BOT_SUB_BANDS.length)]
|
|
74
72
|
});
|
|
75
73
|
}
|
|
@@ -102,9 +102,7 @@ export interface ApiLiberoSubConfig extends ApiLiberoSetSubConfig {
|
|
|
102
102
|
}
|
|
103
103
|
export interface Tactics {
|
|
104
104
|
lineup: StartingLineup;
|
|
105
|
-
substitutionTolerance: number;
|
|
106
105
|
liberoReplacements: string[];
|
|
107
|
-
pinchServerSubs: Record<string, string>;
|
|
108
106
|
receiveRotationOffset: boolean;
|
|
109
107
|
designatedSubs: ApiDesignatedSub[];
|
|
110
108
|
substitutionBand: SubBand;
|
|
@@ -12,7 +12,6 @@ export interface TacticsLineupAttributes {
|
|
|
12
12
|
[CourtPosition.RIGHT_FRONT]: PlayerId;
|
|
13
13
|
bench: PlayerId[];
|
|
14
14
|
}
|
|
15
|
-
export type PinchServerSubsAttributes = Record<PlayerId, PlayerId>;
|
|
16
15
|
export interface SetSubConfigAttributes {
|
|
17
16
|
mode: SubMode;
|
|
18
17
|
benchId?: PlayerId;
|
|
@@ -45,10 +44,8 @@ export interface LiberoSubConfigAttributes extends LiberoSetSubConfigAttributes
|
|
|
45
44
|
}
|
|
46
45
|
export interface TacticsAttributes {
|
|
47
46
|
team_id: string;
|
|
48
|
-
substitution_tolerance: number;
|
|
49
47
|
lineup: TacticsLineupAttributes;
|
|
50
48
|
libero_replacements: PlayerId[];
|
|
51
|
-
pinch_server_subs: PinchServerSubsAttributes;
|
|
52
49
|
receive_rotation_offset: boolean;
|
|
53
50
|
designated_subs: DesignatedSubAttributes[];
|
|
54
51
|
substitution_band: SubBand;
|
|
@@ -61,14 +58,12 @@ export interface TacticsAttributes {
|
|
|
61
58
|
}
|
|
62
59
|
export type TacticsPk = 'team_id';
|
|
63
60
|
export type TacticsId = TacticsModel[TacticsPk];
|
|
64
|
-
export type TacticsOptionalAttributes = '
|
|
61
|
+
export type TacticsOptionalAttributes = 'lineup' | 'libero_replacements' | 'receive_rotation_offset' | 'designated_subs' | 'substitution_band' | 'second_libero' | 'libero_sub' | 'libero_replacement_sets' | 'rotation_system' | 'designated_setters' | 'offensive_preferences';
|
|
65
62
|
export type TacticsCreationAttributes = Optional<TacticsAttributes, TacticsOptionalAttributes>;
|
|
66
63
|
export declare class TacticsModel extends Model<TacticsAttributes, TacticsCreationAttributes> implements TacticsAttributes {
|
|
67
64
|
team_id: string;
|
|
68
|
-
substitution_tolerance: number;
|
|
69
65
|
lineup: TacticsLineupAttributes;
|
|
70
66
|
libero_replacements: PlayerId[];
|
|
71
|
-
pinch_server_subs: PinchServerSubsAttributes;
|
|
72
67
|
receive_rotation_offset: boolean;
|
|
73
68
|
designated_subs: DesignatedSubAttributes[];
|
|
74
69
|
substitution_band: SubBand;
|
|
@@ -12,11 +12,6 @@ export class TacticsModel extends Model {
|
|
|
12
12
|
key: 'team_id'
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
|
-
substitution_tolerance: {
|
|
16
|
-
type: DataTypes.REAL,
|
|
17
|
-
allowNull: false,
|
|
18
|
-
defaultValue: 0
|
|
19
|
-
},
|
|
20
15
|
lineup: {
|
|
21
16
|
type: DataTypes.JSONB,
|
|
22
17
|
allowNull: false,
|
|
@@ -27,11 +22,6 @@ export class TacticsModel extends Model {
|
|
|
27
22
|
allowNull: false,
|
|
28
23
|
defaultValue: []
|
|
29
24
|
},
|
|
30
|
-
pinch_server_subs: {
|
|
31
|
-
type: DataTypes.JSONB,
|
|
32
|
-
allowNull: false,
|
|
33
|
-
defaultValue: {}
|
|
34
|
-
},
|
|
35
25
|
receive_rotation_offset: {
|
|
36
26
|
type: DataTypes.BOOLEAN,
|
|
37
27
|
allowNull: false,
|
|
@@ -44,11 +44,9 @@ function transformToLineup(lineup, roster) {
|
|
|
44
44
|
function transformToAttributes(tactics, teamId) {
|
|
45
45
|
return {
|
|
46
46
|
team_id: teamId,
|
|
47
|
-
substitution_tolerance: tactics.substitutionTolerance ?? 0,
|
|
48
47
|
receive_rotation_offset: tactics.receiveRotationOffset ?? false,
|
|
49
48
|
lineup: transformFromLineup(tactics.lineup),
|
|
50
49
|
libero_replacements: tactics.liberoReplacements.map((lr) => lr.id),
|
|
51
|
-
pinch_server_subs: Object.fromEntries([...tactics.pinchServerSubs].map(([k, v]) => [k.id, v.id])),
|
|
52
50
|
substitution_band: tactics.substitutionBand,
|
|
53
51
|
second_libero: tactics.secondLibero?.id,
|
|
54
52
|
libero_sub: tactics.liberoSub,
|
|
@@ -78,13 +76,6 @@ function transformToAttributes(tactics, teamId) {
|
|
|
78
76
|
}))
|
|
79
77
|
};
|
|
80
78
|
}
|
|
81
|
-
function buildPinchServerSubs(pinchServerSubs, roster) {
|
|
82
|
-
const map = new Map();
|
|
83
|
-
for (const [key, value] of Object.entries(pinchServerSubs)) {
|
|
84
|
-
map.set(findPlayer(key, roster), findPlayer(value, roster));
|
|
85
|
-
}
|
|
86
|
-
return map;
|
|
87
|
-
}
|
|
88
79
|
function transformToObject(model, roster) {
|
|
89
80
|
const lineup = transformToLineup(model.lineup, roster);
|
|
90
81
|
// A second libero is only valid as a RESERVE: it needs a starting libero (LIBERO_ZONE), the L2 player must be
|
|
@@ -110,11 +101,9 @@ function transformToObject(model, roster) {
|
|
|
110
101
|
? roster.find((p) => p.id === model.second_libero)
|
|
111
102
|
: undefined;
|
|
112
103
|
return Tactics.create({
|
|
113
|
-
substitutionTolerance: model.substitution_tolerance,
|
|
114
104
|
receiveRotationOffset: model.receive_rotation_offset,
|
|
115
105
|
lineup,
|
|
116
106
|
liberoReplacements: model.libero_replacements.map((lr) => findPlayer(lr, roster)),
|
|
117
|
-
pinchServerSubs: buildPinchServerSubs(model.pinch_server_subs, roster),
|
|
118
107
|
substitutionBand: model.substitution_band,
|
|
119
108
|
secondLibero,
|
|
120
109
|
liberoSub: secondLibero != null ? (model.libero_sub ?? undefined) : undefined,
|
|
@@ -168,9 +157,7 @@ function tacticsColumnsToApiDto(model) {
|
|
|
168
157
|
: undefined;
|
|
169
158
|
return {
|
|
170
159
|
lineup: model.lineup,
|
|
171
|
-
substitutionTolerance: model.substitution_tolerance,
|
|
172
160
|
liberoReplacements: model.libero_replacements,
|
|
173
|
-
pinchServerSubs: model.pinch_server_subs,
|
|
174
161
|
receiveRotationOffset: model.receive_rotation_offset,
|
|
175
162
|
substitutionBand: model.substitution_band,
|
|
176
163
|
secondLibero: validSecondLibero,
|
|
@@ -5,7 +5,6 @@ import { CourtPosition, EnergyBand } from '../../service';
|
|
|
5
5
|
function makeTactics(designatedSubs) {
|
|
6
6
|
return {
|
|
7
7
|
team_id: 'team-1',
|
|
8
|
-
substitution_tolerance: 10,
|
|
9
8
|
lineup: {
|
|
10
9
|
[CourtPosition.LEFT_FRONT]: 'lf',
|
|
11
10
|
[CourtPosition.MIDDLE_FRONT]: 'mf',
|
|
@@ -16,7 +15,6 @@ function makeTactics(designatedSubs) {
|
|
|
16
15
|
bench: ['b1', 'b2']
|
|
17
16
|
},
|
|
18
17
|
libero_replacements: ['lf'],
|
|
19
|
-
pinch_server_subs: { starter1: 'server1' },
|
|
20
18
|
receive_rotation_offset: true,
|
|
21
19
|
designated_subs: designatedSubs,
|
|
22
20
|
substitution_band: EnergyBand.TIRED,
|
|
@@ -31,12 +29,10 @@ function makeTactics(designatedSubs) {
|
|
|
31
29
|
describe('tacticsColumnsToApiDto()', () => {
|
|
32
30
|
it('passes scalar/array columns through to the API DTO shape', () => {
|
|
33
31
|
const dto = tacticsColumnsToApiDto(makeTactics([]));
|
|
34
|
-
expect(dto.substitutionTolerance).toBe(10);
|
|
35
32
|
expect(dto.receiveRotationOffset).toBe(true);
|
|
36
33
|
expect(dto.substitutionBand).toBe(EnergyBand.TIRED);
|
|
37
34
|
expect(dto.rotationSystem).toBe('5-1');
|
|
38
35
|
expect(dto.liberoReplacements).toEqual(['lf']);
|
|
39
|
-
expect(dto.pinchServerSubs).toEqual({ starter1: 'server1' });
|
|
40
36
|
expect(dto.lineup.bench).toEqual(['b1', 'b2']);
|
|
41
37
|
expect(dto.offensivePreferences).toEqual([{ rotation: 1, order: ['lf', 'rf'] }]);
|
|
42
38
|
});
|
|
@@ -13,10 +13,8 @@ export declare const TacticsInputSchema: z.ZodObject<{
|
|
|
13
13
|
0: z.ZodOptional<z.ZodCustom<Player, Player>>;
|
|
14
14
|
bench: z.ZodArray<z.ZodCustom<Player, Player>>;
|
|
15
15
|
}, z.core.$strip>;
|
|
16
|
-
substitutionTolerance: z.ZodNumber;
|
|
17
16
|
liberoReplacements: z.ZodArray<z.ZodCustom<Player, Player>>;
|
|
18
17
|
receiveRotationOffset: z.ZodDefault<z.ZodBoolean>;
|
|
19
|
-
pinchServerSubs: z.ZodCustom<Map<Player, Player>, Map<Player, Player>>;
|
|
20
18
|
designatedSubs: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
21
19
|
sets: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
22
20
|
mode: z.ZodEnum<{
|
|
@@ -53,12 +53,9 @@ const offensivePreferenceSchema = z.object({
|
|
|
53
53
|
});
|
|
54
54
|
export const TacticsInputSchema = z.object({
|
|
55
55
|
lineup: lineupSchema,
|
|
56
|
-
substitutionTolerance: z.number().int().min(1).max(50),
|
|
57
56
|
liberoReplacements: z.array(playerInstanceSchema),
|
|
58
57
|
// Default false keeps every existing Tactics.create({...}) call (that omits this) valid.
|
|
59
58
|
receiveRotationOffset: z.boolean().default(false),
|
|
60
|
-
pinchServerSubs: z.custom((v) => v instanceof Map &&
|
|
61
|
-
Array.from(v.entries()).every(([k, val]) => k instanceof Player && val instanceof Player), { message: 'INVALID_PINCH_SERVER_SUBS' }),
|
|
62
59
|
// New (designated-subs feature). Defaults keep every existing Tactics.create({...}) call valid.
|
|
63
60
|
designatedSubs: z.array(DesignatedSubSchema).default([]),
|
|
64
61
|
substitutionBand: SubBandSchema.default(EnergyBand.TIRED),
|
|
@@ -21,10 +21,8 @@ export declare const TeamInputSchema: z.ZodObject<{
|
|
|
21
21
|
0: z.ZodOptional<z.ZodCustom<Player, Player>>;
|
|
22
22
|
bench: z.ZodArray<z.ZodCustom<Player, Player>>;
|
|
23
23
|
}, z.core.$strip>;
|
|
24
|
-
substitutionTolerance: z.ZodNumber;
|
|
25
24
|
liberoReplacements: z.ZodArray<z.ZodCustom<Player, Player>>;
|
|
26
25
|
receiveRotationOffset: z.ZodDefault<z.ZodBoolean>;
|
|
27
|
-
pinchServerSubs: z.ZodCustom<Map<Player, Player>, Map<Player, Player>>;
|
|
28
26
|
designatedSubs: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
29
27
|
sets: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
30
28
|
mode: z.ZodEnum<{
|
|
@@ -17,9 +17,7 @@ export interface StartingLineup {
|
|
|
17
17
|
}
|
|
18
18
|
export interface TacticsOpts {
|
|
19
19
|
readonly lineup: StartingLineup;
|
|
20
|
-
readonly substitutionTolerance: number;
|
|
21
20
|
readonly liberoReplacements: Player[];
|
|
22
|
-
readonly pinchServerSubs: Map<Player, Player>;
|
|
23
21
|
readonly receiveRotationOffset: boolean;
|
|
24
22
|
readonly designatedSubs: DesignatedSub[];
|
|
25
23
|
readonly substitutionBand: SubBand;
|
|
@@ -32,9 +30,7 @@ export interface TacticsOpts {
|
|
|
32
30
|
}
|
|
33
31
|
export declare class Tactics {
|
|
34
32
|
readonly lineup: StartingLineup;
|
|
35
|
-
readonly substitutionTolerance: number;
|
|
36
33
|
readonly liberoReplacements: Player[];
|
|
37
|
-
readonly pinchServerSubs: Map<Player, Player>;
|
|
38
34
|
readonly receiveRotationOffset: boolean;
|
|
39
35
|
readonly designatedSubs: DesignatedSub[];
|
|
40
36
|
readonly substitutionBand: SubBand;
|
|
@@ -15,10 +15,8 @@ export class Tactics {
|
|
|
15
15
|
}
|
|
16
16
|
return new Tactics(result.data);
|
|
17
17
|
}
|
|
18
|
-
constructor({ lineup,
|
|
18
|
+
constructor({ lineup, liberoReplacements, receiveRotationOffset = false, designatedSubs = [], substitutionBand = EnergyBand.TIRED, secondLibero, liberoSub, liberoReplacementSets, rotationSystem = RotationSystemEnum.SIX_ZERO, designatedSetters = [], offensivePreferences = [] }) {
|
|
19
19
|
this.lineup = lineup;
|
|
20
|
-
this.substitutionTolerance = substitutionTolerance;
|
|
21
|
-
this.pinchServerSubs = pinchServerSubs;
|
|
22
20
|
this.liberoReplacements = liberoReplacements;
|
|
23
21
|
this.receiveRotationOffset = receiveRotationOffset;
|
|
24
22
|
this.designatedSubs = designatedSubs;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { v4 as uuidv4 } from 'uuid';
|
|
2
2
|
import { calculateRoleScore, Player, PlayerGenerator, RarityEnum, RoleEnum } from '../player';
|
|
3
|
-
import { generateGenericTeamNames
|
|
3
|
+
import { generateGenericTeamNames } from '../utils';
|
|
4
4
|
import { Team } from './team';
|
|
5
5
|
import { Tactics } from './tactics';
|
|
6
6
|
import { EnergyBand } from './energy-band';
|
|
@@ -62,8 +62,6 @@ export class TeamGenerator {
|
|
|
62
62
|
return Tactics.create({
|
|
63
63
|
lineup,
|
|
64
64
|
liberoReplacements: [lineup[3], lineup[6]],
|
|
65
|
-
pinchServerSubs: new Map(),
|
|
66
|
-
substitutionTolerance: Math.round(randomNumber(1, 50)),
|
|
67
65
|
substitutionBand: TeamGenerator.BOT_SUB_BANDS[Math.floor(Math.random() * TeamGenerator.BOT_SUB_BANDS.length)]
|
|
68
66
|
});
|
|
69
67
|
}
|