volleyballsimtypes 0.0.169 → 0.0.170

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.
@@ -30,9 +30,8 @@ function getMultipliers(statName, performanceStats) {
30
30
  };
31
31
  case StatsEnum.SET:
32
32
  return {
33
- setting: 0.7,
33
+ setting: 0.75,
34
34
  overhand: 0.1,
35
- bump: 0.05,
36
35
  awareness: 0.075,
37
36
  attack: 0.075
38
37
  };
@@ -1,26 +1,52 @@
1
- import { PerformanceStats } from './performance-stats';
2
1
  import { Rarity } from './rarity';
3
2
  import { EnumDataType } from 'sequelize';
4
- import { Stats } from './stats';
3
+ import { Role } from './role';
5
4
  interface TraitProps {
6
5
  readonly name: Trait;
7
6
  readonly modifier: number;
8
7
  readonly chance: number;
9
- readonly statThreshold: number;
10
- readonly stat: Stats;
11
- readonly weight: number;
8
+ readonly roles: Role[];
12
9
  }
13
10
  export declare enum TraitEnum {
11
+ /**
12
+ * When triggered, all actions before the net crossing have a bonus.
13
+ */
14
14
  MASTER_MIND = "MASTER_MIND",
15
+ /**
16
+ * When this player is part of the front row, they will always be part of the blocking block
17
+ */
15
18
  MOVING_WALL = "MOVING_WALL",
19
+ /**
20
+ * Enables the player making the second touch to spike or dump
21
+ */
22
+ SURPRISE_ATTACK = "SURPRISE_ATTACK",
23
+ /**
24
+ * Boosts the stat of the action taken and allows the player to choose the best target for the action.
25
+ */
16
26
  MARKSMAN = "MARKSMAN",
27
+ /**
28
+ * The server will perform an extra strong serve.
29
+ */
17
30
  METEOR_SERVE = "METEOR_SERVE",
31
+ /**
32
+ * The player has a 50% chance to perform an action with no energy decrease
33
+ */
18
34
  VIGOROUS = "VIGOROUS",
35
+ /**
36
+ * The player with this trait has a chance to take the receiver's place if their reception stat is higher.
37
+ */
19
38
  GUARDIAN = "GUARDIAN",
20
- FLOAT_SERVE = "FLOAT_SERVE"
39
+ /**
40
+ * Enables the server to perform a float serve, which checks against receiver overhand instead.
41
+ */
42
+ FLOAT_SERVE = "FLOAT_SERVE",
43
+ /**
44
+ * Gives the player a chance to perform a perfect reception.
45
+ */
46
+ DEFENSIVE_SPECIALIST = "DEFENSIVE_SPECIALIST"
21
47
  }
22
- export type Trait = TraitEnum.FLOAT_SERVE | TraitEnum.GUARDIAN | TraitEnum.MASTER_MIND | TraitEnum.MOVING_WALL | TraitEnum.MARKSMAN | TraitEnum.METEOR_SERVE | TraitEnum.VIGOROUS;
48
+ export type Trait = TraitEnum.FLOAT_SERVE | TraitEnum.SURPRISE_ATTACK | TraitEnum.GUARDIAN | TraitEnum.MASTER_MIND | TraitEnum.MOVING_WALL | TraitEnum.MARKSMAN | TraitEnum.METEOR_SERVE | TraitEnum.VIGOROUS | TraitEnum.DEFENSIVE_SPECIALIST;
23
49
  export declare const TraitDataType: EnumDataType<Trait>;
24
- export declare function assignTraits(performanceStats: PerformanceStats, rarity: Rarity): Trait[];
50
+ export declare function assignTraits(roles: Role[], rarity: Rarity): Trait[];
25
51
  export declare const traitMap: Map<Trait, TraitProps>;
26
52
  export {};
@@ -8,40 +8,69 @@ const rarity_1 = require("./rarity");
8
8
  const node_crypto_1 = require("node:crypto");
9
9
  const traits_json_1 = __importDefault(require("../../stat-config/traits.json"));
10
10
  const sequelize_1 = require("sequelize");
