mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-30 03:23:48 +01:00
commit
4b95545f61
36
dist/vendor.bundle.js
vendored
36
dist/vendor.bundle.js
vendored
File diff suppressed because one or more lines are too long
@ -53,5 +53,4 @@
|
|||||||
<body>
|
<body>
|
||||||
<div id="root"/>
|
<div id="root"/>
|
||||||
<script type="text/javascript" src="dist/vendor.bundle.js"></script><script type="text/javascript" src="main.bundle.js"></script></body>
|
<script type="text/javascript" src="dist/vendor.bundle.js"></script><script type="text/javascript" src="main.bundle.js"></script></body>
|
||||||
<script src="src/ThirdParty/raphael.min.js"></script>
|
|
||||||
</html>
|
</html>
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -396,6 +396,15 @@ BitNodes["BitNode9"] = new BitNode(
|
|||||||
<br />
|
<br />
|
||||||
(Note that the Level 3 effect of this Source-File only applies when entering a new BitNode, NOT when installing
|
(Note that the Level 3 effect of this Source-File only applies when entering a new BitNode, NOT when installing
|
||||||
Augmentations)
|
Augmentations)
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
This Source-File also increases your hacknet multipliers by:
|
||||||
|
<br />
|
||||||
|
Level 1: 8%
|
||||||
|
<br />
|
||||||
|
Level 2: 12%
|
||||||
|
<br />
|
||||||
|
Level 3: 14%
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -8,8 +8,7 @@ import { IndustryUpgrades } from "../IndustryUpgrades";
|
|||||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
import { createProgressBarText } from "../../utils/helpers/createProgressBarText";
|
import { createProgressBarText } from "../../utils/helpers/createProgressBarText";
|
||||||
import { MakeProductModal } from "./MakeProductModal";
|
import { MakeProductModal } from "./MakeProductModal";
|
||||||
import { ResearchPopup } from "./ResearchPopup";
|
import { ResearchModal } from "./ResearchModal";
|
||||||
import { createPopup } from "../../ui/React/createPopup";
|
|
||||||
import { Money } from "../../ui/React/Money";
|
import { Money } from "../../ui/React/Money";
|
||||||
import { MoneyRate } from "../../ui/React/MoneyRate";
|
import { MoneyRate } from "../../ui/React/MoneyRate";
|
||||||
import { StatsTable } from "../../ui/React/StatsTable";
|
import { StatsTable } from "../../ui/React/StatsTable";
|
||||||
@ -96,6 +95,7 @@ function Text(): React.ReactElement {
|
|||||||
const corp = useCorporation();
|
const corp = useCorporation();
|
||||||
const division = useDivision();
|
const division = useDivision();
|
||||||
const [helpOpen, setHelpOpen] = useState(false);
|
const [helpOpen, setHelpOpen] = useState(false);
|
||||||
|
const [researchOpen, setResearchOpen] = useState(false);
|
||||||
const vechain = corp.unlockUpgrades[4] === 1;
|
const vechain = corp.unlockUpgrades[4] === 1;
|
||||||
const profit = division.lastCycleRevenue.minus(division.lastCycleExpenses).toNumber();
|
const profit = division.lastCycleRevenue.minus(division.lastCycleExpenses).toNumber();
|
||||||
|
|
||||||
@ -116,14 +116,6 @@ function Text(): React.ReactElement {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function openResearchPopup(): void {
|
|
||||||
const popupId = "corporation-research-popup-box";
|
|
||||||
createPopup(popupId, ResearchPopup, {
|
|
||||||
industry: division,
|
|
||||||
popupId: popupId,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Typography>
|
<Typography>
|
||||||
@ -214,9 +206,10 @@ function Text(): React.ReactElement {
|
|||||||
>
|
>
|
||||||
<Typography>Scientific Research: {numeralWrapper.format(division.sciResearch.qty, "0.000a")}</Typography>
|
<Typography>Scientific Research: {numeralWrapper.format(division.sciResearch.qty, "0.000a")}</Typography>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Button sx={{ mx: 1 }} onClick={openResearchPopup}>
|
<Button sx={{ mx: 1 }} onClick={() => setResearchOpen(true)}>
|
||||||
Research
|
Research
|
||||||
</Button>
|
</Button>
|
||||||
|
<ResearchModal open={researchOpen} onClose={() => setResearchOpen(false)} industry={division} />
|
||||||
</Box>
|
</Box>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
122
src/Corporation/ui/ResearchModal.tsx
Normal file
122
src/Corporation/ui/ResearchModal.tsx
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
import { Modal } from "../../ui/React/Modal";
|
||||||
|
import { IndustryResearchTrees } from "../IndustryData";
|
||||||
|
import { CorporationConstants } from "../data/Constants";
|
||||||
|
import { IIndustry } from "../IIndustry";
|
||||||
|
import { Research } from "../Actions";
|
||||||
|
import { Node } from "../ResearchTree";
|
||||||
|
import { ResearchMap } from "../ResearchMap";
|
||||||
|
import { dialogBoxCreate } from "../../ui/React/DialogBox";
|
||||||
|
import Typography from "@mui/material/Typography";
|
||||||
|
import Tooltip from "@mui/material/Tooltip";
|
||||||
|
import Button from "@mui/material/Button";
|
||||||
|
import Box from "@mui/material/Box";
|
||||||
|
|
||||||
|
import ListItemButton from "@mui/material/ListItemButton";
|
||||||
|
import ListItemText from "@mui/material/ListItemText";
|
||||||
|
import Collapse from "@mui/material/Collapse";
|
||||||
|
import ExpandMore from "@mui/icons-material/ExpandMore";
|
||||||
|
import ExpandLess from "@mui/icons-material/ExpandLess";
|
||||||
|
interface INodeProps {
|
||||||
|
n: Node | null;
|
||||||
|
division: IIndustry;
|
||||||
|
}
|
||||||
|
function Upgrade({ n, division }: INodeProps): React.ReactElement {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
if (n === null) return <></>;
|
||||||
|
const r = ResearchMap[n.text];
|
||||||
|
let disabled = division.sciResearch.qty < r.cost;
|
||||||
|
const parent = n.parent;
|
||||||
|
if (parent !== null) {
|
||||||
|
disabled = disabled || !parent.researched;
|
||||||
|
}
|
||||||
|
|
||||||
|
function research(): void {
|
||||||
|
if (n === null || disabled) return;
|
||||||
|
try {
|
||||||
|
Research(division, n.text);
|
||||||
|
} catch (err) {
|
||||||
|
dialogBoxCreate(err + "");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogBoxCreate(
|
||||||
|
`Researched ${n.text}. It may take a market cycle ` +
|
||||||
|
`(~${CorporationConstants.SecsPerMarketCycle} seconds) before the effects of ` +
|
||||||
|
`the Research apply.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const but = (
|
||||||
|
<Box>
|
||||||
|
<Tooltip
|
||||||
|
title={
|
||||||
|
<Typography>
|
||||||
|
Research points: {r.cost}
|
||||||
|
<br />
|
||||||
|
{r.desc}
|
||||||
|
</Typography>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
<Button disabled={disabled} onClick={research}>
|
||||||
|
{n.text}
|
||||||
|
</Button>
|
||||||
|
</span>
|
||||||
|
</Tooltip>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
|
||||||
|
if (n.children.length === 0) return but;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box>
|
||||||
|
<Box display="flex">
|
||||||
|
{but}
|
||||||
|
<ListItemButton onClick={() => setOpen((old) => !old)}>
|
||||||
|
<ListItemText />
|
||||||
|
{open ? <ExpandLess color="primary" /> : <ExpandMore color="primary" />}
|
||||||
|
</ListItemButton>
|
||||||
|
</Box>
|
||||||
|
<Collapse in={open} unmountOnExit>
|
||||||
|
<Box m={4}>
|
||||||
|
{n.children.map((m) => (
|
||||||
|
<Upgrade key={m.text} division={division} n={m} />
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
|
</Collapse>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
open: boolean;
|
||||||
|
onClose: () => void;
|
||||||
|
industry: IIndustry;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the Research Tree UI for this Industry
|
||||||
|
export function ResearchModal(props: IProps): React.ReactElement {
|
||||||
|
const researchTree = IndustryResearchTrees[props.industry.type];
|
||||||
|
if (researchTree === undefined) return <></>;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal open={props.open} onClose={props.onClose}>
|
||||||
|
<Upgrade division={props.industry} n={researchTree.root} />
|
||||||
|
<Typography>
|
||||||
|
Research points: {props.industry.sciResearch.qty}
|
||||||
|
<br />
|
||||||
|
Multipliers from research:
|
||||||
|
<br />* Advertising Multiplier: x{researchTree.getAdvertisingMultiplier()}
|
||||||
|
<br />* Employee Charisma Multiplier: x{researchTree.getEmployeeChaMultiplier()}
|
||||||
|
<br />* Employee Creativity Multiplier: x{researchTree.getEmployeeCreMultiplier()}
|
||||||
|
<br />* Employee Efficiency Multiplier: x{researchTree.getEmployeeEffMultiplier()}
|
||||||
|
<br />* Employee Intelligence Multiplier: x{researchTree.getEmployeeIntMultiplier()}
|
||||||
|
<br />* Production Multiplier: x{researchTree.getProductionMultiplier()}
|
||||||
|
<br />* Sales Multiplier: x{researchTree.getSalesMultiplier()}
|
||||||
|
<br />* Scientific Research Multiplier: x{researchTree.getScientificResearchMultiplier()}
|
||||||
|
<br />* Storage Multiplier: x{researchTree.getStorageMultiplier()}
|
||||||
|
</Typography>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
@ -1,96 +0,0 @@
|
|||||||
import React, { useEffect } from "react";
|
|
||||||
import { dialogBoxCreate } from "../../ui/React/DialogBox";
|
|
||||||
import { removePopup } from "../../ui/React/createPopup";
|
|
||||||
import { IndustryResearchTrees } from "../IndustryData";
|
|
||||||
import { CorporationConstants } from "../data/Constants";
|
|
||||||
import { Treant } from "treant-js";
|
|
||||||
import { IIndustry } from "../IIndustry";
|
|
||||||
import { Research } from "../Actions";
|
|
||||||
|
|
||||||
interface IProps {
|
|
||||||
industry: IIndustry;
|
|
||||||
popupId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the Research Tree UI for this Industry
|
|
||||||
export function ResearchPopup(props: IProps): React.ReactElement {
|
|
||||||
const researchTree = IndustryResearchTrees[props.industry.type];
|
|
||||||
if (researchTree === undefined) return <></>;
|
|
||||||
useEffect(() => {
|
|
||||||
{
|
|
||||||
const boxContent = document.getElementById(`${props.popupId}-content`);
|
|
||||||
if (boxContent != null) {
|
|
||||||
boxContent.style.minHeight = "80vh";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the tree's markup (i.e. config) for Treant
|
|
||||||
const markup = researchTree.createTreantMarkup();
|
|
||||||
markup.chart.container = "#" + props.popupId + "-content";
|
|
||||||
markup.chart.nodeAlign = "BOTTOM";
|
|
||||||
markup.chart.rootOrientation = "WEST";
|
|
||||||
markup.chart.siblingSeparation = 40;
|
|
||||||
markup.chart.connectors = {
|
|
||||||
type: "step",
|
|
||||||
style: {
|
|
||||||
"arrow-end": "block-wide-long",
|
|
||||||
stroke: "white",
|
|
||||||
"stroke-width": 2,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
Treant(markup);
|
|
||||||
|
|
||||||
// Add Event Listeners for all Nodes
|
|
||||||
const allResearch = researchTree.getAllNodes();
|
|
||||||
for (let i = 0; i < allResearch.length; ++i) {
|
|
||||||
// If this is already Researched, skip it
|
|
||||||
if (props.industry.researched[allResearch[i]] === true) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the DOM Element to add a click listener to it
|
|
||||||
const sanitizedName = allResearch[i].replace(/\s/g, "");
|
|
||||||
const div = document.getElementById(sanitizedName + "-corp-research-click-listener");
|
|
||||||
if (div == null) {
|
|
||||||
console.warn(`Could not find Research Tree div for ${sanitizedName}`);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.addEventListener("click", () => {
|
|
||||||
try {
|
|
||||||
Research(props.industry, allResearch[i]);
|
|
||||||
} catch (err) {
|
|
||||||
dialogBoxCreate(err + "");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dialogBoxCreate(
|
|
||||||
`Researched ${allResearch[i]}. It may take a market cycle ` +
|
|
||||||
`(~${CorporationConstants.SecsPerMarketCycle} seconds) before the effects of ` +
|
|
||||||
`the Research apply.`,
|
|
||||||
);
|
|
||||||
removePopup(props.popupId);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div id={props.popupId}>
|
|
||||||
<div>
|
|
||||||
Research points: {props.industry.sciResearch.qty}
|
|
||||||
<br />
|
|
||||||
Multipliers from research:
|
|
||||||
<br />* Advertising Multiplier: x{researchTree.getAdvertisingMultiplier()}
|
|
||||||
<br />* Employee Charisma Multiplier: x{researchTree.getEmployeeChaMultiplier()}
|
|
||||||
<br />* Employee Creativity Multiplier: x{researchTree.getEmployeeCreMultiplier()}
|
|
||||||
<br />* Employee Efficiency Multiplier: x{researchTree.getEmployeeEffMultiplier()}
|
|
||||||
<br />* Employee Intelligence Multiplier: x{researchTree.getEmployeeIntMultiplier()}
|
|
||||||
<br />* Production Multiplier: x{researchTree.getProductionMultiplier()}
|
|
||||||
<br />* Sales Multiplier: x{researchTree.getSalesMultiplier()}
|
|
||||||
<br />* Scientific Research Multiplier: x{researchTree.getScientificResearchMultiplier()}
|
|
||||||
<br />* Storage Multiplier: x{researchTree.getStorageMultiplier()}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -18,7 +18,7 @@ export const HacknetNodeConstants: {
|
|||||||
MaxRam: number;
|
MaxRam: number;
|
||||||
MaxCores: number;
|
MaxCores: number;
|
||||||
} = {
|
} = {
|
||||||
MoneyGainPerLevel: 1.6,
|
MoneyGainPerLevel: 1.5,
|
||||||
|
|
||||||
BaseCost: 1000,
|
BaseCost: 1000,
|
||||||
LevelBaseCost: 1,
|
LevelBaseCost: 1,
|
||||||
|
@ -150,10 +150,6 @@ import { LogBoxEvents } from "./ui/React/LogBoxManager";
|
|||||||
import { arrayToString } from "./utils/helpers/arrayToString";
|
import { arrayToString } from "./utils/helpers/arrayToString";
|
||||||
import { isString } from "./utils/helpers/isString";
|
import { isString } from "./utils/helpers/isString";
|
||||||
|
|
||||||
import { createElement } from "./ui/uiHelpers/createElement";
|
|
||||||
import { createPopup } from "./ui/uiHelpers/createPopup";
|
|
||||||
import { removeElementById } from "./ui/uiHelpers/removeElementById";
|
|
||||||
|
|
||||||
import { OfficeSpace } from "./Corporation/OfficeSpace";
|
import { OfficeSpace } from "./Corporation/OfficeSpace";
|
||||||
import { Employee } from "./Corporation/Employee";
|
import { Employee } from "./Corporation/Employee";
|
||||||
import { Product } from "./Corporation/Product";
|
import { Product } from "./Corporation/Product";
|
||||||
|
@ -152,6 +152,15 @@ SourceFiles["SourceFile9"] = new SourceFile(
|
|||||||
<br />
|
<br />
|
||||||
(Note that the Level 3 effect of this Source-File only applies when entering a new BitNode, NOT when installing
|
(Note that the Level 3 effect of this Source-File only applies when entering a new BitNode, NOT when installing
|
||||||
Augmentations)
|
Augmentations)
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
This Source-File also increases your hacknet multipliers by:
|
||||||
|
<br />
|
||||||
|
Level 1: 8%
|
||||||
|
<br />
|
||||||
|
Level 2: 12%
|
||||||
|
<br />
|
||||||
|
Level 3: 14%
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -133,7 +133,17 @@ export function applySourceFile(srcFile: PlayerOwnedSourceFile): void {
|
|||||||
}
|
}
|
||||||
case 9: {
|
case 9: {
|
||||||
// Hacktocracy
|
// Hacktocracy
|
||||||
// This has non-multiplier effects
|
let mult = 0;
|
||||||
|
for (let i = 0; i < srcFile.lvl; ++i) {
|
||||||
|
mult += 8 / Math.pow(2, i);
|
||||||
|
}
|
||||||
|
const incMult = 1 + mult / 100;
|
||||||
|
const decMult = 1 - mult / 100;
|
||||||
|
Player.hacknet_node_core_cost_mult *= decMult;
|
||||||
|
Player.hacknet_node_level_cost_mult *= decMult;
|
||||||
|
Player.hacknet_node_money_mult *= incMult;
|
||||||
|
Player.hacknet_node_purchase_cost_mult *= decMult;
|
||||||
|
Player.hacknet_node_ram_cost_mult *= decMult;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 10: {
|
case 10: {
|
||||||
|
4887
src/ThirdParty/raphael.min.js
vendored
4887
src/ThirdParty/raphael.min.js
vendored
File diff suppressed because it is too large
Load Diff
1
src/ThirdParty/treant-js.d.ts
vendored
1
src/ThirdParty/treant-js.d.ts
vendored
@ -1 +0,0 @@
|
|||||||
declare module "treant-js";
|
|
@ -53,5 +53,4 @@
|
|||||||
<body>
|
<body>
|
||||||
<div id="root" />
|
<div id="root" />
|
||||||
</body>
|
</body>
|
||||||
<script src="src/ThirdParty/raphael.min.js"></script>
|
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,81 +0,0 @@
|
|||||||
/**
|
|
||||||
* Wrapper around material-ui's TextField component that styles it with
|
|
||||||
* Bitburner's UI theme
|
|
||||||
*/
|
|
||||||
|
|
||||||
import React from "react";
|
|
||||||
import { TextField, TextFieldProps } from "@mui/material";
|
|
||||||
|
|
||||||
import makeStyles from "@mui/styles/makeStyles";
|
|
||||||
|
|
||||||
const backgroundColorStyles = {
|
|
||||||
backgroundColor: "rgba(57, 54, 54, 0.9)",
|
|
||||||
"&:hover": {
|
|
||||||
backgroundColor: "rgba(70, 70, 70, 0.9)",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const formControlStyles = {
|
|
||||||
border: "1px solid #e2e2e1",
|
|
||||||
overflow: "hidden",
|
|
||||||
borderRadius: 4,
|
|
||||||
color: "white",
|
|
||||||
...backgroundColorStyles,
|
|
||||||
};
|
|
||||||
|
|
||||||
const useStyles = makeStyles({
|
|
||||||
root: {
|
|
||||||
...formControlStyles,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const useInputStyles = makeStyles({
|
|
||||||
root: {
|
|
||||||
...backgroundColorStyles,
|
|
||||||
color: "white",
|
|
||||||
},
|
|
||||||
focused: {
|
|
||||||
backgroundColor: "rgba(70, 70, 70, 0.9)",
|
|
||||||
},
|
|
||||||
disabled: {
|
|
||||||
color: "white",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const useLabelStyles = makeStyles({
|
|
||||||
root: {
|
|
||||||
color: "white",
|
|
||||||
},
|
|
||||||
focused: {
|
|
||||||
color: "white !important", // Need important to override styles from FormLabel
|
|
||||||
},
|
|
||||||
disabled: {
|
|
||||||
color: "white !important", // Need important to override styles from FormLabel
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const MuiTextField: React.FC<TextFieldProps> = (props: TextFieldProps) => {
|
|
||||||
return (
|
|
||||||
<TextField
|
|
||||||
{...props}
|
|
||||||
classes={{
|
|
||||||
...useStyles(),
|
|
||||||
...props.classes,
|
|
||||||
}}
|
|
||||||
InputProps={{
|
|
||||||
classes: {
|
|
||||||
...useInputStyles(),
|
|
||||||
...props.InputProps?.classes,
|
|
||||||
},
|
|
||||||
...props.InputProps,
|
|
||||||
}}
|
|
||||||
InputLabelProps={{
|
|
||||||
classes: {
|
|
||||||
...useLabelStyles(),
|
|
||||||
...props.InputLabelProps?.classes,
|
|
||||||
},
|
|
||||||
...props.InputLabelProps,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
@ -1,38 +0,0 @@
|
|||||||
/**
|
|
||||||
* Wrapper around material-ui's Button component that styles it with
|
|
||||||
* Bitburner's UI theme
|
|
||||||
*/
|
|
||||||
|
|
||||||
import React from "react";
|
|
||||||
import { Select as MuiSelect, SelectProps } from "@mui/material";
|
|
||||||
import { Theme } from "@mui/material/styles";
|
|
||||||
import makeStyles from "@mui/styles/makeStyles";
|
|
||||||
import createStyles from "@mui/styles/createStyles";
|
|
||||||
|
|
||||||
const useStyles = makeStyles((theme: Theme) =>
|
|
||||||
createStyles({
|
|
||||||
root: {
|
|
||||||
backgroundColor: theme.palette.background.paper,
|
|
||||||
color: theme.palette.primary.dark,
|
|
||||||
margin: "5px",
|
|
||||||
padding: "3px 5px",
|
|
||||||
"&:after": {
|
|
||||||
backgroundColor: theme.palette.background.paper,
|
|
||||||
},
|
|
||||||
|
|
||||||
borderRadius: 0,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
export const Select: React.FC<SelectProps> = (props: SelectProps) => {
|
|
||||||
return (
|
|
||||||
<MuiSelect
|
|
||||||
{...props}
|
|
||||||
classes={{
|
|
||||||
...useStyles(),
|
|
||||||
...props.classes,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
@ -1,95 +0,0 @@
|
|||||||
/**
|
|
||||||
* Create a pop-up dialog box using React.
|
|
||||||
*
|
|
||||||
* Calling this function with the same ID and React Root Component will trigger a re-render
|
|
||||||
*
|
|
||||||
* @param id The (hopefully) unique identifier for the popup container
|
|
||||||
* @param rootComponent Root React Component for the content (NOT the popup containers themselves)
|
|
||||||
*/
|
|
||||||
import * as React from "react";
|
|
||||||
import * as ReactDOM from "react-dom";
|
|
||||||
|
|
||||||
import { Popup } from "./Popup";
|
|
||||||
|
|
||||||
import { createElement } from "../uiHelpers/createElement";
|
|
||||||
import { removeElementById } from "../uiHelpers/removeElementById";
|
|
||||||
|
|
||||||
let gameContainer: HTMLElement;
|
|
||||||
|
|
||||||
(function () {
|
|
||||||
function getGameContainer(): void {
|
|
||||||
const container = document.getElementById("root");
|
|
||||||
if (container == null) {
|
|
||||||
throw new Error(`Failed to find game container DOM element`);
|
|
||||||
}
|
|
||||||
|
|
||||||
gameContainer = container;
|
|
||||||
document.removeEventListener("DOMContentLoaded", getGameContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", getGameContainer);
|
|
||||||
})();
|
|
||||||
|
|
||||||
// This variable is used to avoid setting the semi-transparent background
|
|
||||||
// several times on top of one another. Sometimes there's several popup at once.
|
|
||||||
let deepestPopupId = "";
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
||||||
export function createPopup<T>(
|
|
||||||
id: string,
|
|
||||||
rootComponent: (props: T) => React.ReactElement,
|
|
||||||
props: T,
|
|
||||||
onClose?: () => void,
|
|
||||||
): HTMLElement | null {
|
|
||||||
let container = document.getElementById(id);
|
|
||||||
if (container == null) {
|
|
||||||
function onClick(this: HTMLElement, event: MouseEvent): void {
|
|
||||||
if (!event.srcElement) return;
|
|
||||||
if (!(event.srcElement instanceof HTMLElement)) return;
|
|
||||||
const clickedId = (event.srcElement as HTMLElement).id;
|
|
||||||
if (clickedId !== id) return;
|
|
||||||
removePopup(id);
|
|
||||||
if (onClose) onClose();
|
|
||||||
}
|
|
||||||
const backgroundColor = deepestPopupId === "" ? "rgba(0,0,0,0.5)" : "rgba(0,0,0,0)";
|
|
||||||
container = createElement("div", {
|
|
||||||
class: "popup-box-container",
|
|
||||||
display: "flex",
|
|
||||||
id: id,
|
|
||||||
backgroundColor: backgroundColor,
|
|
||||||
mouseDown: onClick,
|
|
||||||
});
|
|
||||||
|
|
||||||
gameContainer.appendChild(container);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (deepestPopupId === "") deepestPopupId = id;
|
|
||||||
ReactDOM.render(
|
|
||||||
<Popup
|
|
||||||
content={rootComponent}
|
|
||||||
id={id}
|
|
||||||
props={props}
|
|
||||||
removePopup={() => {
|
|
||||||
removePopup(id);
|
|
||||||
if (onClose) onClose();
|
|
||||||
}}
|
|
||||||
/>,
|
|
||||||
container,
|
|
||||||
);
|
|
||||||
|
|
||||||
return container;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Closes a popup created with the createPopup() function above
|
|
||||||
*/
|
|
||||||
export function removePopup(id: string): void {
|
|
||||||
const content = document.getElementById(`${id}`);
|
|
||||||
if (content == null) return;
|
|
||||||
|
|
||||||
ReactDOM.unmountComponentAtNode(content);
|
|
||||||
|
|
||||||
removeElementById(id);
|
|
||||||
removeElementById(`${id}-close`);
|
|
||||||
if (id === deepestPopupId) deepestPopupId = "";
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
import { setTimeoutRef } from "../utils/SetTimeoutRef";
|
|
||||||
import { getElementById } from "./uiHelpers/getElementById";
|
|
||||||
import { Action } from "../types";
|
|
||||||
|
|
||||||
const threeSeconds = 3000;
|
|
||||||
let x: number | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Displays a status message to the player for approximately 3 seconds.
|
|
||||||
* @param text The status text to display
|
|
||||||
*/
|
|
||||||
export function createStatusText(text: string): void {
|
|
||||||
const statusElement: HTMLElement = getElementById("status-text");
|
|
||||||
const handler: Action = () => {
|
|
||||||
statusElement.innerText = "";
|
|
||||||
statusElement.style.display = "none";
|
|
||||||
statusElement.classList.remove("status-text");
|
|
||||||
};
|
|
||||||
|
|
||||||
if (x !== undefined) {
|
|
||||||
clearTimeout(x);
|
|
||||||
// Likely not needed due to clearTimeout, but just in case...
|
|
||||||
x = undefined;
|
|
||||||
// reset the element's animation
|
|
||||||
statusElement.style.animation = "none";
|
|
||||||
setTimeout(function () {
|
|
||||||
statusElement.style.animation = "";
|
|
||||||
}, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
statusElement.style.display = "block";
|
|
||||||
statusElement.classList.add("status-text");
|
|
||||||
statusElement.innerText = text;
|
|
||||||
|
|
||||||
x = setTimeoutRef(handler, threeSeconds);
|
|
||||||
}
|
|
@ -1,161 +0,0 @@
|
|||||||
/**
|
|
||||||
* The full-screen page the player is currently be on.
|
|
||||||
* These pages are mutually exclusive.
|
|
||||||
*/
|
|
||||||
export enum Page {
|
|
||||||
/**
|
|
||||||
* (Default) The terminal is where the player issues all commands, executes scripts, etc.
|
|
||||||
*/
|
|
||||||
Terminal = "Terminal",
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Displays most of the statistics about the player.
|
|
||||||
*/
|
|
||||||
CharacterInfo = "CharacterInfo",
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The console for editing Netscript files.
|
|
||||||
*/
|
|
||||||
ScriptEditor = "ScriptEditor",
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Monitor the scripts currently executing across the servers.
|
|
||||||
*/
|
|
||||||
ActiveScripts = "ActiveScripts",
|
|
||||||
|
|
||||||
/**
|
|
||||||
* View, purchase, and upgrade Hacknet nodes.
|
|
||||||
*/
|
|
||||||
HacknetNodes = "HacknetNodes",
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The list of programs the player could potentially build.
|
|
||||||
*/
|
|
||||||
CreateProgram = "CreateProgram",
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The list of all factions, and invites, available to the player.
|
|
||||||
*/
|
|
||||||
Factions = "Factions",
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Information about a specific faction.
|
|
||||||
*/
|
|
||||||
Faction = "Faction",
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The list of installed, and yet-to-be installed, augmentations the player has purchased.
|
|
||||||
*/
|
|
||||||
Augmentations = "Augmentations",
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List of milestones that players should follow.
|
|
||||||
*/
|
|
||||||
Milestones = "Milestones",
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A collection of in-game material to learn about the game.
|
|
||||||
*/
|
|
||||||
Tutorial = "Tutorial",
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A collection of items to manipulate the state of the game. Useful for development.
|
|
||||||
*/
|
|
||||||
DevMenu = "Dev Menu",
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Visiting a location in the world
|
|
||||||
*/
|
|
||||||
Location = "Location",
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A blocking page to show the player they are currently doing some action (building a program, working, etc.).
|
|
||||||
*/
|
|
||||||
workInProgress = "WorkInProgress",
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A special screen to show the player they've reached a certain point in the game.
|
|
||||||
*/
|
|
||||||
RedPill = "RedPill",
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A special screen to show the player they've reached a certain point in the game.
|
|
||||||
*/
|
|
||||||
CinematicText = "CinematicText",
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mini-game to infiltrate a company, gaining experience from successful progress.
|
|
||||||
*/
|
|
||||||
Infiltration = "Infiltration",
|
|
||||||
|
|
||||||
/**
|
|
||||||
* View the in-game stock market.
|
|
||||||
*/
|
|
||||||
StockMarket = "StockMarket",
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Manage gang actions and members.
|
|
||||||
*/
|
|
||||||
Gang = "Gang",
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform missions for a Faction.
|
|
||||||
*/
|
|
||||||
Mission = "Mission",
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Manage a corporation.
|
|
||||||
*/
|
|
||||||
Corporation = "Corporation",
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Manage special Bladeburner activities.
|
|
||||||
*/
|
|
||||||
Bladeburner = "Bladeburner",
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Manage your Sleeves
|
|
||||||
*/
|
|
||||||
Sleeves = "Sleeves",
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Purchase Resleeves
|
|
||||||
*/
|
|
||||||
Resleeves = "Re-sleeving",
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Game options
|
|
||||||
*/
|
|
||||||
GameOptions = "GameOptions",
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class keeps track of player navigation/routing within the game.
|
|
||||||
*/
|
|
||||||
class Routing {
|
|
||||||
/**
|
|
||||||
* Tracking the what page the user is currently on.
|
|
||||||
*/
|
|
||||||
private currentPage: Page | null = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines if the player is currently on the specified page.
|
|
||||||
* @param page The page to compare against the current state.
|
|
||||||
*/
|
|
||||||
isOn(page: Page): boolean {
|
|
||||||
return this.currentPage === page;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Routes the player to the appropriate page.
|
|
||||||
* @param page The page to navigate to.
|
|
||||||
*/
|
|
||||||
navigateTo(page: Page): void {
|
|
||||||
this.currentPage = page;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The routing instance for tracking page navigation.
|
|
||||||
*/
|
|
||||||
export const routing: Routing = new Routing();
|
|
@ -1,29 +0,0 @@
|
|||||||
import { getElementById } from "./getElementById";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given an element by its ID, removes all event listeners from that element by cloning and
|
|
||||||
* replacing. Then returns the new cloned element.
|
|
||||||
* @param elemId The HTML ID to retrieve the element by.
|
|
||||||
*/
|
|
||||||
export function clearEventListeners(elemId: string | HTMLElement): HTMLElement | null {
|
|
||||||
try {
|
|
||||||
let elem: HTMLElement;
|
|
||||||
if (typeof elemId === "string") {
|
|
||||||
elem = getElementById(elemId);
|
|
||||||
} else {
|
|
||||||
elem = elemId;
|
|
||||||
}
|
|
||||||
|
|
||||||
const newElem: HTMLElement = elem.cloneNode(true) as HTMLElement;
|
|
||||||
if (elem.parentNode !== null) {
|
|
||||||
elem.parentNode.replaceChild(newElem, elem);
|
|
||||||
}
|
|
||||||
|
|
||||||
return newElem;
|
|
||||||
} catch (e) {
|
|
||||||
// tslint:disable-next-line:no-console
|
|
||||||
console.error(e);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,308 +0,0 @@
|
|||||||
/**
|
|
||||||
* Options specific to creating an anchor ("<a>") element.
|
|
||||||
*/
|
|
||||||
interface ICreateElementAnchorOptions {
|
|
||||||
href?: string;
|
|
||||||
target?: string;
|
|
||||||
text?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Options specific to creating an input ("<input>") element.
|
|
||||||
*/
|
|
||||||
interface ICreateElementInputOptions {
|
|
||||||
checked?: boolean;
|
|
||||||
max?: string;
|
|
||||||
maxLength?: number;
|
|
||||||
min?: string;
|
|
||||||
name?: string;
|
|
||||||
pattern?: string;
|
|
||||||
placeholder?: string;
|
|
||||||
step?: string;
|
|
||||||
type?: string;
|
|
||||||
value?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Options specific to creating a label ("<label>") element.
|
|
||||||
*/
|
|
||||||
interface ICreateElementLabelOptions {
|
|
||||||
for?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Options for setting up event listeners on the element.
|
|
||||||
*/
|
|
||||||
interface ICreateElementListenerOptions {
|
|
||||||
changeListener?(this: HTMLElement, ev: Event): any;
|
|
||||||
clickListener?(this: HTMLElement, ev: MouseEvent): any;
|
|
||||||
mouseDown?(this: HTMLElement, ev: MouseEvent): any;
|
|
||||||
inputListener?(this: HTMLElement, ev: Event): any;
|
|
||||||
onfocus?(this: HTMLElement, ev: FocusEvent): any;
|
|
||||||
onkeydown?(this: HTMLElement, ev: KeyboardEvent): any;
|
|
||||||
onkeyup?(this: HTMLElement, ev: KeyboardEvent): any;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Options for setting up the inline-styling of element.
|
|
||||||
* NOTE: Relying on CSS styling should be preferred over forcing the higher specificity via inline styles.
|
|
||||||
*/
|
|
||||||
interface ICreateElementStyleOptions {
|
|
||||||
backgroundColor?: string;
|
|
||||||
border?: string;
|
|
||||||
color?: string;
|
|
||||||
display?: string;
|
|
||||||
float?: string;
|
|
||||||
fontSize?: string;
|
|
||||||
margin?: string;
|
|
||||||
marginLeft?: string;
|
|
||||||
marginTop?: string;
|
|
||||||
overflow?: string;
|
|
||||||
padding?: string;
|
|
||||||
position?: string;
|
|
||||||
visibility?: string;
|
|
||||||
whiteSpace?: string;
|
|
||||||
width?: string;
|
|
||||||
height?: string;
|
|
||||||
top?: string;
|
|
||||||
left?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Options for adding an in-game tooltip to the element.
|
|
||||||
*/
|
|
||||||
interface ICreateElementTooltipOptions {
|
|
||||||
tooltip?: string;
|
|
||||||
tooltipleft?: string;
|
|
||||||
tooltipsmall?: string;
|
|
||||||
tooltiplow?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* All possible configuration options when creating an element.
|
|
||||||
*/
|
|
||||||
interface ICreateElementOptions
|
|
||||||
extends ICreateElementStyleOptions,
|
|
||||||
ICreateElementListenerOptions,
|
|
||||||
ICreateElementInputOptions,
|
|
||||||
ICreateElementAnchorOptions,
|
|
||||||
ICreateElementLabelOptions,
|
|
||||||
ICreateElementTooltipOptions {
|
|
||||||
/**
|
|
||||||
* CSS Class(es) to initially set.
|
|
||||||
*/
|
|
||||||
class?: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A (hopefully) unique identifier for the element.
|
|
||||||
*/
|
|
||||||
id?: string;
|
|
||||||
|
|
||||||
innerHTML?: string;
|
|
||||||
innerText?: string;
|
|
||||||
tabIndex?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
function setElementAnchor(el: HTMLAnchorElement, params: ICreateElementAnchorOptions): void {
|
|
||||||
if (params.text !== undefined) {
|
|
||||||
el.text = params.text;
|
|
||||||
}
|
|
||||||
if (params.href !== undefined) {
|
|
||||||
el.href = params.href;
|
|
||||||
}
|
|
||||||
if (params.target !== undefined) {
|
|
||||||
el.target = params.target;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setElementInput(el: HTMLInputElement, params: ICreateElementInputOptions): void {
|
|
||||||
if (params.name !== undefined) {
|
|
||||||
el.name = params.name;
|
|
||||||
}
|
|
||||||
if (params.value !== undefined) {
|
|
||||||
el.value = params.value;
|
|
||||||
}
|
|
||||||
if (params.type !== undefined) {
|
|
||||||
el.type = params.type;
|
|
||||||
}
|
|
||||||
if (params.checked !== undefined) {
|
|
||||||
el.checked = params.checked;
|
|
||||||
}
|
|
||||||
if (params.pattern !== undefined) {
|
|
||||||
el.pattern = params.pattern;
|
|
||||||
}
|
|
||||||
if (params.maxLength !== undefined) {
|
|
||||||
el.maxLength = params.maxLength;
|
|
||||||
}
|
|
||||||
if (params.placeholder !== undefined) {
|
|
||||||
el.placeholder = params.placeholder;
|
|
||||||
}
|
|
||||||
if (params.max !== undefined) {
|
|
||||||
el.max = params.max;
|
|
||||||
}
|
|
||||||
if (params.min !== undefined) {
|
|
||||||
el.min = params.min;
|
|
||||||
}
|
|
||||||
if (params.step !== undefined) {
|
|
||||||
el.step = params.step;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setElementLabel(el: HTMLLabelElement, params: ICreateElementLabelOptions): void {
|
|
||||||
if (params.for !== undefined) {
|
|
||||||
el.htmlFor = params.for;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setElementListeners(el: HTMLElement, params: ICreateElementListenerOptions): void {
|
|
||||||
// tslint:disable:no-unbound-method
|
|
||||||
if (params.clickListener !== undefined) {
|
|
||||||
el.addEventListener("click", params.clickListener);
|
|
||||||
}
|
|
||||||
if (params.mouseDown !== undefined) {
|
|
||||||
el.addEventListener("mousedown", params.mouseDown);
|
|
||||||
}
|
|
||||||
if (params.inputListener !== undefined) {
|
|
||||||
el.addEventListener("input", params.inputListener);
|
|
||||||
}
|
|
||||||
if (params.changeListener !== undefined) {
|
|
||||||
el.addEventListener("change", params.changeListener);
|
|
||||||
}
|
|
||||||
if (params.onkeyup !== undefined) {
|
|
||||||
el.addEventListener("keyup", params.onkeyup);
|
|
||||||
}
|
|
||||||
if (params.onkeydown !== undefined) {
|
|
||||||
el.addEventListener("keydown", params.onkeydown);
|
|
||||||
}
|
|
||||||
if (params.onfocus !== undefined) {
|
|
||||||
el.addEventListener("focus", params.onfocus);
|
|
||||||
}
|
|
||||||
// tslint:enable:no-unbound-method
|
|
||||||
}
|
|
||||||
|
|
||||||
function setElementStyle(el: HTMLElement, params: ICreateElementStyleOptions): void {
|
|
||||||
if (params.display !== undefined) {
|
|
||||||
el.style.display = params.display;
|
|
||||||
}
|
|
||||||
if (params.visibility !== undefined) {
|
|
||||||
el.style.visibility = params.visibility;
|
|
||||||
}
|
|
||||||
if (params.margin !== undefined) {
|
|
||||||
el.style.margin = params.margin;
|
|
||||||
}
|
|
||||||
if (params.marginLeft !== undefined) {
|
|
||||||
el.style.marginLeft = params.marginLeft;
|
|
||||||
}
|
|
||||||
if (params.marginTop !== undefined) {
|
|
||||||
el.style.marginTop = params.marginTop;
|
|
||||||
}
|
|
||||||
if (params.padding !== undefined) {
|
|
||||||
el.style.padding = params.padding;
|
|
||||||
}
|
|
||||||
if (params.color !== undefined) {
|
|
||||||
el.style.color = params.color;
|
|
||||||
}
|
|
||||||
if (params.border !== undefined) {
|
|
||||||
el.style.border = params.border;
|
|
||||||
}
|
|
||||||
if (params.float !== undefined) {
|
|
||||||
el.style.cssFloat = params.float;
|
|
||||||
}
|
|
||||||
if (params.fontSize !== undefined) {
|
|
||||||
el.style.fontSize = params.fontSize;
|
|
||||||
}
|
|
||||||
if (params.whiteSpace !== undefined) {
|
|
||||||
el.style.whiteSpace = params.whiteSpace;
|
|
||||||
}
|
|
||||||
if (params.width !== undefined) {
|
|
||||||
el.style.width = params.width;
|
|
||||||
}
|
|
||||||
if (params.height !== undefined) {
|
|
||||||
el.style.height = params.height;
|
|
||||||
}
|
|
||||||
if (params.top !== undefined) {
|
|
||||||
el.style.top = params.top;
|
|
||||||
}
|
|
||||||
if (params.left !== undefined) {
|
|
||||||
el.style.left = params.left;
|
|
||||||
}
|
|
||||||
if (params.backgroundColor !== undefined) {
|
|
||||||
el.style.backgroundColor = params.backgroundColor;
|
|
||||||
}
|
|
||||||
if (params.position !== undefined) {
|
|
||||||
el.style.position = params.position;
|
|
||||||
}
|
|
||||||
if (params.overflow !== undefined) {
|
|
||||||
el.style.overflow = params.overflow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setElementTooltip(el: HTMLElement, params: ICreateElementTooltipOptions): void {
|
|
||||||
if (params.tooltip !== undefined && params.tooltip !== "") {
|
|
||||||
el.className += " tooltip";
|
|
||||||
el.appendChild(
|
|
||||||
createElement("span", {
|
|
||||||
class: "tooltiptext",
|
|
||||||
innerHTML: params.tooltip,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
} else if (params.tooltipleft !== undefined) {
|
|
||||||
el.className += " tooltip";
|
|
||||||
el.appendChild(
|
|
||||||
createElement("span", {
|
|
||||||
class: "tooltiptextleft",
|
|
||||||
innerHTML: params.tooltipleft,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
} else if (params.tooltipsmall !== undefined) {
|
|
||||||
el.className += " tooltip";
|
|
||||||
el.appendChild(
|
|
||||||
createElement("span", {
|
|
||||||
class: "tooltiptext smallfont",
|
|
||||||
innerHTML: params.tooltipsmall,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
} else if (params.tooltiplow !== undefined) {
|
|
||||||
el.className += "tooltip";
|
|
||||||
el.appendChild(
|
|
||||||
createElement("span", {
|
|
||||||
class: "tooltiptextlow",
|
|
||||||
innerHTML: params.tooltiplow,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An all-in-one-call way of creating an element to be added to the DOM at some point.
|
|
||||||
* @param tagName The HTML tag/element name
|
|
||||||
* @param params Additional parameters to set on the element
|
|
||||||
*/
|
|
||||||
export function createElement(tagName: string, params: ICreateElementOptions = {}): HTMLElement {
|
|
||||||
const el: HTMLElement = document.createElement(tagName);
|
|
||||||
|
|
||||||
if (params.id !== undefined) {
|
|
||||||
el.id = params.id;
|
|
||||||
}
|
|
||||||
if (params.class !== undefined) {
|
|
||||||
el.className = params.class;
|
|
||||||
}
|
|
||||||
if (params.innerHTML !== undefined) {
|
|
||||||
el.innerHTML = params.innerHTML;
|
|
||||||
}
|
|
||||||
if (params.innerText !== undefined) {
|
|
||||||
el.innerText = params.innerText;
|
|
||||||
}
|
|
||||||
if (params.tabIndex !== undefined) {
|
|
||||||
el.tabIndex = params.tabIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
setElementAnchor(el as HTMLAnchorElement, params);
|
|
||||||
setElementInput(el as HTMLInputElement, params);
|
|
||||||
setElementLabel(el as HTMLLabelElement, params);
|
|
||||||
setElementListeners(el, params);
|
|
||||||
setElementStyle(el, params);
|
|
||||||
setElementTooltip(el, params);
|
|
||||||
|
|
||||||
return el;
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
import { createElement } from "./createElement";
|
|
||||||
import { getElementById } from "./getElementById";
|
|
||||||
|
|
||||||
interface ICreatePopupOptions {
|
|
||||||
backgroundColor?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the necessary DOM elements to present an in-game popup to the player.
|
|
||||||
* @param id The (hopefully) unique identifier for the popup container.
|
|
||||||
* @param elems The collection of HTML Elements to show within the popup.
|
|
||||||
*/
|
|
||||||
export function createPopup(id: string, elems: HTMLElement[], options: ICreatePopupOptions = {}): HTMLDivElement {
|
|
||||||
const container: HTMLDivElement = createElement("div", {
|
|
||||||
class: "popup-box-container",
|
|
||||||
display: "flex",
|
|
||||||
id: id,
|
|
||||||
}) as HTMLDivElement;
|
|
||||||
const content: HTMLElement = createElement("div", {
|
|
||||||
class: "popup-box-content",
|
|
||||||
id: `${id}-content`,
|
|
||||||
});
|
|
||||||
|
|
||||||
for (const elem of elems) {
|
|
||||||
content.appendChild(elem);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configurable Options
|
|
||||||
if (options.backgroundColor) {
|
|
||||||
content.style.backgroundColor = options.backgroundColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
container.appendChild(content);
|
|
||||||
getElementById("root").appendChild(container);
|
|
||||||
|
|
||||||
return container;
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
/**
|
|
||||||
* Returns a reference to the first object with the specified value of the ID or NAME attribute,
|
|
||||||
* throwing an error if it is unable to find it.
|
|
||||||
* @param elementId The HTML ID to retrieve the element by.
|
|
||||||
* @throws {Error} When the 'elementId' cannot be found.
|
|
||||||
*/
|
|
||||||
export function getElementById(elementId: string): HTMLElement {
|
|
||||||
const el: HTMLElement | null = document.getElementById(elementId);
|
|
||||||
if (el === null) {
|
|
||||||
throw new Error(`Unable to find element with id '${elementId}'`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return el;
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
export function getSelectValue(selector: HTMLSelectElement | null): string {
|
|
||||||
if (selector == null) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
if (selector.options.length <= 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
if (selector.selectedIndex < 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return selector.options[selector.selectedIndex].value;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getSelectText(selector: HTMLSelectElement | null): string {
|
|
||||||
if (selector == null) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
if (selector.options.length <= 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
if (selector.selectedIndex < 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return selector.options[selector.selectedIndex].text;
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
import { isString } from "../../utils/helpers/isString";
|
|
||||||
import { getElementById } from "./getElementById";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clears out all children from the provided element.
|
|
||||||
* If a string is passed in, it will treat it as an ID and search for the element to delete all children from.
|
|
||||||
* @param el The element or ID of an element to remove all children from.
|
|
||||||
*/
|
|
||||||
export function removeChildrenFromElement(el: string | null | Element): void {
|
|
||||||
if (el === null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const elem: HTMLElement | Element = isString(el) ? getElementById(el as string) : (el as Element);
|
|
||||||
|
|
||||||
if (elem instanceof Element) {
|
|
||||||
while (elem.firstChild !== null) {
|
|
||||||
elem.removeChild(elem.firstChild);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
// tslint:disable-next-line:no-console
|
|
||||||
console.debug(e);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
/**
|
|
||||||
* For a given element, this function removes it AND its children
|
|
||||||
* @param elem The element to remove.
|
|
||||||
*/
|
|
||||||
export function removeElement(elem: Element | null): void {
|
|
||||||
if (elem === null) {
|
|
||||||
// tslint:disable-next-line:no-console
|
|
||||||
console.debug("The element passed into 'removeElement' was null.");
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!(elem instanceof Element)) {
|
|
||||||
// tslint:disable-next-line:no-console
|
|
||||||
console.debug("The element passed into 'removeElement' was not an instance of an Element.");
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (elem.firstChild !== null) {
|
|
||||||
elem.removeChild(elem.firstChild);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (elem.parentNode !== null) {
|
|
||||||
elem.parentNode.removeChild(elem);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
import { getElementById } from "./getElementById";
|
|
||||||
import { removeElement } from "./removeElement";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given its id, this function removes an element AND its children
|
|
||||||
* @param id The HTML identifier to search for and remove.
|
|
||||||
*/
|
|
||||||
export function removeElementById(id: string): void {
|
|
||||||
try {
|
|
||||||
const elem: HTMLElement = getElementById(id);
|
|
||||||
removeElement(elem);
|
|
||||||
} catch (e) {
|
|
||||||
// Probably should log this as we're trying to remove elements that don't exist.
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user