volleyballsimtypes 0.0.506 → 0.0.508

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.
@@ -7,4 +7,5 @@ export interface BaseCoord {
7
7
  export interface BaseConfig {
8
8
  readonly coords: Record<string, Record<string, Record<string, BaseCoord>>>;
9
9
  readonly receive: Record<string, Record<string, boolean>>;
10
+ readonly blocking?: Record<string, Record<string, Record<string, boolean>>>;
10
11
  }
@@ -7,84 +7,84 @@ const player_1 = require("../player");
7
7
  const match_1 = require("../match");
8
8
  const COORDS = {
9
9
  SERVE: {
10
- 1: { 1: { d: 9.90, r: 3.15 }, 2: { d: 0.30, r: -2.55 }, 3: { d: 0.40, r: 0.00 }, 4: { d: 0.30, r: 2.55 }, 5: { d: 6.90, r: -0.15 }, 6: { d: 5.20, r: -2.35 } },
11
- 2: { 1: { d: 10.10, r: 3.00 }, 2: { d: 0.45, r: 0.00 }, 3: { d: 0.55, r: 2.95 }, 4: { d: 0.45, r: -2.95 }, 5: { d: 5.20, r: -2.95 }, 6: { d: 5.25, r: 3.35 } },
12
- 3: { 1: { d: 10.45, r: -3.40 }, 2: { d: 0.35, r: 2.70 }, 3: { d: 0.25, r: -3.00 }, 4: { d: 0.30, r: 0.00 }, 5: { d: 5.35, r: 2.55 }, 6: { d: 6.90, r: -0.05 } },
13
- 4: { 1: { d: 10.50, r: 3.40 }, 2: { d: 0.35, r: -3.05 }, 3: { d: 0.45, r: 0.00 }, 4: { d: 0.45, r: 2.55 }, 5: { d: 7.25, r: 0.15 }, 6: { d: 6.25, r: -2.55 } },
14
- 5: { 1: { d: 10.05, r: 3.50 }, 2: { d: 0.30, r: 0.10 }, 3: { d: 0.25, r: 2.85 }, 4: { d: 0.25, r: -2.80 }, 5: { d: 5.10, r: -2.65 }, 6: { d: 5.15, r: 2.70 } },
15
- 6: { 1: { d: 10.30, r: -3.50 }, 2: { d: 0.65, r: 2.60 }, 3: { d: 0.50, r: -2.55 }, 4: { d: 0.55, r: 0.05 }, 5: { d: 6.45, r: 2.65 }, 6: { d: 6.90, r: 0.10 } }
10
+ 1: { 1: { d: 10.00, r: 3.50 }, 2: { d: 0.50, r: -2.50 }, 3: { d: 0.50, r: 0.00 }, 4: { d: 0.50, r: 2.50 }, 5: { d: 6.50, r: 0.00 }, 6: { d: 5.00, r: -2.50 } },
11
+ 2: { 1: { d: 10.00, r: 3.50 }, 2: { d: 0.50, r: 0.00 }, 3: { d: 0.50, r: 2.50 }, 4: { d: 0.50, r: -2.50 }, 5: { d: 5.00, r: -2.50 }, 6: { d: 5.00, r: 2.50 } },
12
+ 3: { 1: { d: 10.00, r: -3.50 }, 2: { d: 0.50, r: 2.50 }, 3: { d: 0.50, r: -2.50 }, 4: { d: 0.50, r: 0.00 }, 5: { d: 5.00, r: 2.50 }, 6: { d: 6.50, r: 0.00 } },
13
+ 4: { 1: { d: 10.00, r: 3.50 }, 2: { d: 0.50, r: -2.50 }, 3: { d: 0.50, r: 0.00 }, 4: { d: 0.50, r: 2.50 }, 5: { d: 6.50, r: 0.00 }, 6: { d: 5.00, r: -2.50 } },
14
+ 5: { 1: { d: 10.00, r: 3.50 }, 2: { d: 0.50, r: 0.00 }, 3: { d: 0.50, r: 2.50 }, 4: { d: 0.50, r: -2.50 }, 5: { d: 5.00, r: -2.50 }, 6: { d: 5.00, r: 2.50 } },
15
+ 6: { 1: { d: 10.00, r: -3.50 }, 2: { d: 0.50, r: 2.50 }, 3: { d: 0.50, r: -2.50 }, 4: { d: 0.50, r: 0.00 }, 5: { d: 5.00, r: 2.50 }, 6: { d: 6.50, r: 0.00 } }
16
16
  },
17
17
  RECEIVE: {
18
- 1: { 1: { d: 6.75, r: 2.85 }, 2: { d: 6.25, r: 2.05 }, 3: { d: 3.10, r: -3.65 }, 4: { d: 3.80, r: -4.10 }, 5: { d: 6.40, r: -2.80 }, 6: { d: 6.50, r: 0.00 } },
19
- 2: { 1: { d: 6.00, r: 2.50 }, 2: { d: 3.15, r: 4.00 }, 3: { d: 0.50, r: 0.40 }, 4: { d: 5.85, r: -2.85 }, 5: { d: 6.20, r: -0.05 }, 6: { d: 1.50, r: 0.65 } },
20
- 3: { 1: { d: 6.10, r: 2.55 }, 2: { d: 3.15, r: 4.10 }, 3: { d: 6.50, r: -2.80 }, 4: { d: 0.80, r: -3.70 }, 5: { d: 1.10, r: -1.00 }, 6: { d: 6.65, r: -0.10 } },
21
- 4: { 1: { d: 8.45, r: 3.20 }, 2: { d: 6.25, r: -2.85 }, 3: { d: 1.35, r: -3.70 }, 4: { d: 0.50, r: -4.05 }, 5: { d: 6.75, r: -0.35 }, 6: { d: 6.55, r: 2.40 } },
22
- 5: { 1: { d: 5.90, r: 2.65 }, 2: { d: 2.60, r: 3.90 }, 3: { d: 0.65, r: 1.50 }, 4: { d: 6.05, r: -3.05 }, 5: { d: 6.10, r: 0.10 }, 6: { d: 8.45, r: 0.65 } },
23
- 6: { 1: { d: 6.25, r: 2.60 }, 2: { d: 0.80, r: 1.50 }, 3: { d: 6.40, r: -2.60 }, 4: { d: 3.30, r: -4.30 }, 5: { d: 8.65, r: -2.15 }, 6: { d: 6.70, r: 0.00 } }
18
+ 1: { 1: { d: 6.50, r: 3.50 }, 2: { d: 6.00, r: 3.00 }, 3: { d: 3.00, r: -3.50 }, 4: { d: 3.50, r: -4.00 }, 5: { d: 6.00, r: -3.00 }, 6: { d: 6.50, r: 0.00 } },
19
+ 2: { 1: { d: 6.00, r: 3.00 }, 2: { d: 3.00, r: 4.00 }, 3: { d: 0.50, r: 0.50 }, 4: { d: 6.00, r: -3.00 }, 5: { d: 6.50, r: 0.00 }, 6: { d: 1.25, r: 0.75 } },
20
+ 3: { 1: { d: 6.00, r: 3.00 }, 2: { d: 3.00, r: 4.00 }, 3: { d: 6.00, r: -3.00 }, 4: { d: 0.95, r: -4.00 }, 5: { d: 1.00, r: -1.00 }, 6: { d: 6.50, r: 0.00 } },
21
+ 4: { 1: { d: 8.50, r: 4.00 }, 2: { d: 6.00, r: -3.00 }, 3: { d: 1.25, r: -4.00 }, 4: { d: 0.75, r: -4.05 }, 5: { d: 6.50, r: 0.00 }, 6: { d: 6.00, r: 3.00 } },
22
+ 5: { 1: { d: 6.00, r: 3.00 }, 2: { d: 2.50, r: 4.00 }, 3: { d: 1.00, r: 1.50 }, 4: { d: 6.00, r: -3.00 }, 5: { d: 6.50, r: 0.00 }, 6: { d: 8.50, r: 1.50 } },
23
+ 6: { 1: { d: 6.00, r: 3.00 }, 2: { d: 1.00, r: 1.50 }, 3: { d: 6.00, r: -3.00 }, 4: { d: 3.00, r: -4.00 }, 5: { d: 8.50, r: -1.50 }, 6: { d: 6.50, r: 0.00 } }
24
24
  },
25
25
  DEFENCE: {
26
- 1: { 1: { d: 5.95, r: 2.65 }, 2: { d: 0.55, r: -2.95 }, 3: { d: 0.50, r: -0.20 }, 4: { d: 0.45, r: 2.70 }, 5: { d: 6.30, r: -0.30 }, 6: { d: 5.90, r: -3.15 } },
27
- 2: { 1: { d: 6.30, r: -0.40 }, 2: { d: 0.05, r: -0.10 }, 3: { d: 0.05, r: 2.70 }, 4: { d: 0.05, r: -2.85 }, 5: { d: 5.50, r: -3.00 }, 6: { d: 5.55, r: 2.80 } },
28
- 3: { 1: { d: 5.25, r: -2.65 }, 2: { d: 0.05, r: 3.05 }, 3: { d: 0.05, r: -2.80 }, 4: { d: 0.05, r: 0.30 }, 5: { d: 5.35, r: 2.95 }, 6: { d: 6.45, r: 0.20 } },
29
- 4: { 1: { d: 6.00, r: 2.90 }, 2: { d: 0.35, r: -3.10 }, 3: { d: 0.25, r: -0.05 }, 4: { d: 0.35, r: 3.10 }, 5: { d: 6.35, r: -0.10 }, 6: { d: 6.00, r: -2.60 } },
30
- 5: { 1: { d: 6.30, r: 0.00 }, 2: { d: 0.10, r: -0.05 }, 3: { d: 0.05, r: 3.00 }, 4: { d: 0.05, r: -3.05 }, 5: { d: 5.90, r: -2.90 }, 6: { d: 6.15, r: 3.25 } },
31
- 6: { 1: { d: 5.70, r: -2.85 }, 2: { d: 0.55, r: 2.50 }, 3: { d: 0.50, r: -2.95 }, 4: { d: 0.50, r: -0.25 }, 5: { d: 5.80, r: 2.90 }, 6: { d: 6.95, r: 0.00 } }
26
+ 1: { 1: { d: 5.00, r: 3.00 }, 2: { d: 0.50, r: -2.50 }, 3: { d: 0.50, r: 0.00 }, 4: { d: 0.50, r: 2.50 }, 5: { d: 7.00, r: 0.00 }, 6: { d: 5.00, r: -3.00 } },
27
+ 2: { 1: { d: 7.00, r: 0.00 }, 2: { d: 0.50, r: 0.00 }, 3: { d: 0.50, r: 2.50 }, 4: { d: 0.50, r: -2.50 }, 5: { d: 5.00, r: -3.00 }, 6: { d: 5.00, r: 3.00 } },
28
+ 3: { 1: { d: 5.00, r: -3.00 }, 2: { d: 0.50, r: 2.50 }, 3: { d: 0.50, r: -2.50 }, 4: { d: 0.50, r: 0.00 }, 5: { d: 5.00, r: 3.00 }, 6: { d: 7.00, r: 0.00 } },
29
+ 4: { 1: { d: 5.00, r: 3.00 }, 2: { d: 0.50, r: -2.50 }, 3: { d: 0.50, r: 0.00 }, 4: { d: 0.50, r: 2.50 }, 5: { d: 7.00, r: 0.00 }, 6: { d: 5.00, r: -3.00 } },
30
+ 5: { 1: { d: 7.00, r: 0.00 }, 2: { d: 0.50, r: 0.00 }, 3: { d: 0.50, r: 2.50 }, 4: { d: 0.50, r: -2.50 }, 5: { d: 5.00, r: -3.00 }, 6: { d: 5.00, r: 3.00 } },
31
+ 6: { 1: { d: 5.00, r: -3.00 }, 2: { d: 0.50, r: 2.50 }, 3: { d: 0.50, r: -2.50 }, 4: { d: 0.50, r: 0.00 }, 5: { d: 5.00, r: 3.00 }, 6: { d: 7.00, r: 0.00 } }
32
32
  },
33
33
  DEF_L: {
34
- 1: { 1: { d: 5.80, r: 1.50 }, 2: { d: 0.05, r: -3.40 }, 3: { d: 0.05, r: -2.85 }, 4: { d: 1.80, r: 1.30 }, 5: { d: 8.00, r: 0.65 }, 6: { d: 4.50, r: -4.20 } },
35
- 2: { 1: { d: 7.95, r: 0.70 }, 2: { d: 0.05, r: -2.85 }, 3: { d: 1.80, r: 1.30 }, 4: { d: 0.10, r: -3.40 }, 5: { d: 4.50, r: -4.20 }, 6: { d: 5.80, r: 1.50 } },
36
- 3: { 1: { d: 0.05, r: -2.85 }, 2: { d: 1.80, r: 1.30 }, 3: { d: 0.05, r: -3.45 }, 4: { d: 4.50, r: -4.20 }, 5: { d: 5.80, r: 1.50 }, 6: { d: 8.05, r: 0.70 } },
37
- 4: { 1: { d: 5.85, r: 1.50 }, 2: { d: 0.05, r: -3.45 }, 3: { d: 4.50, r: -4.20 }, 4: { d: 1.80, r: 1.30 }, 5: { d: 8.00, r: 0.95 }, 6: { d: 0.05, r: -2.85 } },
38
- 5: { 1: { d: 8.10, r: 0.80 }, 2: { d: 4.50, r: -4.20 }, 3: { d: 1.80, r: 1.30 }, 4: { d: 0.05, r: -3.45 }, 5: { d: 0.05, r: -2.85 }, 6: { d: 5.85, r: 1.50 } },
39
- 6: { 1: { d: 4.50, r: -4.20 }, 2: { d: 1.80, r: 1.30 }, 3: { d: 0.05, r: -3.45 }, 4: { d: 0.05, r: -2.85 }, 5: { d: 5.85, r: 1.50 }, 6: { d: 8.10, r: 0.80 } }
34
+ 1: { 1: { d: 5.00, r: 1.50 }, 2: { d: 0.25, r: -4.00 }, 3: { d: 0.25, r: -3.25 }, 4: { d: 1.75, r: 1.25 }, 5: { d: 8.00, r: -0.50 }, 6: { d: 5.00, r: -4.20 } },
35
+ 2: { 1: { d: 8.00, r: -0.50 }, 2: { d: 0.25, r: -3.25 }, 3: { d: 1.75, r: 1.25 }, 4: { d: 0.25, r: -4.00 }, 5: { d: 5.00, r: -4.20 }, 6: { d: 5.00, r: 1.50 } },
36
+ 3: { 1: { d: 5.00, r: -4.20 }, 2: { d: 1.75, r: 1.25 }, 3: { d: 0.25, r: -4.00 }, 4: { d: 0.25, r: -3.25 }, 5: { d: 5.00, r: 1.50 }, 6: { d: 8.00, r: -0.50 } },
37
+ 4: { 1: { d: 5.00, r: 1.50 }, 2: { d: 0.25, r: -4.00 }, 3: { d: 0.25, r: -3.25 }, 4: { d: 1.75, r: 1.25 }, 5: { d: 8.00, r: -0.50 }, 6: { d: 5.00, r: -4.20 } },
38
+ 5: { 1: { d: 8.00, r: -0.50 }, 2: { d: 0.25, r: -3.25 }, 3: { d: 1.75, r: 1.25 }, 4: { d: 0.25, r: -4.00 }, 5: { d: 5.00, r: -4.20 }, 6: { d: 5.00, r: 1.50 } },
39
+ 6: { 1: { d: 5.00, r: -4.20 }, 2: { d: 1.75, r: 1.25 }, 3: { d: 0.25, r: -4.00 }, 4: { d: 0.25, r: -3.25 }, 5: { d: 5.00, r: 1.50 }, 6: { d: 8.00, r: -0.50 } }
40
40
  },
41
41
  DEF_M: {
42
- 1: { 1: { d: 4.95, r: 2.35 }, 2: { d: 1.70, r: -2.60 }, 3: { d: 0.05, r: -0.15 }, 4: { d: 2.00, r: 2.80 }, 5: { d: 7.20, r: 1.00 }, 6: { d: 4.70, r: -2.35 } },
43
- 2: { 1: { d: 7.15, r: 1.00 }, 2: { d: 0.05, r: -0.15 }, 3: { d: 2.00, r: 2.80 }, 4: { d: 1.70, r: -2.60 }, 5: { d: 4.70, r: -2.35 }, 6: { d: 4.95, r: 2.35 } },
44
- 3: { 1: { d: 4.95, r: -2.35 }, 2: { d: 2.00, r: 2.80 }, 3: { d: 2.35, r: -2.65 }, 4: { d: 0.05, r: 0.00 }, 5: { d: 4.95, r: 2.35 }, 6: { d: 7.00, r: 1.20 } },
45
- 4: { 1: { d: 4.95, r: 2.15 }, 2: { d: 1.70, r: -2.60 }, 3: { d: 0.15, r: -0.10 }, 4: { d: 2.00, r: 2.85 }, 5: { d: 7.15, r: 1.00 }, 6: { d: 4.95, r: -2.25 } },
46
- 5: { 1: { d: 7.25, r: 1.10 }, 2: { d: 0.05, r: 0.00 }, 3: { d: 1.95, r: 2.60 }, 4: { d: 1.70, r: -2.50 }, 5: { d: 4.85, r: -2.05 }, 6: { d: 5.00, r: 2.15 } },
47
- 6: { 1: { d: 4.70, r: -2.35 }, 2: { d: 2.00, r: 2.75 }, 3: { d: 1.80, r: -2.65 }, 4: { d: 0.05, r: -0.15 }, 5: { d: 4.80, r: 2.40 }, 6: { d: 7.40, r: 1.00 } }
42
+ 1: { 1: { d: 5.00, r: 2.50 }, 2: { d: 1.75, r: -2.50 }, 3: { d: 0.25, r: 0.00 }, 4: { d: 1.75, r: 2.50 }, 5: { d: 7.00, r: 0.00 }, 6: { d: 5.00, r: -2.50 } },
43
+ 2: { 1: { d: 7.00, r: 0.00 }, 2: { d: 0.25, r: 0.00 }, 3: { d: 1.75, r: 2.50 }, 4: { d: 1.75, r: -2.50 }, 5: { d: 5.00, r: -2.50 }, 6: { d: 5.00, r: 2.50 } },
44
+ 3: { 1: { d: 5.00, r: -2.50 }, 2: { d: 1.75, r: 2.50 }, 3: { d: 1.75, r: -2.50 }, 4: { d: 0.25, r: 0.00 }, 5: { d: 5.00, r: 2.50 }, 6: { d: 7.00, r: 0.00 } },
45
+ 4: { 1: { d: 5.00, r: 2.50 }, 2: { d: 1.75, r: -2.50 }, 3: { d: 0.25, r: 0.00 }, 4: { d: 1.75, r: 2.50 }, 5: { d: 7.00, r: 0.00 }, 6: { d: 5.00, r: -2.50 } },
46
+ 5: { 1: { d: 7.00, r: 0.00 }, 2: { d: 0.25, r: 0.00 }, 3: { d: 1.75, r: 2.50 }, 4: { d: 1.75, r: -2.50 }, 5: { d: 5.00, r: -2.50 }, 6: { d: 5.00, r: 2.50 } },
47
+ 6: { 1: { d: 5.00, r: -2.50 }, 2: { d: 1.75, r: 2.50 }, 3: { d: 1.75, r: -2.50 }, 4: { d: 0.25, r: 0.00 }, 5: { d: 5.00, r: 2.50 }, 6: { d: 7.00, r: 0.00 } }
48
48
  },
49
49
  DEF_R: {
50
- 1: { 1: { d: 4.45, r: 4.20 }, 2: { d: 1.90, r: -1.50 }, 3: { d: 0.10, r: 2.90 }, 4: { d: 0.10, r: 3.45 }, 5: { d: 8.80, r: 0.45 }, 6: { d: 5.25, r: -1.45 } },
51
- 2: { 1: { d: 8.55, r: -0.65 }, 2: { d: 0.05, r: 2.90 }, 3: { d: 0.05, r: 3.50 }, 4: { d: 2.00, r: -2.20 }, 5: { d: 4.80, r: -1.60 }, 6: { d: 4.50, r: 4.15 } },
52
- 3: { 1: { d: 4.75, r: -1.70 }, 2: { d: 0.05, r: 3.45 }, 3: { d: 1.60, r: -1.75 }, 4: { d: 0.05, r: 2.85 }, 5: { d: 4.55, r: 4.15 }, 6: { d: 8.40, r: -0.35 } },
53
- 4: { 1: { d: 5.20, r: 4.15 }, 2: { d: 1.75, r: -1.85 }, 3: { d: 0.05, r: 3.20 }, 4: { d: 0.05, r: 3.75 }, 5: { d: 8.45, r: -0.65 }, 6: { d: 5.15, r: -1.85 } },
54
- 5: { 1: { d: 8.35, r: -0.75 }, 2: { d: 0.05, r: 2.90 }, 3: { d: 0.05, r: 3.50 }, 4: { d: 1.80, r: -1.25 }, 5: { d: 5.25, r: -1.70 }, 6: { d: 5.00, r: 4.15 } },
55
- 6: { 1: { d: 5.15, r: -1.50 }, 2: { d: 0.05, r: 3.45 }, 3: { d: 2.55, r: -2.40 }, 4: { d: 0.05, r: 2.90 }, 5: { d: 4.60, r: 4.10 }, 6: { d: 8.75, r: 0.25 } }
50
+ 1: { 1: { d: 5.00, r: 4.20 }, 2: { d: 1.75, r: -1.25 }, 3: { d: 0.25, r: 3.25 }, 4: { d: 0.25, r: 4.00 }, 5: { d: 8.00, r: 0.50 }, 6: { d: 5.00, r: -1.50 } },
51
+ 2: { 1: { d: 8.00, r: 0.50 }, 2: { d: 0.25, r: 3.25 }, 3: { d: 0.25, r: 4.00 }, 4: { d: 1.75, r: -1.25 }, 5: { d: 5.00, r: -1.50 }, 6: { d: 5.00, r: 4.20 } },
52
+ 3: { 1: { d: 5.00, r: -1.50 }, 2: { d: 0.25, r: 4.00 }, 3: { d: 1.75, r: -1.25 }, 4: { d: 0.25, r: 3.25 }, 5: { d: 5.00, r: 4.20 }, 6: { d: 8.00, r: 0.50 } },
53
+ 4: { 1: { d: 5.00, r: 4.20 }, 2: { d: 1.75, r: -1.25 }, 3: { d: 0.25, r: 3.25 }, 4: { d: 0.25, r: 4.00 }, 5: { d: 8.00, r: 0.50 }, 6: { d: 5.00, r: -1.50 } },
54
+ 5: { 1: { d: 8.00, r: 0.50 }, 2: { d: 0.25, r: 3.25 }, 3: { d: 0.25, r: 4.00 }, 4: { d: 1.75, r: -1.25 }, 5: { d: 5.00, r: -1.50 }, 6: { d: 5.00, r: 4.20 } },
55
+ 6: { 1: { d: 5.00, r: -1.50 }, 2: { d: 0.25, r: 4.00 }, 3: { d: 1.75, r: -1.25 }, 4: { d: 0.25, r: 3.25 }, 5: { d: 5.00, r: 4.20 }, 6: { d: 8.00, r: 0.50 } }
56
56
  },
57
57
  ATTACK: {
58
- 1: { 1: { d: 0.50, r: 1.55 }, 2: { d: 3.40, r: -5.15 }, 3: { d: 1.15, r: 0.40 }, 4: { d: 4.80, r: 5.20 }, 5: { d: 6.50, r: 0.20 }, 6: { d: 4.85, r: -2.90 } },
59
- 2: { 1: { d: 6.50, r: -0.40 }, 2: { d: 1.60, r: 0.75 }, 3: { d: 3.65, r: 5.05 }, 4: { d: 3.50, r: -5.05 }, 5: { d: 4.45, r: -2.60 }, 6: { d: 0.50, r: 1.60 } },
60
- 3: { 1: { d: 5.05, r: -1.90 }, 2: { d: 3.95, r: 5.00 }, 3: { d: 3.95, r: -4.90 }, 4: { d: 1.80, r: 1.10 }, 5: { d: 0.35, r: 1.55 }, 6: { d: 6.45, r: 0.15 } },
61
- 4: { 1: { d: 6.15, r: 4.95 }, 2: { d: 3.95, r: -5.05 }, 3: { d: 1.45, r: 1.05 }, 4: { d: 0.45, r: 1.80 }, 5: { d: 6.45, r: -0.50 }, 6: { d: 4.95, r: -2.00 } },
62
- 5: { 1: { d: 6.50, r: -0.40 }, 2: { d: 1.80, r: 1.10 }, 3: { d: 0.25, r: 1.85 }, 4: { d: 3.45, r: -4.95 }, 5: { d: 5.35, r: -2.55 }, 6: { d: 6.50, r: 4.90 } },
63
- 6: { 1: { d: 5.85, r: -2.20 }, 2: { d: 0.55, r: 2.00 }, 3: { d: 4.00, r: -4.85 }, 4: { d: 1.35, r: 1.40 }, 5: { d: 6.85, r: 4.90 }, 6: { d: 6.60, r: 0.35 } }
58
+ 1: { 1: { d: 0.50, r: 1.50 }, 2: { d: 3.75, r: -5.00 }, 3: { d: 3.00, r: 0.25 }, 4: { d: 3.75, r: 5.00 }, 5: { d: 6.50, r: 0.00 }, 6: { d: 4.50, r: -2.50 } },
59
+ 2: { 1: { d: 6.50, r: 0.00 }, 2: { d: 3.00, r: 0.25 }, 3: { d: 3.75, r: 5.00 }, 4: { d: 3.75, r: -5.00 }, 5: { d: 4.50, r: -2.50 }, 6: { d: 0.50, r: 1.50 } },
60
+ 3: { 1: { d: 4.50, r: -2.50 }, 2: { d: 3.75, r: 5.00 }, 3: { d: 3.75, r: -5.00 }, 4: { d: 3.00, r: 0.25 }, 5: { d: 0.50, r: 1.50 }, 6: { d: 6.50, r: 0.00 } },
61
+ 4: { 1: { d: 6.50, r: 4.90 }, 2: { d: 3.75, r: -5.00 }, 3: { d: 3.00, r: 0.25 }, 4: { d: 0.50, r: 1.50 }, 5: { d: 6.50, r: 0.00 }, 6: { d: 4.50, r: -2.50 } },
62
+ 5: { 1: { d: 6.50, r: 0.00 }, 2: { d: 3.00, r: 0.25 }, 3: { d: 0.50, r: 1.50 }, 4: { d: 3.75, r: -5.00 }, 5: { d: 4.50, r: -2.50 }, 6: { d: 6.50, r: 4.90 } },
63
+ 6: { 1: { d: 4.50, r: -2.50 }, 2: { d: 0.50, r: 1.50 }, 3: { d: 3.75, r: -5.00 }, 4: { d: 3.00, r: 0.25 }, 5: { d: 6.50, r: 4.90 }, 6: { d: 6.50, r: 0.00 } }
64
64
  },
65
65
  ATK_L: {
66
- 1: { 1: { d: 0.75, r: 0.10 }, 2: { d: 0.50, r: -4.05 }, 3: { d: 0.95, r: -2.55 }, 4: { d: 3.45, r: 0.80 }, 5: { d: 6.25, r: -0.75 }, 6: { d: 3.60, r: -3.95 } },
67
- 2: { 1: { d: 0.50, r: -4.05 }, 2: { d: 0.95, r: -2.55 }, 3: { d: 3.75, r: 1.05 }, 4: { d: 6.25, r: -0.75 }, 5: { d: 3.60, r: -3.95 }, 6: { d: 0.75, r: 0.10 } },
68
- 3: { 1: { d: 0.95, r: -2.55 }, 2: { d: 3.45, r: 0.80 }, 3: { d: 6.25, r: -0.75 }, 4: { d: 3.60, r: -3.95 }, 5: { d: 0.75, r: 0.10 }, 6: { d: 0.50, r: -4.05 } },
69
- 4: { 1: { d: 3.60, r: 0.90 }, 2: { d: 0.55, r: -4.05 }, 3: { d: 1.15, r: -2.60 }, 4: { d: 0.85, r: 0.25 }, 5: { d: 6.25, r: -0.80 }, 6: { d: 3.45, r: -4.10 } },
70
- 5: { 1: { d: 6.25, r: -0.65 }, 2: { d: 1.20, r: -2.55 }, 3: { d: 0.80, r: 0.10 }, 4: { d: 0.50, r: -4.10 }, 5: { d: 3.90, r: -4.00 }, 6: { d: 3.75, r: 0.80 } },
71
- 6: { 1: { d: 3.60, r: -3.95 }, 2: { d: 0.75, r: 0.10 }, 3: { d: 0.50, r: -4.05 }, 4: { d: 0.95, r: -2.55 }, 5: { d: 3.45, r: 0.80 }, 6: { d: 6.25, r: -0.75 } }
66
+ 1: { 1: { d: 0.75, r: 0.00 }, 2: { d: 0.50, r: -4.00 }, 3: { d: 1.00, r: -2.50 }, 4: { d: 3.50, r: 0.75 }, 5: { d: 6.25, r: -0.75 }, 6: { d: 3.50, r: -4.00 } },
67
+ 2: { 1: { d: 6.25, r: -0.75 }, 2: { d: 1.00, r: -2.50 }, 3: { d: 3.50, r: 0.75 }, 4: { d: 0.50, r: -4.00 }, 5: { d: 3.50, r: -4.00 }, 6: { d: 0.75, r: 0.00 } },
68
+ 3: { 1: { d: 3.50, r: -4.00 }, 2: { d: 3.50, r: 0.75 }, 3: { d: 0.50, r: -4.00 }, 4: { d: 1.00, r: -2.50 }, 5: { d: 0.75, r: 0.00 }, 6: { d: 6.25, r: -0.75 } },
69
+ 4: { 1: { d: 3.50, r: 0.75 }, 2: { d: 0.50, r: -4.00 }, 3: { d: 1.00, r: -2.50 }, 4: { d: 0.75, r: 0.00 }, 5: { d: 6.25, r: -0.75 }, 6: { d: 3.50, r: -4.00 } },
70
+ 5: { 1: { d: 6.25, r: -0.75 }, 2: { d: 1.00, r: -2.50 }, 3: { d: 0.75, r: 0.00 }, 4: { d: 0.50, r: -4.00 }, 5: { d: 3.50, r: -4.00 }, 6: { d: 3.50, r: 0.75 } },
71
+ 6: { 1: { d: 3.50, r: -4.00 }, 2: { d: 0.75, r: 0.00 }, 3: { d: 0.50, r: -4.00 }, 4: { d: 1.00, r: -2.50 }, 5: { d: 3.50, r: 0.75 }, 6: { d: 6.25, r: -0.75 } }
72
72
  },
73
73
  ATK_M: {
74
- 1: { 1: { d: 0.60, r: 1.25 }, 2: { d: 1.20, r: -2.00 }, 3: { d: 0.70, r: 0.50 }, 4: { d: 2.25, r: 2.60 }, 5: { d: 6.40, r: 1.40 }, 6: { d: 4.05, r: -1.55 } },
75
- 2: { 1: { d: 6.65, r: 1.55 }, 2: { d: 0.70, r: 0.50 }, 3: { d: 2.25, r: 2.60 }, 4: { d: 1.40, r: -1.90 }, 5: { d: 4.05, r: -1.55 }, 6: { d: 0.60, r: 1.25 } },
76
- 3: { 1: { d: 4.05, r: -1.55 }, 2: { d: 2.25, r: 2.60 }, 3: { d: 1.20, r: -2.00 }, 4: { d: 0.70, r: 0.45 }, 5: { d: 0.65, r: 1.15 }, 6: { d: 6.40, r: 1.40 } },
77
- 4: { 1: { d: 2.25, r: 2.60 }, 2: { d: 1.35, r: -1.90 }, 3: { d: 0.65, r: 0.50 }, 4: { d: 0.60, r: 1.25 }, 5: { d: 6.40, r: 1.45 }, 6: { d: 4.15, r: -1.45 } },
78
- 5: { 1: { d: 6.40, r: 1.40 }, 2: { d: 0.65, r: 0.50 }, 3: { d: 0.60, r: 1.25 }, 4: { d: 1.20, r: -2.00 }, 5: { d: 4.15, r: -1.40 }, 6: { d: 2.25, r: 2.60 } },
79
- 6: { 1: { d: 4.05, r: -1.55 }, 2: { d: 0.60, r: 1.25 }, 3: { d: 1.20, r: -2.00 }, 4: { d: 0.70, r: 0.50 }, 5: { d: 2.25, r: 2.60 }, 6: { d: 6.40, r: 1.40 } }
74
+ 1: { 1: { d: 0.75, r: 1.25 }, 2: { d: 1.25, r: -2.00 }, 3: { d: 0.75, r: 0.50 }, 4: { d: 2.25, r: 2.60 }, 5: { d: 6.50, r: 1.50 }, 6: { d: 4.00, r: -1.50 } },
75
+ 2: { 1: { d: 6.50, r: 1.50 }, 2: { d: 0.75, r: 0.50 }, 3: { d: 2.25, r: 2.60 }, 4: { d: 1.25, r: -2.00 }, 5: { d: 4.00, r: -1.50 }, 6: { d: 0.75, r: 1.25 } },
76
+ 3: { 1: { d: 4.00, r: -1.50 }, 2: { d: 2.25, r: 2.60 }, 3: { d: 1.25, r: -2.00 }, 4: { d: 0.75, r: 0.50 }, 5: { d: 0.75, r: 1.25 }, 6: { d: 6.50, r: 1.50 } },
77
+ 4: { 1: { d: 2.25, r: 2.60 }, 2: { d: 1.25, r: -2.00 }, 3: { d: 0.75, r: 0.50 }, 4: { d: 0.75, r: 1.25 }, 5: { d: 6.50, r: 1.50 }, 6: { d: 4.00, r: -1.50 } },
78
+ 5: { 1: { d: 6.50, r: 1.50 }, 2: { d: 0.75, r: 0.50 }, 3: { d: 0.75, r: 1.25 }, 4: { d: 1.25, r: -2.00 }, 5: { d: 4.00, r: -1.50 }, 6: { d: 2.25, r: 2.60 } },
79
+ 6: { 1: { d: 4.00, r: -1.50 }, 2: { d: 0.75, r: 1.25 }, 3: { d: 1.25, r: -2.00 }, 4: { d: 0.75, r: 0.50 }, 5: { d: 2.25, r: 2.60 }, 6: { d: 6.50, r: 1.50 } }
80
80
  },
81
81
  ATK_R: {
82
- 1: { 1: { d: 1.75, r: 2.60 }, 2: { d: 1.60, r: -1.75 }, 3: { d: 0.75, r: 1.80 }, 4: { d: 0.60, r: 3.90 }, 5: { d: 4.90, r: 3.25 }, 6: { d: 5.85, r: -1.90 } },
83
- 2: { 1: { d: 5.15, r: 3.20 }, 2: { d: 0.75, r: 1.80 }, 3: { d: 0.60, r: 3.90 }, 4: { d: 1.60, r: -1.40 }, 5: { d: 5.85, r: -1.90 }, 6: { d: 1.75, r: 2.60 } },
84
- 3: { 1: { d: 6.05, r: -2.00 }, 2: { d: 0.60, r: 3.90 }, 3: { d: 1.55, r: -1.55 }, 4: { d: 0.75, r: 1.70 }, 5: { d: 1.75, r: 2.60 }, 6: { d: 5.05, r: 3.15 } },
85
- 4: { 1: { d: 2.25, r: 4.20 }, 2: { d: 2.40, r: -1.65 }, 3: { d: 0.85, r: 1.40 }, 4: { d: 1.40, r: 2.30 }, 5: { d: 6.00, r: 1.85 }, 6: { d: 5.25, r: -0.90 } },
86
- 5: { 1: { d: 5.95, r: 2.35 }, 2: { d: 0.85, r: 1.40 }, 3: { d: 1.40, r: 2.30 }, 4: { d: 2.20, r: -1.80 }, 5: { d: 5.25, r: -0.90 }, 6: { d: 2.25, r: 4.20 } },
87
- 6: { 1: { d: 5.30, r: -0.90 }, 2: { d: 1.45, r: 2.30 }, 3: { d: 2.25, r: -1.80 }, 4: { d: 0.75, r: 1.40 }, 5: { d: 2.25, r: 4.05 }, 6: { d: 5.90, r: 2.35 } }
82
+ 1: { 1: { d: 1.75, r: 2.50 }, 2: { d: 1.50, r: -1.75 }, 3: { d: 0.75, r: 1.75 }, 4: { d: 0.50, r: 4.00 }, 5: { d: 5.00, r: 3.25 }, 6: { d: 5.75, r: -2.00 } },
83
+ 2: { 1: { d: 5.00, r: 3.25 }, 2: { d: 0.75, r: 1.75 }, 3: { d: 0.50, r: 4.00 }, 4: { d: 1.50, r: -1.75 }, 5: { d: 5.75, r: -2.00 }, 6: { d: 1.75, r: 2.50 } },
84
+ 3: { 1: { d: 5.75, r: -2.00 }, 2: { d: 0.50, r: 4.00 }, 3: { d: 1.50, r: -1.75 }, 4: { d: 0.75, r: 1.75 }, 5: { d: 1.75, r: 2.50 }, 6: { d: 5.00, r: 3.25 } },
85
+ 4: { 1: { d: 2.25, r: 4.00 }, 2: { d: 2.25, r: -1.75 }, 3: { d: 0.75, r: 1.50 }, 4: { d: 1.50, r: 2.25 }, 5: { d: 6.00, r: 2.25 }, 6: { d: 5.00, r: -0.75 } },
86
+ 5: { 1: { d: 6.00, r: 2.25 }, 2: { d: 0.75, r: 1.50 }, 3: { d: 1.50, r: 2.25 }, 4: { d: 2.25, r: -1.75 }, 5: { d: 5.00, r: -0.75 }, 6: { d: 2.25, r: 4.00 } },
87
+ 6: { 1: { d: 5.00, r: -0.75 }, 2: { d: 1.50, r: 2.25 }, 3: { d: 2.25, r: -1.75 }, 4: { d: 0.75, r: 1.50 }, 5: { d: 2.25, r: 4.00 }, 6: { d: 6.00, r: 2.25 } }
88
88
  }
89
89
  };
90
90
  // The default coordinate table as a BaseConfig.coords (jsonb string keys). Shared, readonly; materialized (and so
@@ -101,6 +101,36 @@ const DEFAULT_COORDS = (() => {
101
101
  }
102
102
  return out;
103
103
  })();
