diff --git a/src/worker/core/player/developSeason.basketball.ts b/src/worker/core/player/developSeason.basketball.ts index d0d2feaf73..bf2c7d1d0b 100644 --- a/src/worker/core/player/developSeason.basketball.ts +++ b/src/worker/core/player/developSeason.basketball.ts @@ -10,192 +10,144 @@ type RatingFormula = { changeLimits: (age: number) => [number, number]; }; -const shootingFormula: RatingFormula = { +const defaultFormula: RatingFormula = { ageModifier: (age: number) => { - // Reverse most of the age-related decline in calcBaseChange - if (age <= 27) { - return 0; - } - - if (age <= 29) { - return 0.5; - } - - if (age <= 31) { - return 1.5; - } - - return 2; + return 0; }, - changeLimits: () => [-3, 13], -}; -const iqFormula: RatingFormula = { - ageModifier: (age: number) => { - if (age <= 21) { - return 4; - } - + changeLimits: (age: number) => { if (age <= 23) { - return 3; - } - - // Reverse most of the age-related decline in calcBaseChange - if (age <= 27) { - return 0; - } - - if (age <= 29) { - return 0.5; - } - - if (age <= 31) { - return 1.5; + return [-2, 20]; + } else if (age <= 25) { + return [-5, 10]; } - - return 2; - }, - changeLimits: age => { - if (age > 24) { - return [-3, 9]; - } - - // For 19: [-3, 32] - // For 23: [-3, 12] - return [-3, 7 + 5 * (24 - age)]; + const age_adj = -0.5 * (age - 25); + return [-5 + age_adj, 5 + age_adj]; }, }; + const ratingsFormulas: Record, RatingFormula> = { stre: { - ageModifier: () => 0, - changeLimits: () => [-Infinity, Infinity], + ageModifier: (age: number) => { + return -0.4; + }, + changeLimits: (age: number) => defaultFormula.changeLimits(age), }, spd: { ageModifier: (age: number) => { - if (age <= 27) { - return 0; - } - - if (age <= 30) { - return -2; + if (age <= 20) { + return -0.1; } - - if (age <= 35) { - return -3; - } - - if (age <= 40) { - return -4; - } - - return -8; + return -0.2 * (age - 20) + -0.1; }, - changeLimits: () => [-12, 2], + changeLimits: (age: number) => defaultFormula.changeLimits(age), }, - jmp: { + jmp: defaultFormula, + endu: { ageModifier: (age: number) => { - if (age <= 26) { - return 0; - } - - if (age <= 30) { - return -3; - } - - if (age <= 35) { - return -4; - } - - if (age <= 40) { - return -5; + if (age <= 20) { + return 3.7; } - - return -10; + return -0.5 * (age - 20) + 3.7; }, - changeLimits: () => [-12, 2], + changeLimits: (age: number) => defaultFormula.changeLimits(age), }, - endu: { + dnk: { ageModifier: (age: number) => { - if (age <= 23) { - return random.uniform(0, 9); + if (age <= 20) { + return -0.2; } - - if (age <= 30) { - return 0; + return 0.1 * (age - 20) + -0.2; + }, + changeLimits: (age: number) => defaultFormula.changeLimits(age), + }, + ins: { + ageModifier: (age: number) => { + if (age <= 20) { + return -1.1; } - - if (age <= 35) { - return -2; + return 0.2 * (age - 20) + -1.1; + }, + changeLimits: (age: number) => defaultFormula.changeLimits(age), + }, + ft: { + ageModifier: (age: number) => { + if (age <= 20) { + return -0.4; } - - if (age <= 40) { - return -4; + return 0.1 * (age - 20) + -0.4; + }, + changeLimits: (age: number) => defaultFormula.changeLimits(age), + }, + fg: defaultFormula, + tp: { + ageModifier: (age: number) => { + if (age <= 20) { + return -1.2; } - - return -8; + return 0.2 * (age - 20) + -1.2; }, - changeLimits: () => [-11, 19], + changeLimits: (age: number) => defaultFormula.changeLimits(age), }, - dnk: { + oiq: { ageModifier: (age: number) => { - // Like shootingForumla, except for old players - if (age <= 27) { - return 0; + return 0; + }, + changeLimits: (age: number) => defaultFormula.changeLimits(age), + }, + diq: { + ageModifier: (age: number) => { + if (age <= 20) { + return -0.7; } - - return 0.5; + return 0.1 * (age - 20) + -0.7; }, - changeLimits: () => [-3, 13], + changeLimits: (age: number) => defaultFormula.changeLimits(age), }, - ins: shootingFormula, - ft: shootingFormula, - fg: shootingFormula, - tp: shootingFormula, - oiq: iqFormula, - diq: iqFormula, drb: { - ageModifier: shootingFormula.ageModifier, - changeLimits: () => [-2, 5], + ageModifier: (age: number) => { + if (age <= 20) { + return -1.4; + } + return 0.2 * (age - 20) + -1.4; + }, + changeLimits: (age: number) => defaultFormula.changeLimits(age), }, pss: { - ageModifier: shootingFormula.ageModifier, - changeLimits: () => [-2, 5], + ageModifier: (age: number) => { + if (age <= 20) { + return -1.1; + } + return 0.2 * (age - 20) + -1.1; + }, + changeLimits: (age: number) => defaultFormula.changeLimits(age), }, reb: { - ageModifier: shootingFormula.ageModifier, - changeLimits: () => [-2, 5], + ageModifier: (age: number) => { + if (age <= 20) { + return -0.7; + } + return 0.1 * (age - 20) + -0.7; + }, + changeLimits: (age: number) => defaultFormula.changeLimits(age), }, }; const calcBaseChange = (age: number, coachingRank: number): number => { let val: number; - if (age <= 21) { - val = 2; - } else if (age <= 25) { - val = 1; - } else if (age <= 27) { - val = 0; - } else if (age <= 29) { - val = -1; - } else if (age <= 31) { - val = -2; - } else if (age <= 34) { - val = -3; - } else if (age <= 40) { - val = -4; - } else if (age <= 43) { - val = -5; + if (age <= 19) { + val = 2.2; } else { - val = -6; + val = -0.3 * (age - 19) + 2.2; } // Noise if (age <= 23) { - val += helpers.bound(random.realGauss(0, 5), -4, 20); - } else if (age <= 25) { - val += helpers.bound(random.realGauss(0, 5), -4, 10); + val += helpers.bound(random.realGauss(0, 8), -2, 8); + } else if (age <= 28) { + val += helpers.bound(random.realGauss(0, 6), -2, 6); } else { - val += helpers.bound(random.realGauss(0, 3), -2, 4); + val += helpers.bound(random.realGauss(0, 4), -2, 4); } // Modulate by coaching. g.get("numActiveTeams") doesn't exist when upgrading DB, but that doesn't matter @@ -227,7 +179,6 @@ const developSeason = ( ratings.hgt += 1; } } - const baseChange = calcBaseChange(age, coachingRank); for (const key of helpers.keys(ratingsFormulas)) { @@ -237,7 +188,7 @@ const developSeason = ( ratings[key] = limitRating( ratings[key] + helpers.bound( - (baseChange + ageModifier) * random.uniform(0.4, 1.4), + (baseChange + ageModifier) * random.uniform(0.1, 1.7), changeLimits[0], changeLimits[1], ), diff --git a/src/worker/core/player/genRatings.basketball.ts b/src/worker/core/player/genRatings.basketball.ts index 05d76b19f9..4a435970d7 100644 --- a/src/worker/core/player/genRatings.basketball.ts +++ b/src/worker/core/player/genRatings.basketball.ts @@ -14,34 +14,36 @@ const typeFactors: Record< Partial> > = { point: { - jmp: 1.65, - spd: 1.65, - drb: 1.5, - pss: 1.5, - ft: 1.4, - fg: 1.4, - tp: 1.4, - oiq: 1.2, - endu: 1.4, - }, - wing: { + jmp: 1.2, + spd: 1.1, drb: 1.2, - dnk: 1.5, - jmp: 1.4, - spd: 1.4, + pss: 1.2, + reb: 0.8, + ins: 0.9, ft: 1.2, fg: 1.2, tp: 1.2, + endu: 1.1, + dnk: 0.9, + }, + wing: { + jmp: 0.9, + pss: 0.9, + tp: 0.9, }, big: { - stre: 1.2, - ins: 1.6, - dnk: 1.5, - reb: 1.4, + stre: 1.1, + ins: 1.1, + dnk: 1.1, + endu: 0.9, + reb: 1.1, + spd: 0.9, + jmp: 0.9, + pss: 0.8, + drb: 0.9, ft: 0.8, fg: 0.8, tp: 0.8, - diq: 1.2, }, }; @@ -100,37 +102,38 @@ const genRatings = ( // Tall players are less talented, and all tend towards dumb and can't shoot because they are rookies const rawRatings = { - stre: 37, - spd: 40, - jmp: 40, - endu: 17, - ins: 27, - dnk: 27, - ft: 32, - fg: 32, - tp: 32, - oiq: 22, - diq: 22, - drb: 37, - pss: 37, - reb: 37, + stre: 44, + spd: 48, + jmp: 48, + endu: 31, + ins: 38, + dnk: 44, + ft: 40, + fg: 40, + tp: 41, + oiq: 37, + diq: 37, + drb: 46, + pss: 43, + reb: 45, }; // For correlation across ratings, to ensure some awesome players, but athleticism and skill are independent to // ensure there are some who are elite in one but not the other - const factorAthleticism = helpers.bound(random.realGauss(1, 0.2), 0.2, 1.2); - const factorShooting = helpers.bound(random.realGauss(1, 0.2), 0.2, 1.2); - const factorSkill = helpers.bound(random.realGauss(1, 0.2), 0.2, 1.2); - const factorIns = helpers.bound(random.realGauss(1, 0.2), 0.2, 1.2); - const athleticismRatings = ["stre", "spd", "jmp", "endu", "dnk"]; + const factorBig = helpers.bound(random.realGauss(1, 0.5), 0.2, 1.8); + const factorAthleticism = helpers.bound(random.realGauss(1, 0.5), 0.2, 1.8); + const factorShooting = helpers.bound(random.realGauss(1, 0.5), 0.2, 1.8); + const factorSkill = helpers.bound(random.realGauss(1, 0.5), 0.2, 1.8); + const bigRatings = ["stre", "ins", "reb", "endu", "dnk"]; + const athleticismRatings = ["spd", "jmp"]; const shootingRatings = ["ft", "fg", "tp"]; - const skillRatings = ["oiq", "diq", "drb", "pss", "reb"]; // ins purposely left out + const skillRatings = ["oiq", "diq", "drb", "pss"]; for (const key of helpers.keys(rawRatings)) { const typeFactor = typeFactors[type].hasOwnProperty(key) ? typeFactors[type][key] : 1; - let factor = factorIns; + let factor = 1; if (athleticismRatings.includes(key)) { factor = factorAthleticism; @@ -138,8 +141,9 @@ const genRatings = ( factor = factorShooting; } else if (skillRatings.includes(key)) { factor = factorSkill; + } else if (bigRatings.includes(key)) { + factor = factorBig; } - // For TypeScript // https://github.com/microsoft/TypeScript/issues/21732 if (typeFactor === undefined) { @@ -147,7 +151,7 @@ const genRatings = ( } rawRatings[key] = limitRating( - factor * typeFactor * random.realGauss(rawRatings[key], 3), + factor * typeFactor ** 3 * random.realGauss(rawRatings[key], 5), ); }