volleyballsimtypes 0.0.358 → 0.0.360
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/src/data/models/player.d.ts +5 -1
- package/dist/cjs/src/data/models/player.js +10 -0
- package/dist/cjs/src/data/transformers/player.js +5 -1
- package/dist/cjs/src/service/player/decline.d.ts +43 -0
- package/dist/cjs/src/service/player/decline.js +55 -0
- package/dist/cjs/src/service/player/index.d.ts +1 -0
- package/dist/cjs/src/service/player/index.js +1 -0
- package/dist/cjs/src/service/player/player-generator.js +12 -9
- package/dist/cjs/src/service/player/player.d.ts +3 -0
- package/dist/cjs/src/service/player/player.js +3 -1
- package/dist/cjs/src/service/player/schemas/player.z.d.ts +8 -0
- package/dist/cjs/src/service/player/schemas/player.z.js +3 -0
- package/dist/cjs/src/service/test-helpers.js +4 -1
- package/dist/cjs/src/stat-config/decline-profiles.json +6 -0
- package/dist/cjs/src/stat-config/index.d.ts +2 -1
- package/dist/cjs/src/stat-config/index.js +3 -1
- package/dist/esm/src/data/models/player.d.ts +5 -1
- package/dist/esm/src/data/models/player.js +11 -1
- package/dist/esm/src/data/transformers/player.js +5 -1
- package/dist/esm/src/service/player/decline.d.ts +43 -0
- package/dist/esm/src/service/player/decline.js +50 -0
- package/dist/esm/src/service/player/index.d.ts +1 -0
- package/dist/esm/src/service/player/index.js +1 -0
- package/dist/esm/src/service/player/player-generator.js +12 -9
- package/dist/esm/src/service/player/player.d.ts +3 -0
- package/dist/esm/src/service/player/player.js +3 -1
- package/dist/esm/src/service/player/schemas/player.z.d.ts +8 -0
- package/dist/esm/src/service/player/schemas/player.z.js +3 -0
- package/dist/esm/src/service/test-helpers.js +4 -1
- package/dist/esm/src/stat-config/decline-profiles.json +6 -0
- package/dist/esm/src/stat-config/index.d.ts +2 -1
- package/dist/esm/src/stat-config/index.js +2 -1
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as Sequelize from 'sequelize';
|
|
2
2
|
import { Model } from 'sequelize';
|
|
3
3
|
import { BoxScoreAttributes, BoxScoreId, BoxScoreModel, BoxScoreTotalsId, BoxScoreTotalsModel, CompetitionMVPId, CompetitionMVPModel, CountryId, CountryModel, MatchSetId, MatchSetModel, PerformanceStatsAttributes, PerformanceStatsId, PerformanceStatsModel, PlayerTeamId, PlayerTeamModel, TeamId, TeamModel, VPERId, VPERModel } from '.';
|
|
4
|
-
import { Rarity, Role, Trait } from '../../service';
|
|
4
|
+
import { DeclineProfile, Rarity, Role, Trait } from '../../service';
|
|
5
5
|
export interface PlayerAttributes {
|
|
6
6
|
player_id: string;
|
|
7
7
|
roles: Role[];
|
|
@@ -10,6 +10,8 @@ export interface PlayerAttributes {
|
|
|
10
10
|
first_name: string;
|
|
11
11
|
last_name: string;
|
|
12
12
|
country_id: string;
|
|
13
|
+
age: number;
|
|
14
|
+
decline_profile: DeclineProfile;
|
|
13
15
|
PerformanceStat?: PerformanceStatsAttributes;
|
|
14
16
|
BoxScores?: BoxScoreAttributes[];
|
|
15
17
|
}
|
|
@@ -24,6 +26,8 @@ export declare class PlayerModel extends Model<PlayerAttributes, PlayerCreationA
|
|
|
24
26
|
first_name: string;
|
|
25
27
|
last_name: string;
|
|
26
28
|
country_id: string;
|
|
29
|
+
age: number;
|
|
30
|
+
decline_profile: DeclineProfile;
|
|
27
31
|
country: CountryModel;
|
|
28
32
|
getCountry: Sequelize.BelongsToGetAssociationMixin<CountryModel>;
|
|
29
33
|
setCountry: Sequelize.BelongsToSetAssociationMixin<CountryModel, CountryId>;
|
|
@@ -39,6 +39,16 @@ class PlayerModel extends sequelize_1.Model {
|
|
|
39
39
|
model: 'Country',
|
|
40
40
|
key: 'country_id'
|
|
41
41
|
}
|
|
42
|
+
},
|
|
43
|
+
age: {
|
|
44
|
+
type: sequelize_1.DataTypes.INTEGER,
|
|
45
|
+
allowNull: false,
|
|
46
|
+
defaultValue: 17
|
|
47
|
+
},
|
|
48
|
+
decline_profile: {
|
|
49
|
+
type: sequelize_1.DataTypes.ENUM(...Object.values(service_1.DeclineProfileEnum)),
|
|
50
|
+
allowNull: false,
|
|
51
|
+
defaultValue: service_1.DeclineProfileEnum.STANDARD
|
|
42
52
|
}
|
|
43
53
|
}, {
|
|
44
54
|
sequelize,
|
|
@@ -20,7 +20,9 @@ function transformToAttributes(player) {
|
|
|
20
20
|
roles: player.roles,
|
|
21
21
|
traits: player.traits,
|
|
22
22
|
PerformanceStat: (0, _1.transformFromPerformanceStats)(player.stats, player.id),
|
|
23
|
-
rarity: player.rarity
|
|
23
|
+
rarity: player.rarity,
|
|
24
|
+
age: player.age,
|
|
25
|
+
decline_profile: player.declineProfile
|
|
24
26
|
};
|
|
25
27
|
}
|
|
26
28
|
function transformToBoxScoreTotals(model) {
|
|
@@ -79,6 +81,8 @@ function transformToObject(model) {
|
|
|
79
81
|
traits: model.traits,
|
|
80
82
|
stats: (0, _1.transformToPerformanceStats)(model.PerformanceStat),
|
|
81
83
|
rarity: model.rarity,
|
|
84
|
+
age: model.age,
|
|
85
|
+
declineProfile: model.decline_profile,
|
|
82
86
|
boxScores: (model.BoxScores ?? []).map(_1.transformToBoxScore),
|
|
83
87
|
boxScoreTotals
|
|
84
88
|
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { PerformanceStatsKey } from './performance-stats-keys';
|
|
2
|
+
export declare enum DeclineProfileEnum {
|
|
3
|
+
PRODIGY = "PRODIGY",
|
|
4
|
+
STANDARD = "STANDARD",
|
|
5
|
+
VETERAN = "VETERAN",
|
|
6
|
+
IRONMAN = "IRONMAN"
|
|
7
|
+
}
|
|
8
|
+
export type DeclineProfile = DeclineProfileEnum.PRODIGY | DeclineProfileEnum.STANDARD | DeclineProfileEnum.VETERAN | DeclineProfileEnum.IRONMAN;
|
|
9
|
+
export declare const declineProfiles: DeclineProfileEnum[];
|
|
10
|
+
interface DeclineProfileEntry {
|
|
11
|
+
profile: string;
|
|
12
|
+
startAge: number;
|
|
13
|
+
initTicks: number;
|
|
14
|
+
accel: number;
|
|
15
|
+
peakTicks: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Stats that decline first (technique / skill). One random stat from this pool is
|
|
19
|
+
* removed per tick during the pre-peak decline phase.
|
|
20
|
+
*/
|
|
21
|
+
export declare const SKILL_POOL: PerformanceStatsKey[];
|
|
22
|
+
/**
|
|
23
|
+
* Energy / reaction stats (incl. crit-chance stats). These only start declining
|
|
24
|
+
* once the player reaches peak decline, alongside the skill pool.
|
|
25
|
+
*/
|
|
26
|
+
export declare const ENERGY_POOL: PerformanceStatsKey[];
|
|
27
|
+
export declare function getDeclineProfile(profile: DeclineProfile): DeclineProfileEntry;
|
|
28
|
+
export type DeclineStatus = 'ACTIVE' | 'DECLINING' | 'PEAK';
|
|
29
|
+
export interface DeclineTick {
|
|
30
|
+
/** Number of decline ticks to apply this iteration. */
|
|
31
|
+
ticks: number;
|
|
32
|
+
/** True once tick rate hits the profile ceiling — both pools decline and training is blocked. */
|
|
33
|
+
atPeak: boolean;
|
|
34
|
+
/** Coarse status for display / gating. */
|
|
35
|
+
status: DeclineStatus;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Decline is fully derivable from age + profile — no running state is persisted.
|
|
39
|
+
* tickRate = min(peakTicks, initTicks + (age - startAge) * accel)
|
|
40
|
+
* Pre-peak: `ticks` random SKILL stats lost. At peak: `ticks` from BOTH pools + training blocked.
|
|
41
|
+
*/
|
|
42
|
+
export declare function computeDeclineTick(age: number, profile: DeclineProfile): DeclineTick;
|
|
43
|
+
export {};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ENERGY_POOL = exports.SKILL_POOL = exports.declineProfiles = exports.DeclineProfileEnum = void 0;
|
|
4
|
+
exports.getDeclineProfile = getDeclineProfile;
|
|
5
|
+
exports.computeDeclineTick = computeDeclineTick;
|
|
6
|
+
const stat_config_1 = require("../../stat-config");
|
|
7
|
+
var DeclineProfileEnum;
|
|
8
|
+
(function (DeclineProfileEnum) {
|
|
9
|
+
DeclineProfileEnum["PRODIGY"] = "PRODIGY";
|
|
10
|
+
DeclineProfileEnum["STANDARD"] = "STANDARD";
|
|
11
|
+
DeclineProfileEnum["VETERAN"] = "VETERAN";
|
|
12
|
+
DeclineProfileEnum["IRONMAN"] = "IRONMAN";
|
|
13
|
+
})(DeclineProfileEnum || (exports.DeclineProfileEnum = DeclineProfileEnum = {}));
|
|
14
|
+
exports.declineProfiles = Object.values(DeclineProfileEnum);
|
|
15
|
+
const profileEntries = stat_config_1.declineProfilesJSON;
|
|
16
|
+
/**
|
|
17
|
+
* Stats that decline first (technique / skill). One random stat from this pool is
|
|
18
|
+
* removed per tick during the pre-peak decline phase.
|
|
19
|
+
*/
|
|
20
|
+
exports.SKILL_POOL = [
|
|
21
|
+
'setting', 'serve', 'spike', 'quick', 'power', 'backAttack',
|
|
22
|
+
'reception', 'overhand', 'bump', 'block', 'attack', 'defense'
|
|
23
|
+
];
|
|
24
|
+
/**
|
|
25
|
+
* Energy / reaction stats (incl. crit-chance stats). These only start declining
|
|
26
|
+
* once the player reaches peak decline, alongside the skill pool.
|
|
27
|
+
*/
|
|
28
|
+
exports.ENERGY_POOL = [
|
|
29
|
+
'stamina', 'reflex', 'read', 'commit', 'awareness', 'focus'
|
|
30
|
+
];
|
|
31
|
+
function getDeclineProfile(profile) {
|
|
32
|
+
const entry = profileEntries.find(e => e.profile === profile);
|
|
33
|
+
if (entry == null)
|
|
34
|
+
throw new Error(`UNKNOWN_DECLINE_PROFILE: ${profile}`);
|
|
35
|
+
return entry;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Decline is fully derivable from age + profile — no running state is persisted.
|
|
39
|
+
* tickRate = min(peakTicks, initTicks + (age - startAge) * accel)
|
|
40
|
+
* Pre-peak: `ticks` random SKILL stats lost. At peak: `ticks` from BOTH pools + training blocked.
|
|
41
|
+
*/
|
|
42
|
+
function computeDeclineTick(age, profile) {
|
|
43
|
+
const { startAge, initTicks, accel, peakTicks } = getDeclineProfile(profile);
|
|
44
|
+
if (age < startAge) {
|
|
45
|
+
return { ticks: 0, atPeak: false, status: 'ACTIVE' };
|
|
46
|
+
}
|
|
47
|
+
const rawRate = initTicks + (age - startAge) * accel;
|
|
48
|
+
const tickRate = Math.min(peakTicks, rawRate);
|
|
49
|
+
const atPeak = rawRate >= peakTicks;
|
|
50
|
+
return {
|
|
51
|
+
ticks: Math.round(tickRate),
|
|
52
|
+
atPeak,
|
|
53
|
+
status: atPeak ? 'PEAK' : 'DECLINING'
|
|
54
|
+
};
|
|
55
|
+
}
|
|
@@ -16,6 +16,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./player"), exports);
|
|
18
18
|
__exportStar(require("./improvement"), exports);
|
|
19
|
+
__exportStar(require("./decline"), exports);
|
|
19
20
|
__exportStar(require("./player-generator"), exports);
|
|
20
21
|
__exportStar(require("./performance-stats"), exports);
|
|
21
22
|
__exportStar(require("./trait"), exports);
|
|
@@ -13,6 +13,7 @@ const stat_config_1 = require("../../stat-config");
|
|
|
13
13
|
const utils_1 = require("../utils");
|
|
14
14
|
const player_1 = require("./player");
|
|
15
15
|
const trait_1 = require("./trait");
|
|
16
|
+
const decline_1 = require("./decline");
|
|
16
17
|
const LEGENDARY_PITY_STEP = 0.004;
|
|
17
18
|
const MYTHIC_PITY_STEP = 0.00001;
|
|
18
19
|
const SPECIAL_PITY_STEP = 0.000005;
|
|
@@ -115,12 +116,12 @@ class PlayerGenerator {
|
|
|
115
116
|
const BLOCK = (0, stats_1.getMultipliers)(stats_1.StatsEnum.BLOCK);
|
|
116
117
|
const SERVE = (0, stats_1.getMultipliers)(stats_1.StatsEnum.SERVE);
|
|
117
118
|
const STAMINA = (0, stats_1.getMultipliers)(stats_1.StatsEnum.STAMINA);
|
|
118
|
-
function buildPerformanceFromRole(weights, maxValue) {
|
|
119
|
+
function buildPerformanceFromRole(weights, minValue, maxValue) {
|
|
119
120
|
return performance_stats_1.PerformanceStats.create(Object.fromEntries(performance_stats_1.performanceStatKeys.map((key) => {
|
|
120
121
|
if (weights[key] > 0)
|
|
121
|
-
return [key, maxValue];
|
|
122
|
+
return [key, (0, node_crypto_1.randomInt)(minValue, maxValue + 1)];
|
|
122
123
|
else
|
|
123
|
-
return [key,
|
|
124
|
+
return [key, (0, node_crypto_1.randomInt)(rarity_1.RarityRanges.COMMON[0], Math.max(minValue - 1, rarity_1.RarityRanges.COMMON[0] + 1))];
|
|
124
125
|
})));
|
|
125
126
|
}
|
|
126
127
|
switch (rarity) {
|
|
@@ -128,7 +129,7 @@ class PlayerGenerator {
|
|
|
128
129
|
if (role != null) {
|
|
129
130
|
const weights = stat_config_1.rolesJSON.find(entry => entry.role === role)?.weight;
|
|
130
131
|
if (weights != null) {
|
|
131
|
-
return buildPerformanceFromRole(weights, rarity_1.RarityRanges.COMMON[1]);
|
|
132
|
+
return buildPerformanceFromRole(weights, rarity_1.RarityRanges.COMMON[0], rarity_1.RarityRanges.COMMON[1]);
|
|
132
133
|
}
|
|
133
134
|
}
|
|
134
135
|
return performance_stats_1.PerformanceStats.create(Object.fromEntries(performance_stats_1.performanceStatKeys.map((key) => [key, Math.round((0, node_crypto_1.randomInt)(rarity_1.RarityRanges.COMMON[0], rarity_1.RarityRanges.COMMON[1]))])));
|
|
@@ -137,7 +138,7 @@ class PlayerGenerator {
|
|
|
137
138
|
if (role != null) {
|
|
138
139
|
const weights = stat_config_1.rolesJSON.find(entry => entry.role === role)?.weight;
|
|
139
140
|
if (weights != null) {
|
|
140
|
-
return buildPerformanceFromRole(weights, rarity_1.RarityRanges.RARE[1]);
|
|
141
|
+
return buildPerformanceFromRole(weights, rarity_1.RarityRanges.RARE[0], rarity_1.RarityRanges.RARE[1]);
|
|
141
142
|
}
|
|
142
143
|
}
|
|
143
144
|
const stats = (0, utils_1.shuffle)([ATTACK, SET, SERVE, RECEIVE, BLOCK]);
|
|
@@ -155,7 +156,7 @@ class PlayerGenerator {
|
|
|
155
156
|
if (role != null) {
|
|
156
157
|
const weights = stat_config_1.rolesJSON.find(entry => entry.role === role)?.weight;
|
|
157
158
|
if (weights != null) {
|
|
158
|
-
return buildPerformanceFromRole(weights, rarity_1.RarityRanges.LEGENDARY[1]);
|
|
159
|
+
return buildPerformanceFromRole(weights, rarity_1.RarityRanges.LEGENDARY[0], rarity_1.RarityRanges.LEGENDARY[1]);
|
|
159
160
|
}
|
|
160
161
|
}
|
|
161
162
|
const s1 = (0, utils_1.shuffle)([ATTACK, SET, RECEIVE, BLOCK]);
|
|
@@ -174,7 +175,7 @@ class PlayerGenerator {
|
|
|
174
175
|
if (role != null) {
|
|
175
176
|
const weights = stat_config_1.rolesJSON.find(entry => entry.role === role)?.weight;
|
|
176
177
|
if (weights != null) {
|
|
177
|
-
return buildPerformanceFromRole(weights, rarity_1.RarityRanges.MYTHIC[1]);
|
|
178
|
+
return buildPerformanceFromRole(weights, rarity_1.RarityRanges.MYTHIC[0], rarity_1.RarityRanges.MYTHIC[1]);
|
|
178
179
|
}
|
|
179
180
|
}
|
|
180
181
|
const stats = (0, utils_1.shuffle)([ATTACK, SET, RECEIVE, BLOCK]);
|
|
@@ -192,7 +193,7 @@ class PlayerGenerator {
|
|
|
192
193
|
if (role != null) {
|
|
193
194
|
const weights = stat_config_1.rolesJSON.find(entry => entry.role === role)?.weight;
|
|
194
195
|
if (weights != null) {
|
|
195
|
-
return buildPerformanceFromRole(weights, rarity_1.RarityRanges.SPECIAL[1]);
|
|
196
|
+
return buildPerformanceFromRole(weights, rarity_1.RarityRanges.SPECIAL[0], rarity_1.RarityRanges.SPECIAL[1]);
|
|
196
197
|
}
|
|
197
198
|
}
|
|
198
199
|
const stats = (0, utils_1.shuffle)([ATTACK, SERVE, SET, RECEIVE, BLOCK]);
|
|
@@ -218,7 +219,9 @@ class PlayerGenerator {
|
|
|
218
219
|
const stats = PlayerGenerator.generatePerformance(rarity, role);
|
|
219
220
|
const roles = (0, role_1.assignRoles)(stats, rarity);
|
|
220
221
|
const traits = (0, trait_1.assignTraits)(roles, rarity, maxTraits);
|
|
221
|
-
|
|
222
|
+
const age = (0, node_crypto_1.randomInt)(15, 21);
|
|
223
|
+
const declineProfile = decline_1.declineProfiles[(0, node_crypto_1.randomInt)(0, decline_1.declineProfiles.length)];
|
|
224
|
+
return player_1.Player.create({ id: (0, uuid_1.v4)(), name, country, stats, roles, traits, rarity, age, declineProfile });
|
|
222
225
|
}
|
|
223
226
|
static generatePlayers(count, countries) {
|
|
224
227
|
const players = [];
|
|
@@ -5,6 +5,7 @@ import { Rarity } from './rarity';
|
|
|
5
5
|
import { Stats } from './stats';
|
|
6
6
|
import { Role } from './role';
|
|
7
7
|
import { BoxScore, BoxScoreTotals } from '../match';
|
|
8
|
+
import { DeclineProfile } from './decline';
|
|
8
9
|
export declare class Stat {
|
|
9
10
|
readonly name: Stats;
|
|
10
11
|
readonly value: number;
|
|
@@ -30,6 +31,8 @@ export declare class Player {
|
|
|
30
31
|
readonly traits: Trait[];
|
|
31
32
|
readonly generalStats: Stat[];
|
|
32
33
|
readonly rarity: Rarity;
|
|
34
|
+
readonly age: number;
|
|
35
|
+
readonly declineProfile: DeclineProfile;
|
|
33
36
|
readonly boxScores?: BoxScore[];
|
|
34
37
|
readonly boxScoreTotals?: BoxScoreTotals;
|
|
35
38
|
static create(input: unknown): Player;
|
|
@@ -54,7 +54,7 @@ class Player {
|
|
|
54
54
|
stats: performance_stats_1.PerformanceStats.create(result.data.stats)
|
|
55
55
|
});
|
|
56
56
|
}
|
|
57
|
-
constructor({ id, name, country, stats, roles, traits, rarity, boxScores, boxScoreTotals }) {
|
|
57
|
+
constructor({ id, name, country, stats, roles, traits, rarity, age, declineProfile, boxScores, boxScoreTotals }) {
|
|
58
58
|
this.id = id;
|
|
59
59
|
this.name = name;
|
|
60
60
|
this.country = country;
|
|
@@ -62,6 +62,8 @@ class Player {
|
|
|
62
62
|
this.roles = roles;
|
|
63
63
|
this.traits = traits;
|
|
64
64
|
this.rarity = rarity;
|
|
65
|
+
this.age = age;
|
|
66
|
+
this.declineProfile = declineProfile;
|
|
65
67
|
this.boxScores = boxScores;
|
|
66
68
|
this.boxScoreTotals = boxScoreTotals;
|
|
67
69
|
this.generalStats = Object.values(stats_1.StatsEnum).map((stat) => ({
|
|
@@ -3,6 +3,7 @@ import { Country } from '../../country';
|
|
|
3
3
|
import { RoleEnum } from '../role';
|
|
4
4
|
import { TraitEnum } from '../trait';
|
|
5
5
|
import { RarityEnum } from '../rarity';
|
|
6
|
+
import { DeclineProfileEnum } from '../decline';
|
|
6
7
|
export declare const NameInputSchema: z.ZodObject<{
|
|
7
8
|
first: z.ZodString;
|
|
8
9
|
last: z.ZodString;
|
|
@@ -59,6 +60,13 @@ export declare const PlayerInputSchema: z.ZodObject<{
|
|
|
59
60
|
MYTHIC: RarityEnum.MYTHIC;
|
|
60
61
|
SPECIAL: RarityEnum.SPECIAL;
|
|
61
62
|
}>;
|
|
63
|
+
age: z.ZodNumber;
|
|
64
|
+
declineProfile: z.ZodEnum<{
|
|
65
|
+
PRODIGY: DeclineProfileEnum.PRODIGY;
|
|
66
|
+
STANDARD: DeclineProfileEnum.STANDARD;
|
|
67
|
+
VETERAN: DeclineProfileEnum.VETERAN;
|
|
68
|
+
IRONMAN: DeclineProfileEnum.IRONMAN;
|
|
69
|
+
}>;
|
|
62
70
|
boxScores: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
63
71
|
playerId: z.ZodUUID;
|
|
64
72
|
matchSetId: z.ZodUUID;
|
|
@@ -6,6 +6,7 @@ const country_1 = require("../../country");
|
|
|
6
6
|
const role_1 = require("../role");
|
|
7
7
|
const trait_1 = require("../trait");
|
|
8
8
|
const rarity_1 = require("../rarity");
|
|
9
|
+
const decline_1 = require("../decline");
|
|
9
10
|
const box_score_z_1 = require("../../match/schemas/box-score.z");
|
|
10
11
|
const performance_stats_z_1 = require("./performance-stats.z");
|
|
11
12
|
exports.NameInputSchema = zod_1.z.object({
|
|
@@ -32,6 +33,8 @@ exports.PlayerInputSchema = zod_1.z.object({
|
|
|
32
33
|
roles: zod_1.z.array(zod_1.z.enum(Object.values(role_1.RoleEnum))).min(1),
|
|
33
34
|
traits: zod_1.z.array(zod_1.z.enum(Object.values(trait_1.TraitEnum))),
|
|
34
35
|
rarity: zod_1.z.enum(Object.values(rarity_1.RarityEnum)),
|
|
36
|
+
age: zod_1.z.number().int().min(0),
|
|
37
|
+
declineProfile: zod_1.z.enum(Object.values(decline_1.DeclineProfileEnum)),
|
|
35
38
|
boxScores: zod_1.z.array(box_score_z_1.BoxScoreInputSchema).optional(),
|
|
36
39
|
boxScoreTotals: BoxScoreTotalsInputSchema.optional()
|
|
37
40
|
});
|
|
@@ -21,6 +21,7 @@ const match_set_1 = require("./match/match-set");
|
|
|
21
21
|
const common_1 = require("../data/common");
|
|
22
22
|
const rarity_1 = require("./player/rarity");
|
|
23
23
|
const role_1 = require("./player/role");
|
|
24
|
+
const decline_1 = require("./player/decline");
|
|
24
25
|
const performance_stats_keys_1 = require("./player/performance-stats-keys");
|
|
25
26
|
// ─── Country ─────────────────────────────────────────────────────────────────
|
|
26
27
|
function makeCountry() {
|
|
@@ -43,7 +44,9 @@ function makePlayer(country, statValue = 50) {
|
|
|
43
44
|
stats,
|
|
44
45
|
roles: [role_1.RoleEnum.OUTSIDE_HITTER],
|
|
45
46
|
traits: [],
|
|
46
|
-
rarity: rarity_1.RarityEnum.COMMON
|
|
47
|
+
rarity: rarity_1.RarityEnum.COMMON,
|
|
48
|
+
age: 20,
|
|
49
|
+
declineProfile: decline_1.DeclineProfileEnum.STANDARD
|
|
47
50
|
});
|
|
48
51
|
}
|
|
49
52
|
// ─── Team ─────────────────────────────────────────────────────────────────────
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
[
|
|
2
|
+
{ "profile": "PRODIGY", "startAge": 27, "initTicks": 13.0, "accel": 1.00, "peakTicks": 16.0 },
|
|
3
|
+
{ "profile": "STANDARD", "startAge": 29, "initTicks": 9.0, "accel": 1.75, "peakTicks": 16.0 },
|
|
4
|
+
{ "profile": "VETERAN", "startAge": 32, "initTicks": 10.0, "accel": 1.50, "peakTicks": 16.0 },
|
|
5
|
+
{ "profile": "IRONMAN", "startAge": 34, "initTicks": 10.0, "accel": 1.50, "peakTicks": 16.0 }
|
|
6
|
+
]
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import rolesJSON from './roles.json';
|
|
2
2
|
import traitsJSON from './traits.json';
|
|
3
3
|
import statCapsJSON from './stat-caps.json';
|
|
4
|
-
|
|
4
|
+
import declineProfilesJSON from './decline-profiles.json';
|
|
5
|
+
export { rolesJSON, traitsJSON, statCapsJSON, declineProfilesJSON };
|
|
@@ -3,10 +3,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.statCapsJSON = exports.traitsJSON = exports.rolesJSON = void 0;
|
|
6
|
+
exports.declineProfilesJSON = exports.statCapsJSON = exports.traitsJSON = exports.rolesJSON = void 0;
|
|
7
7
|
const roles_json_1 = __importDefault(require("./roles.json"));
|
|
8
8
|
exports.rolesJSON = roles_json_1.default;
|
|
9
9
|
const traits_json_1 = __importDefault(require("./traits.json"));
|
|
10
10
|
exports.traitsJSON = traits_json_1.default;
|
|
11
11
|
const stat_caps_json_1 = __importDefault(require("./stat-caps.json"));
|
|
12
12
|
exports.statCapsJSON = stat_caps_json_1.default;
|
|
13
|
+
const decline_profiles_json_1 = __importDefault(require("./decline-profiles.json"));
|
|
14
|
+
exports.declineProfilesJSON = decline_profiles_json_1.default;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as Sequelize from 'sequelize';
|
|
2
2
|
import { Model } from 'sequelize';
|
|
3
3
|
import { BoxScoreAttributes, BoxScoreId, BoxScoreModel, BoxScoreTotalsId, BoxScoreTotalsModel, CompetitionMVPId, CompetitionMVPModel, CountryId, CountryModel, MatchSetId, MatchSetModel, PerformanceStatsAttributes, PerformanceStatsId, PerformanceStatsModel, PlayerTeamId, PlayerTeamModel, TeamId, TeamModel, VPERId, VPERModel } from '.';
|
|
4
|
-
import { Rarity, Role, Trait } from '../../service';
|
|
4
|
+
import { DeclineProfile, Rarity, Role, Trait } from '../../service';
|
|
5
5
|
export interface PlayerAttributes {
|
|
6
6
|
player_id: string;
|
|
7
7
|
roles: Role[];
|
|
@@ -10,6 +10,8 @@ export interface PlayerAttributes {
|
|
|
10
10
|
first_name: string;
|
|
11
11
|
last_name: string;
|
|
12
12
|
country_id: string;
|
|
13
|
+
age: number;
|
|
14
|
+
decline_profile: DeclineProfile;
|
|
13
15
|
PerformanceStat?: PerformanceStatsAttributes;
|
|
14
16
|
BoxScores?: BoxScoreAttributes[];
|
|
15
17
|
}
|
|
@@ -24,6 +26,8 @@ export declare class PlayerModel extends Model<PlayerAttributes, PlayerCreationA
|
|
|
24
26
|
first_name: string;
|
|
25
27
|
last_name: string;
|
|
26
28
|
country_id: string;
|
|
29
|
+
age: number;
|
|
30
|
+
decline_profile: DeclineProfile;
|
|
27
31
|
country: CountryModel;
|
|
28
32
|
getCountry: Sequelize.BelongsToGetAssociationMixin<CountryModel>;
|
|
29
33
|
setCountry: Sequelize.BelongsToSetAssociationMixin<CountryModel, CountryId>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DataTypes, Model } from 'sequelize';
|
|
2
2
|
import { CountryModel, PerformanceStatsModel } from '.';
|
|
3
|
-
import { RarityEnum, RoleEnum, TraitEnum } from '../../service';
|
|
3
|
+
import { DeclineProfileEnum, RarityEnum, RoleEnum, TraitEnum } from '../../service';
|
|
4
4
|
export class PlayerModel extends Model {
|
|
5
5
|
static initModel(sequelize) {
|
|
6
6
|
return PlayerModel.init({
|
|
@@ -36,6 +36,16 @@ export class PlayerModel extends Model {
|
|
|
36
36
|
model: 'Country',
|
|
37
37
|
key: 'country_id'
|
|
38
38
|
}
|
|
39
|
+
},
|
|
40
|
+
age: {
|
|
41
|
+
type: DataTypes.INTEGER,
|
|
42
|
+
allowNull: false,
|
|
43
|
+
defaultValue: 17
|
|
44
|
+
},
|
|
45
|
+
decline_profile: {
|
|
46
|
+
type: DataTypes.ENUM(...Object.values(DeclineProfileEnum)),
|
|
47
|
+
allowNull: false,
|
|
48
|
+
defaultValue: DeclineProfileEnum.STANDARD
|
|
39
49
|
}
|
|
40
50
|
}, {
|
|
41
51
|
sequelize,
|
|
@@ -16,7 +16,9 @@ function transformToAttributes(player) {
|
|
|
16
16
|
roles: player.roles,
|
|
17
17
|
traits: player.traits,
|
|
18
18
|
PerformanceStat: transformFromPerformanceStats(player.stats, player.id),
|
|
19
|
-
rarity: player.rarity
|
|
19
|
+
rarity: player.rarity,
|
|
20
|
+
age: player.age,
|
|
21
|
+
decline_profile: player.declineProfile
|
|
20
22
|
};
|
|
21
23
|
}
|
|
22
24
|
function transformToBoxScoreTotals(model) {
|
|
@@ -75,6 +77,8 @@ function transformToObject(model) {
|
|
|
75
77
|
traits: model.traits,
|
|
76
78
|
stats: transformToPerformanceStats(model.PerformanceStat),
|
|
77
79
|
rarity: model.rarity,
|
|
80
|
+
age: model.age,
|
|
81
|
+
declineProfile: model.decline_profile,
|
|
78
82
|
boxScores: (model.BoxScores ?? []).map(transformToBoxScore),
|
|
79
83
|
boxScoreTotals
|
|
80
84
|
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { PerformanceStatsKey } from './performance-stats-keys';
|
|
2
|
+
export declare enum DeclineProfileEnum {
|
|
3
|
+
PRODIGY = "PRODIGY",
|
|
4
|
+
STANDARD = "STANDARD",
|
|
5
|
+
VETERAN = "VETERAN",
|
|
6
|
+
IRONMAN = "IRONMAN"
|
|
7
|
+
}
|
|
8
|
+
export type DeclineProfile = DeclineProfileEnum.PRODIGY | DeclineProfileEnum.STANDARD | DeclineProfileEnum.VETERAN | DeclineProfileEnum.IRONMAN;
|
|
9
|
+
export declare const declineProfiles: DeclineProfileEnum[];
|
|
10
|
+
interface DeclineProfileEntry {
|
|
11
|
+
profile: string;
|
|
12
|
+
startAge: number;
|
|
13
|
+
initTicks: number;
|
|
14
|
+
accel: number;
|
|
15
|
+
peakTicks: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Stats that decline first (technique / skill). One random stat from this pool is
|
|
19
|
+
* removed per tick during the pre-peak decline phase.
|
|
20
|
+
*/
|
|
21
|
+
export declare const SKILL_POOL: PerformanceStatsKey[];
|
|
22
|
+
/**
|
|
23
|
+
* Energy / reaction stats (incl. crit-chance stats). These only start declining
|
|
24
|
+
* once the player reaches peak decline, alongside the skill pool.
|
|
25
|
+
*/
|
|
26
|
+
export declare const ENERGY_POOL: PerformanceStatsKey[];
|
|
27
|
+
export declare function getDeclineProfile(profile: DeclineProfile): DeclineProfileEntry;
|
|
28
|
+
export type DeclineStatus = 'ACTIVE' | 'DECLINING' | 'PEAK';
|
|
29
|
+
export interface DeclineTick {
|
|
30
|
+
/** Number of decline ticks to apply this iteration. */
|
|
31
|
+
ticks: number;
|
|
32
|
+
/** True once tick rate hits the profile ceiling — both pools decline and training is blocked. */
|
|
33
|
+
atPeak: boolean;
|
|
34
|
+
/** Coarse status for display / gating. */
|
|
35
|
+
status: DeclineStatus;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Decline is fully derivable from age + profile — no running state is persisted.
|
|
39
|
+
* tickRate = min(peakTicks, initTicks + (age - startAge) * accel)
|
|
40
|
+
* Pre-peak: `ticks` random SKILL stats lost. At peak: `ticks` from BOTH pools + training blocked.
|
|
41
|
+
*/
|
|
42
|
+
export declare function computeDeclineTick(age: number, profile: DeclineProfile): DeclineTick;
|
|
43
|
+
export {};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { declineProfilesJSON } from '../../stat-config';
|
|
2
|
+
export var DeclineProfileEnum;
|
|
3
|
+
(function (DeclineProfileEnum) {
|
|
4
|
+
DeclineProfileEnum["PRODIGY"] = "PRODIGY";
|
|
5
|
+
DeclineProfileEnum["STANDARD"] = "STANDARD";
|
|
6
|
+
DeclineProfileEnum["VETERAN"] = "VETERAN";
|
|
7
|
+
DeclineProfileEnum["IRONMAN"] = "IRONMAN";
|
|
8
|
+
})(DeclineProfileEnum || (DeclineProfileEnum = {}));
|
|
9
|
+
export const declineProfiles = Object.values(DeclineProfileEnum);
|
|
10
|
+
const profileEntries = declineProfilesJSON;
|
|
11
|
+
/**
|
|
12
|
+
* Stats that decline first (technique / skill). One random stat from this pool is
|
|
13
|
+
* removed per tick during the pre-peak decline phase.
|
|
14
|
+
*/
|
|
15
|
+
export const SKILL_POOL = [
|
|
16
|
+
'setting', 'serve', 'spike', 'quick', 'power', 'backAttack',
|
|
17
|
+
'reception', 'overhand', 'bump', 'block', 'attack', 'defense'
|
|
18
|
+
];
|
|
19
|
+
/**
|
|
20
|
+
* Energy / reaction stats (incl. crit-chance stats). These only start declining
|
|
21
|
+
* once the player reaches peak decline, alongside the skill pool.
|
|
22
|
+
*/
|
|
23
|
+
export const ENERGY_POOL = [
|
|
24
|
+
'stamina', 'reflex', 'read', 'commit', 'awareness', 'focus'
|
|
25
|
+
];
|
|
26
|
+
export function getDeclineProfile(profile) {
|
|
27
|
+
const entry = profileEntries.find(e => e.profile === profile);
|
|
28
|
+
if (entry == null)
|
|
29
|
+
throw new Error(`UNKNOWN_DECLINE_PROFILE: ${profile}`);
|
|
30
|
+
return entry;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Decline is fully derivable from age + profile — no running state is persisted.
|
|
34
|
+
* tickRate = min(peakTicks, initTicks + (age - startAge) * accel)
|
|
35
|
+
* Pre-peak: `ticks` random SKILL stats lost. At peak: `ticks` from BOTH pools + training blocked.
|
|
36
|
+
*/
|
|
37
|
+
export function computeDeclineTick(age, profile) {
|
|
38
|
+
const { startAge, initTicks, accel, peakTicks } = getDeclineProfile(profile);
|
|
39
|
+
if (age < startAge) {
|
|
40
|
+
return { ticks: 0, atPeak: false, status: 'ACTIVE' };
|
|
41
|
+
}
|
|
42
|
+
const rawRate = initTicks + (age - startAge) * accel;
|
|
43
|
+
const tickRate = Math.min(peakTicks, rawRate);
|
|
44
|
+
const atPeak = rawRate >= peakTicks;
|
|
45
|
+
return {
|
|
46
|
+
ticks: Math.round(tickRate),
|
|
47
|
+
atPeak,
|
|
48
|
+
status: atPeak ? 'PEAK' : 'DECLINING'
|
|
49
|
+
};
|
|
50
|
+
}
|
|
@@ -8,6 +8,7 @@ import { rolesJSON } from '../../stat-config';
|
|
|
8
8
|
import { shuffle, generatePlayerName } from '../utils';
|
|
9
9
|
import { Player } from './player';
|
|
10
10
|
import { assignTraits } from './trait';
|
|
11
|
+
import { declineProfiles } from './decline';
|
|
11
12
|
const LEGENDARY_PITY_STEP = 0.004;
|
|
12
13
|
const MYTHIC_PITY_STEP = 0.00001;
|
|
13
14
|
const SPECIAL_PITY_STEP = 0.000005;
|
|
@@ -110,12 +111,12 @@ export class PlayerGenerator {
|
|
|
110
111
|
const BLOCK = getMultipliers(StatsEnum.BLOCK);
|
|
111
112
|
const SERVE = getMultipliers(StatsEnum.SERVE);
|
|
112
113
|
const STAMINA = getMultipliers(StatsEnum.STAMINA);
|
|
113
|
-
function buildPerformanceFromRole(weights, maxValue) {
|
|
114
|
+
function buildPerformanceFromRole(weights, minValue, maxValue) {
|
|
114
115
|
return PerformanceStats.create(Object.fromEntries(performanceStatKeys.map((key) => {
|
|
115
116
|
if (weights[key] > 0)
|
|
116
|
-
return [key, maxValue];
|
|
117
|
+
return [key, randomInt(minValue, maxValue + 1)];
|
|
117
118
|
else
|
|
118
|
-
return [key,
|
|
119
|
+
return [key, randomInt(RarityRanges.COMMON[0], Math.max(minValue - 1, RarityRanges.COMMON[0] + 1))];
|
|
119
120
|
})));
|
|
120
121
|
}
|
|
121
122
|
switch (rarity) {
|
|
@@ -123,7 +124,7 @@ export class PlayerGenerator {
|
|
|
123
124
|
if (role != null) {
|
|
124
125
|
const weights = rolesJSON.find(entry => entry.role === role)?.weight;
|
|
125
126
|
if (weights != null) {
|
|
126
|
-
return buildPerformanceFromRole(weights, RarityRanges.COMMON[1]);
|
|
127
|
+
return buildPerformanceFromRole(weights, RarityRanges.COMMON[0], RarityRanges.COMMON[1]);
|
|
127
128
|
}
|
|
128
129
|
}
|
|
129
130
|
return PerformanceStats.create(Object.fromEntries(performanceStatKeys.map((key) => [key, Math.round(randomInt(RarityRanges.COMMON[0], RarityRanges.COMMON[1]))])));
|
|
@@ -132,7 +133,7 @@ export class PlayerGenerator {
|
|
|
132
133
|
if (role != null) {
|
|
133
134
|
const weights = rolesJSON.find(entry => entry.role === role)?.weight;
|
|
134
135
|
if (weights != null) {
|
|
135
|
-
return buildPerformanceFromRole(weights, RarityRanges.RARE[1]);
|
|
136
|
+
return buildPerformanceFromRole(weights, RarityRanges.RARE[0], RarityRanges.RARE[1]);
|
|
136
137
|
}
|
|
137
138
|
}
|
|
138
139
|
const stats = shuffle([ATTACK, SET, SERVE, RECEIVE, BLOCK]);
|
|
@@ -150,7 +151,7 @@ export class PlayerGenerator {
|
|
|
150
151
|
if (role != null) {
|
|
151
152
|
const weights = rolesJSON.find(entry => entry.role === role)?.weight;
|
|
152
153
|
if (weights != null) {
|
|
153
|
-
return buildPerformanceFromRole(weights, RarityRanges.LEGENDARY[1]);
|
|
154
|
+
return buildPerformanceFromRole(weights, RarityRanges.LEGENDARY[0], RarityRanges.LEGENDARY[1]);
|
|
154
155
|
}
|
|
155
156
|
}
|
|
156
157
|
const s1 = shuffle([ATTACK, SET, RECEIVE, BLOCK]);
|
|
@@ -169,7 +170,7 @@ export class PlayerGenerator {
|
|
|
169
170
|
if (role != null) {
|
|
170
171
|
const weights = rolesJSON.find(entry => entry.role === role)?.weight;
|
|
171
172
|
if (weights != null) {
|
|
172
|
-
return buildPerformanceFromRole(weights, RarityRanges.MYTHIC[1]);
|
|
173
|
+
return buildPerformanceFromRole(weights, RarityRanges.MYTHIC[0], RarityRanges.MYTHIC[1]);
|
|
173
174
|
}
|
|
174
175
|
}
|
|
175
176
|
const stats = shuffle([ATTACK, SET, RECEIVE, BLOCK]);
|
|
@@ -187,7 +188,7 @@ export class PlayerGenerator {
|
|
|
187
188
|
if (role != null) {
|
|
188
189
|
const weights = rolesJSON.find(entry => entry.role === role)?.weight;
|
|
189
190
|
if (weights != null) {
|
|
190
|
-
return buildPerformanceFromRole(weights, RarityRanges.SPECIAL[1]);
|
|
191
|
+
return buildPerformanceFromRole(weights, RarityRanges.SPECIAL[0], RarityRanges.SPECIAL[1]);
|
|
191
192
|
}
|
|
192
193
|
}
|
|
193
194
|
const stats = shuffle([ATTACK, SERVE, SET, RECEIVE, BLOCK]);
|
|
@@ -213,7 +214,9 @@ export class PlayerGenerator {
|
|
|
213
214
|
const stats = PlayerGenerator.generatePerformance(rarity, role);
|
|
214
215
|
const roles = assignRoles(stats, rarity);
|
|
215
216
|
const traits = assignTraits(roles, rarity, maxTraits);
|
|
216
|
-
|
|
217
|
+
const age = randomInt(15, 21);
|
|
218
|
+
const declineProfile = declineProfiles[randomInt(0, declineProfiles.length)];
|
|
219
|
+
return Player.create({ id: uuidv4(), name, country, stats, roles, traits, rarity, age, declineProfile });
|
|
217
220
|
}
|
|
218
221
|
static generatePlayers(count, countries) {
|
|
219
222
|
const players = [];
|
|
@@ -5,6 +5,7 @@ import { Rarity } from './rarity';
|
|
|
5
5
|
import { Stats } from './stats';
|
|
6
6
|
import { Role } from './role';
|
|
7
7
|
import { BoxScore, BoxScoreTotals } from '../match';
|
|
8
|
+
import { DeclineProfile } from './decline';
|
|
8
9
|
export declare class Stat {
|
|
9
10
|
readonly name: Stats;
|
|
10
11
|
readonly value: number;
|
|
@@ -30,6 +31,8 @@ export declare class Player {
|
|
|
30
31
|
readonly traits: Trait[];
|
|
31
32
|
readonly generalStats: Stat[];
|
|
32
33
|
readonly rarity: Rarity;
|
|
34
|
+
readonly age: number;
|
|
35
|
+
readonly declineProfile: DeclineProfile;
|
|
33
36
|
readonly boxScores?: BoxScore[];
|
|
34
37
|
readonly boxScoreTotals?: BoxScoreTotals;
|
|
35
38
|
static create(input: unknown): Player;
|
|
@@ -49,7 +49,7 @@ export class Player {
|
|
|
49
49
|
stats: PerformanceStats.create(result.data.stats)
|
|
50
50
|
});
|
|
51
51
|
}
|
|
52
|
-
constructor({ id, name, country, stats, roles, traits, rarity, boxScores, boxScoreTotals }) {
|
|
52
|
+
constructor({ id, name, country, stats, roles, traits, rarity, age, declineProfile, boxScores, boxScoreTotals }) {
|
|
53
53
|
this.id = id;
|
|
54
54
|
this.name = name;
|
|
55
55
|
this.country = country;
|
|
@@ -57,6 +57,8 @@ export class Player {
|
|
|
57
57
|
this.roles = roles;
|
|
58
58
|
this.traits = traits;
|
|
59
59
|
this.rarity = rarity;
|
|
60
|
+
this.age = age;
|
|
61
|
+
this.declineProfile = declineProfile;
|
|
60
62
|
this.boxScores = boxScores;
|
|
61
63
|
this.boxScoreTotals = boxScoreTotals;
|
|
62
64
|
this.generalStats = Object.values(StatsEnum).map((stat) => ({
|
|
@@ -3,6 +3,7 @@ import { Country } from '../../country';
|
|
|
3
3
|
import { RoleEnum } from '../role';
|
|
4
4
|
import { TraitEnum } from '../trait';
|
|
5
5
|
import { RarityEnum } from '../rarity';
|
|
6
|
+
import { DeclineProfileEnum } from '../decline';
|
|
6
7
|
export declare const NameInputSchema: z.ZodObject<{
|
|
7
8
|
first: z.ZodString;
|
|
8
9
|
last: z.ZodString;
|
|
@@ -59,6 +60,13 @@ export declare const PlayerInputSchema: z.ZodObject<{
|
|
|
59
60
|
MYTHIC: RarityEnum.MYTHIC;
|
|
60
61
|
SPECIAL: RarityEnum.SPECIAL;
|
|
61
62
|
}>;
|
|
63
|
+
age: z.ZodNumber;
|
|
64
|
+
declineProfile: z.ZodEnum<{
|
|
65
|
+
PRODIGY: DeclineProfileEnum.PRODIGY;
|
|
66
|
+
STANDARD: DeclineProfileEnum.STANDARD;
|
|
67
|
+
VETERAN: DeclineProfileEnum.VETERAN;
|
|
68
|
+
IRONMAN: DeclineProfileEnum.IRONMAN;
|
|
69
|
+
}>;
|
|
62
70
|
boxScores: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
63
71
|
playerId: z.ZodUUID;
|
|
64
72
|
matchSetId: z.ZodUUID;
|
|
@@ -3,6 +3,7 @@ import { Country } from '../../country';
|
|
|
3
3
|
import { RoleEnum } from '../role';
|
|
4
4
|
import { TraitEnum } from '../trait';
|
|
5
5
|
import { RarityEnum } from '../rarity';
|
|
6
|
+
import { DeclineProfileEnum } from '../decline';
|
|
6
7
|
import { AttackStatsSchema, BlockStatsSchema, BoxScoreInputSchema, DefenseStatsSchema, MiscStatsSchema, ReceptionStatsSchema, ServeStatsSchema, SettingStatsSchema } from '../../match/schemas/box-score.z';
|
|
7
8
|
import { PerformanceStatsInputSchema } from './performance-stats.z';
|
|
8
9
|
export const NameInputSchema = z.object({
|
|
@@ -29,6 +30,8 @@ export const PlayerInputSchema = z.object({
|
|
|
29
30
|
roles: z.array(z.enum(Object.values(RoleEnum))).min(1),
|
|
30
31
|
traits: z.array(z.enum(Object.values(TraitEnum))),
|
|
31
32
|
rarity: z.enum(Object.values(RarityEnum)),
|
|
33
|
+
age: z.number().int().min(0),
|
|
34
|
+
declineProfile: z.enum(Object.values(DeclineProfileEnum)),
|
|
32
35
|
boxScores: z.array(BoxScoreInputSchema).optional(),
|
|
33
36
|
boxScoreTotals: BoxScoreTotalsInputSchema.optional()
|
|
34
37
|
});
|
|
@@ -11,6 +11,7 @@ import { MatchSet } from './match/match-set';
|
|
|
11
11
|
import { StatusEnum } from '../data/common';
|
|
12
12
|
import { RarityEnum } from './player/rarity';
|
|
13
13
|
import { RoleEnum } from './player/role';
|
|
14
|
+
import { DeclineProfileEnum } from './player/decline';
|
|
14
15
|
import { performanceStatKeys } from './player/performance-stats-keys';
|
|
15
16
|
// ─── Country ─────────────────────────────────────────────────────────────────
|
|
16
17
|
export function makeCountry() {
|
|
@@ -33,7 +34,9 @@ export function makePlayer(country, statValue = 50) {
|
|
|
33
34
|
stats,
|
|
34
35
|
roles: [RoleEnum.OUTSIDE_HITTER],
|
|
35
36
|
traits: [],
|
|
36
|
-
rarity: RarityEnum.COMMON
|
|
37
|
+
rarity: RarityEnum.COMMON,
|
|
38
|
+
age: 20,
|
|
39
|
+
declineProfile: DeclineProfileEnum.STANDARD
|
|
37
40
|
});
|
|
38
41
|
}
|
|
39
42
|
// ─── Team ─────────────────────────────────────────────────────────────────────
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
[
|
|
2
|
+
{ "profile": "PRODIGY", "startAge": 27, "initTicks": 13.0, "accel": 1.00, "peakTicks": 16.0 },
|
|
3
|
+
{ "profile": "STANDARD", "startAge": 29, "initTicks": 9.0, "accel": 1.75, "peakTicks": 16.0 },
|
|
4
|
+
{ "profile": "VETERAN", "startAge": 32, "initTicks": 10.0, "accel": 1.50, "peakTicks": 16.0 },
|
|
5
|
+
{ "profile": "IRONMAN", "startAge": 34, "initTicks": 10.0, "accel": 1.50, "peakTicks": 16.0 }
|
|
6
|
+
]
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import rolesJSON from './roles.json';
|
|
2
2
|
import traitsJSON from './traits.json';
|
|
3
3
|
import statCapsJSON from './stat-caps.json';
|
|
4
|
-
|
|
4
|
+
import declineProfilesJSON from './decline-profiles.json';
|
|
5
|
+
export { rolesJSON, traitsJSON, statCapsJSON, declineProfilesJSON };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import rolesJSON from './roles.json';
|
|
2
2
|
import traitsJSON from './traits.json';
|
|
3
3
|
import statCapsJSON from './stat-caps.json';
|
|
4
|
-
|
|
4
|
+
import declineProfilesJSON from './decline-profiles.json';
|
|
5
|
+
export { rolesJSON, traitsJSON, statCapsJSON, declineProfilesJSON };
|