104
+ // The owner's authored per-point-of-attack block map for the 5-1 (owner 2026-08-07), keyed
105
+ // [DEF_L|DEF_M|DEF_R][rotation][zone] -> canBlock. `false` = that front-row zone sits OUT of the block for an attack
106
+ // from that side; `true` = reads/joins the wall. Only front-row zones (2/3/4) are tagged. Same rotation convention
107
+ // as DEFAULT_COORDS. Generated from the finalized 5-1 sr-mapper preset's Def L/M/R block/noblock tags.
108
+ const DEFAULT_BLOCKING = {
109
+ DEF_L: {
110
+ 1: { 2: true, 3: true, 4: false },
111
+ 2: { 2: true, 3: false, 4: true },
112
+ 3: { 2: false, 3: true, 4: true },
113
+ 4: { 2: true, 3: true, 4: false },
114
+ 5: { 2: true, 3: false, 4: true },
115
+ 6: { 2: false, 3: true, 4: true }
116
+ },
117
+ DEF_M: {
118
+ 1: { 2: false, 3: true, 4: false },
119
+ 2: { 2: true, 3: false, 4: false },
120
+ 3: { 2: false, 3: false, 4: true },
121
+ 4: { 2: false, 3: true, 4: false },
122
+ 5: { 2: true, 3: false, 4: false },
123
+ 6: { 2: false, 3: false, 4: true }
124
+ },
125
+ DEF_R: {
126
+ 1: { 2: false, 3: true, 4: true },
127
+ 2: { 2: true, 3: true, 4: false },
128
+ 3: { 2: true, 3: false, 4: true },
129
+ 4: { 2: false, 3: true, 4: true },
130
+ 5: { 2: true, 3: true, 4: false },
131
+ 6: { 2: true, 3: false, 4: true }
132
+ }
133
+ };
104
134
  // Rotation index -> the setter's rotational zone (inverse of SETTER_ZONE_TO_ROTATION {1:1,6:2,5:3,4:4,3:5,2:6}).