11
- const stats_1 = require("./stats");
11
+ const utils_1 = require("../utils");
12
12
  const traits = traits_json_1.default;
13
13
  var TraitEnum;
14
14
  (function (TraitEnum) {
15
+ /**
16
+ * When triggered, all actions before the net crossing have a bonus.
17
+ */
15
18
  TraitEnum["MASTER_MIND"] = "MASTER_MIND";
19
+ /**
20
+ * When this player is part of the front row, they will always be part of the blocking block
21
+ */
16
22
  TraitEnum["MOVING_WALL"] = "MOVING_WALL";
23
+ /**
24
+ * Enables the player making the second touch to spike or dump
25
+ */
26
+ TraitEnum["SURPRISE_ATTACK"] = "SURPRISE_ATTACK";
27
+ /**
28
+ * Boosts the stat of the action taken and allows the player to choose the best target for the action.
29
+ */
17
30
  TraitEnum["MARKSMAN"] = "MARKSMAN";
31
+ /**
32
+ * The server will perform an extra strong serve.
33
+ */
18
34
  TraitEnum["METEOR_SERVE"] = "METEOR_SERVE";
35
+ /**
36
+ * The player has a 50% chance to perform an action with no energy decrease
37
+ */
19
38
  TraitEnum["VIGOROUS"] = "VIGOROUS";
39
+ /**
40
+ * The player with this trait has a chance to take the receiver's place if their reception stat is higher.
41
+ */
20
42
  TraitEnum["GUARDIAN"] = "GUARDIAN";
43
+ /**
44
+ * Enables the server to perform a float serve, which checks against receiver overhand instead.
45
+ */
21
46
  TraitEnum["FLOAT_SERVE"] = "FLOAT_SERVE";
47
+ /**
48
+ * Gives the player a chance to perform a perfect reception.
49
+ */
50
+ TraitEnum["DEFENSIVE_SPECIALIST"] = "DEFENSIVE_SPECIALIST";
22
51
  })(TraitEnum = exports.TraitEnum || (exports.TraitEnum = {}));
23
52
  exports.TraitDataType = sequelize_1.DataTypes.ENUM(...Object.values(TraitEnum));
