Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rookie scales customizable #378

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
5 changes: 5 additions & 0 deletions src/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@ export type GameAttributesLeague = {
aiTradesFactor: number;
allStarGame: number | null;
autoDeleteOldBoxScores: boolean;
automaticRookieScale: boolean;
brotherRate: number;
budget: boolean;
challengeNoDraftPicks: boolean;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -1006,6 +1010,7 @@ export type PlayersPlusOptions = {
numGamesRemaining?: number;
statType?: PlayerStatType;
mergeStats?: boolean;
draft?: boolean;
};

export type Race = "asian" | "black" | "brown" | "white";
Expand Down
21 changes: 18 additions & 3 deletions src/ui/views/NegotiationList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand All @@ -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: [
Expand Down Expand Up @@ -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
Expand Down
99 changes: 95 additions & 4 deletions src/ui/views/Settings/SettingsForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -1038,7 +1100,11 @@ const Input = ({
id: string;
maxWidth?: true;
name: string;
onChange: (event: ChangeEvent<HTMLInputElement | HTMLSelectElement>) => void;
onChange: (
event: ChangeEvent<
HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement
>,
) => void;
type: FieldType;
value: string;
values?: Values;
Expand Down Expand Up @@ -1077,6 +1143,16 @@ const Input = ({
<label className="custom-control-label" htmlFor={id}></label>
</div>
);
} else if (type === "rookieScale") {
inputElement = (
<textarea
rows={3}
value={value}
onChange={onChange}
style={{ width: "90%" }}
disabled={disabled}
/>
);
} else if (type === "rangePercent") {
inputElement = (
<div className="d-flex" style={inputStyle}>
Expand Down Expand Up @@ -1203,7 +1279,11 @@ const Option = ({
godModeRequired?: "always" | "existingLeagueOnly";
newLeague?: boolean;
maxWidth?: true;
onChange: (event: ChangeEvent<HTMLInputElement | HTMLSelectElement>) => void;
onChange: (
event: ChangeEvent<
HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement
>,
) => void;
type: FieldType;
value: string;
values?: Values;
Expand All @@ -1213,7 +1293,14 @@ const Option = ({

return (
<>
<div className="d-flex align-items-center" style={{ minHeight: 33 }}>
<div
className="d-flex align-items-center"
style={
type != "rookieScale"
? { minHeight: 33 }
: { minHeight: 33, flexDirection: "column" }
}
>
<div className="mr-auto text-nowrap">
<label
className="mb-0"
Expand Down Expand Up @@ -1413,11 +1500,15 @@ const SettingsForm = ({
};

const handleChange = (name: Key, type: FieldType) => (
event: ChangeEvent<HTMLInputElement | HTMLSelectElement>,
event: ChangeEvent<
HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement
>,
) => {
let value: string;
if (type === "bool") {
value = String((event.target as any).checked);
} else if (type === "rookieScale") {
value = event.target.value;
} else if (type === "floatValuesOrCustom") {
if (event.target.value === "custom") {
value = JSON.stringify([true, JSON.parse(state[name])[1]]);
Expand Down
85 changes: 85 additions & 0 deletions src/ui/views/Settings/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,91 @@ export const settings: {
}
},
},
{
category: "Contracts",
key: "rookieScale",
name: "Rookie Scale",
godModeRequired: "always",
type: "bool",
description: (
<p>
If enabled the rookies have to be signed to a fixed salary, determined
by the Rookie Scales setting
</p>
),
},
{
category: "Contracts",
key: "automaticRookieScale",
name: "Automatic Rookie Scale",
godModeRequired: "always",
type: "bool",
description: (
<p>
If enabled the rookie scale is fixed for the max and mins contracts,
earning the top pick a fixed percentage of the max contract.
</p>
),
},
{
category: "Contracts",
key: "rookieScaleMaxContract",
name: "Rookie Scale Max Contract ratio",
godModeRequired: "always",
type: "float",
descriptionLong: (
<p>
If Automatic Rookie Scale is enabled this determines the maximum
contract of the rookie scale as a percentage of the max contract.
</p>
),
},
{
category: "Contracts",
maxWidth: true,
key: "rookieScales",
name: "Rookie Scales",
godModeRequired: "always",
type: "rookieScale",
descriptionLong: (
<>
<p>
If the Hard Cap is enabled these values establish the rookie salary
for each position in the draft.
</p>
<p>
The first scale belongs to the first round (ordered by position), the
second to the second and following rounds. It does not matter if you
put less values than the number of teams, the scale will be filled
with the last value, as long as you have one value.
<a
href="https://en.wikipedia.org/wiki/NBA_salary_cap#Rookie_scale_salary"
target="_blank"
rel="noopener noreferrer"
>
Rookie scale salary
</a>
</p>
</>
),
validator: (value, output) => {
console.log(value);
if (value[0])
if (value.length < 2) {
if (value < 1) {
throw new Error("Rookie scale must have two ");
} else if (value[0].length < 1) {
throw new Error(
"Rookie scale of first round must have at least one value",
);
} else if (value[1].length < 1) {
throw new Error(
"Rookie scale of second round must have at least one value",
);
}
}
},
},
{
category: "Finances",
key: "hardCap",
Expand Down
7 changes: 6 additions & 1 deletion src/ui/views/Settings/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ export type Key =
| "foulsUntilBonus"
| "threePointers"
| "pace"
| "automaticRookieScale"
| "rookieScaleMaxContract"
| "rookieScale"
| "rookieScales"
| "threePointTendencyFactor"
| "threePointAccuracyFactor"
| "twoPointAccuracyFactor"
Expand Down Expand Up @@ -100,7 +104,8 @@ export type FieldType =
| "jsonString"
| "string"
| "rangePercent"
| "floatValuesOrCustom";
| "floatValuesOrCustom"
| "rookieScale";

export type Decoration = "currency" | "percent";

Expand Down
Loading