105
135
  const ROTATION_TO_SETTER_ZONE = { 1: 1, 2: 6, 3: 5, 4: 4, 5: 3, 6: 2 };
106
136
  // The default serve-receive participation map: the standard 3-passer formation. A rotational slot passes iff its
@@ -124,5 +154,5 @@ function defaultReceiveMap(system) {
124
154
  // creation and by the backfill migration); the coordinates are the same 5-1 table for every system, only the
125
155
  // receive map is derived per system.
126
156
  function defaultBaseConfig(system) {
127
- return { coords: DEFAULT_COORDS, receive: defaultReceiveMap(system) };
157
+ return { coords: DEFAULT_COORDS, receive: defaultReceiveMap(system), blocking: DEFAULT_BLOCKING };
128
158
  }
@@ -4,6 +4,7 @@ export * from './formation';
4
4
  export * from './tactics';
5
5
  export * from './base-config';
6
6
  export * from './default-base-config';
7
+ export * from './receive-overlap';
7
8
  export * from './team-name';
8
9
  export * from './energy-band';
9
10
  export * from './pinch-condition';
@@ -20,6 +20,7 @@ __exportStar(require("./formation"), exports);
20
20
  __exportStar(require("./tactics"), exports);
21
21
  __exportStar(require("./base-config"), exports);
22
22
  __exportStar(require("./default-base-config"), exports);
23
+ __exportStar(require("./receive-overlap"), exports);
23
24
  __exportStar(require("./team-name"), exports);
24
25
  __exportStar(require("./energy-band"), exports);
25
26
  __exportStar(require("./pinch-condition"), exports);
@@ -0,0 +1,33 @@
1
+ import { BaseConfig } from './base-config';
2
+ export interface ReceiveOverlapViolation {
3
+ /** Rotation (1..6) that has at least one violation. */
4
+ readonly rotation: number;
5
+ /** The rotational zones (1..6) involved in a violation, to flag in the editor. */
6
+ readonly zones: number[];
7
+ /** Human-readable violation messages for that rotation. */
8
+ readonly messages: string[];
9
+ }
10
+ /**
11
+ * Returns every RECEIVE rotation that breaks the overlap rule (empty if the whole receive formation is legal).
12
+ * A missing RECEIVE map or a missing zone is skipped rather than flagged, so partial/legacy configs never throw.
13
+ */
14
+ export declare function receiveOverlapViolations(config: BaseConfig): ReceiveOverlapViolation[];
15
+ /** True when the RECEIVE formation of `config` respects the overlap rule in every rotation. */
16
+ export declare function isReceiveOverlapLegal(config: BaseConfig): boolean;
17
+ /**
18
+ * Returns every SERVE rotation whose server (zone 1) is NOT behind the end line (owner 2026-08-10: on Serve, only
19
+ * the server is constrained; the rest of the serving formation is free). A missing SERVE map or zone-1 coord is
20
+ * skipped rather than flagged, so partial/legacy configs never throw.
21
+ */
22
+ export declare function serveLineViolations(config: BaseConfig): ReceiveOverlapViolation[];
23
+ /** A base-config rule violation, tagged with the formation it belongs to so the editor/API can point at it. */
24
+ export interface FormationViolation extends ReceiveOverlapViolation {
25
+ readonly formation: 'RECEIVE' | 'SERVE';
26
+ }
27
+ /**
28
+ * Every base-config rule violation across the constrained formations: the RECEIVE overlap rule and the SERVE
29
+ * server-behind-the-line rule. This is the single check the tactics save (UI + API) and the editor flagging share.
30
+ */
31
+ export declare function baseConfigViolations(config: BaseConfig): FormationViolation[];
32
+ /** True when `config` breaks no RECEIVE overlap rule and no SERVE server-line rule. */
33
+ export declare function isBaseConfigLegal(config: BaseConfig): boolean;
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.receiveOverlapViolations = receiveOverlapViolations;
4
+ exports.isReceiveOverlapLegal = isReceiveOverlapLegal;
5
+ exports.serveLineViolations = serveLineViolations;
6
+ exports.baseConfigViolations = baseConfigViolations;
7
+ exports.isBaseConfigLegal = isBaseConfigLegal;
8
+ /**
9
+ * Returns every RECEIVE rotation that breaks the overlap rule (empty if the whole receive formation is legal).
10
+ * A missing RECEIVE map or a missing zone is skipped rather than flagged, so partial/legacy configs never throw.
11
+ */
12
+ function receiveOverlapViolations(config) {
13
+ const rc = config.coords?.RECEIVE;
14
+ if (rc == null)
15
+ return [];
16
+ const out = [];
17
+ for (let rot = 1; rot <= 6; rot++) {
18
+ const row = rc[String(rot)];
19
+ if (row == null)
20
+ continue;
21
+ const at = (zone) => row[String(zone)];
22
+ const bad = new Set();
23
+ const messages = [];
24
+ const lateral = (left, right, ln, rn) => {
25
+ const a = at(left);
26
+ const b = at(right);
27
+ if (a == null || b == null)
28
+ return;
29
+ if (a.r >= b.r) {
30
+ bad.add(left);
31
+ bad.add(right);
32
+ messages.push(`${ln} must be left of ${rn}`);
33
+ }
34
+ };
35
+ const depth = (front, back, fn, bn) => {
36
+ const a = at(front);
37
+ const b = at(back);
38
+ if (a == null || b == null)
39
+ return;
40
+ if (a.d >= b.d) {
41
+ bad.add(front);
42
+ bad.add(back);
43
+ messages.push(`${fn} must be in front of ${bn}`);
44
+ }
45
+ };
46
+ lateral(4, 3, 'left-front', 'middle-front');
47
+ lateral(3, 2, 'middle-front', 'right-front');
48
+ lateral(5, 6, 'left-back', 'middle-back');
49
+ lateral(6, 1, 'middle-back', 'right-back');
50
+ depth(2, 1, 'right-front', 'right-back');
51
+ depth(3, 6, 'middle-front', 'middle-back');
52
+ depth(4, 5, 'left-front', 'left-back');
53
+ if (bad.size > 0)
54
+ out.push({ rotation: rot, zones: [...bad].sort((a, b) => a - b), messages });
55
+ }
56
+ return out;
57
+ }
58
+ /** True when the RECEIVE formation of `config` respects the overlap rule in every rotation. */
59
+ function isReceiveOverlapLegal(config) {
60
+ return receiveOverlapViolations(config).length === 0;
61
+ }
62
+ // The end line sits 9 m off the net (the FIVB court depth; matches the court editor's END_LINE). A server must
63
+ // contact the ball from BEHIND it, so on the SERVE formation the server (rotational zone 1) must have d >= this.
64
+ const END_LINE_DEPTH = 9;
65
+ /**
66
+ * Returns every SERVE rotation whose server (zone 1) is NOT behind the end line (owner 2026-08-10: on Serve, only
67
+ * the server is constrained; the rest of the serving formation is free). A missing SERVE map or zone-1 coord is
68
+ * skipped rather than flagged, so partial/legacy configs never throw.
69
+ */
70
+ function serveLineViolations(config) {
71
+ const sc = config.coords?.SERVE;
72
+ if (sc == null)
73
+ return [];
74
+ const out = [];
75
+ for (let rot = 1; rot <= 6; rot++) {
76
+ const server = sc[String(rot)]?.['1'];
77
+ if (server == null)
78
+ continue;
79
+ if (server.d < END_LINE_DEPTH)
80
+ out.push({ rotation: rot, zones: [1], messages: ['server must be behind the end line'] });
81
+ }
82
+ return out;
83
+ }
84
+ /**
85
+ * Every base-config rule violation across the constrained formations: the RECEIVE overlap rule and the SERVE
86
+ * server-behind-the-line rule. This is the single check the tactics save (UI + API) and the editor flagging share.
87
+ */
88
+ function baseConfigViolations(config) {
89
+ return [
90
+ ...receiveOverlapViolations(config).map(v => ({ ...v, formation: 'RECEIVE' })),
91
+ ...serveLineViolations(config).map(v => ({ ...v, formation: 'SERVE' }))
92
+ ];
93
+ }
94
+ /** True when `config` breaks no RECEIVE overlap rule and no SERVE server-line rule. */
95
+ function isBaseConfigLegal(config) {
96
+ return baseConfigViolations(config).length === 0;
97
+ }
@@ -302,6 +302,7 @@ export declare const TacticsInputSchema: z.ZodObject<{
302
302
  r: z.ZodNumber;
303
303
  }, z.core.$strip>>>>;
304
304
  receive: z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodBoolean>>;
305
+ blocking: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodBoolean>>>>;
305
306
  }, z.core.$strip>>;