24
- function assignTraits(performanceStats, rarity) {
53
+ function assignTraits(roles, rarity) {
25
54
  let traitCount;
26
55
  switch (rarity) {
27
56
  case rarity_1.RarityEnum.COMMON: {
28
- traitCount = 0;
57
+ traitCount = (0, node_crypto_1.randomInt)(0, 1);
29
58
  break;
30
59
  }
31
60
  case rarity_1.RarityEnum.RARE: {
32
- traitCount = (0, node_crypto_1.randomInt)(0, 1);
61
+ traitCount = (0, node_crypto_1.randomInt)(0, 2);
33
62
  break;
34
63
  }
35
64
  case rarity_1.RarityEnum.LEGENDARY: {
36
- traitCount = (0, node_crypto_1.randomInt)(0, 2);
65
+ traitCount = (0, node_crypto_1.randomInt)(1, 3);
37
66
  break;
38
67
  }
39
68
  case rarity_1.RarityEnum.MYTHIC: {
40
- traitCount = (0, node_crypto_1.randomInt)(1, 3);
69
+ traitCount = (0, node_crypto_1.randomInt)(2, 4);
41
70
  break;
42
71
  }
43
72
  case rarity_1.RarityEnum.SPECIAL: {
44
- traitCount = (0, node_crypto_1.randomInt)(2, 3);
73
+ traitCount = 4;
45
74
  break;
46
75
  }
47
76
  default:
@@ -49,10 +78,11 @@ function assignTraits(performanceStats, rarity) {
49
78
  }
50
79
  if (traitCount < 1)
51
80
  return [];
52
- return traits.filter((trait) => (0, stats_1.calculateStatScore)(performanceStats, trait.stat) >= trait.statThreshold)
53
- .sort((t1, t2) => t2.weight - t1.weight)
54
- .map((trait) => trait.name)
55
- .slice(0, traitCount);
81
+ const filteredTraits = traits.filter((trait) => {
82
+ const setA = new Set(trait.roles);
83
+ return roles.some(el => setA.has(el));
84
+ }).map(trait => trait.name);
85
+ return (0, utils_1.shuffle)(filteredTraits).slice(0, traitCount);
56
86
  }
57
87
  exports.assignTraits = assignTraits;
58
88
  exports.traitMap = new Map(traits.map((trait) => [trait.name, trait]));
@@ -1,2 +1,4 @@
1
1
  export * from './string-utils';
2
2
  export * from './object-utils';
3
+ export * from './number-utils';
4
+ export * from './rng-utils';
@@ -16,3 +16,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./string-utils"), exports);
18
18
  __exportStar(require("./object-utils"), exports);
19
+ __exportStar(require("./number-utils"), exports);
20
+ __exportStar(require("./rng-utils"), exports);
@@ -0,0 +1 @@
1
+ export declare function clamp(min: number, max: number, value: number): number;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.clamp = void 0;
4
+ function clamp(min, max, value) {
5
+ return Math.max(min, Math.min(value, max));
6
+ }
7
+ exports.clamp = clamp;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Fisher-Yates shuffle algorithm
3
+ * Shuffles array IN-PLACE
4
+ * @param {any[]} array
5
+ */
6
+ export declare function shuffle<Type>(array: Type[]): Type[];
7
+ export declare function calculateProbability(score: number, scale: number, minP: number, maxP: number): number;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.calculateProbability = exports.shuffle = void 0;
4
+ const number_utils_1 = require("./number-utils");
5
+ /**
6
+ * Fisher-Yates shuffle algorithm
7
+ * Shuffles array IN-PLACE
8
+ * @param {any[]} array
9
+ */
10
+ function shuffle(array) {
11
+ let m = array.length;
12
+ let t;
13
+ let i;
14
+ // While there remain elements to shuffle…
15
+ while (m > 0) {
16
+ // Pick a remaining element…
17
+ i = Math.floor(Math.random() * m--);
18
+ // And swap it with the current element.
19
+ t = array[m];
20
+ array[m] = array[i];
21
+ array[i] = t;
22
+ }
23
+ return array;
24
+ }
25
+ exports.shuffle = shuffle;
26
+ function calculateProbability(score, scale, minP, maxP) {
27
+ const x = score / scale;
28
+ const sigmoid = 1 / (1 + Math.exp(-x));
29
+ const p = minP + (maxP - minP) * sigmoid;
30
+ return (0, number_utils_1.clamp)(0, 1, p);
31
+ }
32
+ exports.calculateProbability = calculateProbability;
@@ -3,56 +3,92 @@
3
3
  "name": "MASTER_MIND",
4
4
  "modifier": 1.1,
5
5
  "chance": 0.2,
6
- "statThreshold": 80,
7
- "stat": "SET",
8
- "weight": 10
6
+ "roles": [
7
+ "SETTER",
8
+ "LIBERO"
9
+ ]
10
+ },
11
+ {
12
+ "name": "SURPRISE_ATTACK",
13
+ "modifier": 1.2,
14
+ "chance": 0.07,
15
+ "roles": [
16
+ "SETTER",
17
+ "OPPOSITE_HITTER"
18
+ ]
9
19
  },
10
20
  {
11
21
  "name": "MOVING_WALL",
12
22
  "modifier": 1.1,
13
23
  "chance": 1,
14
- "statThreshold": 75,
15
- "stat": "BLOCK",
16
- "weight": 5
24
+ "roles": [
25
+ "MIDDLE_BLOCKER",
26
+ "OPPOSITE_HITTER",
27
+ "SETTER"
28
+ ]
17
29
  },
18
30
  {
19
31
  "name": "MARKSMAN",
20
32
  "modifier": 1.05,
21
33
  "chance": 0.5,
22
- "statThreshold": 75,
23
- "stat": "ATTACK",
24
- "weight": 5
34
+ "stat": [
35
+ "SETTER",
36
+ "OPPOSITE_HITTER",
37
+ "OUTSIDE_HITTER",
38
+ "MIDDLE_BLOCKER"
39
+ ]
25
40
  },
26
41
  {
27
42
  "name": "METEOR_SERVE",
28
- "modifier": 1.1,
43
+ "modifier": 1.2,
29
44
  "chance": 0.5,
30
- "statThreshold": 75,
31
- "stat": "SERVE",
32
- "weight": 10
45
+ "stat": [
46
+ "SETTER",
47
+ "OPPOSITE_HITTER",
48
+ "OUTSIDE_HITTER",
49
+ "MIDDLE_BLOCKER"
50
+ ]
33
51
  },
34
52
  {
35
53
  "name": "FLOAT_SERVE",
36
- "modifier": 1,
54
+ "modifier": 1.2,
37
55
  "chance": 0.5,
38
- "statThreshold": 60,
39
- "stat": "SERVE",
40
- "weight": 10
56
+ "stat": [
57
+ "SETTER",
58
+ "OPPOSITE_HITTER",
59
+ "LIBERO",
60
+ "OUTSIDE_HITTER",
61
+ "MIDDLE_BLOCKER"
62
+ ]
41
63
  },
42
64
  {
43
65
  "name": "VIGOROUS",
44
66
  "modifier": 1,
45
- "statThreshold": 60,
46
67
  "chance": 0.5,
47
- "stat": "STAMINA",
48
- "weight": 1
68
+ "roles": [
69
+ "SETTER",
70
+ "OPPOSITE_HITTER",
71
+ "LIBERO",
72
+ "OUTSIDE_HITTER",
73
+ "MIDDLE_BLOCKER"
74
+ ]
49
75
  },
50
76
  {
51
77
  "name": "GUARDIAN",
52
78
  "chance": 0.2,
53
- "statThreshold": 75,
54
79
  "modifier": 1.15,
55
- "stat": "RECEIVE",
56
- "weight": 10
80
+ "stat": [
81
+ "LIBERO",
82
+ "OUTSIDE_HITTER"
83
+ ]
84
+ },
85
+ {
86
+ "name": "DEFENSIVE_SPECIALIST",
87
+ "chance": 0.2,
88
+ "modifier": 1.2,
89
+ "stat": [
90
+ "LIBERO",
91
+ "OUTSIDE_HITTER"
92
+ ]
57
93
  }
58
94
  ]
