diff --git a/src/common/constants.ts b/src/common/constants.ts index 2dd545ed08..57ba4d9e86 100644 --- a/src/common/constants.ts +++ b/src/common/constants.ts @@ -21,7 +21,7 @@ const DIFFICULTY = { Insane: 1, }; -const MAX_SUPPORTED_LEAGUE_VERSION = 43; +const MAX_SUPPORTED_LEAGUE_VERSION = 44; const NO_LOTTERY_DRAFT_TYPES: DraftType[] = [ "freeAgents", diff --git a/src/common/types.ts b/src/common/types.ts index 6236128ebc..0dc30f59a1 100644 --- a/src/common/types.ts +++ b/src/common/types.ts @@ -357,6 +357,7 @@ export type GameAttributesLeague = { aiTradesFactor: number; allStarGame: number | null; autoDeleteOldBoxScores: boolean; + automaticRookieScale: boolean; brotherRate: number; budget: boolean; challengeNoDraftPicks: boolean; @@ -415,6 +416,9 @@ export type GameAttributesLeague = { numTeams: number; playerMoodTraits: boolean; pointsFormula: string; + rookieScale: boolean; + rookieScaleMaxContract: number; + rookieScales: number[][]; spectator: boolean; otl: boolean; otherTeamsWantToHire: boolean; @@ -1006,6 +1010,7 @@ export type PlayersPlusOptions = { numGamesRemaining?: number; statType?: PlayerStatType; mergeStats?: boolean; + draft?: boolean; }; export type Race = "asian" | "black" | "brown" | "white"; diff --git a/src/ui/views/NegotiationList.tsx b/src/ui/views/NegotiationList.tsx index 16de8320ae..d8b4bc768a 100644 --- a/src/ui/views/NegotiationList.tsx +++ b/src/ui/views/NegotiationList.tsx @@ -23,6 +23,10 @@ const NegotiationList = ({ stats, sumContracts, userPlayers, + rookieScale, + season, + numActiveTeams, + yearsRookieContracts, }: View<"negotiationList">) => { const title = hardCap ? "Rookies and Expiring Contracts" : "Re-sign Players"; @@ -45,8 +49,8 @@ const NegotiationList = ({ "Exp", "Negotiate", ); - const rows = players.map(p => { + const isRookie = rookieScale != undefined && p.draft.year === season; return { key: p.pid, data: [ @@ -74,8 +78,19 @@ const NegotiationList = ({ maxWidth: true, p, }), - helpers.formatCurrency(p.mood.user.contractAmount / 1000, "M"), - p.contract.exp, + isRookie && rookieScale != undefined + ? helpers.formatCurrency( + rookieScale[ + p.draft.pick - 1 + numActiveTeams * (p.draft.round - 1) + ] / 1000, + "M", + ) + : helpers.formatCurrency(p.mood.user.contractAmount / 1000, "M"), + isRookie && rookieScale != undefined + ? yearsRookieContracts[ + Math.min(yearsRookieContracts.length - 1, p.draft.round - 1) + ] + season + : p.contract.exp, { value: ( // https://github.com/DefinitelyTyped/DefinitelyTyped/issues/20544 diff --git a/src/ui/views/Settings/SettingsForm.tsx b/src/ui/views/Settings/SettingsForm.tsx index 5b16504a84..093a8207c7 100644 --- a/src/ui/views/Settings/SettingsForm.tsx +++ b/src/ui/views/Settings/SettingsForm.tsx @@ -904,6 +904,68 @@ const encodeDecodeFunctions = { return parsed; }, }, + rookieScale: { + stringify: (value: number[][]) => { + var val = "{" + String(value[0]) + "};{" + String(value[1]) + "}"; + + return val; + }, + parse: (value: string) => { + var values = value.split(";"); + if (values.length != 2 || !value.match("{.*}s*;s*{.*}")) { + throw new Error( + "Must have two array with brackets separated by a ;. i.e. {1000,800};{1000,750}", + ); + } + + var val0 = values[0]; + var val1 = values[1]; + + var scale0 = (val0.match(/\{(.*?)\}/) || ["", ""])[1] + .split(",") + .map((x, i) => { + if (i == 0 && x == "") { + throw new Error("First round scale must have at least one number"); + } + var num = Number(x); + if (Number.isNaN(num)) { + throw new Error( + x + " is not a number. Rookie scales must be composed of numbers", + ); + } else { + return num; + } + }); + var scale1 = (val1.match(/\{(.*?)\}/) || ["", ""])[1] + .split(",") + .map((x, i) => { + if (i == 0 && x == "") { + throw new Error("Second round scale must have at least one number"); + } + var num = Number(x); + if (Number.isNaN(num)) { + throw new Error( + x + " is not a number. Rookie scales must be composed of numbers", + ); + } else { + return num; + } + }); + + if (scale0.length < 1) { + throw new Error( + "Rookie scale of first round must have at least one value", + ); + } + if (scale1.length < 1) { + throw new Error( + "Rookie scale of second round must have at least one value", + ); + } + + return [scale0, scale1]; + }, + }, string: {}, jsonString: { stringify: (value: any) => JSON.stringify(value), @@ -1038,7 +1100,11 @@ const Input = ({ id: string; maxWidth?: true; name: string; - onChange: (event: ChangeEvent) => void; + onChange: ( + event: ChangeEvent< + HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement + >, + ) => void; type: FieldType; value: string; values?: Values; @@ -1077,6 +1143,16 @@ const Input = ({ ); + } else if (type === "rookieScale") { + inputElement = ( +