306
307
  replaceKnockedImmediately: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodBoolean>>;
307
308
  injuryReplacements: z.ZodDefault<z.ZodArray<z.ZodObject<{
@@ -91,7 +91,10 @@ const systemSetSchema = zod_1.z.object({
91
91
  const baseCoordSchema = zod_1.z.object({ d: zod_1.z.number().finite(), r: zod_1.z.number().finite() });
92
92
  const baseConfigSchema = zod_1.z.object({
93
93
  coords: zod_1.z.record(zod_1.z.string(), zod_1.z.record(zod_1.z.string(), zod_1.z.record(zod_1.z.string(), baseCoordSchema))),
94
- receive: zod_1.z.record(zod_1.z.string(), zod_1.z.record(zod_1.z.string(), zod_1.z.boolean()))
94
+ receive: zod_1.z.record(zod_1.z.string(), zod_1.z.record(zod_1.z.string(), zod_1.z.boolean())),
95
+ // Optional per-point-of-attack blocking (owner 2026-08-07): [DEF_L|DEF_M|DEF_R][rotation][zone] -> canBlock.
96
+ // Optional so presets/tactics saved before this field validate unchanged.
97
+ blocking: zod_1.z.record(zod_1.z.string(), zod_1.z.record(zod_1.z.string(), zod_1.z.record(zod_1.z.string(), zod_1.z.boolean()))).optional()
95
98
  });
96
99
  exports.TacticsInputSchema = zod_1.z.object({
97
100
  lineup: lineupSchema,
@@ -310,6 +310,7 @@ export declare const TeamInputSchema: z.ZodObject<{
310
310
  r: z.ZodNumber;
311
311
  }, z.core.$strip>>>>;
312
312
  receive: z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodBoolean>>;
313
+ blocking: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodBoolean>>>>;
313
314
  }, z.core.$strip>>;
314
315
  replaceKnockedImmediately: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodBoolean>>;
315
316
  injuryReplacements: z.ZodDefault<z.ZodArray<z.ZodObject<{
@@ -7,4 +7,5 @@ export interface BaseCoord {
7
7
  export interface BaseConfig {
8
8
  readonly coords: Record<string, Record<string, Record<string, BaseCoord>>>;
9
9
  readonly receive: Record<string, Record<string, boolean>>;
10
+ readonly blocking?: Record<string, Record<string, Record<string, boolean>>>;
10
11
  }
@@ -3,84 +3,84 @@ import { RoleEnum } from '../player';
3
3
  import { isBackRow } from '../match';
4
4
  const COORDS = {
5
5
  SERVE: {
6
- 1: { 1: { d: 9.90, r: 3.15 }, 2: { d: 0.30, r: -2.55 }, 3: { d: 0.40, r: 0.00 }, 4: { d: 0.30, r: 2.55 }, 5: { d: 6.90, r: -0.15 }, 6: { d: 5.20, r: -2.35 } },
7
- 2: { 1: { d: 10.10, r: 3.00 }, 2: { d: 0.45, r: 0.00 }, 3: { d: 0.55, r: 2.95 }, 4: { d: 0.45, r: -2.95 }, 5: { d: 5.20, r: -2.95 }, 6: { d: 5.25, r: 3.35 } },
8
- 3: { 1: { d: 10.45, r: -3.40 }, 2: { d: 0.35, r: 2.70 }, 3: { d: 0.25, r: -3.00 }, 4: { d: 0.30, r: 0.00 }, 5: { d: 5.35, r: 2.55 }, 6: { d: 6.90, r: -0.05 } },
9
- 4: { 1: { d: 10.50, r: 3.40 }, 2: { d: 0.35, r: -3.05 }, 3: { d: 0.45, r: 0.00 }, 4: { d: 0.45, r: 2.55 }, 5: { d: 7.25, r: 0.15 }, 6: { d: 6.25, r: -2.55 } },
10
- 5: { 1: { d: 10.05, r: 3.50 }, 2: { d: 0.30, r: 0.10 }, 3: { d: 0.25, r: 2.85 }, 4: { d: 0.25, r: -2.80 }, 5: { d: 5.10, r: -2.65 }, 6: { d: 5.15, r: 2.70 } },
11
- 6: { 1: { d: 10.30, r: -3.50 }, 2: { d: 0.65, r: 2.60 }, 3: { d: 0.50, r: -2.55 }, 4: { d: 0.55, r: 0.05 }, 5: { d: 6.45, r: 2.65 }, 6: { d: 6.90, r: 0.10 } }
6
+ 1: { 1: { d: 10.00, r: 3.50 }, 2: { d: 0.50, r: -2.50 }, 3: { d: 0.50, r: 0.00 }, 4: { d: 0.50, r: 2.50 }, 5: { d: 6.50, r: 0.00 }, 6: { d: 5.00, r: -2.50 } },
7
+ 2: { 1: { d: 10.00, r: 3.50 }, 2: { d: 0.50, r: 0.00 }, 3: { d: 0.50, r: 2.50 }, 4: { d: 0.50, r: -2.50 }, 5: { d: 5.00, r: -2.50 }, 6: { d: 5.00, r: 2.50 } },
8
+ 3: { 1: { d: 10.00, r: -3.50 }, 2: { d: 0.50, r: 2.50 }, 3: { d: 0.50, r: -2.50 }, 4: { d: 0.50, r: 0.00 }, 5: { d: 5.00, r: 2.50 }, 6: { d: 6.50, r: 0.00 } },
9
+ 4: { 1: { d: 10.00, r: 3.50 }, 2: { d: 0.50, r: -2.50 }, 3: { d: 0.50, r: 0.00 }, 4: { d: 0.50, r: 2.50 }, 5: { d: 6.50, r: 0.00 }, 6: { d: 5.00, r: -2.50 } },
10
+ 5: { 1: { d: 10.00, r: 3.50 }, 2: { d: 0.50, r: 0.00 }, 3: { d: 0.50, r: 2.50 }, 4: { d: 0.50, r: -2.50 }, 5: { d: 5.00, r: -2.50 }, 6: { d: 5.00, r: 2.50 } },
11
+ 6: { 1: { d: 10.00, r: -3.50 }, 2: { d: 0.50, r: 2.50 }, 3: { d: 0.50, r: -2.50 }, 4: { d: 0.50, r: 0.00 }, 5: { d: 5.00, r: 2.50 }, 6: { d: 6.50, r: 0.00 } }
12
12
  },
13
13
  RECEIVE: {
14
- 1: { 1: { d: 6.75, r: 2.85 }, 2: { d: 6.25, r: 2.05 }, 3: { d: 3.10, r: -3.65 }, 4: { d: 3.80, r: -4.10 }, 5: { d: 6.40, r: -2.80 }, 6: { d: 6.50, r: 0.00 } },
15
- 2: { 1: { d: 6.00, r: 2.50 }, 2: { d: 3.15, r: 4.00 }, 3: { d: 0.50, r: 0.40 }, 4: { d: 5.85, r: -2.85 }, 5: { d: 6.20, r: -0.05 }, 6: { d: 1.50, r: 0.65 } },
16
- 3: { 1: { d: 6.10, r: 2.55 }, 2: { d: 3.15, r: 4.10 }, 3: { d: 6.50, r: -2.80 }, 4: { d: 0.80, r: -3.70 }, 5: { d: 1.10, r: -1.00 }, 6: { d: 6.65, r: -0.10 } },
17
- 4: { 1: { d: 8.45, r: 3.20 }, 2: { d: 6.25, r: -2.85 }, 3: { d: 1.35, r: -3.70 }, 4: { d: 0.50, r: -4.05 }, 5: { d: 6.75, r: -0.35 }, 6: { d: 6.55, r: 2.40 } },
18
- 5: { 1: { d: 5.90, r: 2.65 }, 2: { d: 2.60, r: 3.90 }, 3: { d: 0.65, r: 1.50 }, 4: { d: 6.05, r: -3.05 }, 5: { d: 6.10, r: 0.10 }, 6: { d: 8.45, r: 0.65 } },
19
- 6: { 1: { d: 6.25, r: 2.60 }, 2: { d: 0.80, r: 1.50 }, 3: { d: 6.40, r: -2.60 }, 4: { d: 3.30, r: -4.30 }, 5: { d: 8.65, r: -2.15 }, 6: { d: 6.70, r: 0.00 } }
14
+ 1: { 1: { d: 6.50, r: 3.50 }, 2: { d: 6.00, r: 3.00 }, 3: { d: 3.00, r: -3.50 }, 4: { d: 3.50, r: -4.00 }, 5: { d: 6.00, r: -3.00 }, 6: { d: 6.50, r: 0.00 } },
15
+ 2: { 1: { d: 6.00, r: 3.00 }, 2: { d: 3.00, r: 4.00 }, 3: { d: 0.50, r: 0.50 }, 4: { d: 6.00, r: -3.00 }, 5: { d: 6.50, r: 0.00 }, 6: { d: 1.25, r: 0.75 } },
16
+ 3: { 1: { d: 6.00, r: 3.00 }, 2: { d: 3.00, r: 4.00 }, 3: { d: 6.00, r: -3.00 }, 4: { d: 0.95, r: -4.00 }, 5: { d: 1.00, r: -1.00 }, 6: { d: 6.50, r: 0.00 } },
17
+ 4: { 1: { d: 8.50, r: 4.00 }, 2: { d: 6.00, r: -3.00 }, 3: { d: 1.25, r: -4.00 }, 4: { d: 0.75, r: -4.05 }, 5: { d: 6.50, r: 0.00 }, 6: { d: 6.00, r: 3.00 } },
18
+ 5: { 1: { d: 6.00, r: 3.00 }, 2: { d: 2.50, r: 4.00 }, 3: { d: 1.00, r: 1.50 }, 4: { d: 6.00, r: -3.00 }, 5: { d: 6.50, r: 0.00 }, 6: { d: 8.50, r: 1.50 } },
19
+ 6: { 1: { d: 6.00, r: 3.00 }, 2: { d: 1.00, r: 1.50 }, 3: { d: 6.00, r: -3.00 }, 4: { d: 3.00, r: -4.00 }, 5: { d: 8.50, r: -1.50 }, 6: { d: 6.50, r: 0.00 } }
20
20
  },
21
21
  DEFENCE: {
22
- 1: { 1: { d: 5.95, r: 2.65 }, 2: { d: 0.55, r: -2.95 }, 3: { d: 0.50, r: -0.20 }, 4: { d: 0.45, r: 2.70 }, 5: { d: 6.30, r: -0.30 }, 6: { d: 5.90, r: -3.15 } },
23
- 2: { 1: { d: 6.30, r: -0.40 }, 2: { d: 0.05, r: -0.10 }, 3: { d: 0.05, r: 2.70 }, 4: { d: 0.05, r: -2.85 }, 5: { d: 5.50, r: -3.00 }, 6: { d: 5.55, r: 2.80 } },
24
- 3: { 1: { d: 5.25, r: -2.65 }, 2: { d: 0.05, r: 3.05 }, 3: { d: 0.05, r: -2.80 }, 4: { d: 0.05, r: 0.30 }, 5: { d: 5.35, r: 2.95 }, 6: { d: 6.45, r: 0.20 } },
25
- 4: { 1: { d: 6.00, r: 2.90 }, 2: { d: 0.35, r: -3.10 }, 3: { d: 0.25, r: -0.05 }, 4: { d: 0.35, r: 3.10 }, 5: { d: 6.35, r: -0.10 }, 6: { d: 6.00, r: -2.60 } },
26
- 5: { 1: { d: 6.30, r: 0.00 }, 2: { d: 0.10, r: -0.05 }, 3: { d: 0.05, r: 3.00 }, 4: { d: 0.05, r: -3.05 }, 5: { d: 5.90, r: -2.90 }, 6: { d: 6.15, r: 3.25 } },
27
- 6: { 1: { d: 5.70, r: -2.85 }, 2: { d: 0.55, r: 2.50 }, 3: { d: 0.50, r: -2.95 }, 4: { d: 0.50, r: -0.25 }, 5: { d: 5.80, r: 2.90 }, 6: { d: 6.95, r: 0.00 } }
22
+ 1: { 1: { d: 5.00, r: 3.00 }, 2: { d: 0.50, r: -2.50 }, 3: { d: 0.50, r: 0.00 }, 4: { d: 0.50, r: 2.50 }, 5: { d: 7.00, r: 0.00 }, 6: { d: 5.00, r: -3.00 } },
23
+ 2: { 1: { d: 7.00, r: 0.00 }, 2: { d: 0.50, r: 0.00 }, 3: { d: 0.50, r: 2.50 }, 4: { d: 0.50, r: -2.50 }, 5: { d: 5.00, r: -3.00 }, 6: { d: 5.00, r: 3.00 } },
24
+ 3: { 1: { d: 5.00, r: -3.00 }, 2: { d: 0.50, r: 2.50 }, 3: { d: 0.50, r: -2.50 }, 4: { d: 0.50, r: 0.00 }, 5: { d: 5.00, r: 3.00 }, 6: { d: 7.00, r: 0.00 } },
25
+ 4: { 1: { d: 5.00, r: 3.00 }, 2: { d: 0.50, r: -2.50 }, 3: { d: 0.50, r: 0.00 }, 4: { d: 0.50, r: 2.50 }, 5: { d: 7.00, r: 0.00 }, 6: { d: 5.00, r: -3.00 } },
26
+ 5: { 1: { d: 7.00, r: 0.00 }, 2: { d: 0.50, r: 0.00 }, 3: { d: 0.50, r: 2.50 }, 4: { d: 0.50, r: -2.50 }, 5: { d: 5.00, r: -3.00 }, 6: { d: 5.00, r: 3.00 } },
27
+ 6: { 1: { d: 5.00, r: -3.00 }, 2: { d: 0.50, r: 2.50 }, 3: { d: 0.50, r: -2.50 }, 4: { d: 0.50, r: 0.00 }, 5: { d: 5.00, r: 3.00 }, 6: { d: 7.00, r: 0.00 } }
28
28
  },
29
29
  DEF_L: {
30
- 1: { 1: { d: 5.80, r: 1.50 }, 2: { d: 0.05, r: -3.40 }, 3: { d: 0.05, r: -2.85 }, 4: { d: 1.80, r: 1.30 }, 5: { d: 8.00, r: 0.65 }, 6: { d: 4.50, r: -4.20 } },
31
- 2: { 1: { d: 7.95, r: 0.70 }, 2: { d: 0.05, r: -2.85 }, 3: { d: 1.80, r: 1.30 }, 4: { d: 0.10, r: -3.40 }, 5: { d: 4.50, r: -4.20 }, 6: { d: 5.80, r: 1.50 } },
32
- 3: { 1: { d: 0.05, r: -2.85 }, 2: { d: 1.80, r: 1.30 }, 3: { d: 0.05, r: -3.45 }, 4: { d: 4.50, r: -4.20 }, 5: { d: 5.80, r: 1.50 }, 6: { d: 8.05, r: 0.70 } },
33
- 4: { 1: { d: 5.85, r: 1.50 }, 2: { d: 0.05, r: -3.45 }, 3: { d: 4.50, r: -4.20 }, 4: { d: 1.80, r: 1.30 }, 5: { d: 8.00, r: 0.95 }, 6: { d: 0.05, r: -2.85 } },
34
- 5: { 1: { d: 8.10, r: 0.80 }, 2: { d: 4.50, r: -4.20 }, 3: { d: 1.80, r: 1.30 }, 4: { d: 0.05, r: -3.45 }, 5: { d: 0.05, r: -2.85 }, 6: { d: 5.85, r: 1.50 } },
35
- 6: { 1: { d: 4.50, r: -4.20 }, 2: { d: 1.80, r: 1.30 }, 3: { d: 0.05, r: -3.45 }, 4: { d: 0.05, r: -2.85 }, 5: { d: 5.85, r: 1.50 }, 6: { d: 8.10, r: 0.80 } }
30
+ 1: { 1: { d: 5.00, r: 1.50 }, 2: { d: 0.25, r: -4.00 }, 3: { d: 0.25, r: -3.25 }, 4: { d: 1.75, r: 1.25 }, 5: { d: 8.00, r: -0.50 }, 6: { d: 5.00, r: -4.20 } },
31
+ 2: { 1: { d: 8.00, r: -0.50 }, 2: { d: 0.25, r: -3.25 }, 3: { d: 1.75, r: 1.25 }, 4: { d: 0.25, r: -4.00 }, 5: { d: 5.00, r: -4.20 }, 6: { d: 5.00, r: 1.50 } },
32
+ 3: { 1: { d: 5.00, r: -4.20 }, 2: { d: 1.75, r: 1.25 }, 3: { d: 0.25, r: -4.00 }, 4: { d: 0.25, r: -3.25 }, 5: { d: 5.00, r: 1.50 }, 6: { d: 8.00, r: -0.50 } },
33
+ 4: { 1: { d: 5.00, r: 1.50 }, 2: { d: 0.25, r: -4.00 }, 3: { d: 0.25, r: -3.25 }, 4: { d: 1.75, r: 1.25 }, 5: { d: 8.00, r: -0.50 }, 6: { d: 5.00, r: -4.20 } },
34
+ 5: { 1: { d: 8.00, r: -0.50 }, 2: { d: 0.25, r: -3.25 }, 3: { d: 1.75, r: 1.25 }, 4: { d: 0.25, r: -4.00 }, 5: { d: 5.00, r: -4.20 }, 6: { d: 5.00, r: 1.50 } },
35
+ 6: { 1: { d: 5.00, r: -4.20 }, 2: { d: 1.75, r: 1.25 }, 3: { d: 0.25, r: -4.00 }, 4: { d: 0.25, r: -3.25 }, 5: { d: 5.00, r: 1.50 }, 6: { d: 8.00, r: -0.50 } }
36
36
  },
37
37
  DEF_M: {
38
- 1: { 1: { d: 4.95, r: 2.35 }, 2: { d: 1.70, r: -2.60 }, 3: { d: 0.05, r: -0.15 }, 4: { d: 2.00, r: 2.80 }, 5: { d: 7.20, r: 1.00 }, 6: { d: 4.70, r: -2.35 } },
39
- 2: { 1: { d: 7.15, r: 1.00 }, 2: { d: 0.05, r: -0.15 }, 3: { d: 2.00, r: 2.80 }, 4: { d: 1.70, r: -2.60 }, 5: { d: 4.70, r: -2.35 }, 6: { d: 4.95, r: 2.35 } },
40
- 3: { 1: { d: 4.95, r: -2.35 }, 2: { d: 2.00, r: 2.80 }, 3: { d: 2.35, r: -2.65 }, 4: { d: 0.05, r: 0.00 }, 5: { d: 4.95, r: 2.35 }, 6: { d: 7.00, r: 1.20 } },
41
- 4: { 1: { d: 4.95, r: 2.15 }, 2: { d: 1.70, r: -2.60 }, 3: { d: 0.15, r: -0.10 }, 4: { d: 2.00, r: 2.85 }, 5: { d: 7.15, r: 1.00 }, 6: { d: 4.95, r: -2.25 } },
42
- 5: { 1: { d: 7.25, r: 1.10 }, 2: { d: 0.05, r: 0.00 }, 3: { d: 1.95, r: 2.60 }, 4: { d: 1.70, r: -2.50 }, 5: { d: 4.85, r: -2.05 }, 6: { d: 5.00, r: 2.15 } },
43
- 6: { 1: { d: 4.70, r: -2.35 }, 2: { d: 2.00, r: 2.75 }, 3: { d: 1.80, r: -2.65 }, 4: { d: 0.05, r: -0.15 }, 5: { d: 4.80, r: 2.40 }, 6: { d: 7.40, r: 1.00 } }
38
+ 1: { 1: { d: 5.00, r: 2.50 }, 2: { d: 1.75, r: -2.50 }, 3: { d: 0.25, r: 0.00 }, 4: { d: 1.75, r: 2.50 }, 5: { d: 7.00, r: 0.00 }, 6: { d: 5.00, r: -2.50 } },
39
+ 2: { 1: { d: 7.00, r: 0.00 }, 2: { d: 0.25, r: 0.00 }, 3: { d: 1.75, r: 2.50 }, 4: { d: 1.75, r: -2.50 }, 5: { d: 5.00, r: -2.50 }, 6: { d: 5.00, r: 2.50 } },
40
+ 3: { 1: { d: 5.00, r: -2.50 }, 2: { d: 1.75, r: 2.50 }, 3: { d: 1.75, r: -2.50 }, 4: { d: 0.25, r: 0.00 }, 5: { d: 5.00, r: 2.50 }, 6: { d: 7.00, r: 0.00 } },
41
+ 4: { 1: { d: 5.00, r: 2.50 }, 2: { d: 1.75, r: -2.50 }, 3: { d: 0.25, r: 0.00 }, 4: { d: 1.75, r: 2.50 }, 5: { d: 7.00, r: 0.00 }, 6: { d: 5.00, r: -2.50 } },
42
+ 5: { 1: { d: 7.00, r: 0.00 }, 2: { d: 0.25, r: 0.00 }, 3: { d: 1.75, r: 2.50 }, 4: { d: 1.75, r: -2.50 }, 5: { d: 5.00, r: -2.50 }, 6: { d: 5.00, r: 2.50 } },
43
+ 6: { 1: { d: 5.00, r: -2.50 }, 2: { d: 1.75, r: 2.50 }, 3: { d: 1.75, r: -2.50 }, 4: { d: 0.25, r: 0.00 }, 5: { d: 5.00, r: 2.50 }, 6: { d: 7.00, r: 0.00 } }
44
44
  },
45
45
  DEF_R: {
46
- 1: { 1: { d: 4.45, r: 4.20 }, 2: { d: 1.90, r: -1.50 }, 3: { d: 0.10, r: 2.90 }, 4: { d: 0.10, r: 3.45 }, 5: { d: 8.80, r: 0.45 }, 6: { d: 5.25, r: -1.45 } },
47
- 2: { 1: { d: 8.55, r: -0.65 }, 2: { d: 0.05, r: 2.90 }, 3: { d: 0.05, r: 3.50 }, 4: { d: 2.00, r: -2.20 }, 5: { d: 4.80, r: -1.60 }, 6: { d: 4.50, r: 4.15 } },
48
- 3: { 1: { d: 4.75, r: -1.70 }, 2: { d: 0.05, r: 3.45 }, 3: { d: 1.60, r: -1.75 }, 4: { d: 0.05, r: 2.85 }, 5: { d: 4.55, r: 4.15 }, 6: { d: 8.40, r: -0.35 } },
49
- 4: { 1: { d: 5.20, r: 4.15 }, 2: { d: 1.75, r: -1.85 }, 3: { d: 0.05, r: 3.20 }, 4: { d: 0.05, r: 3.75 }, 5: { d: 8.45, r: -0.65 }, 6: { d: 5.15, r: -1.85 } },
50
- 5: { 1: { d: 8.35, r: -0.75 }, 2: { d: 0.05, r: 2.90 }, 3: { d: 0.05, r: 3.50 }, 4: { d: 1.80, r: -1.25 }, 5: { d: 5.25, r: -1.70 }, 6: { d: 5.00, r: 4.15 } },
51
- 6: { 1: { d: 5.15, r: -1.50 }, 2: { d: 0.05, r: 3.45 }, 3: { d: 2.55, r: -2.40 }, 4: { d: 0.05, r: 2.90 }, 5: { d: 4.60, r: 4.10 }, 6: { d: 8.75, r: 0.25 } }
46
+ 1: { 1: { d: 5.00, r: 4.20 }, 2: { d: 1.75, r: -1.25 }, 3: { d: 0.25, r: 3.25 }, 4: { d: 0.25, r: 4.00 }, 5: { d: 8.00, r: 0.50 }, 6: { d: 5.00, r: -1.50 } },
47
+ 2: { 1: { d: 8.00, r: 0.50 }, 2: { d: 0.25, r: 3.25 }, 3: { d: 0.25, r: 4.00 }, 4: { d: 1.75, r: -1.25 }, 5: { d: 5.00, r: -1.50 }, 6: { d: 5.00, r: 4.20 } },
48
+ 3: { 1: { d: 5.00, r: -1.50 }, 2: { d: 0.25, r: 4.00 }, 3: { d: 1.75, r: -1.25 }, 4: { d: 0.25, r: 3.25 }, 5: { d: 5.00, r: 4.20 }, 6: { d: 8.00, r: 0.50 } },
49
+ 4: { 1: { d: 5.00, r: 4.20 }, 2: { d: 1.75, r: -1.25 }, 3: { d: 0.25, r: 3.25 }, 4: { d: 0.25, r: 4.00 }, 5: { d: 8.00, r: 0.50 }, 6: { d: 5.00, r: -1.50 } },
50
+ 5: { 1: { d: 8.00, r: 0.50 }, 2: { d: 0.25, r: 3.25 }, 3: { d: 0.25, r: 4.00 }, 4: { d: 1.75, r: -1.25 }, 5: { d: 5.00, r: -1.50 }, 6: { d: 5.00, r: 4.20 } },
51
+ 6: { 1: { d: 5.00, r: -1.50 }, 2: { d: 0.25, r: 4.00 }, 3: { d: 1.75, r: -1.25 }, 4: { d: 0.25, r: 3.25 }, 5: { d: 5.00, r: 4.20 }, 6: { d: 8.00, r: 0.50 } }
52
52
  },
53
53
  ATTACK: {
54
- 1: { 1: { d: 0.50, r: 1.55 }, 2: { d: 3.40, r: -5.15 }, 3: { d: 1.15, r: 0.40 }, 4: { d: 4.80, r: 5.20 }, 5: { d: 6.50, r: 0.20 }, 6: { d: 4.85, r: -2.90 } },
55
- 2: { 1: { d: 6.50, r: -0.40 }, 2: { d: 1.60, r: 0.75 }, 3: { d: 3.65, r: 5.05 }, 4: { d: 3.50, r: -5.05 }, 5: { d: 4.45, r: -2.60 }, 6: { d: 0.50, r: 1.60 } },
56
- 3: { 1: { d: 5.05, r: -1.90 }, 2: { d: 3.95, r: 5.00 }, 3: { d: 3.95, r: -4.90 }, 4: { d: 1.80, r: 1.10 }, 5: { d: 0.35, r: 1.55 }, 6: { d: 6.45, r: 0.15 } },
57
- 4: { 1: { d: 6.15, r: 4.95 }, 2: { d: 3.95, r: -5.05 }, 3: { d: 1.45, r: 1.05 }, 4: { d: 0.45, r: 1.80 }, 5: { d: 6.45, r: -0.50 }, 6: { d: 4.95, r: -2.00 } },
58
- 5: { 1: { d: 6.50, r: -0.40 }, 2: { d: 1.80, r: 1.10 }, 3: { d: 0.25, r: 1.85 }, 4: { d: 3.45, r: -4.95 }, 5: { d: 5.35, r: -2.55 }, 6: { d: 6.50, r: 4.90 } },
59
- 6: { 1: { d: 5.85, r: -2.20 }, 2: { d: 0.55, r: 2.00 }, 3: { d: 4.00, r: -4.85 }, 4: { d: 1.35, r: 1.40 }, 5: { d: 6.85, r: 4.90 }, 6: { d: 6.60, r: 0.35 } }
54
+ 1: { 1: { d: 0.50, r: 1.50 }, 2: { d: 3.75, r: -5.00 }, 3: { d: 3.00, r: 0.25 }, 4: { d: 3.75, r: 5.00 }, 5: { d: 6.50, r: 0.00 }, 6: { d: 4.50, r: -2.50 } },
55
+ 2: { 1: { d: 6.50, r: 0.00 }, 2: { d: 3.00, r: 0.25 }, 3: { d: 3.75, r: 5.00 }, 4: { d: 3.75, r: -5.00 }, 5: { d: 4.50, r: -2.50 }, 6: { d: 0.50, r: 1.50 } },
56
+ 3: { 1: { d: 4.50, r: -2.50 }, 2: { d: 3.75, r: 5.00 }, 3: { d: 3.75, r: -5.00 }, 4: { d: 3.00, r: 0.25 }, 5: { d: 0.50, r: 1.50 }, 6: { d: 6.50, r: 0.00 } },
57
+ 4: { 1: { d: 6.50, r: 4.90 }, 2: { d: 3.75, r: -5.00 }, 3: { d: 3.00, r: 0.25 }, 4: { d: 0.50, r: 1.50 }, 5: { d: 6.50, r: 0.00 }, 6: { d: 4.50, r: -2.50 } },
58
+ 5: { 1: { d: 6.50, r: 0.00 }, 2: { d: 3.00, r: 0.25 }, 3: { d: 0.50, r: 1.50 }, 4: { d: 3.75, r: -5.00 }, 5: { d: 4.50, r: -2.50 }, 6: { d: 6.50, r: 4.90 } },
59
+ 6: { 1: { d: 4.50, r: -2.50 }, 2: { d: 0.50, r: 1.50 }, 3: { d: 3.75, r: -5.00 }, 4: { d: 3.00, r: 0.25 }, 5: { d: 6.50, r: 4.90 }, 6: { d: 6.50, r: 0.00 } }
60
60
  },
61
61
  ATK_L: {
62
- 1: { 1: { d: 0.75, r: 0.10 }, 2: { d: 0.50, r: -4.05 }, 3: { d: 0.95, r: -2.55 }, 4: { d: 3.45, r: 0.80 }, 5: { d: 6.25, r: -0.75 }, 6: { d: 3.60, r: -3.95 } },
63
- 2: { 1: { d: 0.50, r: -4.05 }, 2: { d: 0.95, r: -2.55 }, 3: { d: 3.75, r: 1.05 }, 4: { d: 6.25, r: -0.75 }, 5: { d: 3.60, r: -3.95 }, 6: { d: 0.75, r: 0.10 } },
64
- 3: { 1: { d: 0.95, r: -2.55 }, 2: { d: 3.45, r: 0.80 }, 3: { d: 6.25, r: -0.75 }, 4: { d: 3.60, r: -3.95 }, 5: { d: 0.75, r: 0.10 }, 6: { d: 0.50, r: -4.05 } },
65
- 4: { 1: { d: 3.60, r: 0.90 }, 2: { d: 0.55, r: -4.05 }, 3: { d: 1.15, r: -2.60 }, 4: { d: 0.85, r: 0.25 }, 5: { d: 6.25, r: -0.80 }, 6: { d: 3.45, r: -4.10 } },
66
- 5: { 1: { d: 6.25, r: -0.65 }, 2: { d: 1.20, r: -2.55 }, 3: { d: 0.80, r: 0.10 }, 4: { d: 0.50, r: -4.10 }, 5: { d: 3.90, r: -4.00 }, 6: { d: 3.75, r: 0.80 } },
67
- 6: { 1: { d: 3.60, r: -3.95 }, 2: { d: 0.75, r: 0.10 }, 3: { d: 0.50, r: -4.05 }, 4: { d: 0.95, r: -2.55 }, 5: { d: 3.45, r: 0.80 }, 6: { d: 6.25, r: -0.75 } }
62
+ 1: { 1: { d: 0.75, r: 0.00 }, 2: { d: 0.50, r: -4.00 }, 3: { d: 1.00, r: -2.50 }, 4: { d: 3.50, r: 0.75 }, 5: { d: 6.25, r: -0.75 }, 6: { d: 3.50, r: -4.00 } },
63
+ 2: { 1: { d: 6.25, r: -0.75 }, 2: { d: 1.00, r: -2.50 }, 3: { d: 3.50, r: 0.75 }, 4: { d: 0.50, r: -4.00 }, 5: { d: 3.50, r: -4.00 }, 6: { d: 0.75, r: 0.00 } },
64
+ 3: { 1: { d: 3.50, r: -4.00 }, 2: { d: 3.50, r: 0.75 }, 3: { d: 0.50, r: -4.00 }, 4: { d: 1.00, r: -2.50 }, 5: { d: 0.75, r: 0.00 }, 6: { d: 6.25, r: -0.75 } },
65
+ 4: { 1: { d: 3.50, r: 0.75 }, 2: { d: 0.50, r: -4.00 }, 3: { d: 1.00, r: -2.50 }, 4: { d: 0.75, r: 0.00 }, 5: { d: 6.25, r: -0.75 }, 6: { d: 3.50, r: -4.00 } },
66
+ 5: { 1: { d: 6.25, r: -0.75 }, 2: { d: 1.00, r: -2.50 }, 3: { d: 0.75, r: 0.00 }, 4: { d: 0.50, r: -4.00 }, 5: { d: 3.50, r: -4.00 }, 6: { d: 3.50, r: 0.75 } },
67
+ 6: { 1: { d: 3.50, r: -4.00 }, 2: { d: 0.75, r: 0.00 }, 3: { d: 0.50, r: -4.00 }, 4: { d: 1.00, r: -2.50 }, 5: { d: 3.50, r: 0.75 }, 6: { d: 6.25, r: -0.75 } }
68
68
  },
69
69
  ATK_M: {
70
- 1: { 1: { d: 0.60, r: 1.25 }, 2: { d: 1.20, r: -2.00 }, 3: { d: 0.70, r: 0.50 }, 4: { d: 2.25, r: 2.60 }, 5: { d: 6.40, r: 1.40 }, 6: { d: 4.05, r: -1.55 } },
71
- 2: { 1: { d: 6.65, r: 1.55 }, 2: { d: 0.70, r: 0.50 }, 3: { d: 2.25, r: 2.60 }, 4: { d: 1.40, r: -1.90 }, 5: { d: 4.05, r: -1.55 }, 6: { d: 0.60, r: 1.25 } },
72
- 3: { 1: { d: 4.05, r: -1.55 }, 2: { d: 2.25, r: 2.60 }, 3: { d: 1.20, r: -2.00 }, 4: { d: 0.70, r: 0.45 }, 5: { d: 0.65, r: 1.15 }, 6: { d: 6.40, r: 1.40 } },
73
- 4: { 1: { d: 2.25, r: 2.60 }, 2: { d: 1.35, r: -1.90 }, 3: { d: 0.65, r: 0.50 }, 4: { d: 0.60, r: 1.25 }, 5: { d: 6.40, r: 1.45 }, 6: { d: 4.15, r: -1.45 } },
74
- 5: { 1: { d: 6.40, r: 1.40 }, 2: { d: 0.65, r: 0.50 }, 3: { d: 0.60, r: 1.25 }, 4: { d: 1.20, r: -2.00 }, 5: { d: 4.15, r: -1.40 }, 6: { d: 2.25, r: 2.60 } },
75
- 6: { 1: { d: 4.05, r: -1.55 }, 2: { d: 0.60, r: 1.25 }, 3: { d: 1.20, r: -2.00 }, 4: { d: 0.70, r: 0.50 }, 5: { d: 2.25, r: 2.60 }, 6: { d: 6.40, r: 1.40 } }
70
+ 1: { 1: { d: 0.75, r: 1.25 }, 2: { d: 1.25, r: -2.00 }, 3: { d: 0.75, r: 0.50 }, 4: { d: 2.25, r: 2.60 }, 5: { d: 6.50, r: 1.50 }, 6: { d: 4.00, r: -1.50 } },
71
+ 2: { 1: { d: 6.50, r: 1.50 }, 2: { d: 0.75, r: 0.50 }, 3: { d: 2.25, r: 2.60 }, 4: { d: 1.25, r: -2.00 }, 5: { d: 4.00, r: -1.50 }, 6: { d: 0.75, r: 1.25 } },
72
+ 3: { 1: { d: 4.00, r: -1.50 }, 2: { d: 2.25, r: 2.60 }, 3: { d: 1.25, r: -2.00 }, 4: { d: 0.75, r: 0.50 }, 5: { d: 0.75, r: 1.25 }, 6: { d: 6.50, r: 1.50 } },
73
+ 4: { 1: { d: 2.25, r: 2.60 }, 2: { d: 1.25, r: -2.00 }, 3: { d: 0.75, r: 0.50 }, 4: { d: 0.75, r: 1.25 }, 5: { d: 6.50, r: 1.50 }, 6: { d: 4.00, r: -1.50 } },
74
+ 5: { 1: { d: 6.50, r: 1.50 }, 2: { d: 0.75, r: 0.50 }, 3: { d: 0.75, r: 1.25 }, 4: { d: 1.25, r: -2.00 }, 5: { d: 4.00, r: -1.50 }, 6: { d: 2.25, r: 2.60 } },
75
+ 6: { 1: { d: 4.00, r: -1.50 }, 2: { d: 0.75, r: 1.25 }, 3: { d: 1.25, r: -2.00 }, 4: { d: 0.75, r: 0.50 }, 5: { d: 2.25, r: 2.60 }, 6: { d: 6.50, r: 1.50 } }
76
76
  },
77
77
  ATK_R: {
78
- 1: { 1: { d: 1.75, r: 2.60 }, 2: { d: 1.60, r: -1.75 }, 3: { d: 0.75, r: 1.80 }, 4: { d: 0.60, r: 3.90 }, 5: { d: 4.90, r: 3.25 }, 6: { d: 5.85, r: -1.90 } },
79
- 2: { 1: { d: 5.15, r: 3.20 }, 2: { d: 0.75, r: 1.80 }, 3: { d: 0.60, r: 3.90 }, 4: { d: 1.60, r: -1.40 }, 5: { d: 5.85, r: -1.90 }, 6: { d: 1.75, r: 2.60 } },
80
- 3: { 1: { d: 6.05, r: -2.00 }, 2: { d: 0.60, r: 3.90 }, 3: { d: 1.55, r: -1.55 }, 4: { d: 0.75, r: 1.70 }, 5: { d: 1.75, r: 2.60 }, 6: { d: 5.05, r: 3.15 } },
81
- 4: { 1: { d: 2.25, r: 4.20 }, 2: { d: 2.40, r: -1.65 }, 3: { d: 0.85, r: 1.40 }, 4: { d: 1.40, r: 2.30 }, 5: { d: 6.00, r: 1.85 }, 6: { d: 5.25, r: -0.90 } },
82
- 5: { 1: { d: 5.95, r: 2.35 }, 2: { d: 0.85, r: 1.40 }, 3: { d: 1.40, r: 2.30 }, 4: { d: 2.20, r: -1.80 }, 5: { d: 5.25, r: -0.90 }, 6: { d: 2.25, r: 4.20 } },
83
- 6: { 1: { d: 5.30, r: -0.90 }, 2: { d: 1.45, r: 2.30 }, 3: { d: 2.25, r: -1.80 }, 4: { d: 0.75, r: 1.40 }, 5: { d: 2.25, r: 4.05 }, 6: { d: 5.90, r: 2.35 } }
78
+ 1: { 1: { d: 1.75, r: 2.50 }, 2: { d: 1.50, r: -1.75 }, 3: { d: 0.75, r: 1.75 }, 4: { d: 0.50, r: 4.00 }, 5: { d: 5.00, r: 3.25 }, 6: { d: 5.75, r: -2.00 } },
79
+ 2: { 1: { d: 5.00, r: 3.25 }, 2: { d: 0.75, r: 1.75 }, 3: { d: 0.50, r: 4.00 }, 4: { d: 1.50, r: -1.75 }, 5: { d: 5.75, r: -2.00 }, 6: { d: 1.75, r: 2.50 } },
80
+ 3: { 1: { d: 5.75, r: -2.00 }, 2: { d: 0.50, r: 4.00 }, 3: { d: 1.50, r: -1.75 }, 4: { d: 0.75, r: 1.75 }, 5: { d: 1.75, r: 2.50 }, 6: { d: 5.00, r: 3.25 } },
81
+ 4: { 1: { d: 2.25, r: 4.00 }, 2: { d: 2.25, r: -1.75 }, 3: { d: 0.75, r: 1.50 }, 4: { d: 1.50, r: 2.25 }, 5: { d: 6.00, r: 2.25 }, 6: { d: 5.00, r: -0.75 } },
82
+ 5: { 1: { d: 6.00, r: 2.25 }, 2: { d: 0.75, r: 1.50 }, 3: { d: 1.50, r: 2.25 }, 4: { d: 2.25, r: -1.75 }, 5: { d: 5.00, r: -0.75 }, 6: { d: 2.25, r: 4.00 } },
83
+ 6: { 1: { d: 5.00, r: -0.75 }, 2: { d: 1.50, r: 2.25 }, 3: { d: 2.25, r: -1.75 }, 4: { d: 0.75, r: 1.50 }, 5: { d: 2.25, r: 4.00 }, 6: { d: 6.00, r: 2.25 } }
84
84
  }
85
85
  };
86
86
  // The default coordinate table as a BaseConfig.coords (jsonb string keys). Shared, readonly; materialized (and so
@@ -97,6 +97,36 @@ const DEFAULT_COORDS = (() => {
97
97
  }
98
98
  return out;
99
99
  })();
100
+ // The owner's authored per-point-of-attack block map for the 5-1 (owner 2026-08-07), keyed
101
+ // [DEF_L|DEF_M|DEF_R][rotation][zone] -> canBlock. `false` = that front-row zone sits OUT of the block for an attack
102
+ // from that side; `true` = reads/joins the wall. Only front-row zones (2/3/4) are tagged. Same rotation convention
103
+ // as DEFAULT_COORDS. Generated from the finalized 5-1 sr-mapper preset's Def L/M/R block/noblock tags.
104
+ const DEFAULT_BLOCKING = {
105
+ DEF_L: {
106
+ 1: { 2: true, 3: true, 4: false },
107
+ 2: { 2: true, 3: false, 4: true },
108
+ 3: { 2: false, 3: true, 4: true },
109
+ 4: { 2: true, 3: true, 4: false },
110
+ 5: { 2: true, 3: false, 4: true },
111
+ 6: { 2: false, 3: true, 4: true }
112
+ },
113
+ DEF_M: {
114
+ 1: { 2: false, 3: true, 4: false },
115
+ 2: { 2: true, 3: false, 4: false },
116
+ 3: { 2: false, 3: false, 4: true },
117
+ 4: { 2: false, 3: true, 4: false },
118
+ 5: { 2: true, 3: false, 4: false },
119
+ 6: { 2: false, 3: false, 4: true }
120
+ },
121
+ DEF_R: {
122
+ 1: { 2: false, 3: true, 4: true },
123
+ 2: { 2: true, 3: true, 4: false },
124
+ 3: { 2: true, 3: false, 4: true },
125
+ 4: { 2: false, 3: true, 4: true },
126
+ 5: { 2: true, 3: true, 4: false },
127
+ 6: { 2: true, 3: false, 4: true }
128
+ }
129
+ };
100
130
  // Rotation index -> the setter's rotational zone (inverse of SETTER_ZONE_TO_ROTATION {1:1,6:2,5:3,4:4,3:5,2:6}).
101
131
  const ROTATION_TO_SETTER_ZONE = { 1: 1, 2: 6, 3: 5, 4: 4, 5: 3, 6: 2 };
102
132
  // The default serve-receive participation map: the standard 3-passer formation. A rotational slot passes iff its
@@ -120,5 +150,5 @@ export function defaultReceiveMap(system) {
120
150
  // creation and by the backfill migration); the coordinates are the same 5-1 table for every system, only the
121
151
  // receive map is derived per system.
122
152
  export function defaultBaseConfig(system) {
123
- return { coords: DEFAULT_COORDS, receive: defaultReceiveMap(system) };
153
+ return { coords: DEFAULT_COORDS, receive: defaultReceiveMap(system), blocking: DEFAULT_BLOCKING };
124
154
  }
@@ -4,6 +4,7 @@ export * from './formation';
4
4
  export * from './tactics';
5
5
  export * from './base-config';
6
6
  export * from './default-base-config';
7
+ export * from './receive-overlap';
7
8
  export * from './team-name';
8
9
  export * from './energy-band';
9
10
  export * from './pinch-condition';
@@ -4,6 +4,7 @@ export * from './formation';
4
4
  export * from './tactics';
5
5
  export * from './base-config';
6
6
  export * from './default-base-config';
7
+ export * from './receive-overlap';
7
8
  export * from './team-name';
8
9
  export * from './energy-band';
9
10
  export * from './pinch-condition';
@@ -0,0 +1,33 @@
1
+ import { BaseConfig } from './base-config';
2
+ export interface ReceiveOverlapViolation {
3
+ /** Rotation (1..6) that has at least one violation. */
4
+ readonly rotation: number;
5
+ /** The rotational zones (1..6) involved in a violation, to flag in the editor. */
6
+ readonly zones: number[];
7
+ /** Human-readable violation messages for that rotation. */
8
+ readonly messages: string[];
9
+ }
10
+ /**
11
+ * Returns every RECEIVE rotation that breaks the overlap rule (empty if the whole receive formation is legal).
12
+ * A missing RECEIVE map or a missing zone is skipped rather than flagged, so partial/legacy configs never throw.
13
+ */
14
+ export declare function receiveOverlapViolations(config: BaseConfig): ReceiveOverlapViolation[];
15
+ /** True when the RECEIVE formation of `config` respects the overlap rule in every rotation. */
16
+ export declare function isReceiveOverlapLegal(config: BaseConfig): boolean;
17
+ /**
18
+ * Returns every SERVE rotation whose server (zone 1) is NOT behind the end line (owner 2026-08-10: on Serve, only
19
+ * the server is constrained; the rest of the serving formation is free). A missing SERVE map or zone-1 coord is
20
+ * skipped rather than flagged, so partial/legacy configs never throw.
21
+ */
22
+ export declare function serveLineViolations(config: BaseConfig): ReceiveOverlapViolation[];
23
+ /** A base-config rule violation, tagged with the formation it belongs to so the editor/API can point at it. */
24
+ export interface FormationViolation extends ReceiveOverlapViolation {
25
+ readonly formation: 'RECEIVE' | 'SERVE';
26
+ }
27
+ /**
28
+ * Every base-config rule violation across the constrained formations: the RECEIVE overlap rule and the SERVE
29
+ * server-behind-the-line rule. This is the single check the tactics save (UI + API) and the editor flagging share.
30
+ */
31
+ export declare function baseConfigViolations(config: BaseConfig): FormationViolation[];
32
+ /** True when `config` breaks no RECEIVE overlap rule and no SERVE server-line rule. */
33
+ export declare function isBaseConfigLegal(config: BaseConfig): boolean;
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Returns every RECEIVE rotation that breaks the overlap rule (empty if the whole receive formation is legal).
3
+ * A missing RECEIVE map or a missing zone is skipped rather than flagged, so partial/legacy configs never throw.
4
+ */
5
+ export function receiveOverlapViolations(config) {
6
+ const rc = config.coords?.RECEIVE;
7
+ if (rc == null)
8
+ return [];
9
+ const out = [];
10
+ for (let rot = 1; rot <= 6; rot++) {
11
+ const row = rc[String(rot)];
12
+ if (row == null)
13
+ continue;
14
+ const at = (zone) => row[String(zone)];
15
+ const bad = new Set();
16
+ const messages = [];
17
+ const lateral = (left, right, ln, rn) => {
18
+ const a = at(left);
19
+ const b = at(right);
20
+ if (a == null || b == null)
21
+ return;
22
+ if (a.r >= b.r) {
23
+ bad.add(left);
24
+ bad.add(right);
25
+ messages.push(`${ln} must be left of ${rn}`);
26
+ }
27
+ };
28
+ const depth = (front, back, fn, bn) => {
29
+ const a = at(front);
30
+ const b = at(back);
31
+ if (a == null || b == null)
32
+ return;
33
+ if (a.d >= b.d) {
34
+ bad.add(front);
35
+ bad.add(back);
36
+ messages.push(`${fn} must be in front of ${bn}`);
37
+ }
38
+ };
39
+ lateral(4, 3, 'left-front', 'middle-front');
40
+ lateral(3, 2, 'middle-front', 'right-front');
41
+ lateral(5, 6, 'left-back', 'middle-back');
42
+ lateral(6, 1, 'middle-back', 'right-back');
43
+ depth(2, 1, 'right-front', 'right-back');
44
+ depth(3, 6, 'middle-front', 'middle-back');
45
+ depth(4, 5, 'left-front', 'left-back');
46
+ if (bad.size > 0)
47
+ out.push({ rotation: rot, zones: [...bad].sort((a, b) => a - b), messages });
48
+ }
49
+ return out;
50
+ }
51
+ /** True when the RECEIVE formation of `config` respects the overlap rule in every rotation. */
52
+ export function isReceiveOverlapLegal(config) {
53
+ return receiveOverlapViolations(config).length === 0;
54
+ }
55
+ // The end line sits 9 m off the net (the FIVB court depth; matches the court editor's END_LINE). A server must
56
+ // contact the ball from BEHIND it, so on the SERVE formation the server (rotational zone 1) must have d >= this.
57
+ const END_LINE_DEPTH = 9;
58
+ /**
59
+ * Returns every SERVE rotation whose server (zone 1) is NOT behind the end line (owner 2026-08-10: on Serve, only
60
+ * the server is constrained; the rest of the serving formation is free). A missing SERVE map or zone-1 coord is
61
+ * skipped rather than flagged, so partial/legacy configs never throw.
62
+ */
63
+ export function serveLineViolations(config) {
64
+ const sc = config.coords?.SERVE;
65
+ if (sc == null)
66
+ return [];
67
+ const out = [];
68
+ for (let rot = 1; rot <= 6; rot++) {
69
+ const server = sc[String(rot)]?.['1'];
70
+ if (server == null)
71
+ continue;
72
+ if (server.d < END_LINE_DEPTH)
73
+ out.push({ rotation: rot, zones: [1], messages: ['server must be behind the end line'] });
74
+ }
75
+ return out;
76
+ }
77
+ /**
78
+ * Every base-config rule violation across the constrained formations: the RECEIVE overlap rule and the SERVE
79
+ * server-behind-the-line rule. This is the single check the tactics save (UI + API) and the editor flagging share.
80
+ */
81
+ export function baseConfigViolations(config) {
82
+ return [
83
+ ...receiveOverlapViolations(config).map(v => ({ ...v, formation: 'RECEIVE' })),
84
+ ...serveLineViolations(config).map(v => ({ ...v, formation: 'SERVE' }))
85
+ ];
86
+ }
87
+ /** True when `config` breaks no RECEIVE overlap rule and no SERVE server-line rule. */
88
+ export function isBaseConfigLegal(config) {
89
+ return baseConfigViolations(config).length === 0;
90
+ }
@@ -302,6 +302,7 @@ export declare const TacticsInputSchema: z.ZodObject<{
302
302
  r: z.ZodNumber;
303
303
  }, z.core.$strip>>>>;
304
304
  receive: z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodBoolean>>;
305
+ blocking: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodBoolean>>>>;
305
306
  }, z.core.$strip>>;
306
307
  replaceKnockedImmediately: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodBoolean>>;
307
308
  injuryReplacements: z.ZodDefault<z.ZodArray<z.ZodObject<{
@@ -88,7 +88,10 @@ const systemSetSchema = z.object({
88
88
  const baseCoordSchema = z.object({ d: z.number().finite(), r: z.number().finite() });
89
89
  const baseConfigSchema = z.object({
90
90
  coords: z.record(z.string(), z.record(z.string(), z.record(z.string(), baseCoordSchema))),
91
- receive: z.record(z.string(), z.record(z.string(), z.boolean()))
91
+ receive: z.record(z.string(), z.record(z.string(), z.boolean())),
92
+ // Optional per-point-of-attack blocking (owner 2026-08-07): [DEF_L|DEF_M|DEF_R][rotation][zone] -> canBlock.
93
+ // Optional so presets/tactics saved before this field validate unchanged.
94
+ blocking: z.record(z.string(), z.record(z.string(), z.record(z.string(), z.boolean()))).optional()
92
95
  });
93
96
  export const TacticsInputSchema = z.object({
94
97
  lineup: lineupSchema,
@@ -310,6 +310,7 @@ export declare const TeamInputSchema: z.ZodObject<{
310
310
  r: z.ZodNumber;
311
311
  }, z.core.$strip>>>>;
312
312
  receive: z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodBoolean>>;
313
+ blocking: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodBoolean>>>>;
313
314
  }, z.core.$strip>>;
314
315
  replaceKnockedImmediately: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodBoolean>>;
315
316
  injuryReplacements: z.ZodDefault<z.ZodArray<z.ZodObject<{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "volleyballsimtypes",
3
- "version": "0.0.506",
3
+ "version": "0.0.508",
4
4
  "description": "vbsim types",
5
5
  "main": "./dist/cjs/src/index.js",
6
6
  "module": "./dist/esm/src/index.js",