@@ -26,9 +26,8 @@ export function getMultipliers(statName, performanceStats) {
26
26
  };
27
27
  case StatsEnum.SET:
28
28
  return {
29
- setting: 0.7,
29
+ setting: 0.75,
30
30
  overhand: 0.1,
31
- bump: 0.05,
32
31
  awareness: 0.075,
33
32
  attack: 0.075
34
33
  };
@@ -1,26 +1,52 @@
1
- import { PerformanceStats } from './performance-stats';
2
1
  import { Rarity } from './rarity';
3
2
  import { EnumDataType } from 'sequelize';
4
- import { Stats } from './stats';
3
+ import { Role } from './role';
5
4
  interface TraitProps {
6
5
  readonly name: Trait;
7
6
  readonly modifier: number;
8
7
  readonly chance: number;
9
- readonly statThreshold: number;
10
- readonly stat: Stats;
11
- readonly weight: number;
8
+ readonly roles: Role[];
12
9
  }
13
10
  export declare enum TraitEnum {
11
+ /**
12
+ * When triggered, all actions before the net crossing have a bonus.
13
+ */
14
14
  MASTER_MIND = "MASTER_MIND",
15
+ /**
16
+ * When this player is part of the front row, they will always be part of the blocking block
17
+ */
15
18
  MOVING_WALL = "MOVING_WALL",
19
+ /**
20
+ * Enables the player making the second touch to spike or dump
21
+ */
22
+ SURPRISE_ATTACK = "SURPRISE_ATTACK",
23
+ /**
24
+ * Boosts the stat of the action taken and allows the player to choose the best target for the action.
25
+ */
16
26
  MARKSMAN = "MARKSMAN",
27
+ /**
28
+ * The server will perform an extra strong serve.
29
+ */
17
30
  METEOR_SERVE = "METEOR_SERVE",
31
+ /**
32
+ * The player has a 50% chance to perform an action with no energy decrease
33
+ */
18
34
  VIGOROUS = "VIGOROUS",
35
+ /**
36
+ * The player with this trait has a chance to take the receiver's place if their reception stat is higher.
37
+ */
19
38
  GUARDIAN = "GUARDIAN",
20
- FLOAT_SERVE = "FLOAT_SERVE"
39
+ /**
40
+ * Enables the server to perform a float serve, which checks against receiver overhand instead.
41
+ */
42
+ FLOAT_SERVE = "FLOAT_SERVE",
43
+ /**
44
+ * Gives the player a chance to perform a perfect reception.
45
+ */
46
+ DEFENSIVE_SPECIALIST = "DEFENSIVE_SPECIALIST"
21
47
  }
