mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-10 01:33:54 +01:00
commit
93f8785ec6
4
dist/engine.bundle.js
vendored
4
dist/engine.bundle.js
vendored
File diff suppressed because one or more lines are too long
18
dist/vendor.bundle.js
vendored
18
dist/vendor.bundle.js
vendored
File diff suppressed because one or more lines are too long
@ -66,7 +66,7 @@ documentation_title = '{0} Documentation'.format(project)
|
|||||||
# The short X.Y version.
|
# The short X.Y version.
|
||||||
version = '0.50'
|
version = '0.50'
|
||||||
# The full version, including alpha/beta/rc tags.
|
# The full version, including alpha/beta/rc tags.
|
||||||
release = '0.50.1'
|
release = '0.50.2'
|
||||||
|
|
||||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
# for a list of supported languages.
|
# for a list of supported languages.
|
||||||
|
@ -24,6 +24,8 @@ level 3, then you will be able to access all of the Singularity Functions.
|
|||||||
travelToCity() <singularityfunctions/travelToCity>
|
travelToCity() <singularityfunctions/travelToCity>
|
||||||
purchaseTor() <singularityfunctions/purchaseTor>
|
purchaseTor() <singularityfunctions/purchaseTor>
|
||||||
purchaseProgram() <singularityfunctions/purchaseProgram>
|
purchaseProgram() <singularityfunctions/purchaseProgram>
|
||||||
|
connect() <singularityfunctions/connect>
|
||||||
|
manualHack() <singularityfunctions/manualHack>
|
||||||
getStats() <singularityfunctions/getStats>
|
getStats() <singularityfunctions/getStats>
|
||||||
getCharacterInformation() <singularityfunctions/getCharacterInformation>
|
getCharacterInformation() <singularityfunctions/getCharacterInformation>
|
||||||
isBusy() <singularityfunctions/isBusy>
|
isBusy() <singularityfunctions/isBusy>
|
||||||
|
20
doc/source/netscript/singularityfunctions/connect.rst
Normal file
20
doc/source/netscript/singularityfunctions/connect.rst
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
connect() Netscript Function
|
||||||
|
============================
|
||||||
|
|
||||||
|
.. js:function:: connect(hostname)
|
||||||
|
|
||||||
|
:RAM cost: 2 GB
|
||||||
|
:param string hostname: hostname of the server to connect.
|
||||||
|
:returns: ``true`` if the connection was a success.
|
||||||
|
|
||||||
|
If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to use this function.
|
||||||
|
|
||||||
|
This function will connect you to the specified server if it's directly connected to the current server.
|
||||||
|
You can also pass in 'home' to return to your home server from anywhere.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
connect("joesguns");
|
||||||
|
connect("CSEC");
|
24
doc/source/netscript/singularityfunctions/manualHack.rst
Normal file
24
doc/source/netscript/singularityfunctions/manualHack.rst
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
manualHack() Netscript Function
|
||||||
|
===============================
|
||||||
|
|
||||||
|
.. js:function:: manualHack()
|
||||||
|
|
||||||
|
:RAM cost: 2 GB
|
||||||
|
:returns: The amount of money stolen if the hack is successful, and zero otherwise
|
||||||
|
|
||||||
|
If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to use this function.
|
||||||
|
|
||||||
|
This function will perform a manual hack on the server you are currently connected to.
|
||||||
|
This is typically required to join factions.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
connect("CSEC");
|
||||||
|
manualHack();
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
For NS2 users:
|
||||||
|
|
||||||
|
This function is async.
|
@ -31,6 +31,8 @@ Alt + f Switch to 'Factions' page
|
|||||||
Alt + a Switch to 'Augmentations' page
|
Alt + a Switch to 'Augmentations' page
|
||||||
Alt + u Switch to 'Tutorial' page
|
Alt + u Switch to 'Tutorial' page
|
||||||
Alt + o Switch to 'Options' page
|
Alt + o Switch to 'Options' page
|
||||||
|
Alt + g Switch to 'Gang' page
|
||||||
|
Alt + b Switch to 'Bladeburner' page
|
||||||
========== ===========================================================================
|
========== ===========================================================================
|
||||||
|
|
||||||
Script Editor
|
Script Editor
|
||||||
|
@ -274,6 +274,7 @@ export function initBitNodeMultipliers(p: IPlayer) {
|
|||||||
BitNodeMultipliers.InfiltrationMoney = 3;
|
BitNodeMultipliers.InfiltrationMoney = 3;
|
||||||
BitNodeMultipliers.FactionWorkRepGain = 0.5;
|
BitNodeMultipliers.FactionWorkRepGain = 0.5;
|
||||||
BitNodeMultipliers.FactionPassiveRepGain = 0;
|
BitNodeMultipliers.FactionPassiveRepGain = 0;
|
||||||
|
BitNodeMultipliers.GangKarmaRequirement = 0;
|
||||||
break;
|
break;
|
||||||
case 3: // Corporatocracy
|
case 3: // Corporatocracy
|
||||||
BitNodeMultipliers.HackingLevelMultiplier = 0.8;
|
BitNodeMultipliers.HackingLevelMultiplier = 0.8;
|
||||||
@ -289,6 +290,7 @@ export function initBitNodeMultipliers(p: IPlayer) {
|
|||||||
BitNodeMultipliers.HacknetNodeMoney = 0.25;
|
BitNodeMultipliers.HacknetNodeMoney = 0.25;
|
||||||
BitNodeMultipliers.HomeComputerRamCost = 1.5;
|
BitNodeMultipliers.HomeComputerRamCost = 1.5;
|
||||||
BitNodeMultipliers.PurchasedServerCost = 2;
|
BitNodeMultipliers.PurchasedServerCost = 2;
|
||||||
|
BitNodeMultipliers.GangKarmaRequirement = 3;
|
||||||
break;
|
break;
|
||||||
case 4: // The Singularity
|
case 4: // The Singularity
|
||||||
BitNodeMultipliers.ServerMaxMoney = 0.15;
|
BitNodeMultipliers.ServerMaxMoney = 0.15;
|
||||||
@ -331,6 +333,7 @@ export function initBitNodeMultipliers(p: IPlayer) {
|
|||||||
BitNodeMultipliers.FactionPassiveRepGain = 0;
|
BitNodeMultipliers.FactionPassiveRepGain = 0;
|
||||||
BitNodeMultipliers.HackExpGain = 0.25;
|
BitNodeMultipliers.HackExpGain = 0.25;
|
||||||
BitNodeMultipliers.DaedalusAugsRequirement = 1.166; // Results in 35 Augs needed
|
BitNodeMultipliers.DaedalusAugsRequirement = 1.166; // Results in 35 Augs needed
|
||||||
|
BitNodeMultipliers.GangKarmaRequirement = 5;
|
||||||
break;
|
break;
|
||||||
case 7: // Bladeburner 2079
|
case 7: // Bladeburner 2079
|
||||||
BitNodeMultipliers.BladeburnerRank = 0.6;
|
BitNodeMultipliers.BladeburnerRank = 0.6;
|
||||||
@ -351,6 +354,7 @@ export function initBitNodeMultipliers(p: IPlayer) {
|
|||||||
BitNodeMultipliers.FourSigmaMarketDataCost = 2;
|
BitNodeMultipliers.FourSigmaMarketDataCost = 2;
|
||||||
BitNodeMultipliers.FourSigmaMarketDataApiCost = 2;
|
BitNodeMultipliers.FourSigmaMarketDataApiCost = 2;
|
||||||
BitNodeMultipliers.DaedalusAugsRequirement = 1.166; // Results in 35 Augs needed
|
BitNodeMultipliers.DaedalusAugsRequirement = 1.166; // Results in 35 Augs needed
|
||||||
|
BitNodeMultipliers.GangKarmaRequirement = 5;
|
||||||
break;
|
break;
|
||||||
case 8: // Ghost of Wall Street
|
case 8: // Ghost of Wall Street
|
||||||
BitNodeMultipliers.ScriptHackMoney = 0.3;
|
BitNodeMultipliers.ScriptHackMoney = 0.3;
|
||||||
@ -363,6 +367,7 @@ export function initBitNodeMultipliers(p: IPlayer) {
|
|||||||
BitNodeMultipliers.RepToDonateToFaction = 0;
|
BitNodeMultipliers.RepToDonateToFaction = 0;
|
||||||
BitNodeMultipliers.CorporationValuation = 0;
|
BitNodeMultipliers.CorporationValuation = 0;
|
||||||
BitNodeMultipliers.CodingContractMoney = 0;
|
BitNodeMultipliers.CodingContractMoney = 0;
|
||||||
|
BitNodeMultipliers.GangKarmaRequirement = 10;
|
||||||
break;
|
break;
|
||||||
case 9: // Hacktocracy
|
case 9: // Hacktocracy
|
||||||
BitNodeMultipliers.HackingLevelMultiplier = 0.4;
|
BitNodeMultipliers.HackingLevelMultiplier = 0.4;
|
||||||
@ -384,6 +389,7 @@ export function initBitNodeMultipliers(p: IPlayer) {
|
|||||||
BitNodeMultipliers.FourSigmaMarketDataApiCost = 4;
|
BitNodeMultipliers.FourSigmaMarketDataApiCost = 4;
|
||||||
BitNodeMultipliers.BladeburnerRank = 0.9;
|
BitNodeMultipliers.BladeburnerRank = 0.9;
|
||||||
BitNodeMultipliers.BladeburnerSkillCost = 1.2;
|
BitNodeMultipliers.BladeburnerSkillCost = 1.2;
|
||||||
|
BitNodeMultipliers.GangKarmaRequirement = 3;
|
||||||
break;
|
break;
|
||||||
case 10: // Digital Carbon
|
case 10: // Digital Carbon
|
||||||
BitNodeMultipliers.HackingLevelMultiplier = 0.2;
|
BitNodeMultipliers.HackingLevelMultiplier = 0.2;
|
||||||
@ -407,6 +413,7 @@ export function initBitNodeMultipliers(p: IPlayer) {
|
|||||||
BitNodeMultipliers.PurchasedServerLimit = 0.6;
|
BitNodeMultipliers.PurchasedServerLimit = 0.6;
|
||||||
BitNodeMultipliers.PurchasedServerMaxRam = 0.5;
|
BitNodeMultipliers.PurchasedServerMaxRam = 0.5;
|
||||||
BitNodeMultipliers.BladeburnerRank = 0.8;
|
BitNodeMultipliers.BladeburnerRank = 0.8;
|
||||||
|
BitNodeMultipliers.GangKarmaRequirement = 3;
|
||||||
break;
|
break;
|
||||||
case 11: //The Big Crash
|
case 11: //The Big Crash
|
||||||
BitNodeMultipliers.HackingLevelMultiplier = 0.5;
|
BitNodeMultipliers.HackingLevelMultiplier = 0.5;
|
||||||
|
@ -109,6 +109,11 @@ interface IBitNodeMultipliers {
|
|||||||
*/
|
*/
|
||||||
FourSigmaMarketDataCost: number;
|
FourSigmaMarketDataCost: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Influences how much negative karma is required to create a gang in this bitnode.
|
||||||
|
*/
|
||||||
|
GangKarmaRequirement: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Influences the experienced gained when hacking a server.
|
* Influences the experienced gained when hacking a server.
|
||||||
*/
|
*/
|
||||||
@ -268,4 +273,5 @@ export const BitNodeMultipliers: IBitNodeMultipliers = {
|
|||||||
BladeburnerSkillCost: 1,
|
BladeburnerSkillCost: 1,
|
||||||
|
|
||||||
DaedalusAugsRequirement: 1,
|
DaedalusAugsRequirement: 1,
|
||||||
|
GangKarmaRequirement: 1,
|
||||||
};
|
};
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
import { IMap } from "./types";
|
import { IMap } from "./types";
|
||||||
|
|
||||||
export let CONSTANTS: IMap<any> = {
|
export let CONSTANTS: IMap<any> = {
|
||||||
Version: "0.50.1",
|
Version: "0.50.2",
|
||||||
|
|
||||||
/** Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience
|
/** Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience
|
||||||
* and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then
|
* and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then
|
||||||
@ -228,21 +228,18 @@ export let CONSTANTS: IMap<any> = {
|
|||||||
|
|
||||||
LatestUpdate:
|
LatestUpdate:
|
||||||
`
|
`
|
||||||
v0.50.1 - 2021-03-22 (hydroflame)
|
v0.50.2 - 2021-03-25 Everyone asked for this one. (hydroflame)
|
||||||
-------
|
-------
|
||||||
|
BitNodeMultipliers
|
||||||
|
* 'GangKarmaRequirements': a new multipler that influences how much karma is required to make a gang different bitnodes.
|
||||||
|
|
||||||
Netscript
|
Netscript
|
||||||
* getTaskStats works
|
* 'connect': a new singularity function that connects you to a server. (like the terminal command)
|
||||||
|
* 'manualHack': a new singularity function that performs a manual hack on the players current server.
|
||||||
Source-File -1
|
* ns2 stack trace works on Firefox now.
|
||||||
* Added a new Exploit
|
|
||||||
|
|
||||||
Factions
|
|
||||||
* Augmentations offered by a Faction but already bought are in a separate list at the bottom of the page.
|
|
||||||
|
|
||||||
Bug fixed
|
|
||||||
* Fixed a bug where completing a maxed non-repeatable BitNode would make its color on the BitVerse like level 1.
|
|
||||||
|
|
||||||
Misc.
|
Misc.
|
||||||
* Minor spacing in stats tables.
|
* New shortcut, Alt + b, brings you to bladeburner
|
||||||
|
* New shortcut, Alt + g, brings you to gang
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
@ -1516,7 +1516,6 @@ HackingMission.prototype.finishMission = function(win) {
|
|||||||
var gain = this.reward * Player.faction_rep_mult * favorMult;
|
var gain = this.reward * Player.faction_rep_mult * favorMult;
|
||||||
dialogBoxCreate("Mission won! You earned " +
|
dialogBoxCreate("Mission won! You earned " +
|
||||||
numeralWrapper.format(gain, '0.000a') + " reputation with " + this.faction.name);
|
numeralWrapper.format(gain, '0.000a') + " reputation with " + this.faction.name);
|
||||||
console.log(`diff ${this.difficulty}`);
|
|
||||||
Player.gainIntelligenceExp(this.difficulty * CONSTANTS.IntelligenceHackingMissionBaseExpGain);
|
Player.gainIntelligenceExp(this.difficulty * CONSTANTS.IntelligenceHackingMissionBaseExpGain);
|
||||||
this.faction.playerReputation += gain;
|
this.faction.playerReputation += gain;
|
||||||
} else {
|
} else {
|
||||||
|
@ -176,6 +176,8 @@ export const RamCosts: IMap<any> = {
|
|||||||
travelToCity: () => RamCostConstants.ScriptSingularityFn1RamCost,
|
travelToCity: () => RamCostConstants.ScriptSingularityFn1RamCost,
|
||||||
purchaseTor: () => RamCostConstants.ScriptSingularityFn1RamCost,
|
purchaseTor: () => RamCostConstants.ScriptSingularityFn1RamCost,
|
||||||
purchaseProgram: () => RamCostConstants.ScriptSingularityFn1RamCost,
|
purchaseProgram: () => RamCostConstants.ScriptSingularityFn1RamCost,
|
||||||
|
connect: () => RamCostConstants.ScriptSingularityFn1RamCost,
|
||||||
|
manualHack: () => RamCostConstants.ScriptSingularityFn1RamCost,
|
||||||
getStats: () => RamCostConstants.ScriptSingularityFn1RamCost / 4,
|
getStats: () => RamCostConstants.ScriptSingularityFn1RamCost / 4,
|
||||||
getCharacterInformation: () => RamCostConstants.ScriptSingularityFn1RamCost / 4,
|
getCharacterInformation: () => RamCostConstants.ScriptSingularityFn1RamCost / 4,
|
||||||
isBusy: () => RamCostConstants.ScriptSingularityFn1RamCost / 4,
|
isBusy: () => RamCostConstants.ScriptSingularityFn1RamCost / 4,
|
||||||
|
@ -59,6 +59,7 @@ import {
|
|||||||
import { HacknetServer, MaxNumberHacknetServers } from "./Hacknet/HacknetServer";
|
import { HacknetServer, MaxNumberHacknetServers } from "./Hacknet/HacknetServer";
|
||||||
import { CityName } from "./Locations/data/CityNames";
|
import { CityName } from "./Locations/data/CityNames";
|
||||||
import { LocationName } from "./Locations/data/LocationNames";
|
import { LocationName } from "./Locations/data/LocationNames";
|
||||||
|
import { Terminal } from "./Terminal";
|
||||||
|
|
||||||
import { Message } from "./Message/Message";
|
import { Message } from "./Message/Message";
|
||||||
import { Messages } from "./Message/MessageHelpers";
|
import { Messages } from "./Message/MessageHelpers";
|
||||||
@ -405,16 +406,42 @@ function NetscriptFunctions(workerScript) {
|
|||||||
}
|
}
|
||||||
if(!filename) continue
|
if(!filename) continue
|
||||||
|
|
||||||
const lineRe = /.*:(\d+):\d+.*/;
|
function parseChromeStackline(line) {
|
||||||
const lineMatch = stackline.match(lineRe);
|
const lineRe = /.*:(\d+):\d+.*/;
|
||||||
|
const funcRe = /.*at (.+) \(.*/;
|
||||||
|
|
||||||
|
const lineMatch = line.match(lineRe);
|
||||||
|
const funcMatch = line.match(funcRe);
|
||||||
|
if(lineMatch && funcMatch) {
|
||||||
|
let func = funcMatch[1];
|
||||||
|
return {line: lineMatch[1], func: func};
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
let call = {line: "-1", func: "unknown"};;
|
||||||
|
let chromeCall = parseChromeStackline(stackline);
|
||||||
|
if (chromeCall) {
|
||||||
|
call = chromeCall;
|
||||||
|
}
|
||||||
|
|
||||||
const funcRe = /.*at (.+) \(.*/;
|
function parseFirefoxStackline(line) {
|
||||||
const funcMatch = stackline.match(funcRe);
|
const lineRe = /.*:(\d+):\d+$/;
|
||||||
let func = funcMatch[1];
|
const lineMatch = line.match(lineRe);
|
||||||
if(func.includes('.')) func = func.split('.')[1];
|
|
||||||
|
|
||||||
userstack.push(`${filename}:L${lineMatch[1]}@${func}`);
|
const lio = line.lastIndexOf("@");
|
||||||
|
|
||||||
|
if(lineMatch && lio !== -1) {
|
||||||
|
return {line: lineMatch[1], func: line.slice(0, lio)};
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let firefoxCall = parseFirefoxStackline(stackline);
|
||||||
|
if (firefoxCall) {
|
||||||
|
call = firefoxCall;
|
||||||
|
}
|
||||||
|
|
||||||
|
userstack.push(`${filename}:L${call.line}@${call.func}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
workerScript.log(caller, msg);
|
workerScript.log(caller, msg);
|
||||||
@ -537,29 +564,97 @@ function NetscriptFunctions(workerScript) {
|
|||||||
|
|
||||||
const runAfterReset = function(cbScript=null) {
|
const runAfterReset = function(cbScript=null) {
|
||||||
//Run a script after reset
|
//Run a script after reset
|
||||||
console.log(cbScript);
|
|
||||||
if (cbScript && isString(cbScript)) {
|
if (cbScript && isString(cbScript)) {
|
||||||
console.log('here');
|
|
||||||
const home = Player.getHomeComputer();
|
const home = Player.getHomeComputer();
|
||||||
for (const script of home.scripts) {
|
for (const script of home.scripts) {
|
||||||
console.log('here 2'+script);
|
|
||||||
if (script.filename === cbScript) {
|
if (script.filename === cbScript) {
|
||||||
console.log('here 3');
|
|
||||||
const ramUsage = script.ramUsage;
|
const ramUsage = script.ramUsage;
|
||||||
const ramAvailable = home.maxRam - home.ramUsed;
|
const ramAvailable = home.maxRam - home.ramUsed;
|
||||||
if (ramUsage > ramAvailable) {
|
if (ramUsage > ramAvailable) {
|
||||||
console.log('here 4');
|
|
||||||
return; // Not enough RAM
|
return; // Not enough RAM
|
||||||
}
|
}
|
||||||
const runningScriptObj = new RunningScript(script, []); // No args
|
const runningScriptObj = new RunningScript(script, []); // No args
|
||||||
runningScriptObj.threads = 1; // Only 1 thread
|
runningScriptObj.threads = 1; // Only 1 thread
|
||||||
console.log('running!');
|
|
||||||
startWorkerScript(runningScriptObj, home);
|
startWorkerScript(runningScriptObj, home);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const hack = function(ip, manual, { threads: requestedThreads, stock } = {}) {
|
||||||
|
if (ip === undefined) {
|
||||||
|
throw makeRuntimeErrorMsg("hack", "Takes 1 argument.");
|
||||||
|
}
|
||||||
|
const threads = resolveNetscriptRequestedThreads(workerScript, "hack", requestedThreads);
|
||||||
|
const server = getServer(ip);
|
||||||
|
if (server == null) {
|
||||||
|
throw makeRuntimeErrorMsg("hack", `Invalid IP/hostname: ${ip}.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the hacking time
|
||||||
|
var hackingTime = calculateHackingTime(server); // This is in seconds
|
||||||
|
|
||||||
|
// No root access or skill level too low
|
||||||
|
const canHack = netscriptCanHack(server, Player);
|
||||||
|
if (!canHack.res) {
|
||||||
|
throw makeRuntimeErrorMsg('hack', canHack.msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
workerScript.log("hack", `Executing ${ip} in ${hackingTime.toFixed(3)} seconds (t=${threads})`);
|
||||||
|
|
||||||
|
return netscriptDelay(hackingTime * 1000, workerScript).then(function() {
|
||||||
|
if (workerScript.env.stopFlag) {return Promise.reject(workerScript);}
|
||||||
|
var hackChance = calculateHackingChance(server);
|
||||||
|
var rand = Math.random();
|
||||||
|
var expGainedOnSuccess = calculateHackingExpGain(server) * threads;
|
||||||
|
var expGainedOnFailure = (expGainedOnSuccess / 4);
|
||||||
|
if (rand < hackChance) { // Success!
|
||||||
|
const percentHacked = calculatePercentMoneyHacked(server);
|
||||||
|
let maxThreadNeeded = Math.ceil(1/percentHacked*(server.moneyAvailable/server.moneyMax));
|
||||||
|
if (isNaN(maxThreadNeeded)) {
|
||||||
|
// Server has a 'max money' of 0 (probably). We'll set this to an arbitrarily large value
|
||||||
|
maxThreadNeeded = 1e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
let moneyDrained = Math.floor(server.moneyAvailable * percentHacked) * threads;
|
||||||
|
|
||||||
|
// Over-the-top safety checks
|
||||||
|
if (moneyDrained <= 0) {
|
||||||
|
moneyDrained = 0;
|
||||||
|
expGainedOnSuccess = expGainedOnFailure;
|
||||||
|
}
|
||||||
|
if (moneyDrained > server.moneyAvailable) {moneyDrained = server.moneyAvailable;}
|
||||||
|
server.moneyAvailable -= moneyDrained;
|
||||||
|
if (server.moneyAvailable < 0) {server.moneyAvailable = 0;}
|
||||||
|
|
||||||
|
const moneyGained = moneyDrained * BitNodeMultipliers.ScriptHackMoneyGain;
|
||||||
|
|
||||||
|
Player.gainMoney(moneyGained);
|
||||||
|
workerScript.scriptRef.onlineMoneyMade += moneyGained;
|
||||||
|
Player.scriptProdSinceLastAug += moneyGained;
|
||||||
|
Player.recordMoneySource(moneyGained, "hacking");
|
||||||
|
workerScript.scriptRef.recordHack(server.ip, moneyGained, threads);
|
||||||
|
Player.gainHackingExp(expGainedOnSuccess);
|
||||||
|
workerScript.scriptRef.onlineExpGained += expGainedOnSuccess;
|
||||||
|
workerScript.log("hack", `Successfully hacked '${server.hostname}' for ${numeralWrapper.format(moneyGained, '$0.000a')} and ${numeralWrapper.format(expGainedOnSuccess, '0.000a')} exp (t=${threads})`);
|
||||||
|
server.fortify(CONSTANTS.ServerFortifyAmount * Math.min(threads, maxThreadNeeded));
|
||||||
|
if (stock) {
|
||||||
|
influenceStockThroughServerHack(server, moneyGained);
|
||||||
|
}
|
||||||
|
if(manual) {
|
||||||
|
server.manuallyHacked = true;
|
||||||
|
}
|
||||||
|
return Promise.resolve(moneyGained);
|
||||||
|
} else {
|
||||||
|
// Player only gains 25% exp for failure?
|
||||||
|
Player.gainHackingExp(expGainedOnFailure);
|
||||||
|
workerScript.scriptRef.onlineExpGained += expGainedOnFailure;
|
||||||
|
workerScript.log("hack", `Failed to hack '${server.hostname}'. Gained ${numeralWrapper.format(expGainedOnFailure, '0.000a')} exp (t=${threads})`);
|
||||||
|
return Promise.resolve(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
hacknet : {
|
hacknet : {
|
||||||
numNodes : function() {
|
numNodes : function() {
|
||||||
@ -676,74 +771,7 @@ function NetscriptFunctions(workerScript) {
|
|||||||
},
|
},
|
||||||
hack : function(ip, { threads: requestedThreads, stock } = {}){
|
hack : function(ip, { threads: requestedThreads, stock } = {}){
|
||||||
updateDynamicRam("hack", getRamCost("hack"));
|
updateDynamicRam("hack", getRamCost("hack"));
|
||||||
if (ip === undefined) {
|
return hack(ip, false, {threads: requestedThreads, stock: stock});
|
||||||
throw makeRuntimeErrorMsg("hack", "Takes 1 argument.");
|
|
||||||
}
|
|
||||||
const threads = resolveNetscriptRequestedThreads(workerScript, "hack", requestedThreads);
|
|
||||||
const server = getServer(ip);
|
|
||||||
if (server == null) {
|
|
||||||
throw makeRuntimeErrorMsg("hack", `Invalid IP/hostname: ${ip}.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate the hacking time
|
|
||||||
var hackingTime = calculateHackingTime(server); // This is in seconds
|
|
||||||
|
|
||||||
// No root access or skill level too low
|
|
||||||
const canHack = netscriptCanHack(server, Player);
|
|
||||||
if (!canHack.res) {
|
|
||||||
throw makeRuntimeErrorMsg('hack', canHack.msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
workerScript.log("hack", `Executing ${ip} in ${hackingTime.toFixed(3)} seconds (t=${threads})`);
|
|
||||||
|
|
||||||
return netscriptDelay(hackingTime * 1000, workerScript).then(function() {
|
|
||||||
if (workerScript.env.stopFlag) {return Promise.reject(workerScript);}
|
|
||||||
var hackChance = calculateHackingChance(server);
|
|
||||||
var rand = Math.random();
|
|
||||||
var expGainedOnSuccess = calculateHackingExpGain(server) * threads;
|
|
||||||
var expGainedOnFailure = (expGainedOnSuccess / 4);
|
|
||||||
if (rand < hackChance) { // Success!
|
|
||||||
const percentHacked = calculatePercentMoneyHacked(server);
|
|
||||||
let maxThreadNeeded = Math.ceil(1/percentHacked*(server.moneyAvailable/server.moneyMax));
|
|
||||||
if (isNaN(maxThreadNeeded)) {
|
|
||||||
// Server has a 'max money' of 0 (probably). We'll set this to an arbitrarily large value
|
|
||||||
maxThreadNeeded = 1e6;
|
|
||||||
}
|
|
||||||
|
|
||||||
let moneyDrained = Math.floor(server.moneyAvailable * percentHacked) * threads;
|
|
||||||
|
|
||||||
// Over-the-top safety checks
|
|
||||||
if (moneyDrained <= 0) {
|
|
||||||
moneyDrained = 0;
|
|
||||||
expGainedOnSuccess = expGainedOnFailure;
|
|
||||||
}
|
|
||||||
if (moneyDrained > server.moneyAvailable) {moneyDrained = server.moneyAvailable;}
|
|
||||||
server.moneyAvailable -= moneyDrained;
|
|
||||||
if (server.moneyAvailable < 0) {server.moneyAvailable = 0;}
|
|
||||||
|
|
||||||
const moneyGained = moneyDrained * BitNodeMultipliers.ScriptHackMoneyGain;
|
|
||||||
|
|
||||||
Player.gainMoney(moneyGained);
|
|
||||||
workerScript.scriptRef.onlineMoneyMade += moneyGained;
|
|
||||||
Player.scriptProdSinceLastAug += moneyGained;
|
|
||||||
Player.recordMoneySource(moneyGained, "hacking");
|
|
||||||
workerScript.scriptRef.recordHack(server.ip, moneyGained, threads);
|
|
||||||
Player.gainHackingExp(expGainedOnSuccess);
|
|
||||||
workerScript.scriptRef.onlineExpGained += expGainedOnSuccess;
|
|
||||||
workerScript.log("hack", `Successfully hacked '${server.hostname}' for ${numeralWrapper.format(moneyGained, '$0.000a')} and ${numeralWrapper.format(expGainedOnSuccess, '0.000a')} exp (t=${threads})`);
|
|
||||||
server.fortify(CONSTANTS.ServerFortifyAmount * Math.min(threads, maxThreadNeeded));
|
|
||||||
if (stock) {
|
|
||||||
influenceStockThroughServerHack(server, moneyGained);
|
|
||||||
}
|
|
||||||
return Promise.resolve(moneyGained);
|
|
||||||
} else {
|
|
||||||
// Player only gains 25% exp for failure?
|
|
||||||
Player.gainHackingExp(expGainedOnFailure);
|
|
||||||
workerScript.scriptRef.onlineExpGained += expGainedOnFailure;
|
|
||||||
workerScript.log("hack", `Failed to hack '${server.hostname}'. Gained ${numeralWrapper.format(expGainedOnFailure, '0.000a')} exp (t=${threads})`);
|
|
||||||
return Promise.resolve(0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
hackAnalyzeThreads : function(ip, hackAmount) {
|
hackAnalyzeThreads : function(ip, hackAmount) {
|
||||||
updateDynamicRam("hackAnalyzeThreads", getRamCost("hackAnalyzeThreads"));
|
updateDynamicRam("hackAnalyzeThreads", getRamCost("hackAnalyzeThreads"));
|
||||||
@ -1686,8 +1714,6 @@ function NetscriptFunctions(workerScript) {
|
|||||||
checkTixApiAccess("buyStock");
|
checkTixApiAccess("buyStock");
|
||||||
const stock = getStockFromSymbol(symbol, "buyStock");
|
const stock = getStockFromSymbol(symbol, "buyStock");
|
||||||
const res = buyStock(stock, shares, workerScript, { rerenderFn: displayStockMarketContent });
|
const res = buyStock(stock, shares, workerScript, { rerenderFn: displayStockMarketContent });
|
||||||
console.log(stock);
|
|
||||||
console.log(res);
|
|
||||||
return res ? stock.price : 0;
|
return res ? stock.price : 0;
|
||||||
},
|
},
|
||||||
sellStock: function(symbol, shares) {
|
sellStock: function(symbol, shares) {
|
||||||
@ -2684,6 +2710,47 @@ function NetscriptFunctions(workerScript) {
|
|||||||
workerScript.log("purchaseProgram", `You have purchased the '${item.program}' program. The new program can be found on your home computer.`);
|
workerScript.log("purchaseProgram", `You have purchased the '${item.program}' program. The new program can be found on your home computer.`);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
connect: function(hostname) {
|
||||||
|
if (!hostname) {
|
||||||
|
throw makeRuntimeErrorMsg("connect", `Invalid hostname: '${hostname}'`);
|
||||||
|
}
|
||||||
|
|
||||||
|
let target = getServer(hostname);
|
||||||
|
if (target == null) {
|
||||||
|
throw makeRuntimeErrorMsg("connect", `Invalid hostname: '${hostname}'`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(hostname === 'home') {
|
||||||
|
Player.getCurrentServer().isConnectedTo = false;
|
||||||
|
Player.currentServer = Player.getHomeComputer().ip;
|
||||||
|
Player.getCurrentServer().isConnectedTo = true;
|
||||||
|
Terminal.currDir = "/";
|
||||||
|
Terminal.resetTerminalInput(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const server = Player.getCurrentServer();
|
||||||
|
for (let i = 0; i < server.serversOnNetwork.length; i++) {
|
||||||
|
const other = getServerOnNetwork(server, i);
|
||||||
|
if (other.ip == hostname || other.hostname == hostname) {
|
||||||
|
Player.getCurrentServer().isConnectedTo = false;
|
||||||
|
Player.currentServer = target.ip;
|
||||||
|
Player.getCurrentServer().isConnectedTo = true;
|
||||||
|
Terminal.currDir = "/";
|
||||||
|
Terminal.resetTerminalInput(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
manualHack: function() {
|
||||||
|
updateDynamicRam("manualHack", getRamCost("manualHack"));
|
||||||
|
checkSingularityAccess("manualHack", 1);
|
||||||
|
const server = Player.getCurrentServer();
|
||||||
|
return hack(server.hostname, true);
|
||||||
|
},
|
||||||
getStats: function() {
|
getStats: function() {
|
||||||
updateDynamicRam("getStats", getRamCost("getStats"));
|
updateDynamicRam("getStats", getRamCost("getStats"));
|
||||||
checkSingularityAccess("getStats", 1);
|
checkSingularityAccess("getStats", 1);
|
||||||
|
@ -163,7 +163,7 @@ function startNetscript1Script(workerScript) {
|
|||||||
if (typeof entry === "function") {
|
if (typeof entry === "function") {
|
||||||
//Async functions need to be wrapped. See JS-Interpreter documentation
|
//Async functions need to be wrapped. See JS-Interpreter documentation
|
||||||
if (name === "hack" || name === "grow" || name === "weaken" || name === "sleep" ||
|
if (name === "hack" || name === "grow" || name === "weaken" || name === "sleep" ||
|
||||||
name === "prompt") {
|
name === "prompt" || name === "manualHack") {
|
||||||
let tempWrapper = function() {
|
let tempWrapper = function() {
|
||||||
let fnArgs = [];
|
let fnArgs = [];
|
||||||
|
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
import { Factions } from "../../Faction/Factions";
|
import { Factions } from "../../Faction/Factions";
|
||||||
import { Gang } from "../../Gang";
|
import { Gang } from "../../Gang";
|
||||||
import { SourceFileFlags } from "../../SourceFile/SourceFileFlags";
|
import { SourceFileFlags } from "../../SourceFile/SourceFileFlags";
|
||||||
|
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
|
||||||
|
|
||||||
// Amount of negative karma needed to manage a gang in BitNodes other than 2
|
// Amount of negative karma needed to manage a gang in BitNodes other than 2
|
||||||
const GangKarmaRequirement = -54000;
|
const GangKarmaRequirement = -54000;
|
||||||
|
|
||||||
export function canAccessGang() {
|
export function canAccessGang() {
|
||||||
if (this.bitNodeN === 2) { return true; }
|
if (this.bitNodeN === 2) { return true; }
|
||||||
|
|
||||||
if (SourceFileFlags[2] <= 0) { return false; }
|
if (SourceFileFlags[2] <= 0) { return false; }
|
||||||
|
|
||||||
return (this.karma <= GangKarmaRequirement);
|
return (this.karma <= BitNodeMultipliers.GangKarmaRequirement*GangKarmaRequirement);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getGangFaction() {
|
export function getGangFaction() {
|
||||||
|
@ -113,6 +113,10 @@ function isNumber(str) {
|
|||||||
return !isNaN(str) && !isNaN(parseFloat(str));
|
return !isNaN(str) && !isNaN(parseFloat(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getTerminalInput() {
|
||||||
|
return document.getElementById("terminal-input-text-box").value;
|
||||||
|
}
|
||||||
|
|
||||||
// Defines key commands in terminal
|
// Defines key commands in terminal
|
||||||
$(document).keydown(function(event) {
|
$(document).keydown(function(event) {
|
||||||
// Terminal
|
// Terminal
|
||||||
@ -122,7 +126,7 @@ $(document).keydown(function(event) {
|
|||||||
|
|
||||||
if (event.keyCode === KEY.ENTER) {
|
if (event.keyCode === KEY.ENTER) {
|
||||||
event.preventDefault(); // Prevent newline from being entered in Script Editor
|
event.preventDefault(); // Prevent newline from being entered in Script Editor
|
||||||
const command = terminalInput.value;
|
const command = getTerminalInput();
|
||||||
const dir = Terminal.currDir;
|
const dir = Terminal.currDir;
|
||||||
post(
|
post(
|
||||||
"<span class='prompt'>[" +
|
"<span class='prompt'>[" +
|
||||||
@ -344,22 +348,36 @@ let Terminal = {
|
|||||||
// Excludes the trailing forward slash
|
// Excludes the trailing forward slash
|
||||||
currDir: "/",
|
currDir: "/",
|
||||||
|
|
||||||
resetTerminalInput: function() {
|
resetTerminalInput: function(keepInput=false) {
|
||||||
|
let input = "";
|
||||||
|
if(keepInput) {
|
||||||
|
input = getTerminalInput();
|
||||||
|
}
|
||||||
const dir = Terminal.currDir;
|
const dir = Terminal.currDir;
|
||||||
if (FconfSettings.WRAP_INPUT) {
|
if (FconfSettings.WRAP_INPUT) {
|
||||||
document.getElementById("terminal-input-td").innerHTML =
|
document.getElementById("terminal-input-td").innerHTML =
|
||||||
`<div id='terminal-input-header' class='prompt'>[${Player.getCurrentServer().hostname} ~${dir}]$ </div>` +
|
`<div id='terminal-input-header' class='prompt'>[${Player.getCurrentServer().hostname} ~${dir}]$ </div>` +
|
||||||
'<textarea type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1"/>';
|
`<textarea type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1" value=\"${input}\"/>`;
|
||||||
|
|
||||||
// Auto re-size the line element as it wraps
|
// Auto re-size the line element as it wraps
|
||||||
autosize(document.getElementById("terminal-input-text-box"));
|
autosize(document.getElementById("terminal-input-text-box"));
|
||||||
} else {
|
} else {
|
||||||
document.getElementById("terminal-input-td").innerHTML =
|
document.getElementById("terminal-input-td").innerHTML =
|
||||||
`<div id='terminal-input-header' class='prompt'>[${Player.getCurrentServer().hostname} ~${dir}]$ </div>` +
|
`<div id='terminal-input-header' class='prompt'>[${Player.getCurrentServer().hostname} ~${dir}]$ </div>` +
|
||||||
`<input type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1"/>`;
|
`<input type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1" value=\"${input}\"/>`;
|
||||||
}
|
}
|
||||||
var hdr = document.getElementById("terminal-input-header");
|
const hdr = document.getElementById("terminal-input-header");
|
||||||
hdr.style.display = "inline";
|
hdr.style.display = "inline";
|
||||||
|
|
||||||
|
const terminalInput = document.getElementById("terminal-input-text-box");
|
||||||
|
if (typeof terminalInput.selectionStart == "number") {
|
||||||
|
terminalInput.selectionStart = terminalInput.selectionEnd = terminalInput.value.length;
|
||||||
|
} else if (typeof terminalInput.createTextRange != "undefined") {
|
||||||
|
terminalInput.focus();
|
||||||
|
var range = el.createTextRange();
|
||||||
|
range.collapse(false);
|
||||||
|
range.select();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
modifyInput: function(mod) {
|
modifyInput: function(mod) {
|
||||||
|
@ -134,7 +134,7 @@ $(document).keydown(function(e) {
|
|||||||
} catch(e) {}
|
} catch(e) {}
|
||||||
|
|
||||||
if (!Player.isWorking && !redPillFlag && !inMission && !cinematicTextFlag) {
|
if (!Player.isWorking && !redPillFlag && !inMission && !cinematicTextFlag) {
|
||||||
if (e.keyCode == 84 && e.altKey) {
|
if (e.keyCode == KEY.T && e.altKey) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
Engine.loadTerminalContent();
|
Engine.loadTerminalContent();
|
||||||
} else if (e.keyCode === KEY.C && e.altKey) {
|
} else if (e.keyCode === KEY.C && e.altKey) {
|
||||||
@ -174,6 +174,12 @@ $(document).keydown(function(e) {
|
|||||||
} else if (e.keyCode === KEY.U && e.altKey) {
|
} else if (e.keyCode === KEY.U && e.altKey) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
Engine.loadTutorialContent();
|
Engine.loadTutorialContent();
|
||||||
|
} else if (e.keyCode === KEY.B && e.altKey) {
|
||||||
|
e.preventDefault();
|
||||||
|
Engine.loadBladeburnerContent();
|
||||||
|
} else if (e.keyCode === KEY.G && e.altKey) {
|
||||||
|
e.preventDefault();
|
||||||
|
Engine.loadGangContent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,30 +4,48 @@ import { IMap } from "../../src/types";
|
|||||||
* Keyboard key codes
|
* Keyboard key codes
|
||||||
*/
|
*/
|
||||||
export const KEY: IMap<number> = {
|
export const KEY: IMap<number> = {
|
||||||
A: 65,
|
CTRL: 17,
|
||||||
B: 66,
|
DOWNARROW: 40,
|
||||||
C: 67,
|
ENTER: 13,
|
||||||
CTRL: 17,
|
ESC: 27,
|
||||||
D: 68,
|
TAB: 9,
|
||||||
DOWNARROW: 40,
|
UPARROW: 38,
|
||||||
E: 69,
|
|
||||||
ENTER: 13,
|
"0": 48,
|
||||||
ESC: 27,
|
"1": 49,
|
||||||
F: 70,
|
"2": 50,
|
||||||
H: 72,
|
"3": 51,
|
||||||
J: 74,
|
"4": 52,
|
||||||
K: 75,
|
"5": 53,
|
||||||
L: 76,
|
"6": 54,
|
||||||
M: 77,
|
"7": 55,
|
||||||
N: 78,
|
"8": 56,
|
||||||
O: 79,
|
"9": 57,
|
||||||
P: 80,
|
|
||||||
R: 82,
|
A: 65,
|
||||||
S: 83,
|
B: 66,
|
||||||
TAB: 9,
|
C: 67,
|
||||||
U: 85,
|
D: 68,
|
||||||
UPARROW: 38,
|
E: 69,
|
||||||
W: 87,
|
F: 70,
|
||||||
"1": 49,
|
G: 71,
|
||||||
"2": 50,
|
H: 72,
|
||||||
|
I: 73,
|
||||||
|
J: 74,
|
||||||
|
K: 75,
|
||||||
|
L: 76,
|
||||||
|
M: 77,
|
||||||
|
N: 78,
|
||||||
|
O: 79,
|
||||||
|
P: 80,
|
||||||
|
Q: 81,
|
||||||
|
R: 82,
|
||||||
|
S: 83,
|
||||||
|
T: 84,
|
||||||
|
U: 85,
|
||||||
|
V: 86,
|
||||||
|
W: 87,
|
||||||
|
X: 88,
|
||||||
|
Y: 89,
|
||||||
|
Z: 90,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user