volleyballsimtypes 0.0.448 → 0.0.451

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.
@@ -33,14 +33,17 @@ function transformToAttributes(season) {
33
33
  };
34
34
  }
35
35
  function transformToObject(model) {
36
- const standings = model.CompetitionStandings != null && model.CompetitionStandings.length > 0
37
- ? model.CompetitionStandings.map(_1.transformToStanding)
38
- : undefined;
36
+ const teams = (0, _1.sortTeamsByCompetitionIndex)(model.Teams ?? []).map(_1.transformToTeam);
37
+ // One standing per roster team: the persisted CompetitionStandings aggregate where it exists, a zero-stat
38
+ // row otherwise. CompetitionStandings only gains a row once a team plays (the DB trigger fires on match
39
+ // COMPLETE), so mapping it directly dropped un-played teams from the table for the first part of a season.
40
+ const standingByTeam = new Map((model.CompetitionStandings ?? []).map(s => [s.team_id, (0, _1.transformToStanding)(s)]));
41
+ const standings = teams.map(t => standingByTeam.get(t.id) ?? service_1.Standing.create({ teamId: t.id }));
39
42
  return service_1.Season.create({
40
43
  id: model.competition_id,
41
44
  matches: (model.CompetitionMatches ?? []).map((matches) => (0, _1.transformToMatch)(matches.Match)),
42
45
  iteration: (0, _1.transformToIteration)(model.Iteration),
43
- teams: (0, _1.sortTeamsByCompetitionIndex)(model.Teams ?? []).map(_1.transformToTeam),
46
+ teams,
44
47
  champion: model.CompetitionChampion != null ? (0, _1.transformToTeam)(model.CompetitionChampion.team) : undefined,
45
48
  status: model.status,
46
49
  divisionId: model.DivisionSeason.division_id,
@@ -304,7 +304,7 @@ class PlayerGenerator {
304
304
  const rarity = _rarity ?? rollRarity({ legendaryPity: 0, mythicPity: 0, specialPity: 0 }).rarity;
305
305
  const name = (0, utils_1.generatePlayerName)(country.locales, 1)[0];
306
306
  const stats = PlayerGenerator.generatePerformance(rarity, role);
307
- const roles = (0, role_1.assignRoles)(stats, rarity);
307
+ const roles = (0, role_1.assignRoles)(stats, rarity, role);
308
308
  const traits = (0, trait_1.assignTraits)(roles, rarity, maxTraits);
309
309
  const birthAge = (0, node_crypto_1.randomInt)(15, 21);
310
310
  const declineProfile = decline_1.declineProfiles[(0, node_crypto_1.randomInt)(0, decline_1.declineProfiles.length)];
@@ -14,7 +14,7 @@ export interface RolesFormula {
14
14
  weight: PerformanceStatsParams;
15
15
  }
16
16
  export declare function calculateRoleScore(stats: PerformanceStats, role: Role): number;
17
- export declare function assignRoles(stats: PerformanceStats, rarity: Rarity): Role[];
17
+ export declare function assignRoles(stats: PerformanceStats, rarity: Rarity, forcedRole?: Role): Role[];
18
18
  /**
19
19
  * Returns the role-based multiplier for a player performing a given action.
20
20
  * When the player holds multiple roles, the least-penalising role wins.
@@ -43,7 +43,7 @@ function getRoleCountRange(rarity) {
43
43
  default: return [1, 1];
44
44
  }
45
45
  }
46
- function assignRoles(stats, rarity) {
46
+ function assignRoles(stats, rarity, forcedRole) {
47
47
  const scores = Object.values(RoleEnum)
48
48
  .map((role) => ({
49
49
  role,
@@ -52,6 +52,12 @@ function assignRoles(stats, rarity) {
52
52
  .sort((x, y) => y.score - x.score);
53
53
  const [min, max] = getRoleCountRange(rarity);
54
54
  const count = min + Math.floor(Math.random() * (max - min + 1));
55
+ // A forced role (role pick, wishlist proc, team seeding) must be the player's primary role.
56
+ // Remaining slots fill with the top-scoring other roles so multi-role rarity flavour is kept.
57
+ if (forcedRole != null) {
58
+ const others = scores.map(s => s.role).filter(r => r !== forcedRole);
59
+ return [forcedRole, ...others].slice(0, count);
60
+ }
55
61
  return scores.slice(0, count).map(s => s.role);
56
62
  }
57
63
  // ─── Role event penalties ─────────────────────────────────────────────────────
@@ -1,5 +1,5 @@
1
1
  import { sortTeamsByCompetitionIndex, transformFromSeasonMatch, transformToIteration, transformToMatch, transformToStanding, transformToTeam } from '.';
2
- import { Season } from '../../service';
2
+ import { Season, Standing } from '../../service';
3
3
  function transformToAttributes(season) {
4
4
  const matches = (season.matches ?? []).map((match, index) => transformFromSeasonMatch(season.id, match, index));
5
5
  const teams = season.teams.map((team, index) => ({
@@ -29,14 +29,17 @@ function transformToAttributes(season) {
29
29
  };
30
30
  }
31
31
  function transformToObject(model) {
32
- const standings = model.CompetitionStandings != null && model.CompetitionStandings.length > 0
33
- ? model.CompetitionStandings.map(transformToStanding)
34
- : undefined;
32
+ const teams = sortTeamsByCompetitionIndex(model.Teams ?? []).map(transformToTeam);
33
+ // One standing per roster team: the persisted CompetitionStandings aggregate where it exists, a zero-stat
34
+ // row otherwise. CompetitionStandings only gains a row once a team plays (the DB trigger fires on match
35
+ // COMPLETE), so mapping it directly dropped un-played teams from the table for the first part of a season.
36
+ const standingByTeam = new Map((model.CompetitionStandings ?? []).map(s => [s.team_id, transformToStanding(s)]));
37
+ const standings = teams.map(t => standingByTeam.get(t.id) ?? Standing.create({ teamId: t.id }));
35
38
  return Season.create({
36
39
  id: model.competition_id,
37
40
  matches: (model.CompetitionMatches ?? []).map((matches) => transformToMatch(matches.Match)),
38
41
  iteration: transformToIteration(model.Iteration),
39
- teams: sortTeamsByCompetitionIndex(model.Teams ?? []).map(transformToTeam),
42
+ teams,
40
43
  champion: model.CompetitionChampion != null ? transformToTeam(model.CompetitionChampion.team) : undefined,
41
44
  status: model.status,
42
45
  divisionId: model.DivisionSeason.division_id,
@@ -298,7 +298,7 @@ export class PlayerGenerator {
298
298
  const rarity = _rarity ?? rollRarity({ legendaryPity: 0, mythicPity: 0, specialPity: 0 }).rarity;
299
299
  const name = generatePlayerName(country.locales, 1)[0];
300
300
  const stats = PlayerGenerator.generatePerformance(rarity, role);
301
- const roles = assignRoles(stats, rarity);
301
+ const roles = assignRoles(stats, rarity, role);
302
302
  const traits = assignTraits(roles, rarity, maxTraits);
303
303
  const birthAge = randomInt(15, 21);
304
304
  const declineProfile = declineProfiles[randomInt(0, declineProfiles.length)];
@@ -14,7 +14,7 @@ export interface RolesFormula {
14
14
  weight: PerformanceStatsParams;
15
15
  }
16
16
  export declare function calculateRoleScore(stats: PerformanceStats, role: Role): number;
17
- export declare function assignRoles(stats: PerformanceStats, rarity: Rarity): Role[];
17
+ export declare function assignRoles(stats: PerformanceStats, rarity: Rarity, forcedRole?: Role): Role[];
18
18
  /**
19
19
  * Returns the role-based multiplier for a player performing a given action.
20
20
  * When the player holds multiple roles, the least-penalising role wins.
@@ -33,7 +33,7 @@ function getRoleCountRange(rarity) {
33
33
  default: return [1, 1];
34
34
  }
35
35
  }
36
- export function assignRoles(stats, rarity) {
36
+ export function assignRoles(stats, rarity, forcedRole) {
37
37
  const scores = Object.values(RoleEnum)
38
38
  .map((role) => ({
39
39
  role,
@@ -42,6 +42,12 @@ export function assignRoles(stats, rarity) {
42
42
  .sort((x, y) => y.score - x.score);
43
43
  const [min, max] = getRoleCountRange(rarity);
44
44
  const count = min + Math.floor(Math.random() * (max - min + 1));
45
+ // A forced role (role pick, wishlist proc, team seeding) must be the player's primary role.
46
+ // Remaining slots fill with the top-scoring other roles so multi-role rarity flavour is kept.
47
+ if (forcedRole != null) {
48
+ const others = scores.map(s => s.role).filter(r => r !== forcedRole);
49
+ return [forcedRole, ...others].slice(0, count);
50
+ }
45
51
  return scores.slice(0, count).map(s => s.role);
46
52
  }
47
53
  // ─── Role event penalties ─────────────────────────────────────────────────────
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "volleyballsimtypes",
3
- "version": "0.0.448",
3
+ "version": "0.0.451",
4
4
  "description": "vbsim types",
5
5
  "main": "./dist/cjs/src/index.js",
6
6
  "module": "./dist/esm/src/index.js",