22
- export type Trait = TraitEnum.FLOAT_SERVE | TraitEnum.GUARDIAN | TraitEnum.MASTER_MIND | TraitEnum.MOVING_WALL | TraitEnum.MARKSMAN | TraitEnum.METEOR_SERVE | TraitEnum.VIGOROUS;
48
+ export type Trait = TraitEnum.FLOAT_SERVE | TraitEnum.SURPRISE_ATTACK | TraitEnum.GUARDIAN | TraitEnum.MASTER_MIND | TraitEnum.MOVING_WALL | TraitEnum.MARKSMAN | TraitEnum.METEOR_SERVE | TraitEnum.VIGOROUS | TraitEnum.DEFENSIVE_SPECIALIST;
23
49
  export declare const TraitDataType: EnumDataType<Trait>;
24
- export declare function assignTraits(performanceStats: PerformanceStats, rarity: Rarity): Trait[];
50
+ export declare function assignTraits(roles: Role[], rarity: Rarity): Trait[];
25
51
  export declare const traitMap: Map<Trait, TraitProps>;
26
52
  export {};
@@ -2,40 +2,69 @@ import { RarityEnum } from './rarity';
2
2
  import { randomInt } from 'node:crypto';
3
3
  import rawTraits from '../../stat-config/traits.json';
4
4
  import { DataTypes } from 'sequelize';
5
- import { calculateStatScore } from './stats';
5
+ import { shuffle } from '../utils';
6
6
  const traits = rawTraits;
7
7
  export var TraitEnum;
8
8
  (function (TraitEnum) {
9
+ /**
10
+ * When triggered, all actions before the net crossing have a bonus.
11
+ */
9
12
  TraitEnum["MASTER_MIND"] = "MASTER_MIND";
13
+ /**
14
+ * When this player is part of the front row, they will always be part of the blocking block
15
+ */
10
16
  TraitEnum["MOVING_WALL"] = "MOVING_WALL";
17
+ /**
18
+ * Enables the player making the second touch to spike or dump
19
+ */
20
+ TraitEnum["SURPRISE_ATTACK"] = "SURPRISE_ATTACK";
21
+ /**
22
+ * Boosts the stat of the action taken and allows the player to choose the best target for the action.
23
+ */
11
24
  TraitEnum["MARKSMAN"] = "MARKSMAN";
25
+ /**
26
+ * The server will perform an extra strong serve.
27
+ */
12
28
  TraitEnum["METEOR_SERVE"] = "METEOR_SERVE";
29
+ /**
30
+ * The player has a 50% chance to perform an action with no energy decrease
31
+ */
13
32
  TraitEnum["VIGOROUS"] = "VIGOROUS";
33
+ /**
34
+ * The player with this trait has a chance to take the receiver's place if their reception stat is higher.
35
+ */
14
36
  TraitEnum["GUARDIAN"] = "GUARDIAN";
37
+ /**
38
+ * Enables the server to perform a float serve, which checks against receiver overhand instead.
39
+ */
15
40
  TraitEnum["FLOAT_SERVE"] = "FLOAT_SERVE";
41
+ /**
42
+ * Gives the player a chance to perform a perfect reception.
43
+ */
44
+ TraitEnum["DEFENSIVE_SPECIALIST"] = "DEFENSIVE_SPECIALIST";
16
45
  })(TraitEnum || (TraitEnum = {}));
