mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-19 14:13:48 +01:00
Merge branch 'dev' of github.com:danielyxie/bitburner into improvement/bitnode-multipliers
This commit is contained in:
commit
430d1dad9d
4
dist/main.bundle.js
vendored
4
dist/main.bundle.js
vendored
File diff suppressed because one or more lines are too long
2
dist/main.bundle.js.map
vendored
2
dist/main.bundle.js.map
vendored
File diff suppressed because one or more lines are too long
@ -488,7 +488,7 @@ export const defaultMultipliers: IBitNodeMultipliers = {
|
||||
FourSigmaMarketDataApiCost: 1,
|
||||
|
||||
CorporationValuation: 1,
|
||||
CorporationSoftCap: 1,
|
||||
CorporationSoftcap: 1,
|
||||
|
||||
BladeburnerRank: 1,
|
||||
BladeburnerSkillCost: 1,
|
||||
@ -525,7 +525,7 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie
|
||||
StaneksGiftPowerMultiplier: 2,
|
||||
StaneksGiftExtraSize: -6,
|
||||
PurchasedServerSoftcap: 1.3,
|
||||
CorporationSoftCap: 0.9,
|
||||
CorporationSoftcap: 0.9,
|
||||
WorldDaemonDifficulty: 5,
|
||||
});
|
||||
}
|
||||
@ -611,7 +611,7 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie
|
||||
StaneksGiftPowerMultiplier: 0.5,
|
||||
StaneksGiftExtraSize: 2,
|
||||
GangSoftcap: 0.7,
|
||||
CorporationSoftCap: 0.9,
|
||||
CorporationSoftcap: 0.9,
|
||||
WorldDaemonDifficulty: 2,
|
||||
GangUniqueAugs: 0.2,
|
||||
});
|
||||
@ -639,7 +639,7 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie
|
||||
StaneksGiftPowerMultiplier: 0.9,
|
||||
StaneksGiftExtraSize: -1,
|
||||
GangSoftcap: 0.7,
|
||||
CorporationSoftCap: 0.9,
|
||||
CorporationSoftcap: 0.9,
|
||||
WorldDaemonDifficulty: 2,
|
||||
GangUniqueAugs: 0.2,
|
||||
});
|
||||
@ -659,7 +659,7 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie
|
||||
StaneksGiftExtraSize: -99,
|
||||
PurchasedServerSoftcap: 4,
|
||||
GangSoftcap: 0,
|
||||
CorporationSoftCap: 0,
|
||||
CorporationSoftcap: 0,
|
||||
GangUniqueAugs: 0,
|
||||
});
|
||||
}
|
||||
@ -687,7 +687,7 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie
|
||||
StaneksGiftPowerMultiplier: 0.5,
|
||||
StaneksGiftExtraSize: 2,
|
||||
GangSoftcap: 0.8,
|
||||
CorporationSoftCap: 0.7,
|
||||
CorporationSoftcap: 0.7,
|
||||
WorldDaemonDifficulty: 2,
|
||||
GangUniqueAugs: 0.25,
|
||||
});
|
||||
@ -719,7 +719,7 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie
|
||||
StaneksGiftExtraSize: -3,
|
||||
PurchasedServerSoftcap: 1.1,
|
||||
GangSoftcap: 0.9,
|
||||
CorporationSoftCap: 0.9,
|
||||
CorporationSoftcap: 0.9,
|
||||
WorldDaemonDifficulty: 2,
|
||||
GangUniqueAugs: 0.25,
|
||||
});
|
||||
@ -743,7 +743,7 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie
|
||||
FourSigmaMarketDataCost: 4,
|
||||
FourSigmaMarketDataApiCost: 4,
|
||||
PurchasedServerSoftcap: 2,
|
||||
CorporationSoftCap: 0.9,
|
||||
CorporationSoftcap: 0.9,
|
||||
WorldDaemonDifficulty: 1.5,
|
||||
GangUniqueAugs: 0.75,
|
||||
});
|
||||
@ -811,7 +811,7 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie
|
||||
StaneksGiftPowerMultiplier: inc,
|
||||
StaneksGiftExtraSize: inc,
|
||||
GangSoftcap: 0.8,
|
||||
CorporationSoftCap: 0.8,
|
||||
CorporationSoftcap: 0.8,
|
||||
WorldDaemonDifficulty: inc,
|
||||
|
||||
GangUniqueAugs: dec,
|
||||
@ -856,7 +856,7 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie
|
||||
StaneksGiftPowerMultiplier: 2,
|
||||
StaneksGiftExtraSize: 1,
|
||||
GangSoftcap: 0.3,
|
||||
CorporationSoftCap: 0.3,
|
||||
CorporationSoftcap: 0.3,
|
||||
WorldDaemonDifficulty: 3,
|
||||
GangUniqueAugs: 0.1,
|
||||
});
|
||||
|
@ -242,7 +242,7 @@ export interface IBitNodeMultipliers {
|
||||
/**
|
||||
* Influences corporation dividends.
|
||||
*/
|
||||
CorporationSoftCap: number;
|
||||
CorporationSoftcap: number;
|
||||
|
||||
// Index signature
|
||||
[key: string]: number;
|
||||
|
@ -320,9 +320,9 @@ function CorporationMults({ mults }: IMultsProps): React.ReactElement {
|
||||
if (!player.canAccessCorporation()) return <></>;
|
||||
|
||||
const rows: IBNMultRows = {
|
||||
CorporationSoftCap: {
|
||||
CorporationSoftcap: {
|
||||
name: "Corporation Softcap",
|
||||
content: mults.CorporationSoftCap.toFixed(3),
|
||||
content: mults.CorporationSoftcap.toFixed(3),
|
||||
},
|
||||
CorporationValuation: { name: "Valuation" },
|
||||
};
|
||||
|
@ -697,7 +697,7 @@ export class Bladeburner implements IBladeburner {
|
||||
|
||||
// Set variables
|
||||
if (args.length === 4) {
|
||||
const variable = args[1];
|
||||
const variable = args[1].toLowerCase(); // allows Action Type to be with or without capitalisation.
|
||||
const val = args[2];
|
||||
|
||||
let highLow = false; // True for high, false for low
|
||||
@ -1919,7 +1919,7 @@ export class Bladeburner implements IBladeburner {
|
||||
}
|
||||
|
||||
// If the Player starts doing some other actions, set action to idle and alert
|
||||
if (player.hasAugmentation(AugmentationNames.BladesSimulacrum) === false && player.isWorking) {
|
||||
if (!player.hasAugmentation(AugmentationNames.BladesSimulacrum, true) && player.isWorking) {
|
||||
if (this.action.type !== ActionTypes["Idle"]) {
|
||||
let msg = "Your Bladeburner action was cancelled because you started doing something else.";
|
||||
if (this.automateEnabled) {
|
||||
|
@ -159,7 +159,7 @@ export class Corporation {
|
||||
if (this.unlockUpgrades[6] === 1) {
|
||||
upgrades += 0.1;
|
||||
}
|
||||
return Math.pow(dividends, BitNodeMultipliers.CorporationSoftCap + upgrades);
|
||||
return Math.pow(dividends, BitNodeMultipliers.CorporationSoftcap + upgrades);
|
||||
}
|
||||
|
||||
determineValuation(): number {
|
||||
|
@ -70,7 +70,7 @@ export const CurrentOptionsPage = (props: IProps): React.ReactElement => {
|
||||
<>
|
||||
<OptionsSlider
|
||||
label=".script exec time (ms)"
|
||||
value={execTime}
|
||||
initialValue={execTime}
|
||||
callback={handleExecTimeChange}
|
||||
step={1}
|
||||
min={5}
|
||||
@ -84,7 +84,7 @@ export const CurrentOptionsPage = (props: IProps): React.ReactElement => {
|
||||
/>
|
||||
<OptionsSlider
|
||||
label="Recently killed scripts size"
|
||||
value={recentScriptsSize}
|
||||
initialValue={recentScriptsSize}
|
||||
callback={handleRecentScriptsSizeChange}
|
||||
step={25}
|
||||
min={0}
|
||||
@ -98,7 +98,7 @@ export const CurrentOptionsPage = (props: IProps): React.ReactElement => {
|
||||
/>
|
||||
<OptionsSlider
|
||||
label="Netscript log size"
|
||||
value={logSize}
|
||||
initialValue={logSize}
|
||||
callback={handleLogSizeChange}
|
||||
step={20}
|
||||
min={20}
|
||||
@ -112,7 +112,7 @@ export const CurrentOptionsPage = (props: IProps): React.ReactElement => {
|
||||
/>
|
||||
<OptionsSlider
|
||||
label="Netscript port size"
|
||||
value={portSize}
|
||||
initialValue={portSize}
|
||||
callback={handlePortSizeChange}
|
||||
step={1}
|
||||
min={20}
|
||||
@ -126,7 +126,7 @@ export const CurrentOptionsPage = (props: IProps): React.ReactElement => {
|
||||
/>
|
||||
<OptionsSlider
|
||||
label="Terminal capacity"
|
||||
value={terminalSize}
|
||||
initialValue={terminalSize}
|
||||
callback={handleTerminalSizeChange}
|
||||
step={50}
|
||||
min={50}
|
||||
@ -141,7 +141,7 @@ export const CurrentOptionsPage = (props: IProps): React.ReactElement => {
|
||||
/>
|
||||
<OptionsSlider
|
||||
label="Autosave interval (s)"
|
||||
value={autosaveInterval}
|
||||
initialValue={autosaveInterval}
|
||||
callback={handleAutosaveIntervalChange}
|
||||
step={30}
|
||||
min={0}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { Slider, Tooltip, Typography, Box } from "@mui/material";
|
||||
import React from "react";
|
||||
import React, { useState } from "react";
|
||||
|
||||
interface IProps {
|
||||
value: any;
|
||||
initialValue: any;
|
||||
callback: (event: any, newValue: number | number[]) => void;
|
||||
step: number;
|
||||
min: number;
|
||||
@ -13,14 +13,21 @@ interface IProps {
|
||||
}
|
||||
|
||||
export const OptionsSlider = (props: IProps): React.ReactElement => {
|
||||
const [value, setValue] = useState(props.initialValue);
|
||||
|
||||
const onChange = (_evt: Event, newValue: number | Array<number>): void => {
|
||||
setValue(newValue);
|
||||
};
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Tooltip title={<Typography>{props.tooltip}</Typography>}>
|
||||
<Typography>{props.label}</Typography>
|
||||
</Tooltip>
|
||||
<Slider
|
||||
value={props.value}
|
||||
onChange={props.callback}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
onChangeCommitted={props.callback}
|
||||
step={props.step}
|
||||
min={props.min}
|
||||
max={props.max}
|
||||
|
@ -85,9 +85,15 @@ export function TerritorySubpage(): React.ReactElement {
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box sx={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)" }}>
|
||||
{gangNames.map((name) => (
|
||||
<OtherGangTerritory key={name} name={name} />
|
||||
))}
|
||||
{gangNames
|
||||
.sort((a, b) => {
|
||||
if (AllGangs[a].territory <= 0 && AllGangs[b].territory > 0) return 1;
|
||||
if (AllGangs[a].territory > 0 && AllGangs[b].territory <= 0) return -1;
|
||||
return 0;
|
||||
})
|
||||
.map((name) => (
|
||||
<OtherGangTerritory key={name} name={name} />
|
||||
))}
|
||||
</Box>
|
||||
<TerritoryInfoModal open={infoOpen} onClose={() => setInfoOpen(false)} />
|
||||
</Container>
|
||||
@ -114,14 +120,16 @@ function OtherGangTerritory(props: ITerritoryProps): React.ReactElement {
|
||||
const playerPower = AllGangs[gang.facName].power;
|
||||
const power = AllGangs[props.name].power;
|
||||
const clashVictoryChance = playerPower / (power + playerPower);
|
||||
const territory = AllGangs[props.name].territory;
|
||||
const opacity = territory ? 1 : 0.75;
|
||||
return (
|
||||
<Box component={Paper} sx={{ p: 1 }}>
|
||||
<Box component={Paper} sx={{ p: 1, opacity }}>
|
||||
<Typography variant="h6" sx={{ display: "flex", alignItems: "center", flexWrap: "wrap" }}>
|
||||
{props.name}
|
||||
</Typography>
|
||||
<Typography>
|
||||
<b>Power:</b> {formatNumber(power, 3)} <br />
|
||||
<b>Territory:</b> {formatTerritory(AllGangs[props.name].territory)}% <br />
|
||||
<b>Territory:</b> {formatTerritory(territory)}% <br />
|
||||
<b>Clash Win Chance:</b> {numeralWrapper.formatPercentage(clashVictoryChance, 3)}
|
||||
</Typography>
|
||||
</Box>
|
||||
|
@ -36,7 +36,7 @@ export function calculateTradeInformationRepReward(
|
||||
30 *
|
||||
levelBonus *
|
||||
(player.hasAugmentation(AugmentationNames.WKSharmonizer, true) ? 1.5 : 1) *
|
||||
BitNodeMultipliers.InfiltrationMoney
|
||||
BitNodeMultipliers.InfiltrationRep
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -37,9 +37,13 @@ export function BackwardGame(props: IMinigameProps): React.ReactElement {
|
||||
const [guess, setGuess] = useState("");
|
||||
const hasAugment = Player.hasAugmentation(AugmentationNames.ChaosOfDionysus, true);
|
||||
|
||||
function ignorableKeyboardEvent(event: KeyboardEvent): boolean {
|
||||
return event.key === KEY.BACKSPACE || (event.shiftKey && event.key === "Shift") || event.ctrlKey || event.altKey;
|
||||
}
|
||||
|
||||
function press(this: Document, event: KeyboardEvent): void {
|
||||
event.preventDefault();
|
||||
if (event.key === KEY.BACKSPACE) return;
|
||||
if (ignorableKeyboardEvent(event)) return;
|
||||
const nextGuess = guess + event.key.toUpperCase();
|
||||
if (!answer.startsWith(nextGuess)) props.onFailure();
|
||||
else if (answer === nextGuess) props.onSuccess();
|
||||
|
@ -317,7 +317,7 @@ export function SpecialLocation(props: IProps): React.ReactElement {
|
||||
return renderGrafting();
|
||||
}
|
||||
case LocationName.Sector12CityHall: {
|
||||
return (BitNodeMultipliers.CorporationSoftCap < 0.15 && <></>) || <CreateCorporation />;
|
||||
return (BitNodeMultipliers.CorporationSoftcap < 0.15 && <></>) || <CreateCorporation />;
|
||||
}
|
||||
case LocationName.Sector12NSA: {
|
||||
return renderBladeburner();
|
||||
|
@ -51,6 +51,7 @@ export const RamCostConstants: IMap<number> = {
|
||||
ScriptCodingContractBaseRamCost: 10,
|
||||
ScriptSleeveBaseRamCost: 4,
|
||||
ScriptGetOwnedSourceFiles: 5,
|
||||
ScriptClearTerminalCost: 0.2,
|
||||
|
||||
ScriptSingularityFn1RamCost: 2,
|
||||
ScriptSingularityFn2RamCost: 3,
|
||||
@ -358,6 +359,7 @@ export const RamCosts: IMap<any> = {
|
||||
enableLog: 0,
|
||||
isLogEnabled: 0,
|
||||
getScriptLogs: 0,
|
||||
clearTerminal: RamCostConstants.ScriptClearTerminalCost,
|
||||
nuke: RamCostConstants.ScriptPortProgramRamCost,
|
||||
brutessh: RamCostConstants.ScriptPortProgramRamCost,
|
||||
ftpcrack: RamCostConstants.ScriptPortProgramRamCost,
|
||||
|
@ -78,7 +78,7 @@ export function NetscriptCorporation(
|
||||
if (!player.canAccessCorporation() || player.hasCorporation()) return false;
|
||||
if (!corporationName) return false;
|
||||
if (player.bitNodeN !== 3 && !selfFund) throw new Error("cannot use seed funds outside of BitNode 3");
|
||||
if (BitNodeMultipliers.CorporationSoftCap < 0.15)
|
||||
if (BitNodeMultipliers.CorporationSoftcap < 0.15)
|
||||
throw new Error(`You cannot create a corporation in Bitnode ${player.bitNodeN}`);
|
||||
|
||||
if (selfFund) {
|
||||
|
@ -84,7 +84,7 @@ export function NetscriptSingularity(player: IPlayer, workerScript: WorkerScript
|
||||
if (script.filename === cbScript) {
|
||||
const ramUsage = script.ramUsage;
|
||||
const ramAvailable = home.maxRam - home.ramUsed;
|
||||
if (ramUsage > ramAvailable) {
|
||||
if (ramUsage > ramAvailable + 0.001) {
|
||||
return; // Not enough RAM
|
||||
}
|
||||
const runningScriptObj = new RunningScript(script, []); // No args
|
||||
@ -123,7 +123,8 @@ export function NetscriptSingularity(player: IPlayer, workerScript: WorkerScript
|
||||
_ctx.helper.checkSingularityAccess();
|
||||
const augName = _ctx.helper.string("augName", _augName);
|
||||
const aug = getAugmentation(_ctx, augName);
|
||||
return [aug.getCost(player).moneyCost, aug.getCost(player).repCost];
|
||||
const costs = aug.getCost(player);
|
||||
return [costs.repCost, costs.moneyCost];
|
||||
},
|
||||
getAugmentationPrereq: (_ctx: NetscriptContext) =>
|
||||
function (_augName: unknown): string[] {
|
||||
|
@ -5,6 +5,7 @@ import { netscriptDelay } from "../NetscriptEvaluator";
|
||||
|
||||
import { staneksGift } from "../CotMG/Helper";
|
||||
import { Fragments, FragmentById } from "../CotMG/Fragment";
|
||||
import { FragmentType } from "../CotMG/FragmentType";
|
||||
|
||||
import {
|
||||
Fragment as IFragment,
|
||||
@ -42,11 +43,19 @@ export function NetscriptStanek(
|
||||
},
|
||||
chargeFragment: (_ctx: NetscriptContext) =>
|
||||
function (_rootX: unknown, _rootY: unknown): Promise<void> {
|
||||
//Get the fragment object using the given coordinates
|
||||
const rootX = _ctx.helper.number("rootX", _rootX);
|
||||
const rootY = _ctx.helper.number("rootY", _rootY);
|
||||
checkStanekAPIAccess("chargeFragment");
|
||||
const fragment = staneksGift.findFragment(rootX, rootY);
|
||||
//Check whether the selected fragment can ge charged
|
||||
if (!fragment) throw _ctx.makeRuntimeErrorMsg(`No fragment with root (${rootX}, ${rootY}).`);
|
||||
if (fragment.fragment().type == FragmentType.Booster) {
|
||||
throw _ctx.makeRuntimeErrorMsg(
|
||||
`The fragment with root (${rootX}, ${rootY}) is a Booster Fragment and thus cannot be charged.`,
|
||||
);
|
||||
}
|
||||
//Charge the fragment
|
||||
const time = staneksGift.inBonus() ? 200 : 1000;
|
||||
return netscriptDelay(time, workerScript).then(function () {
|
||||
const charge = staneksGift.charge(player, fragment, workerScript.scriptRef.threads);
|
||||
|
@ -14,6 +14,7 @@ import { defaultTheme } from "../Themes/Themes";
|
||||
import { defaultStyles } from "../Themes/Styles";
|
||||
import { CONSTANTS } from "../Constants";
|
||||
import { hash } from "../hash/hash";
|
||||
import { Terminal } from "../../src/Terminal";
|
||||
|
||||
export function NetscriptUserInterface(
|
||||
player: IPlayer,
|
||||
@ -108,5 +109,11 @@ export function NetscriptUserInterface(
|
||||
|
||||
return gameInfo;
|
||||
},
|
||||
|
||||
clearTerminal: function (): void {
|
||||
updateRam("clearTerminal");
|
||||
workerScript.log("ui.clearTerminal", () => `Clearing terminal`);
|
||||
Terminal.clear();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -532,7 +532,7 @@ function createAndAddWorkerScript(
|
||||
const oneRamUsage = getRamUsageFromRunningScript(runningScriptObj);
|
||||
const ramUsage = roundToTwo(oneRamUsage * threads);
|
||||
const ramAvailable = server.maxRam - server.ramUsed;
|
||||
if (ramUsage > ramAvailable) {
|
||||
if (ramUsage > ramAvailable + 0.001) {
|
||||
dialogBoxCreate(
|
||||
`Not enough RAM to run script ${runningScriptObj.filename} with args ` +
|
||||
`${arrayToString(runningScriptObj.args)}. This likely occurred because you re-loaded ` +
|
||||
@ -750,7 +750,7 @@ export function runScriptFromScript(
|
||||
if (server.hasAdminRights == false) {
|
||||
workerScript.log(caller, () => `You do not have root access on '${server.hostname}'`);
|
||||
return 0;
|
||||
} else if (ramUsage > ramAvailable) {
|
||||
} else if (ramUsage > ramAvailable + 0.001) {
|
||||
workerScript.log(
|
||||
caller,
|
||||
() =>
|
||||
|
@ -95,11 +95,21 @@ export const GraftingRoot = (): React.ReactElement => {
|
||||
{getGraftingAvailableAugs(player).length > 0 ? (
|
||||
<Paper sx={{ my: 1, width: "fit-content", display: "grid", gridTemplateColumns: "1fr 3fr" }}>
|
||||
<List sx={{ height: 400, overflowY: "scroll", borderRight: `1px solid ${Settings.theme.welllight}` }}>
|
||||
{getGraftingAvailableAugs(player).map((k, i) => (
|
||||
<ListItemButton key={i + 1} onClick={() => setSelectedAug(k)} selected={selectedAug === k}>
|
||||
<Typography>{k}</Typography>
|
||||
</ListItemButton>
|
||||
))}
|
||||
{getGraftingAvailableAugs(player)
|
||||
.sort((a, b) => GraftableAugmentations[a].cost - GraftableAugmentations[b].cost)
|
||||
.map((k, i) => (
|
||||
<ListItemButton key={i + 1} onClick={() => setSelectedAug(k)} selected={selectedAug === k}>
|
||||
<Typography
|
||||
sx={{
|
||||
color: canGraft(player, GraftableAugmentations[k])
|
||||
? Settings.theme.primary
|
||||
: Settings.theme.disabled,
|
||||
}}
|
||||
>
|
||||
{k}
|
||||
</Typography>
|
||||
</ListItemButton>
|
||||
))}
|
||||
</List>
|
||||
<Box sx={{ m: 1 }}>
|
||||
<Typography variant="h6" sx={{ display: "flex", alignItems: "center", flexWrap: "wrap" }}>
|
||||
|
9
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
9
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
@ -560,7 +560,7 @@ export interface BitNodeMultipliers {
|
||||
/** Influences how much money the player earns when completing working their job. */
|
||||
CompanyWorkMoney: number;
|
||||
/** Influences the money gain from dividends of corporations created by the player. */
|
||||
CorporationSoftCap: number;
|
||||
CorporationSoftcap: number;
|
||||
/** Influences the valuation of corporations created by the player. */
|
||||
CorporationValuation: number;
|
||||
/** Influences the base experience gained for each ability when the player commits a crime. */
|
||||
@ -4391,6 +4391,13 @@ interface UserInterface {
|
||||
* RAM cost: 0 GB
|
||||
*/
|
||||
getGameInfo(): GameInfo;
|
||||
|
||||
/**
|
||||
* Clear the Terminal window, as if the player ran `clear` in the terminal
|
||||
* @remarks
|
||||
* RAM cost: 0.2 GB
|
||||
*/
|
||||
clearTerminal(): void;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -463,6 +463,12 @@ export class Terminal implements ITerminal {
|
||||
this.contractOpen = true;
|
||||
const res = await contract.prompt();
|
||||
|
||||
//Check if the contract still exists by the time the promise is fullfilled
|
||||
if (serv.getContract(contractName) == null) {
|
||||
this.contractOpen = false;
|
||||
return this.error("Contract no longer exists (Was it solved by a script?)");
|
||||
}
|
||||
|
||||
switch (res) {
|
||||
case CodingContractResult.Success:
|
||||
if (contract.reward !== null) {
|
||||
|
@ -63,13 +63,11 @@ export function runScript(
|
||||
return;
|
||||
}
|
||||
|
||||
if (ramUsage > ramAvailable) {
|
||||
if (ramUsage > ramAvailable + 0.001) {
|
||||
terminal.error(
|
||||
"This machine does not have enough RAM to run this script with " +
|
||||
numThreads +
|
||||
" threads. Script requires " +
|
||||
numeralWrapper.formatRAM(ramUsage) +
|
||||
" of RAM",
|
||||
"This machine does not have enough RAM to run this script" +
|
||||
(numThreads === 1 ? "" : ` with ${numThreads} threads`) +
|
||||
`. Script requires ${numeralWrapper.formatRAM(ramUsage)} of RAM`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ export function NSSelection(props: IProps): React.ReactElement {
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal open={props.open} onClose={props.onClose}>
|
||||
<Modal open={props.open} onClose={props.onClose} sx={{ zIndex: 999999 }}>
|
||||
<Tabs variant="fullWidth" value={value} onChange={handleChange}>
|
||||
<Tab label="NS1" />
|
||||
<Tab label="NS2" />
|
||||
|
@ -18,6 +18,7 @@ import { Theme } from "@mui/material";
|
||||
import { findRunningScript } from "../../Script/ScriptHelpers";
|
||||
import { Player } from "../../Player";
|
||||
import { debounce } from "lodash";
|
||||
import { Settings } from "../../Settings/Settings";
|
||||
|
||||
let layerCounter = 0;
|
||||
|
||||
@ -77,42 +78,18 @@ interface IProps {
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
const useStyles = makeStyles((theme: Theme) =>
|
||||
const useStyles = makeStyles((_theme: Theme) =>
|
||||
createStyles({
|
||||
title: {
|
||||
"&.is-minimized + *": {
|
||||
border: "none",
|
||||
margin: 0,
|
||||
"max-height": 0,
|
||||
padding: 0,
|
||||
"pointer-events": "none",
|
||||
visibility: "hidden",
|
||||
},
|
||||
},
|
||||
logs: {
|
||||
overflowY: "scroll",
|
||||
overflowX: "hidden",
|
||||
scrollbarWidth: "auto",
|
||||
display: "flex",
|
||||
flexDirection: "column-reverse",
|
||||
whiteSpace: "pre-wrap",
|
||||
},
|
||||
titleButton: {
|
||||
padding: "1px 6px",
|
||||
},
|
||||
success: {
|
||||
color: theme.colors.success,
|
||||
},
|
||||
error: {
|
||||
color: theme.palette.error.main,
|
||||
},
|
||||
primary: {
|
||||
color: theme.palette.primary.main,
|
||||
},
|
||||
info: {
|
||||
color: theme.palette.info.main,
|
||||
},
|
||||
warning: {
|
||||
color: theme.palette.warning.main,
|
||||
padding: "1px 0",
|
||||
height: "100%",
|
||||
},
|
||||
}),
|
||||
);
|
||||
@ -190,20 +167,20 @@ function LogWindow(props: IProps): React.ReactElement {
|
||||
setMinimized(!minimized);
|
||||
}
|
||||
|
||||
function lineClass(s: string): string {
|
||||
function lineColor(s: string): string {
|
||||
if (s.match(/(^\[[^\]]+\] )?ERROR/) || s.match(/(^\[[^\]]+\] )?FAIL/)) {
|
||||
return classes.error;
|
||||
return Settings.theme.error;
|
||||
}
|
||||
if (s.match(/(^\[[^\]]+\] )?SUCCESS/)) {
|
||||
return classes.success;
|
||||
return Settings.theme.success;
|
||||
}
|
||||
if (s.match(/(^\[[^\]]+\] )?WARN/)) {
|
||||
return classes.warning;
|
||||
return Settings.theme.warning;
|
||||
}
|
||||
if (s.match(/(^\[[^\]]+\] )?INFO/)) {
|
||||
return classes.info;
|
||||
return Settings.theme.info;
|
||||
}
|
||||
return classes.primary;
|
||||
return Settings.theme.primary;
|
||||
}
|
||||
|
||||
// And trigger fakeDrag when the window is resized
|
||||
@ -242,74 +219,99 @@ function LogWindow(props: IProps): React.ReactElement {
|
||||
if (e.clientX < 0 || e.clientY < 0 || e.clientX > innerWidth || e.clientY > innerHeight) return false;
|
||||
};
|
||||
|
||||
// Max [width, height]
|
||||
const minConstraints: [number, number] = [250, 33];
|
||||
|
||||
return (
|
||||
<Draggable handle=".drag" onDrag={boundToBody} ref={rootRef}>
|
||||
<Paper
|
||||
style={{
|
||||
display: "flex",
|
||||
<Draggable handle=".drag" onDrag={boundToBody} ref={rootRef} onMouseDown={updateLayer}>
|
||||
<Box
|
||||
display="flex"
|
||||
sx={{
|
||||
flexFlow: "column",
|
||||
position: "fixed",
|
||||
left: "40%",
|
||||
top: "30%",
|
||||
zIndex: 1400,
|
||||
minWidth: `${minConstraints[0]}px`,
|
||||
minHeight: `${minConstraints[1]}px`,
|
||||
...(minimized
|
||||
? {
|
||||
border: "none",
|
||||
margin: 0,
|
||||
maxHeight: 0,
|
||||
padding: 0,
|
||||
}
|
||||
: {
|
||||
border: `1px solid ${Settings.theme.welllight}`,
|
||||
}),
|
||||
}}
|
||||
ref={container}
|
||||
>
|
||||
<div onMouseDown={updateLayer}>
|
||||
<Paper
|
||||
className={classes.title + " " + (minimized ? "is-minimized" : "")}
|
||||
style={{
|
||||
cursor: "grab",
|
||||
}}
|
||||
>
|
||||
<Box className="drag" display="flex" alignItems="center" ref={draggableRef}>
|
||||
<Typography color="primary" variant="h6" sx={{ marginRight: "auto" }} title={title(true)}>
|
||||
{title()}
|
||||
<ResizableBox
|
||||
height={500}
|
||||
width={500}
|
||||
minConstraints={minConstraints}
|
||||
handle={
|
||||
<span
|
||||
style={{
|
||||
position: "absolute",
|
||||
right: "-10px",
|
||||
bottom: "-16px",
|
||||
cursor: "nw-resize",
|
||||
display: minimized ? "none" : "inline-block",
|
||||
}}
|
||||
>
|
||||
<ArrowForwardIosIcon color="primary" style={{ transform: "rotate(45deg)", fontSize: "1.75rem" }} />
|
||||
</span>
|
||||
}
|
||||
>
|
||||
<>
|
||||
<Paper className="drag" sx={{ display: "flex", alignItems: "center", cursor: "grab" }} ref={draggableRef}>
|
||||
<Typography
|
||||
variant="h6"
|
||||
sx={{ marginRight: "auto", textOverflow: "ellipsis", whiteSpace: "nowrap", overflow: "hidden" }}
|
||||
title={title(true)}
|
||||
>
|
||||
{title(true)}
|
||||
</Typography>
|
||||
|
||||
{!workerScripts.has(script.pid) ? (
|
||||
<Button className={classes.titleButton} onClick={run} onTouchEnd={run}>
|
||||
Run
|
||||
<span style={{ minWidth: "fit-content", height: `${minConstraints[1]}px` }}>
|
||||
{!workerScripts.has(script.pid) ? (
|
||||
<Button className={classes.titleButton} onClick={run} onTouchEnd={run}>
|
||||
Run
|
||||
</Button>
|
||||
) : (
|
||||
<Button className={classes.titleButton} onClick={kill} onTouchEnd={kill}>
|
||||
Kill
|
||||
</Button>
|
||||
)}
|
||||
<Button className={classes.titleButton} onClick={minimize} onTouchEnd={minimize}>
|
||||
{minimized ? "\u{1F5D6}" : "\u{1F5D5}"}
|
||||
</Button>
|
||||
) : (
|
||||
<Button className={classes.titleButton} onClick={kill} onTouchEnd={kill}>
|
||||
Kill
|
||||
<Button className={classes.titleButton} onClick={props.onClose} onTouchEnd={props.onClose}>
|
||||
Close
|
||||
</Button>
|
||||
)}
|
||||
<Button className={classes.titleButton} onClick={minimize} onTouchEnd={minimize}>
|
||||
{minimized ? "\u{1F5D6}" : "\u{1F5D5}"}
|
||||
</Button>
|
||||
<Button className={classes.titleButton} onClick={props.onClose} onTouchEnd={props.onClose}>
|
||||
Close
|
||||
</Button>
|
||||
</Box>
|
||||
</Paper>
|
||||
<Paper sx={{ overflow: "scroll", overflowWrap: "break-word", whiteSpace: "pre-wrap" }}>
|
||||
<ResizableBox
|
||||
</span>
|
||||
</Paper>
|
||||
|
||||
<Paper
|
||||
className={classes.logs}
|
||||
height={500}
|
||||
width={500}
|
||||
minConstraints={[250, 30]}
|
||||
handle={
|
||||
<span style={{ position: "absolute", right: "-10px", bottom: "-13px", cursor: "nw-resize" }}>
|
||||
<ArrowForwardIosIcon color="primary" style={{ transform: "rotate(45deg)" }} />
|
||||
</span>
|
||||
}
|
||||
sx={{ height: `calc(100% - ${minConstraints[1]}px)`, display: minimized ? "none" : "flex" }}
|
||||
>
|
||||
<Box>
|
||||
<span style={{ display: "flex", flexDirection: "column" }}>
|
||||
{script.logs.map(
|
||||
(line: string, i: number): JSX.Element => (
|
||||
<Typography key={i} className={lineClass(line)}>
|
||||
<Typography key={i} sx={{ color: lineColor(line) }}>
|
||||
{line}
|
||||
<br />
|
||||
</Typography>
|
||||
),
|
||||
)}
|
||||
</Box>
|
||||
</ResizableBox>
|
||||
</Paper>
|
||||
</div>
|
||||
</Paper>
|
||||
</span>
|
||||
</Paper>
|
||||
</>
|
||||
</ResizableBox>
|
||||
</Box>
|
||||
</Draggable>
|
||||
);
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
import React from "react";
|
||||
import { Theme } from "@mui/material";
|
||||
import makeStyles from "@mui/styles/makeStyles";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import M from "@mui/material/Modal";
|
||||
import Fade from "@mui/material/Fade";
|
||||
import Box from "@mui/material/Box";
|
||||
import Fade from "@mui/material/Fade";
|
||||
import M from "@mui/material/Modal";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import makeStyles from "@mui/styles/makeStyles";
|
||||
import { SxProps } from "@mui/system";
|
||||
import React from "react";
|
||||
|
||||
const useStyles = makeStyles((theme: Theme) =>
|
||||
createStyles({
|
||||
@ -12,7 +13,6 @@ const useStyles = makeStyles((theme: Theme) =>
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
zIndex: 999999,
|
||||
},
|
||||
paper: {
|
||||
backgroundColor: theme.palette.background.default,
|
||||
@ -35,6 +35,7 @@ interface IProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
children: React.ReactNode;
|
||||
sx?: SxProps<Theme>;
|
||||
}
|
||||
|
||||
export const Modal = (props: IProps): React.ReactElement => {
|
||||
@ -49,6 +50,7 @@ export const Modal = (props: IProps): React.ReactElement => {
|
||||
onClose={props.onClose}
|
||||
closeAfterTransition
|
||||
className={classes.modal}
|
||||
sx={props.sx}
|
||||
>
|
||||
<Fade in={props.open}>
|
||||
<div className={classes.paper}>
|
||||
|
Loading…
Reference in New Issue
Block a user