volleyballsimtypes 0.0.419 → 0.0.421
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/src/api/index.d.ts +2 -1
- package/dist/cjs/src/data/init-models.js +4 -0
- package/dist/cjs/src/data/models/currency-transaction.d.ts +2 -1
- package/dist/cjs/src/data/models/currency-transaction.js +1 -0
- package/dist/cjs/src/data/models/index.d.ts +1 -0
- package/dist/cjs/src/data/models/index.js +1 -0
- package/dist/cjs/src/data/models/player.d.ts +2 -0
- package/dist/cjs/src/data/models/player.js +4 -0
- package/dist/cjs/src/data/models/scout.d.ts +25 -0
- package/dist/cjs/src/data/models/scout.js +57 -0
- package/dist/cjs/src/data/transformers/player.js +2 -0
- package/dist/cjs/src/service/player/player-generator.d.ts +1 -0
- package/dist/cjs/src/service/player/player-generator.js +63 -1
- package/dist/cjs/src/service/player/player.d.ts +1 -0
- package/dist/cjs/src/service/player/player.js +2 -1
- package/dist/cjs/src/service/player/schemas/player.z.d.ts +1 -0
- package/dist/cjs/src/service/player/schemas/player.z.js +1 -0
- package/dist/esm/src/api/index.d.ts +2 -1
- package/dist/esm/src/data/init-models.js +5 -1
- package/dist/esm/src/data/models/currency-transaction.d.ts +2 -1
- package/dist/esm/src/data/models/currency-transaction.js +1 -0
- package/dist/esm/src/data/models/index.d.ts +1 -0
- package/dist/esm/src/data/models/index.js +1 -0
- package/dist/esm/src/data/models/player.d.ts +2 -0
- package/dist/esm/src/data/models/player.js +4 -0
- package/dist/esm/src/data/models/scout.d.ts +25 -0
- package/dist/esm/src/data/models/scout.js +53 -0
- package/dist/esm/src/data/transformers/player.js +2 -0
- package/dist/esm/src/service/player/player-generator.d.ts +1 -0
- package/dist/esm/src/service/player/player-generator.js +62 -1
- package/dist/esm/src/service/player/player.d.ts +1 -0
- package/dist/esm/src/service/player/player.js +2 -1
- package/dist/esm/src/service/player/schemas/player.z.d.ts +1 -0
- package/dist/esm/src/service/player/schemas/player.z.js +1 -0
- package/package.json +1 -1
|
@@ -40,7 +40,7 @@ export type Match = Omit<DataProps<_Match>, 'sets' | 'homeTeam' | 'awayTeam' | '
|
|
|
40
40
|
export type RallyEvent = DataProps<_RallyEvent> & {
|
|
41
41
|
team?: Team;
|
|
42
42
|
};
|
|
43
|
-
export type Player = Omit<DataProps<_Player>, 'stats' | 'birthAge' | 'birthIteration' | 'declineProfile'> & {
|
|
43
|
+
export type Player = Omit<DataProps<_Player>, 'stats' | 'birthAge' | 'birthIteration' | 'declineProfile' | 'nickname'> & {
|
|
44
44
|
-readonly [K in 'birthAge' | 'birthIteration' | 'declineProfile']?: DataProps<_Player>[K];
|
|
45
45
|
} & {
|
|
46
46
|
stats?: PerformanceStats;
|
|
@@ -48,6 +48,7 @@ export type Player = Omit<DataProps<_Player>, 'stats' | 'birthAge' | 'birthItera
|
|
|
48
48
|
jerseyNumber: number;
|
|
49
49
|
locked?: boolean;
|
|
50
50
|
declineStatus?: DeclineStatus;
|
|
51
|
+
nickname?: string;
|
|
51
52
|
};
|
|
52
53
|
export interface StartingLineup {
|
|
53
54
|
[CourtPosition.LEFT_FRONT]: string;
|
|
@@ -4,6 +4,7 @@ exports.initModels = initModels;
|
|
|
4
4
|
const models_1 = require("./models");
|
|
5
5
|
function initModels(sequelize) {
|
|
6
6
|
const Coach = models_1.CoachModel.initModel(sequelize);
|
|
7
|
+
const Scout = models_1.ScoutModel.initModel(sequelize);
|
|
7
8
|
const CurrencyTransaction = models_1.CurrencyTransactionModel.initModel(sequelize);
|
|
8
9
|
const Tactics = models_1.TacticsModel.initModel(sequelize);
|
|
9
10
|
const AuthUser = models_1.AuthUserModel.initModel(sequelize);
|
|
@@ -195,6 +196,8 @@ function initModels(sequelize) {
|
|
|
195
196
|
VPER.belongsTo(Match, { as: 'Match', foreignKey: 'match_id' });
|
|
196
197
|
Team.hasOne(Coach, { as: 'Coach', foreignKey: 'team_id' });
|
|
197
198
|
Coach.belongsTo(Team, { as: 'team', foreignKey: 'team_id' });
|
|
199
|
+
Team.hasOne(Scout, { as: 'Scout', foreignKey: 'team_id' });
|
|
200
|
+
Scout.belongsTo(Team, { as: 'team', foreignKey: 'team_id' });
|
|
198
201
|
Team.hasOne(Tactics, { as: 'tactics', foreignKey: 'team_id' });
|
|
199
202
|
Team.belongsTo(Country, { as: 'country', foreignKey: 'country_id' });
|
|
200
203
|
Team.belongsToMany(Competition, {
|
|
@@ -277,6 +280,7 @@ function initModels(sequelize) {
|
|
|
277
280
|
UserSettings,
|
|
278
281
|
Notification,
|
|
279
282
|
Coach,
|
|
283
|
+
Scout,
|
|
280
284
|
CurrencyTransaction,
|
|
281
285
|
VPER,
|
|
282
286
|
LegacyTeamFlag,
|
|
@@ -10,12 +10,13 @@ export declare enum CurrencyTransactionSourceEnum {
|
|
|
10
10
|
MATCH_REWARD = "MATCH_REWARD",
|
|
11
11
|
GACHA_PULL = "GACHA_PULL",
|
|
12
12
|
COACH_UPGRADE = "COACH_UPGRADE",
|
|
13
|
+
SCOUT_UPGRADE = "SCOUT_UPGRADE",
|
|
13
14
|
PLAYER_DISMISS = "PLAYER_DISMISS",
|
|
14
15
|
PLAYER_RETIRE = "PLAYER_RETIRE",
|
|
15
16
|
ADMIN_GRANT = "ADMIN_GRANT",
|
|
16
17
|
SEASON_REWARD = "SEASON_REWARD"
|
|
17
18
|
}
|
|
18
|
-
export type CurrencyTransactionSource = CurrencyTransactionSourceEnum.MATCH_REWARD | CurrencyTransactionSourceEnum.GACHA_PULL | CurrencyTransactionSourceEnum.COACH_UPGRADE | CurrencyTransactionSourceEnum.PLAYER_DISMISS | CurrencyTransactionSourceEnum.PLAYER_RETIRE | CurrencyTransactionSourceEnum.ADMIN_GRANT | CurrencyTransactionSourceEnum.SEASON_REWARD;
|
|
19
|
+
export type CurrencyTransactionSource = CurrencyTransactionSourceEnum.MATCH_REWARD | CurrencyTransactionSourceEnum.GACHA_PULL | CurrencyTransactionSourceEnum.COACH_UPGRADE | CurrencyTransactionSourceEnum.SCOUT_UPGRADE | CurrencyTransactionSourceEnum.PLAYER_DISMISS | CurrencyTransactionSourceEnum.PLAYER_RETIRE | CurrencyTransactionSourceEnum.ADMIN_GRANT | CurrencyTransactionSourceEnum.SEASON_REWARD;
|
|
19
20
|
export interface CurrencyTransactionAttributes {
|
|
20
21
|
transaction_id: string;
|
|
21
22
|
user_id: string;
|
|
@@ -12,6 +12,7 @@ var CurrencyTransactionSourceEnum;
|
|
|
12
12
|
CurrencyTransactionSourceEnum["MATCH_REWARD"] = "MATCH_REWARD";
|
|
13
13
|
CurrencyTransactionSourceEnum["GACHA_PULL"] = "GACHA_PULL";
|
|
14
14
|
CurrencyTransactionSourceEnum["COACH_UPGRADE"] = "COACH_UPGRADE";
|
|
15
|
+
CurrencyTransactionSourceEnum["SCOUT_UPGRADE"] = "SCOUT_UPGRADE";
|
|
15
16
|
CurrencyTransactionSourceEnum["PLAYER_DISMISS"] = "PLAYER_DISMISS";
|
|
16
17
|
CurrencyTransactionSourceEnum["PLAYER_RETIRE"] = "PLAYER_RETIRE";
|
|
17
18
|
CurrencyTransactionSourceEnum["ADMIN_GRANT"] = "ADMIN_GRANT";
|
|
@@ -29,6 +29,7 @@ export * from './promotion-match';
|
|
|
29
29
|
export * from './region-qualifier';
|
|
30
30
|
export * from './national-country';
|
|
31
31
|
export * from './coach';
|
|
32
|
+
export * from './scout';
|
|
32
33
|
export * from './team';
|
|
33
34
|
export * from './team-replacement';
|
|
34
35
|
export * from './tactics';
|
|
@@ -45,6 +45,7 @@ __exportStar(require("./promotion-match"), exports);
|
|
|
45
45
|
__exportStar(require("./region-qualifier"), exports);
|
|
46
46
|
__exportStar(require("./national-country"), exports);
|
|
47
47
|
__exportStar(require("./coach"), exports);
|
|
48
|
+
__exportStar(require("./scout"), exports);
|
|
48
49
|
__exportStar(require("./team"), exports);
|
|
49
50
|
__exportStar(require("./team-replacement"), exports);
|
|
50
51
|
__exportStar(require("./tactics"), exports);
|
|
@@ -9,6 +9,7 @@ export interface PlayerAttributes {
|
|
|
9
9
|
rarity: Rarity;
|
|
10
10
|
first_name: string;
|
|
11
11
|
last_name: string;
|
|
12
|
+
nickname?: string | null;
|
|
12
13
|
country_id: string;
|
|
13
14
|
birth_age: number;
|
|
14
15
|
birth_iteration: number;
|
|
@@ -27,6 +28,7 @@ export declare class PlayerModel extends Model<PlayerAttributes, PlayerCreationA
|
|
|
27
28
|
rarity: Rarity;
|
|
28
29
|
first_name: string;
|
|
29
30
|
last_name: string;
|
|
31
|
+
nickname: string | null;
|
|
30
32
|
country_id: string;
|
|
31
33
|
birth_age: number;
|
|
32
34
|
birth_iteration: number;
|
|
@@ -32,6 +32,10 @@ class PlayerModel extends sequelize_1.Model {
|
|
|
32
32
|
type: sequelize_1.DataTypes.STRING,
|
|
33
33
|
allowNull: false
|
|
34
34
|
},
|
|
35
|
+
nickname: {
|
|
36
|
+
type: sequelize_1.DataTypes.STRING(16),
|
|
37
|
+
allowNull: true
|
|
38
|
+
},
|
|
35
39
|
country_id: {
|
|
36
40
|
type: sequelize_1.DataTypes.UUID,
|
|
37
41
|
allowNull: false,
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as Sequelize from 'sequelize';
|
|
2
|
+
import { Model } from 'sequelize';
|
|
3
|
+
import { TeamId, TeamModel } from '.';
|
|
4
|
+
export interface ScoutAttributes {
|
|
5
|
+
scout_id: string;
|
|
6
|
+
team_id: string;
|
|
7
|
+
name: string;
|
|
8
|
+
rarity: string;
|
|
9
|
+
currency_invested: number;
|
|
10
|
+
}
|
|
11
|
+
export type ScoutPk = 'scout_id';
|
|
12
|
+
export type ScoutId = ScoutModel[ScoutPk];
|
|
13
|
+
export type ScoutCreationAttributes = ScoutAttributes;
|
|
14
|
+
export declare class ScoutModel extends Model<ScoutAttributes, ScoutCreationAttributes> implements ScoutAttributes {
|
|
15
|
+
scout_id: string;
|
|
16
|
+
team_id: string;
|
|
17
|
+
name: string;
|
|
18
|
+
rarity: string;
|
|
19
|
+
currency_invested: number;
|
|
20
|
+
team: TeamModel;
|
|
21
|
+
getTeam: Sequelize.BelongsToGetAssociationMixin<TeamModel>;
|
|
22
|
+
setTeam: Sequelize.BelongsToSetAssociationMixin<TeamModel, TeamId>;
|
|
23
|
+
createTeam: Sequelize.BelongsToCreateAssociationMixin<TeamModel>;
|
|
24
|
+
static initModel(sequelize: Sequelize.Sequelize): typeof ScoutModel;
|
|
25
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ScoutModel = void 0;
|
|
4
|
+
const sequelize_1 = require("sequelize");
|
|
5
|
+
class ScoutModel extends sequelize_1.Model {
|
|
6
|
+
static initModel(sequelize) {
|
|
7
|
+
return ScoutModel.init({
|
|
8
|
+
scout_id: {
|
|
9
|
+
type: sequelize_1.DataTypes.UUID,
|
|
10
|
+
allowNull: false,
|
|
11
|
+
primaryKey: true
|
|
12
|
+
},
|
|
13
|
+
team_id: {
|
|
14
|
+
type: sequelize_1.DataTypes.UUID,
|
|
15
|
+
allowNull: false,
|
|
16
|
+
unique: true,
|
|
17
|
+
references: {
|
|
18
|
+
model: 'Team',
|
|
19
|
+
key: 'team_id'
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
name: {
|
|
23
|
+
type: sequelize_1.DataTypes.STRING,
|
|
24
|
+
allowNull: false,
|
|
25
|
+
defaultValue: ''
|
|
26
|
+
},
|
|
27
|
+
rarity: {
|
|
28
|
+
type: sequelize_1.DataTypes.STRING,
|
|
29
|
+
allowNull: false,
|
|
30
|
+
defaultValue: 'COMMON'
|
|
31
|
+
},
|
|
32
|
+
currency_invested: {
|
|
33
|
+
type: sequelize_1.DataTypes.INTEGER,
|
|
34
|
+
allowNull: false,
|
|
35
|
+
defaultValue: 0
|
|
36
|
+
}
|
|
37
|
+
}, {
|
|
38
|
+
sequelize,
|
|
39
|
+
tableName: 'Scout',
|
|
40
|
+
schema: 'public',
|
|
41
|
+
timestamps: false,
|
|
42
|
+
indexes: [
|
|
43
|
+
{
|
|
44
|
+
name: 'Scout_pk',
|
|
45
|
+
unique: true,
|
|
46
|
+
fields: [{ name: 'scout_id' }]
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: 'Scout_team_id_unique',
|
|
50
|
+
unique: true,
|
|
51
|
+
fields: [{ name: 'team_id' }]
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
exports.ScoutModel = ScoutModel;
|
|
@@ -17,6 +17,7 @@ function transformToAttributes(player) {
|
|
|
17
17
|
country_id: player.country.id,
|
|
18
18
|
first_name: player.name.first,
|
|
19
19
|
last_name: player.name.last,
|
|
20
|
+
nickname: player.nickname ?? null,
|
|
20
21
|
roles: player.roles,
|
|
21
22
|
traits: player.traits,
|
|
22
23
|
PerformanceStat: (0, _1.transformFromPerformanceStats)(player.stats, player.id),
|
|
@@ -80,6 +81,7 @@ function transformToObject(model, currentIteration) {
|
|
|
80
81
|
first: model.first_name,
|
|
81
82
|
last: model.last_name
|
|
82
83
|
},
|
|
84
|
+
nickname: model.nickname ?? undefined,
|
|
83
85
|
country: (0, _1.transformToCountry)(model.country),
|
|
84
86
|
roles: model.roles,
|
|
85
87
|
traits: model.traits,
|
|
@@ -36,6 +36,7 @@ export interface GachaPullConfig {
|
|
|
36
36
|
export declare const NORMAL_PULL_CONFIG: GachaPullConfig;
|
|
37
37
|
export declare const QUALIFIER_PULL_CONFIG: GachaPullConfig;
|
|
38
38
|
export declare const TOURNAMENT_PULL_CONFIG: GachaPullConfig;
|
|
39
|
+
export declare function scoutPullConfig(level: string): GachaPullConfig;
|
|
39
40
|
export declare function rollRarity(pity: PityState, config?: GachaPullConfig): RollResult;
|
|
40
41
|
export declare class PlayerGenerator {
|
|
41
42
|
private constructor();
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PlayerGenerator = exports.TOURNAMENT_PULL_CONFIG = exports.QUALIFIER_PULL_CONFIG = exports.NORMAL_PULL_CONFIG = exports.PITY_STEP = exports.PITY_THRESHOLDS = void 0;
|
|
4
|
+
exports.scoutPullConfig = scoutPullConfig;
|
|
4
5
|
exports.rollRarity = rollRarity;
|
|
5
6
|
exports.pickPlayerCountry = pickPlayerCountry;
|
|
6
7
|
const uuid_1 = require("uuid");
|
|
@@ -20,7 +21,7 @@ const decline_1 = require("./decline");
|
|
|
20
21
|
exports.PITY_THRESHOLDS = {
|
|
21
22
|
legendary: 25,
|
|
22
23
|
mythic: 200,
|
|
23
|
-
special:
|
|
24
|
+
special: 600
|
|
24
25
|
};
|
|
25
26
|
// Per-pull soft-pity step: how much a rarity's odds increase for each pull without it. Small enough
|
|
26
27
|
// that base rates stay honest until the hard-pity threshold guarantees the drop.
|
|
@@ -81,6 +82,67 @@ exports.TOURNAMENT_PULL_CONFIG = {
|
|
|
81
82
|
accumulateMythicPity: true,
|
|
82
83
|
accumulateSpecialPity: true
|
|
83
84
|
};
|
|
85
|
+
// Scout employee: each upgrade level shifts a team's NORMAL-pull odds - fewer commons, more legendary+,
|
|
86
|
+
// and at MYTHIC+ a tiny SPECIAL chance plus special pity (apply + accumulate). RARE band width stays 0.25
|
|
87
|
+
// and COMMON is the remainder. Levels reuse the Rarity ladder: COMMON = no scout / base, up to SPECIAL =
|
|
88
|
+
// max. Caps at max scout: legendary 5%, mythic 1.5%, special 0.1%. See plans/scout-employee.md.
|
|
89
|
+
const SCOUT_PULL_CONFIGS = {
|
|
90
|
+
COMMON: exports.NORMAL_PULL_CONFIG,
|
|
91
|
+
RARE: {
|
|
92
|
+
special: 0,
|
|
93
|
+
mythic: 0.007,
|
|
94
|
+
legendary: 0.03,
|
|
95
|
+
rare: 0.25,
|
|
96
|
+
applyLegendaryPity: true,
|
|
97
|
+
applyMythicPity: true,
|
|
98
|
+
applySpecialPity: false,
|
|
99
|
+
accumulateLegendaryPity: true,
|
|
100
|
+
accumulateMythicPity: true,
|
|
101
|
+
accumulateSpecialPity: false
|
|
102
|
+
},
|
|
103
|
+
LEGENDARY: {
|
|
104
|
+
special: 0,
|
|
105
|
+
mythic: 0.01,
|
|
106
|
+
legendary: 0.04,
|
|
107
|
+
rare: 0.25,
|
|
108
|
+
applyLegendaryPity: true,
|
|
109
|
+
applyMythicPity: true,
|
|
110
|
+
applySpecialPity: false,
|
|
111
|
+
accumulateLegendaryPity: true,
|
|
112
|
+
accumulateMythicPity: true,
|
|
113
|
+
accumulateSpecialPity: false
|
|
114
|
+
},
|
|
115
|
+
MYTHIC: {
|
|
116
|
+
special: 0.0005,
|
|
117
|
+
mythic: 0.013,
|
|
118
|
+
legendary: 0.045,
|
|
119
|
+
rare: 0.25,
|
|
120
|
+
applyLegendaryPity: true,
|
|
121
|
+
applyMythicPity: true,
|
|
122
|
+
applySpecialPity: true,
|
|
123
|
+
accumulateLegendaryPity: true,
|
|
124
|
+
accumulateMythicPity: true,
|
|
125
|
+
accumulateSpecialPity: true
|
|
126
|
+
},
|
|
127
|
+
SPECIAL: {
|
|
128
|
+
special: 0.001,
|
|
129
|
+
mythic: 0.015,
|
|
130
|
+
legendary: 0.05,
|
|
131
|
+
rare: 0.25,
|
|
132
|
+
applyLegendaryPity: true,
|
|
133
|
+
applyMythicPity: true,
|
|
134
|
+
applySpecialPity: true,
|
|
135
|
+
accumulateLegendaryPity: true,
|
|
136
|
+
accumulateMythicPity: true,
|
|
137
|
+
accumulateSpecialPity: true
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
// The pull config for a team's scout level (the scout's rarity field). Unknown levels fall back to the
|
|
141
|
+
// base NORMAL_PULL_CONFIG. The API uses this for normal pulls and to derive the scout-tied SPECIAL rate
|
|
142
|
+
// for match grants (national/qualifier = this special, tournament = 2x), gated by applySpecialPity.
|
|
143
|
+
function scoutPullConfig(level) {
|
|
144
|
+
return SCOUT_PULL_CONFIGS[level] ?? exports.NORMAL_PULL_CONFIG;
|
|
145
|
+
}
|
|
84
146
|
// Effective odds for a rarity: the base rate plus a gentle per-pull soft-pity increase, until the
|
|
85
147
|
// counter reaches its threshold, at which point the rarity is a guaranteed drop (odds = 1). Returns
|
|
86
148
|
// the base rate unchanged when pity is not applied for this pull type.
|
|
@@ -54,9 +54,10 @@ 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, age, birthAge, birthIteration, declineProfile, boxScores, boxScoreTotals }) {
|
|
57
|
+
constructor({ id, name, nickname, country, stats, roles, traits, rarity, age, birthAge, birthIteration, declineProfile, boxScores, boxScoreTotals }) {
|
|
58
58
|
this.id = id;
|
|
59
59
|
this.name = name;
|
|
60
|
+
this.nickname = nickname;
|
|
60
61
|
this.country = country;
|
|
61
62
|
this.stats = stats;
|
|
62
63
|
this.roles = roles;
|
|
@@ -28,6 +28,7 @@ const BoxScoreTotalsInputSchema = zod_1.z.object({
|
|
|
28
28
|
exports.PlayerInputSchema = zod_1.z.object({
|
|
29
29
|
id: zod_1.z.uuid(),
|
|
30
30
|
name: exports.NameInputSchema,
|
|
31
|
+
nickname: zod_1.z.string().max(16).optional(),
|
|
31
32
|
country: countrySchema,
|
|
32
33
|
stats: performance_stats_z_1.PerformanceStatsInputSchema,
|
|
33
34
|
roles: zod_1.z.array(zod_1.z.enum(Object.values(role_1.RoleEnum))).min(1),
|
|
@@ -40,7 +40,7 @@ export type Match = Omit<DataProps<_Match>, 'sets' | 'homeTeam' | 'awayTeam' | '
|
|
|
40
40
|
export type RallyEvent = DataProps<_RallyEvent> & {
|
|
41
41
|
team?: Team;
|
|
42
42
|
};
|
|
43
|
-
export type Player = Omit<DataProps<_Player>, 'stats' | 'birthAge' | 'birthIteration' | 'declineProfile'> & {
|
|
43
|
+
export type Player = Omit<DataProps<_Player>, 'stats' | 'birthAge' | 'birthIteration' | 'declineProfile' | 'nickname'> & {
|
|
44
44
|
-readonly [K in 'birthAge' | 'birthIteration' | 'declineProfile']?: DataProps<_Player>[K];
|
|
45
45
|
} & {
|
|
46
46
|
stats?: PerformanceStats;
|
|
@@ -48,6 +48,7 @@ export type Player = Omit<DataProps<_Player>, 'stats' | 'birthAge' | 'birthItera
|
|
|
48
48
|
jerseyNumber: number;
|
|
49
49
|
locked?: boolean;
|
|
50
50
|
declineStatus?: DeclineStatus;
|
|
51
|
+
nickname?: string;
|
|
51
52
|
};
|
|
52
53
|
export interface StartingLineup {
|
|
53
54
|
[CourtPosition.LEFT_FRONT]: string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { AuthIdentityModel, AuthSessionModel, AuthUserModel, BoxScoreModel, CoachModel, BoxScoreTotalsModel, CompetitionChampionModel, CurrencyTransactionModel, GachaPityModel, GachaPullHistoryModel, WishlistModel, UserSettingsModel, CompetitionMatchModel, CompetitionMVPModel, CompetitionModel, CompetitionStandingsMatchModel, CompetitionStandingsModel, CompetitionTeamsModel, CountryModel, DivisionModel, DivisionSeasonModel, IterationModel, LeagueModel, MatchModel, MatchRatingModel, MatchResultModel, MatchSetModel, PerformanceStatsModel, PlayerModel, PlayerImprovementLogModel, PlayerTeamModel, RetiredPlayerModel, PromotionMatchModel, RegionQualifierModel, NationalCountryModel, RallyModel, TacticsModel, TeamModel, TeamReplacementModel, UserCurrencyModel, UserPlayerProgressModel, UserPullGrantModel, UserTeamModel, VPERModel, NotificationModel, AppConfigModel, LegacyTeamFlagModel } from './models';
|
|
1
|
+
import { AuthIdentityModel, AuthSessionModel, AuthUserModel, BoxScoreModel, CoachModel, ScoutModel, BoxScoreTotalsModel, CompetitionChampionModel, CurrencyTransactionModel, GachaPityModel, GachaPullHistoryModel, WishlistModel, UserSettingsModel, CompetitionMatchModel, CompetitionMVPModel, CompetitionModel, CompetitionStandingsMatchModel, CompetitionStandingsModel, CompetitionTeamsModel, CountryModel, DivisionModel, DivisionSeasonModel, IterationModel, LeagueModel, MatchModel, MatchRatingModel, MatchResultModel, MatchSetModel, PerformanceStatsModel, PlayerModel, PlayerImprovementLogModel, PlayerTeamModel, RetiredPlayerModel, PromotionMatchModel, RegionQualifierModel, NationalCountryModel, RallyModel, TacticsModel, TeamModel, TeamReplacementModel, UserCurrencyModel, UserPlayerProgressModel, UserPullGrantModel, UserTeamModel, VPERModel, NotificationModel, AppConfigModel, LegacyTeamFlagModel } from './models';
|
|
2
2
|
export function initModels(sequelize) {
|
|
3
3
|
const Coach = CoachModel.initModel(sequelize);
|
|
4
|
+
const Scout = ScoutModel.initModel(sequelize);
|
|
4
5
|
const CurrencyTransaction = CurrencyTransactionModel.initModel(sequelize);
|
|
5
6
|
const Tactics = TacticsModel.initModel(sequelize);
|
|
6
7
|
const AuthUser = AuthUserModel.initModel(sequelize);
|
|
@@ -192,6 +193,8 @@ export function initModels(sequelize) {
|
|
|
192
193
|
VPER.belongsTo(Match, { as: 'Match', foreignKey: 'match_id' });
|
|
193
194
|
Team.hasOne(Coach, { as: 'Coach', foreignKey: 'team_id' });
|
|
194
195
|
Coach.belongsTo(Team, { as: 'team', foreignKey: 'team_id' });
|
|
196
|
+
Team.hasOne(Scout, { as: 'Scout', foreignKey: 'team_id' });
|
|
197
|
+
Scout.belongsTo(Team, { as: 'team', foreignKey: 'team_id' });
|
|
195
198
|
Team.hasOne(Tactics, { as: 'tactics', foreignKey: 'team_id' });
|
|
196
199
|
Team.belongsTo(Country, { as: 'country', foreignKey: 'country_id' });
|
|
197
200
|
Team.belongsToMany(Competition, {
|
|
@@ -274,6 +277,7 @@ export function initModels(sequelize) {
|
|
|
274
277
|
UserSettings,
|
|
275
278
|
Notification,
|
|
276
279
|
Coach,
|
|
280
|
+
Scout,
|
|
277
281
|
CurrencyTransaction,
|
|
278
282
|
VPER,
|
|
279
283
|
LegacyTeamFlag,
|
|
@@ -10,12 +10,13 @@ export declare enum CurrencyTransactionSourceEnum {
|
|
|
10
10
|
MATCH_REWARD = "MATCH_REWARD",
|
|
11
11
|
GACHA_PULL = "GACHA_PULL",
|
|
12
12
|
COACH_UPGRADE = "COACH_UPGRADE",
|
|
13
|
+
SCOUT_UPGRADE = "SCOUT_UPGRADE",
|
|
13
14
|
PLAYER_DISMISS = "PLAYER_DISMISS",
|
|
14
15
|
PLAYER_RETIRE = "PLAYER_RETIRE",
|
|
15
16
|
ADMIN_GRANT = "ADMIN_GRANT",
|
|
16
17
|
SEASON_REWARD = "SEASON_REWARD"
|
|
17
18
|
}
|
|
18
|
-
export type CurrencyTransactionSource = CurrencyTransactionSourceEnum.MATCH_REWARD | CurrencyTransactionSourceEnum.GACHA_PULL | CurrencyTransactionSourceEnum.COACH_UPGRADE | CurrencyTransactionSourceEnum.PLAYER_DISMISS | CurrencyTransactionSourceEnum.PLAYER_RETIRE | CurrencyTransactionSourceEnum.ADMIN_GRANT | CurrencyTransactionSourceEnum.SEASON_REWARD;
|
|
19
|
+
export type CurrencyTransactionSource = CurrencyTransactionSourceEnum.MATCH_REWARD | CurrencyTransactionSourceEnum.GACHA_PULL | CurrencyTransactionSourceEnum.COACH_UPGRADE | CurrencyTransactionSourceEnum.SCOUT_UPGRADE | CurrencyTransactionSourceEnum.PLAYER_DISMISS | CurrencyTransactionSourceEnum.PLAYER_RETIRE | CurrencyTransactionSourceEnum.ADMIN_GRANT | CurrencyTransactionSourceEnum.SEASON_REWARD;
|
|
19
20
|
export interface CurrencyTransactionAttributes {
|
|
20
21
|
transaction_id: string;
|
|
21
22
|
user_id: string;
|
|
@@ -9,6 +9,7 @@ export var CurrencyTransactionSourceEnum;
|
|
|
9
9
|
CurrencyTransactionSourceEnum["MATCH_REWARD"] = "MATCH_REWARD";
|
|
10
10
|
CurrencyTransactionSourceEnum["GACHA_PULL"] = "GACHA_PULL";
|
|
11
11
|
CurrencyTransactionSourceEnum["COACH_UPGRADE"] = "COACH_UPGRADE";
|
|
12
|
+
CurrencyTransactionSourceEnum["SCOUT_UPGRADE"] = "SCOUT_UPGRADE";
|
|
12
13
|
CurrencyTransactionSourceEnum["PLAYER_DISMISS"] = "PLAYER_DISMISS";
|
|
13
14
|
CurrencyTransactionSourceEnum["PLAYER_RETIRE"] = "PLAYER_RETIRE";
|
|
14
15
|
CurrencyTransactionSourceEnum["ADMIN_GRANT"] = "ADMIN_GRANT";
|
|
@@ -29,6 +29,7 @@ export * from './promotion-match';
|
|
|
29
29
|
export * from './region-qualifier';
|
|
30
30
|
export * from './national-country';
|
|
31
31
|
export * from './coach';
|
|
32
|
+
export * from './scout';
|
|
32
33
|
export * from './team';
|
|
33
34
|
export * from './team-replacement';
|
|
34
35
|
export * from './tactics';
|
|
@@ -29,6 +29,7 @@ export * from './promotion-match';
|
|
|
29
29
|
export * from './region-qualifier';
|
|
30
30
|
export * from './national-country';
|
|
31
31
|
export * from './coach';
|
|
32
|
+
export * from './scout';
|
|
32
33
|
export * from './team';
|
|
33
34
|
export * from './team-replacement';
|
|
34
35
|
export * from './tactics';
|
|
@@ -9,6 +9,7 @@ export interface PlayerAttributes {
|
|
|
9
9
|
rarity: Rarity;
|
|
10
10
|
first_name: string;
|
|
11
11
|
last_name: string;
|
|
12
|
+
nickname?: string | null;
|
|
12
13
|
country_id: string;
|
|
13
14
|
birth_age: number;
|
|
14
15
|
birth_iteration: number;
|
|
@@ -27,6 +28,7 @@ export declare class PlayerModel extends Model<PlayerAttributes, PlayerCreationA
|
|
|
27
28
|
rarity: Rarity;
|
|
28
29
|
first_name: string;
|
|
29
30
|
last_name: string;
|
|
31
|
+
nickname: string | null;
|
|
30
32
|
country_id: string;
|
|
31
33
|
birth_age: number;
|
|
32
34
|
birth_iteration: number;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as Sequelize from 'sequelize';
|
|
2
|
+
import { Model } from 'sequelize';
|
|
3
|
+
import { TeamId, TeamModel } from '.';
|
|
4
|
+
export interface ScoutAttributes {
|
|
5
|
+
scout_id: string;
|
|
6
|
+
team_id: string;
|
|
7
|
+
name: string;
|
|
8
|
+
rarity: string;
|
|
9
|
+
currency_invested: number;
|
|
10
|
+
}
|
|
11
|
+
export type ScoutPk = 'scout_id';
|
|
12
|
+
export type ScoutId = ScoutModel[ScoutPk];
|
|
13
|
+
export type ScoutCreationAttributes = ScoutAttributes;
|
|
14
|
+
export declare class ScoutModel extends Model<ScoutAttributes, ScoutCreationAttributes> implements ScoutAttributes {
|
|
15
|
+
scout_id: string;
|
|
16
|
+
team_id: string;
|
|
17
|
+
name: string;
|
|
18
|
+
rarity: string;
|
|
19
|
+
currency_invested: number;
|
|
20
|
+
team: TeamModel;
|
|
21
|
+
getTeam: Sequelize.BelongsToGetAssociationMixin<TeamModel>;
|
|
22
|
+
setTeam: Sequelize.BelongsToSetAssociationMixin<TeamModel, TeamId>;
|
|
23
|
+
createTeam: Sequelize.BelongsToCreateAssociationMixin<TeamModel>;
|
|
24
|
+
static initModel(sequelize: Sequelize.Sequelize): typeof ScoutModel;
|
|
25
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { DataTypes, Model } from 'sequelize';
|
|
2
|
+
export class ScoutModel extends Model {
|
|
3
|
+
static initModel(sequelize) {
|
|
4
|
+
return ScoutModel.init({
|
|
5
|
+
scout_id: {
|
|
6
|
+
type: DataTypes.UUID,
|
|
7
|
+
allowNull: false,
|
|
8
|
+
primaryKey: true
|
|
9
|
+
},
|
|
10
|
+
team_id: {
|
|
11
|
+
type: DataTypes.UUID,
|
|
12
|
+
allowNull: false,
|
|
13
|
+
unique: true,
|
|
14
|
+
references: {
|
|
15
|
+
model: 'Team',
|
|
16
|
+
key: 'team_id'
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
name: {
|
|
20
|
+
type: DataTypes.STRING,
|
|
21
|
+
allowNull: false,
|
|
22
|
+
defaultValue: ''
|
|
23
|
+
},
|
|
24
|
+
rarity: {
|
|
25
|
+
type: DataTypes.STRING,
|
|
26
|
+
allowNull: false,
|
|
27
|
+
defaultValue: 'COMMON'
|
|
28
|
+
},
|
|
29
|
+
currency_invested: {
|
|
30
|
+
type: DataTypes.INTEGER,
|
|
31
|
+
allowNull: false,
|
|
32
|
+
defaultValue: 0
|
|
33
|
+
}
|
|
34
|
+
}, {
|
|
35
|
+
sequelize,
|
|
36
|
+
tableName: 'Scout',
|
|
37
|
+
schema: 'public',
|
|
38
|
+
timestamps: false,
|
|
39
|
+
indexes: [
|
|
40
|
+
{
|
|
41
|
+
name: 'Scout_pk',
|
|
42
|
+
unique: true,
|
|
43
|
+
fields: [{ name: 'scout_id' }]
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'Scout_team_id_unique',
|
|
47
|
+
unique: true,
|
|
48
|
+
fields: [{ name: 'team_id' }]
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -13,6 +13,7 @@ function transformToAttributes(player) {
|
|
|
13
13
|
country_id: player.country.id,
|
|
14
14
|
first_name: player.name.first,
|
|
15
15
|
last_name: player.name.last,
|
|
16
|
+
nickname: player.nickname ?? null,
|
|
16
17
|
roles: player.roles,
|
|
17
18
|
traits: player.traits,
|
|
18
19
|
PerformanceStat: transformFromPerformanceStats(player.stats, player.id),
|
|
@@ -76,6 +77,7 @@ function transformToObject(model, currentIteration) {
|
|
|
76
77
|
first: model.first_name,
|
|
77
78
|
last: model.last_name
|
|
78
79
|
},
|
|
80
|
+
nickname: model.nickname ?? undefined,
|
|
79
81
|
country: transformToCountry(model.country),
|
|
80
82
|
roles: model.roles,
|
|
81
83
|
traits: model.traits,
|
|
@@ -36,6 +36,7 @@ export interface GachaPullConfig {
|
|
|
36
36
|
export declare const NORMAL_PULL_CONFIG: GachaPullConfig;
|
|
37
37
|
export declare const QUALIFIER_PULL_CONFIG: GachaPullConfig;
|
|
38
38
|
export declare const TOURNAMENT_PULL_CONFIG: GachaPullConfig;
|
|
39
|
+
export declare function scoutPullConfig(level: string): GachaPullConfig;
|
|
39
40
|
export declare function rollRarity(pity: PityState, config?: GachaPullConfig): RollResult;
|
|
40
41
|
export declare class PlayerGenerator {
|
|
41
42
|
private constructor();
|
|
@@ -15,7 +15,7 @@ import { declineProfiles } from './decline';
|
|
|
15
15
|
export const PITY_THRESHOLDS = {
|
|
16
16
|
legendary: 25,
|
|
17
17
|
mythic: 200,
|
|
18
|
-
special:
|
|
18
|
+
special: 600
|
|
19
19
|
};
|
|
20
20
|
// Per-pull soft-pity step: how much a rarity's odds increase for each pull without it. Small enough
|
|
21
21
|
// that base rates stay honest until the hard-pity threshold guarantees the drop.
|
|
@@ -76,6 +76,67 @@ export const TOURNAMENT_PULL_CONFIG = {
|
|
|
76
76
|
accumulateMythicPity: true,
|
|
77
77
|
accumulateSpecialPity: true
|
|
78
78
|
};
|
|
79
|
+
// Scout employee: each upgrade level shifts a team's NORMAL-pull odds - fewer commons, more legendary+,
|
|
80
|
+
// and at MYTHIC+ a tiny SPECIAL chance plus special pity (apply + accumulate). RARE band width stays 0.25
|
|
81
|
+
// and COMMON is the remainder. Levels reuse the Rarity ladder: COMMON = no scout / base, up to SPECIAL =
|
|
82
|
+
// max. Caps at max scout: legendary 5%, mythic 1.5%, special 0.1%. See plans/scout-employee.md.
|
|
83
|
+
const SCOUT_PULL_CONFIGS = {
|
|
84
|
+
COMMON: NORMAL_PULL_CONFIG,
|
|
85
|
+
RARE: {
|
|
86
|
+
special: 0,
|
|
87
|
+
mythic: 0.007,
|
|
88
|
+
legendary: 0.03,
|
|
89
|
+
rare: 0.25,
|
|
90
|
+
applyLegendaryPity: true,
|
|
91
|
+
applyMythicPity: true,
|
|
92
|
+
applySpecialPity: false,
|
|
93
|
+
accumulateLegendaryPity: true,
|
|
94
|
+
accumulateMythicPity: true,
|
|
95
|
+
accumulateSpecialPity: false
|
|
96
|
+
},
|
|
97
|
+
LEGENDARY: {
|
|
98
|
+
special: 0,
|
|
99
|
+
mythic: 0.01,
|
|
100
|
+
legendary: 0.04,
|
|
101
|
+
rare: 0.25,
|
|
102
|
+
applyLegendaryPity: true,
|
|
103
|
+
applyMythicPity: true,
|
|
104
|
+
applySpecialPity: false,
|
|
105
|
+
accumulateLegendaryPity: true,
|
|
106
|
+
accumulateMythicPity: true,
|
|
107
|
+
accumulateSpecialPity: false
|
|
108
|
+
},
|
|
109
|
+
MYTHIC: {
|
|
110
|
+
special: 0.0005,
|
|
111
|
+
mythic: 0.013,
|
|
112
|
+
legendary: 0.045,
|
|
113
|
+
rare: 0.25,
|
|
114
|
+
applyLegendaryPity: true,
|
|
115
|
+
applyMythicPity: true,
|
|
116
|
+
applySpecialPity: true,
|
|
117
|
+
accumulateLegendaryPity: true,
|
|
118
|
+
accumulateMythicPity: true,
|
|
119
|
+
accumulateSpecialPity: true
|
|
120
|
+
},
|
|
121
|
+
SPECIAL: {
|
|
122
|
+
special: 0.001,
|
|
123
|
+
mythic: 0.015,
|
|
124
|
+
legendary: 0.05,
|
|
125
|
+
rare: 0.25,
|
|
126
|
+
applyLegendaryPity: true,
|
|
127
|
+
applyMythicPity: true,
|
|
128
|
+
applySpecialPity: true,
|
|
129
|
+
accumulateLegendaryPity: true,
|
|
130
|
+
accumulateMythicPity: true,
|
|
131
|
+
accumulateSpecialPity: true
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
// The pull config for a team's scout level (the scout's rarity field). Unknown levels fall back to the
|
|
135
|
+
// base NORMAL_PULL_CONFIG. The API uses this for normal pulls and to derive the scout-tied SPECIAL rate
|
|
136
|
+
// for match grants (national/qualifier = this special, tournament = 2x), gated by applySpecialPity.
|
|
137
|
+
export function scoutPullConfig(level) {
|
|
138
|
+
return SCOUT_PULL_CONFIGS[level] ?? NORMAL_PULL_CONFIG;
|
|
139
|
+
}
|
|
79
140
|
// Effective odds for a rarity: the base rate plus a gentle per-pull soft-pity increase, until the
|
|
80
141
|
// counter reaches its threshold, at which point the rarity is a guaranteed drop (odds = 1). Returns
|
|
81
142
|
// the base rate unchanged when pity is not applied for this pull type.
|
|
@@ -49,9 +49,10 @@ export class Player {
|
|
|
49
49
|
stats: PerformanceStats.create(result.data.stats)
|
|
50
50
|
});
|
|
51
51
|
}
|
|
52
|
-
constructor({ id, name, country, stats, roles, traits, rarity, age, birthAge, birthIteration, declineProfile, boxScores, boxScoreTotals }) {
|
|
52
|
+
constructor({ id, name, nickname, country, stats, roles, traits, rarity, age, birthAge, birthIteration, declineProfile, boxScores, boxScoreTotals }) {
|
|
53
53
|
this.id = id;
|
|
54
54
|
this.name = name;
|
|
55
|
+
this.nickname = nickname;
|
|
55
56
|
this.country = country;
|
|
56
57
|
this.stats = stats;
|
|
57
58
|
this.roles = roles;
|
|
@@ -25,6 +25,7 @@ const BoxScoreTotalsInputSchema = z.object({
|
|
|
25
25
|
export const PlayerInputSchema = z.object({
|
|
26
26
|
id: z.uuid(),
|
|
27
27
|
name: NameInputSchema,
|
|
28
|
+
nickname: z.string().max(16).optional(),
|
|
28
29
|
country: countrySchema,
|
|
29
30
|
stats: PerformanceStatsInputSchema,
|
|
30
31
|
roles: z.array(z.enum(Object.values(RoleEnum))).min(1),
|