17
46
  export const TraitDataType = DataTypes.ENUM(...Object.values(TraitEnum));
18
- export function assignTraits(performanceStats, rarity) {
47
+ export function assignTraits(roles, rarity) {
19
48
  let traitCount;
20
49
  switch (rarity) {
21
50
  case RarityEnum.COMMON: {
22
- traitCount = 0;
51
+ traitCount = randomInt(0, 1);
23
52
  break;
24
53
  }
25
54
  case RarityEnum.RARE: {
26
- traitCount = randomInt(0, 1);
55
+ traitCount = randomInt(0, 2);
27
56
  break;
28
57
  }
29
58
  case RarityEnum.LEGENDARY: {
30
- traitCount = randomInt(0, 2);
59
+ traitCount = randomInt(1, 3);
31
60
  break;
32
61
  }
33
62
  case RarityEnum.MYTHIC: {
34
- traitCount = randomInt(1, 3);
63
+ traitCount = randomInt(2, 4);
35
64
  break;
36
65
  }
37
66
  case RarityEnum.SPECIAL: {
38
- traitCount = randomInt(2, 3);
67
+ traitCount = 4;
39
68
  break;
40
69
  }
41
70
  default:
@@ -43,9 +72,10 @@ export function assignTraits(performanceStats, rarity) {
43
72
  }
44
73
  if (traitCount < 1)
45
74
  return [];
46
- return traits.filter((trait) => calculateStatScore(performanceStats, trait.stat) >= trait.statThreshold)
47
- .sort((t1, t2) => t2.weight - t1.weight)
48
- .map((trait) => trait.name)
49
- .slice(0, traitCount);
75
+ const filteredTraits = traits.filter((trait) => {
76
+ const setA = new Set(trait.roles);
77
+ return roles.some(el => setA.has(el));
78
+ }).map(trait => trait.name);
79
+ return shuffle(filteredTraits).slice(0, traitCount);
50
80
  }
51
81
  export const traitMap = new Map(traits.map((trait) => [trait.name, trait]));
@@ -1,2 +1,4 @@
1
1
  export * from './string-utils';
2
2
  export * from './object-utils';
3
+ export * from './number-utils';
4
+ export * from './rng-utils';
@@ -1,2 +1,4 @@
1
1
  export * from './string-utils';
2
2
  export * from './object-utils';
3
+ export * from './number-utils';
4
+ export * from './rng-utils';
@@ -0,0 +1 @@
1
+ export declare function clamp(min: number, max: number, value: number): number;
@@ -0,0 +1,3 @@
1
+ export function clamp(min, max, value) {
2
+ return Math.max(min, Math.min(value, max));
3
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Fisher-Yates shuffle algorithm
3
+ * Shuffles array IN-PLACE
4
+ * @param {any[]} array
5
+ */
6
+ export declare function shuffle<Type>(array: Type[]): Type[];
7
+ export declare function calculateProbability(score: number, scale: number, minP: number, maxP: number): number;
@@ -0,0 +1,27 @@
1
+ import { clamp } from './number-utils';
2
+ /**
3
+ * Fisher-Yates shuffle algorithm
4
+ * Shuffles array IN-PLACE
5
+ * @param {any[]} array
6
+ */
7
+ export function shuffle(array) {
8
+ let m = array.length;
9
+ let t;
10
+ let i;
11
+ // While there remain elements to shuffle…
12
+ while (m > 0) {
13
+ // Pick a remaining element…
14
+ i = Math.floor(Math.random() * m--);
15
+ // And swap it with the current element.
16
+ t = array[m];
17
+ array[m] = array[i];
18
+ array[i] = t;
19
+ }
20
+ return array;
21
+ }
22
+ export function calculateProbability(score, scale, minP, maxP) {
23
+ const x = score / scale;
24
+ const sigmoid = 1 / (1 + Math.exp(-x));
25
+ const p = minP + (maxP - minP) * sigmoid;
26
+ return clamp(0, 1, p);
27
+ }
@@ -3,56 +3,92 @@
3
3
  "name": "MASTER_MIND",
4
4
  "modifier": 1.1,
5
5
  "chance": 0.2,
6
- "statThreshold": 80,
7
- "stat": "SET",
8
- "weight": 10
6
+ "roles": [
7
+ "SETTER",
8
+ "LIBERO"
9
+ ]
10
+ },
11
+ {
12
+ "name": "SURPRISE_ATTACK",
13
+ "modifier": 1.2,
14
+ "chance": 0.07,
15
+ "roles": [
16
+ "SETTER",
17
+ "OPPOSITE_HITTER"
18
+ ]
9
19
  },
10
20
  {
11
21
  "name": "MOVING_WALL",
12
22
  "modifier": 1.1,
13
23
  "chance": 1,
14
- "statThreshold": 75,
15
- "stat": "BLOCK",
16
- "weight": 5
24
+ "roles": [
25
+ "MIDDLE_BLOCKER",
26
+ "OPPOSITE_HITTER",
27
+ "SETTER"
28
+ ]
17
29
  },
18
30
  {
19
31
  "name": "MARKSMAN",
20
32
  "modifier": 1.05,
21
33
  "chance": 0.5,
22
- "statThreshold": 75,
23
- "stat": "ATTACK",
24
- "weight": 5
34
+ "stat": [
35
+ "SETTER",
36
+ "OPPOSITE_HITTER",
37
+ "OUTSIDE_HITTER",
38
+ "MIDDLE_BLOCKER"
39
+ ]
25
40
  },
26
41
  {
27
42
  "name": "METEOR_SERVE",
28
- "modifier": 1.1,
43
+ "modifier": 1.2,
29
44
  "chance": 0.5,
30
- "statThreshold": 75,
31
- "stat": "SERVE",
32
- "weight": 10
45
+ "stat": [
46
+ "SETTER",
47
+ "OPPOSITE_HITTER",
48
+ "OUTSIDE_HITTER",
49
+ "MIDDLE_BLOCKER"
50
+ ]
33
51
  },
34
52
  {
35
53
  "name": "FLOAT_SERVE",
36
- "modifier": 1,
54
+ "modifier": 1.2,
37
55
  "chance": 0.5,
38
- "statThreshold": 60,
39
- "stat": "SERVE",
40
- "weight": 10
56
+ "stat": [
57
+ "SETTER",
58
+ "OPPOSITE_HITTER",
59
+ "LIBERO",
60
+ "OUTSIDE_HITTER",
61
+ "MIDDLE_BLOCKER"
62
+ ]
41
63
  },
42
64
  {
43
65
  "name": "VIGOROUS",
44
66
  "modifier": 1,
45
- "statThreshold": 60,
46
67
  "chance": 0.5,
47
- "stat": "STAMINA",
48
- "weight": 1
68
+ "roles": [
69
+ "SETTER",
70
+ "OPPOSITE_HITTER",
71
+ "LIBERO",
72
+ "OUTSIDE_HITTER",
73
+ "MIDDLE_BLOCKER"
74
+ ]
49
75
  },
50
76
  {
51
77
  "name": "GUARDIAN",
52
78
  "chance": 0.2,
53
- "statThreshold": 75,
54
79
  "modifier": 1.15,
55
- "stat": "RECEIVE",
56
- "weight": 10
80
+ "stat": [
81
+ "LIBERO",
82
+ "OUTSIDE_HITTER"
83
+ ]
84
+ },
85
+ {
86
+ "name": "DEFENSIVE_SPECIALIST",
87
+ "chance": 0.2,
88
+ "modifier": 1.2,
89
+ "stat": [
90
+ "LIBERO",
91
+ "OUTSIDE_HITTER"
92
+ ]
57
93
  }
58
94
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "volleyballsimtypes",
3
- "version": "0.0.169",
3
+ "version": "0.0.170",
4
4
  "description": "vbsim types",
5
5
  "main": "./dist/cjs/src/index.js",
6
6
  "module": "./dist/esm/src/index.js",