Merge pull request #3525 from Snarling/GhostDirectoryFix

TERMINAL: FIX #3492 Allow cd .. even when destination directory is empty
This commit is contained in:
hydroflame 2022-04-20 13:05:19 -04:00 committed by GitHub
commit 84eb4379d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 58 additions and 21 deletions

@ -1,5 +1,4 @@
module.exports = {
setupFiles: ["./jest.setup.js"],
moduleFileExtensions: ["ts", "tsx", "js", "jsx"],
transform: {
"^.+\\.(js|jsx|ts|tsx)$": "babel-jest",

@ -1,2 +0,0 @@
import "regenerator-runtime/runtime";
global.$ = require("jquery");

@ -59,8 +59,9 @@
"@types/acorn": "^4.0.6",
"@types/escodegen": "^0.0.7",
"@types/file-saver": "^2.0.3",
"@types/jquery": "^3.5.14",
"@types/lodash": "^4.14.168",
"@types/numeral": "0.0.25",
"@types/numeral": "^2.0.2",
"@types/react": "^17.0.21",
"@types/react-beautiful-dnd": "^13.1.2",
"@types/react-dom": "^17.0.9",
@ -84,7 +85,6 @@
"prettier": "^2.3.2",
"raw-loader": "^4.0.2",
"react-refresh": "^0.10.0",
"regenerator-runtime": "^0.13.9",
"source-map": "^0.7.3",
"start-server-and-test": "^1.14.0",
"typescript": "^4.2.4",

@ -70,6 +70,7 @@ export const RamCostConstants: IMap<number> = {
ScriptStanekPlace: 5,
ScriptStanekFragmentAt: 2,
ScriptStanekDeleteAt: 0.15,
ScriptStanekAcceptGift: 2,
};
function SF4Cost(cost: number): (player: IPlayer) => number {
@ -284,6 +285,7 @@ const stanek: IMap<any> = {
placeFragment: RamCostConstants.ScriptStanekPlace,
getFragment: RamCostConstants.ScriptStanekFragmentAt,
removeFragment: RamCostConstants.ScriptStanekDeleteAt,
acceptGift: RamCostConstants.ScriptStanekAcceptGift,
};
// UI API

@ -1,3 +1,4 @@
import $ from "jquery";
import { vsprintf, sprintf } from "sprintf-js";
import { getRamCost } from "./Netscript/RamCostGenerator";

@ -13,6 +13,10 @@ import {
} from "../ScriptEditor/NetscriptDefinitions";
import { AugmentationNames } from "../Augmentation/data/AugmentationNames";
import { NetscriptContext, InternalAPI } from "../Netscript/APIWrapper";
import { applyAugmentation } from "../Augmentation/AugmentationHelpers";
import { FactionNames } from "../Faction/data/FactionNames";
import { joinFaction } from "../Faction/FactionHelpers";
import { Factions } from "../Faction/Factions";
export function NetscriptStanek(
player: IPlayer,
@ -109,5 +113,29 @@ export function NetscriptStanek(
checkStanekAPIAccess("removeFragment");
return staneksGift.delete(rootX, rootY);
},
acceptGift: (_ctx: NetscriptContext) =>
function (): boolean {
//Check if the player is eligible to join the church
if (
player.canAccessCotMG() &&
player.augmentations.filter((a) => a.name !== AugmentationNames.NeuroFluxGovernor).length == 0 &&
player.queuedAugmentations.filter((a) => a.name !== AugmentationNames.NeuroFluxGovernor).length == 0
) {
//Attempt to join CotMG
joinFaction(Factions[FactionNames.ChurchOfTheMachineGod]);
//Attempt to install the first Stanek aug
if (
!player.hasAugmentation(AugmentationNames.StaneksGift1) &&
!player.queuedAugmentations.some((a) => a.name === AugmentationNames.StaneksGift1)
) {
applyAugmentation({ name: AugmentationNames.StaneksGift1, level: 1 });
}
}
//Return true iff the player is in CotMG and has the first Stanek aug installed
return (
Factions[FactionNames.ChurchOfTheMachineGod].isMember &&
player.hasAugmentation(AugmentationNames.StaneksGift1)
);
},
};
}

@ -4261,6 +4261,16 @@ interface Stanek {
* @returns The fragment at [rootX, rootY], if any.
*/
removeFragment(rootX: number, rootY: number): boolean;
/**
* Accept Stanek's Gift by joining the Church of the Machine God
* @remarks
* RAM cost: 2 GB
*
* @returns true if the player is a member of the church and has the gift installed,
* false otherwise.
*/
acceptGift(): boolean;
}
/**

@ -30,6 +30,10 @@ export function cd(
terminal.error("Invalid path. Failed to change directories");
return;
}
if (terminal.cwd().length > 1 && dir === "..") {
terminal.setcwd(evaledDir);
return;
}
const server = player.getCurrentServer();
if (!containsFiles(server, evaledDir)) {

@ -1,3 +1,5 @@
import $ from "jquery";
import { ITerminal } from "../ITerminal";
import { IRouter } from "../../ui/Router";
import { IPlayer } from "../../PersonObjects/IPlayer";

@ -223,19 +223,21 @@ class NumeralFormatter {
const parsed = parseFloat(s);
const selfParsed = this.parseCustomLargeNumber(s);
// Check for one or more NaN values
if (isNaN(parsed) && numeralValue === null && isNaN(selfParsed)) {
// 3x NaN
return NaN;
} else if (isNaN(parsed) && isNaN(selfParsed)) {
if (isNaN(parsed) && isNaN(selfParsed)) {
if (numeralValue === null) {
// 3x NaN
return NaN;
}
// 2x NaN
return numeralValue;
} else if (numeralValue === null && isNaN(selfParsed)) {
// 2x NaN
return parsed;
} else if (isNaN(parsed) && numeralValue === null) {
// 2x NaN
return selfParsed;
} else if (isNaN(parsed)) {
if (numeralValue === null) {
// 2x NaN
return selfParsed;
}
// 1x NaN
return this.largestAbsoluteNumber(numeralValue, selfParsed);
} else if (numeralValue === null) {

@ -93,15 +93,6 @@ module.exports = (env, argv) => {
new webpack.DefinePlugin({
"process.env.NODE_ENV": isDevelopment ? '"development"' : '"production"',
}),
// http://stackoverflow.com/questions/29080148/expose-jquery-to-real-window-object-with-webpack
new webpack.ProvidePlugin({
// Automtically detect jQuery and $ as free var in modules
// and inject the jquery library
// This is required by many jquery plugins
jquery: "jquery",
jQuery: "jquery",
$: "jquery",
}),
new HtmlWebpackPlugin(htmlConfig),
new MiniCssExtractPlugin({
filename: "[name].css",