* BladeBurner
    * nerfed int exp gained.

    Documentation
    * purchaseServer specifies what happens on failure.
    * Fixed typo in recommended bitnode page.
    * Removed misleading ram requirements for hacking factions.

    Netscript
    * growthAnalyze handles Infinity correctly.

    Misc.
    * Faction Augmentation will list how much reputation is required even after
      that goal has been reached.
    * Removed dollar sign in travel agency confirmation.
    * Fixed typo in alpha-omega.lit

* the game save text no longer obstruct the save game and options button

* the text editors now remember where your cursor was and restores it when loading the same script again.

* v0.51.4
This commit is contained in:
hydroflame 2021-04-19 21:26:51 -04:00 committed by GitHub
parent 4743801e86
commit 135df8703c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 265 additions and 83 deletions

@ -228,14 +228,15 @@ a:visited {
} }
.status-text { .status-text {
display: inline-block;
position: fixed;
z-index: 2; z-index: 2;
-webkit-animation: status-text 3s 1; -webkit-animation: status-text 3s 1;
} }
#status-text-container { #status-text-container {
background-color: transparent; background-color: transparent;
position:absolute;
top:0;
left:50%;
} }
#status-text { #status-text {

File diff suppressed because one or more lines are too long

@ -1,2 +1,2 @@
!function(n){function t(t){for(var e,i,f=t[0],c=t[1],l=t[2],p=0,s=[];p<f.length;p++)i=f[p],u[i]&&s.push(u[i][0]),u[i]=0;for(e in c)Object.prototype.hasOwnProperty.call(c,e)&&(n[e]=c[e]);for(a&&a(t);s.length;)s.shift()();return r.push.apply(r,l||[]),o()}function o(){for(var n,t=0;t<r.length;t++){for(var o=r[t],e=!0,f=1;f<o.length;f++){var c=o[f];0!==u[c]&&(e=!1)}e&&(r.splice(t--,1),n=i(i.s=o[0]))}return n}var e={},u={1:0},r=[];function i(t){if(e[t])return e[t].exports;var o=e[t]={i:t,l:!1,exports:{}};return n[t].call(o.exports,o,o.exports,i),o.l=!0,o.exports}i.m=n,i.c=e,i.d=function(n,t,o){i.o(n,t)||Object.defineProperty(n,t,{enumerable:!0,get:o})},i.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},i.t=function(n,t){if(1&t&&(n=i(n)),8&t)return n;if(4&t&&"object"==typeof n&&n&&n.__esModule)return n;var o=Object.create(null);if(i.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:n}),2&t&&"string"!=typeof n)for(var e in n)i.d(o,e,function(t){return n[t]}.bind(null,e));return o},i.n=function(n){var t=n&&n.__esModule?function(){return n.default}:function(){return n};return i.d(t,"a",t),t},i.o=function(n,t){return Object.prototype.hasOwnProperty.call(n,t)},i.p="";var f=window.webpackJsonp=window.webpackJsonp||[],c=f.push.bind(f);f.push=t,f=f.slice();for(var l=0;l<f.length;l++)t(f[l]);var a=c;r.push([400,0]),o()}({343:function(n,t,o){},345:function(n,t,o){},347:function(n,t,o){},349:function(n,t,o){},351:function(n,t,o){},353:function(n,t,o){},355:function(n,t,o){},357:function(n,t,o){},359:function(n,t,o){},361:function(n,t,o){},363:function(n,t,o){},365:function(n,t,o){},367:function(n,t,o){},369:function(n,t,o){},371:function(n,t,o){},373:function(n,t,o){},375:function(n,t,o){},377:function(n,t,o){},379:function(n,t,o){},381:function(n,t,o){},383:function(n,t,o){},385:function(n,t,o){},387:function(n,t,o){},389:function(n,t,o){},391:function(n,t,o){},393:function(n,t,o){},395:function(n,t,o){},397:function(n,t,o){},400:function(n,t,o){"use strict";o.r(t);o(399),o(397),o(395),o(393),o(391),o(389),o(387),o(385),o(383),o(381),o(379),o(377),o(375),o(373),o(371),o(369),o(367),o(365),o(363),o(361),o(359),o(357),o(355),o(353),o(351),o(349),o(347),o(345),o(343)}}); !function(n){function t(t){for(var e,i,f=t[0],c=t[1],l=t[2],p=0,s=[];p<f.length;p++)i=f[p],u[i]&&s.push(u[i][0]),u[i]=0;for(e in c)Object.prototype.hasOwnProperty.call(c,e)&&(n[e]=c[e]);for(a&&a(t);s.length;)s.shift()();return r.push.apply(r,l||[]),o()}function o(){for(var n,t=0;t<r.length;t++){for(var o=r[t],e=!0,f=1;f<o.length;f++){var c=o[f];0!==u[c]&&(e=!1)}e&&(r.splice(t--,1),n=i(i.s=o[0]))}return n}var e={},u={1:0},r=[];function i(t){if(e[t])return e[t].exports;var o=e[t]={i:t,l:!1,exports:{}};return n[t].call(o.exports,o,o.exports,i),o.l=!0,o.exports}i.m=n,i.c=e,i.d=function(n,t,o){i.o(n,t)||Object.defineProperty(n,t,{enumerable:!0,get:o})},i.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},i.t=function(n,t){if(1&t&&(n=i(n)),8&t)return n;if(4&t&&"object"==typeof n&&n&&n.__esModule)return n;var o=Object.create(null);if(i.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:n}),2&t&&"string"!=typeof n)for(var e in n)i.d(o,e,function(t){return n[t]}.bind(null,e));return o},i.n=function(n){var t=n&&n.__esModule?function(){return n.default}:function(){return n};return i.d(t,"a",t),t},i.o=function(n,t){return Object.prototype.hasOwnProperty.call(n,t)},i.p="";var f=window.webpackJsonp=window.webpackJsonp||[],c=f.push.bind(f);f.push=t,f=f.slice();for(var l=0;l<f.length;l++)t(f[l]);var a=c;r.push([401,0]),o()}({344:function(n,t,o){},346:function(n,t,o){},348:function(n,t,o){},350:function(n,t,o){},352:function(n,t,o){},354:function(n,t,o){},356:function(n,t,o){},358:function(n,t,o){},360:function(n,t,o){},362:function(n,t,o){},364:function(n,t,o){},366:function(n,t,o){},368:function(n,t,o){},370:function(n,t,o){},372:function(n,t,o){},374:function(n,t,o){},376:function(n,t,o){},378:function(n,t,o){},380:function(n,t,o){},382:function(n,t,o){},384:function(n,t,o){},386:function(n,t,o){},388:function(n,t,o){},390:function(n,t,o){},392:function(n,t,o){},394:function(n,t,o){},396:function(n,t,o){},398:function(n,t,o){},401:function(n,t,o){"use strict";o.r(t);o(400),o(398),o(396),o(394),o(392),o(390),o(388),o(386),o(384),o(382),o(380),o(378),o(376),o(374),o(372),o(370),o(368),o(366),o(364),o(362),o(360),o(358),o(356),o(354),o(352),o(350),o(348),o(346),o(344)}});
//# sourceMappingURL=engineStyle.bundle.js.map //# sourceMappingURL=engineStyle.bundle.js.map

@ -250,13 +250,14 @@ a:visited {
opacity: 0; } } opacity: 0; } }
.status-text { .status-text {
display: inline-block;
position: fixed;
z-index: 2; z-index: 2;
-webkit-animation: status-text 3s 1; } -webkit-animation: status-text 3s 1; }
#status-text-container { #status-text-container {
background-color: transparent; } background-color: transparent;
position: absolute;
top: 0;
left: 50%; }
#status-text { #status-text {
background-color: transparent; background-color: transparent;

26
dist/vendor.bundle.js vendored

File diff suppressed because one or more lines are too long

@ -75,13 +75,10 @@ List of Factions and their Requirements
| | | | * Ishima | | | | | * Ishima |
+---------------------+----------------+-----------------------------------------+-------------------------------+ +---------------------+----------------+-----------------------------------------+-------------------------------+
| Hacking | NiteSec | * Hack avmnite-02h manually | | | Hacking | NiteSec | * Hack avmnite-02h manually | |
| Groups | | * Home Computer RAM of at least 32GB | |
+ +----------------+-----------------------------------------+-------------------------------+ + +----------------+-----------------------------------------+-------------------------------+
| | The Black Hand | * Hack I.I.I.I manually | | | | The Black Hand | * Hack I.I.I.I manually | |
| | | * Home Computer RAM of at least 64GB | |
+ +----------------+-----------------------------------------+-------------------------------+ + +----------------+-----------------------------------------+-------------------------------+
| | Bitrunners | * Hack run4theh111z manually | | | | Bitrunners | * Hack run4theh111z manually | |
| | | * Home Computer RAM of at least 128GB | |
+---------------------+----------------+-----------------------------------------+-------------------------------+ +---------------------+----------------+-----------------------------------------+-------------------------------+
| Megacorporations | ECorp | * Have 200k reputation with | | | Megacorporations | ECorp | * Have 200k reputation with | |
| | | the Corporation | | | | | the Corporation | |

@ -3,6 +3,41 @@
Changelog Changelog
========= =========
v0.51.4 - 2021-04-19 Manual hacking is fun (hydroflame)
-------------------------------------------------------
Manual hacking
* These bonus require an install or a soft reset to take effect.
* Manual hacking gyms and university gives you a 10% discount.
* Manual hacking a corporation server decreases the penalty for leaving work
early.
BladeBurner
* nerfed int exp gained.
Documentation
* purchaseServer specifies what happens on failure.
* Fixed typo in recommended bitnode page.
* Removed misleading ram requirements for hacking factions.
Netscript
* growthAnalyze handles Infinity correctly.
Misc.
* Faction Augmentation will list how much reputation is required even after
that goal has been reached.
* Removed dollar sign in travel agency confirmation dialog box.
* Fixed typo in alpha-omega.lit
* the 'Game saved!' text no longer blocks the save game/options button.
* The text editor now remembers the location of your cursor and restores it.
* skills are recalculated instantly.
* Fix typo in Operation Zero description.
v0.51.3 - 2021-04-16 Y'all broke it on the first day (hydroflame) v0.51.3 - 2021-04-16 Y'all broke it on the first day (hydroflame)
----------------------------------------------------------------- -----------------------------------------------------------------

@ -66,7 +66,7 @@ documentation_title = '{0} Documentation'.format(project)
# The short X.Y version. # The short X.Y version.
version = '0.51' version = '0.51'
# The full version, including alpha/beta/rc tags. # The full version, including alpha/beta/rc tags.
release = '0.51.3' release = '0.51.4'
# 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.

@ -278,6 +278,7 @@ Description
hashes, which can be spent on a variety of different upgrades. hashes, which can be spent on a variety of different upgrades.
In this BitNode: In this BitNode:
* Your stats are significantly decreased * Your stats are significantly decreased
* You cannnot purchase additional servers * You cannnot purchase additional servers
* Hacking is significantly less profitable * Hacking is significantly less profitable
@ -312,6 +313,7 @@ Description
2. Duplicate Sleeves: Duplicate your consciousness into Synthoids, allowing you to perform different tasks synchronously 2. Duplicate Sleeves: Duplicate your consciousness into Synthoids, allowing you to perform different tasks synchronously
In this BitNode: In this BitNode:
* Your stats are significantly decreased * Your stats are significantly decreased
* All methods of gaining money are half as profitable (except Stock Market) * All methods of gaining money are half as profitable (except Stock Market)
* Purchased servers are more expensive, have less max RAM, and a lower maximum limit * Purchased servers are more expensive, have less max RAM, and a lower maximum limit

@ -7,7 +7,7 @@ purchaseServer() Netscript Function
:param string hostname: Hostname of the purchased server. :param string hostname: Hostname of the purchased server.
:param number ram: Amount of RAM of the purchased server. Must be a power of :param number ram: Amount of RAM of the purchased server. Must be a power of
2. Maximum value of :doc:`getPurchasedServerMaxRam<getPurchasedServerMaxRam>` 2. Maximum value of :doc:`getPurchasedServerMaxRam<getPurchasedServerMaxRam>`
:returns: The hostname of the newly purchased server. :returns: The hostname of the newly purchased server. Empty string on failure.
Purchased a server with the specified hostname and amount of RAM. Purchased a server with the specified hostname and amount of RAM.

@ -381,7 +381,7 @@
<!-- Status text --> <!-- Status text -->
<div id="status-text-container"> <div id="status-text-container">
<p id="status-text"> </p> <p id="status-text"></p>
</div> </div>
<!-- Game Options --> <!-- Game Options -->

@ -121,5 +121,5 @@
"watch": "webpack --watch --mode production", "watch": "webpack --watch --mode production",
"watch:dev": "webpack --watch --mode development" "watch:dev": "webpack --watch --mode development"
}, },
"version": "0.51.3" "version": "0.51.4"
} }

@ -89,7 +89,7 @@ export let AugmentationNames: IMap<string> = {
BrachiBlades: "BrachiBlades", BrachiBlades: "BrachiBlades",
BionicArms: "Bionic Arms", BionicArms: "Bionic Arms",
SNA: "Social Negotiation Assistant (S.N.A)", SNA: "Social Negotiation Assistant (S.N.A)",
HydroflameLeftArm: "Hydroflame left arm", HydroflameLeftArm: "Hydroflame Left Arm",
EsperEyewear: "EsperTech Bladeburner Eyewear", EsperEyewear: "EsperTech Bladeburner Eyewear",
EMS4Recombination: "EMS-4 Recombination", EMS4Recombination: "EMS-4 Recombination",
OrionShoulder: "ORION-MKIV Shoulder", OrionShoulder: "ORION-MKIV Shoulder",

@ -1069,7 +1069,11 @@ Bladeburner.prototype.gainActionStats = function(action, success) {
Player.gainDexterityExp(unweightedGain * action.weights.dex * Player.dexterity_exp_mult * skillMult); Player.gainDexterityExp(unweightedGain * action.weights.dex * Player.dexterity_exp_mult * skillMult);
Player.gainAgilityExp(unweightedGain * action.weights.agi * Player.agility_exp_mult * skillMult); Player.gainAgilityExp(unweightedGain * action.weights.agi * Player.agility_exp_mult * skillMult);
Player.gainCharismaExp(unweightedGain * action.weights.cha * Player.charisma_exp_mult * skillMult); Player.gainCharismaExp(unweightedGain * action.weights.cha * Player.charisma_exp_mult * skillMult);
Player.gainIntelligenceExp(unweightedIntGain * action.weights.int * skillMult); let intExp = unweightedIntGain * action.weights.int * skillMult;
if (intExp > 1) {
intExp = Math.pow(intExp, 0.8);
}
Player.gainIntelligenceExp(intExp);
} }
Bladeburner.prototype.randomEvent = function() { Bladeburner.prototype.randomEvent = function() {

@ -21,7 +21,7 @@ export const BlackOperations: IMap<BlackOperation> = {};
BlackOperations["Operation Zero"] = new BlackOperation({ BlackOperations["Operation Zero"] = new BlackOperation({
name:"Operation Zero", name:"Operation Zero",
desc:"AeroCorp is one of the world's largest defense contractors. " + desc:"AeroCorp is one of the world's largest defense contractors. " +
"It's leader, Steve Watataki, is thought to be a supporter of " + "Its leader, Steve Watataki, is thought to be a supporter of " +
"Synthoid rights. He must be removed.<br><br>" + "Synthoid rights. He must be removed.<br><br>" +
"The goal of Operation Zero is to covertly infiltrate AeroCorp and " + "The goal of Operation Zero is to covertly infiltrate AeroCorp and " +
"uncover any incriminating evidence or " + "uncover any incriminating evidence or " +

@ -6,7 +6,7 @@
import { IMap } from "./types"; import { IMap } from "./types";
export let CONSTANTS: IMap<any> = { export let CONSTANTS: IMap<any> = {
Version: "0.51.3", Version: "0.51.4",
/** 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,39 +228,34 @@ export let CONSTANTS: IMap<any> = {
LatestUpdate: LatestUpdate:
` `
v0.51.3 - 2021-04-16 Y'all broke it on the first day (hydroflame) v0.51.4 - 2021-04-19 Manual hacking is fun (hydroflame)
------- -------
Passive faction reputation Manual hacking
* Reworked, from 1 rep / 2 minute. Now is a complicated percentage of the * These bonus require an install or a soft reset to take effect.
reputation you'd gain working for them. It's not op but it feels a bit * Manual hacking gyms and university gives you a 10% discount.
more useful. * Manual hacking a corporation server decreases the penalty for leaving work
early.
Netscript BladeBurner
* print/tprint now take any number of arguments. * nerfed int exp gained.
* print/tprint will now print object as json.
* print/tprint now handle passing in an undefined argument properly.
Casino
* Cannot bet negative money anymore.
* Roulette max bet is a bit higher.
* Coin Flip has a small cooldown.
* All buttons reject unstrusted mouse events.
Documentation Documentation
* Changed a message that said nsjs only works on Chrome. * purchaseServer specifies what happens on failure.
* Fixed typo in recommended bitnode page.
* Removed misleading ram requirements for hacking factions.
Bugfix Netscript
* hacknet.maxNumNodes now works for both nodes and servers. * growthAnalyze handles Infinity correctly.
* Fixed a bug where the popup boxes would contain data from previous popup boxes.
* .js files will also have the export async function boilerplate.
Misc. Misc.
* turned off autocomplete for the terminal text input. * Faction Augmentation will list how much reputation is required even after
* Fixed an issue on Windows+Firefox where pressing up on the terminal would that goal has been reached.
bring the cursor to the begining of the line. (Issue #836) * Removed dollar sign in travel agency confirmation dialog box.
* Hacknet node names is easier to handle for screen readers. * Fixed typo in alpha-omega.lit
* Money spent on classes is now tracked independently of work money. * the 'Game saved!' text no longer blocks the save game/options button.
* running coding contract from the terminal will display its name. * The text editor now remembers the location of your cursor and restores it.
* skills are recalculated instantly.
* Fix typo in Operation Zero description.
` `
} }

@ -118,7 +118,7 @@ export class PurchaseableAugmentation extends React.Component<IProps, any> {
} else if (this.aug.name !== AugmentationNames.NeuroFluxGovernor && (this.aug.owned || this.owned())) { } else if (this.aug.name !== AugmentationNames.NeuroFluxGovernor && (this.aug.owned || this.owned())) {
disabled = true; disabled = true;
} else if (this.hasReputation()) { } else if (this.hasReputation()) {
status = <>UNLOCKED - {Money(moneyCost)}</>; status = <>UNLOCKED (at {Reputation(repCost)} faction reputation) - {Money(moneyCost)}</>;
} else { } else {
disabled = true; disabled = true;
status = <>LOCKED (Requires {Reputation(repCost)} faction reputation - {Money(moneyCost)})</>; status = <>LOCKED (Requires {Reputation(repCost)} faction reputation - {Money(moneyCost)})</>;

@ -148,7 +148,7 @@ export const Literatures: IMap<Literature> = {};
"will be our people, and we will be with them as their Gods. We will wipe away every tear from their eyes, and death " + "will be our people, and we will be with them as their Gods. We will wipe away every tear from their eyes, and death " +
"shall be no more, neither shall there be mourning, nor crying, nor pain anymore, for the former things " + "shall be no more, neither shall there be mourning, nor crying, nor pain anymore, for the former things " +
"have passed away.'<br><br>" + "have passed away.'<br><br>" +
"And once were were seated on the throne we said 'Behold, I am making all things new.' " + "And once we were seated on the throne we said 'Behold, I am making all things new.' " +
"Also we said, 'Write this down, for these words are trustworthy and true.' And we said to you, " + "Also we said, 'Write this down, for these words are trustworthy and true.' And we said to you, " +
"'It is done! I am the Alpha and the Omega, the beginning and the end. To the thirsty I will give from the spring " + "'It is done! I am the Alpha and the Omega, the beginning and the end. To the thirsty I will give from the spring " +
"of the water of life without payment. The one who conquers will have this heritage, and we will be his God and " + "of the water of life without payment. The one who conquers will have this heritage, and we will be his God and " +

@ -78,7 +78,7 @@ export function createTravelPopup(destination: CityName, travelFn: TravelFunctio
return false; return false;
}); });
yesNoBoxCreate(<span>Would you like to travel to ${destination}? The trip will yesNoBoxCreate(<span>Would you like to travel to {destination}? The trip will
cost {Money(cost)}.</span>); cost {Money(cost)}.</span>);
} }

@ -7,8 +7,11 @@ import * as React from "react";
import { Location } from "../Location"; import { Location } from "../Location";
import { CONSTANTS } from "../../Constants"; import { CONSTANTS } from "../../Constants";
import { IPlayer } from "../../PersonObjects/IPlayer"; import { IPlayer } from "../../PersonObjects/IPlayer";
import { getServer } from "../../Server/ServerHelpers";
import { Server } from "../../Server/Server";
import { SpecialServerIps } from "../../Server/SpecialServerIps";
import { numeralWrapper } from "../../ui/numeralFormat"; import { numeralWrapper } from "../../ui/numeralFormat";
import { StdButton } from "../../ui/React/StdButton"; import { StdButton } from "../../ui/React/StdButton";
@ -34,11 +37,22 @@ export class GymLocation extends React.Component<IProps, any> {
this.trainDefense = this.trainDefense.bind(this); this.trainDefense = this.trainDefense.bind(this);
this.trainDexterity = this.trainDexterity.bind(this); this.trainDexterity = this.trainDexterity.bind(this);
this.trainAgility = this.trainAgility.bind(this); this.trainAgility = this.trainAgility.bind(this);
this.calculateCost = this.calculateCost.bind(this);
}
calculateCost(): number {
const ip = SpecialServerIps.getIp(this.props.loc.name);
console.log(`ip: ${ip}`);
const server = getServer(ip);
if(server == null || !server.hasOwnProperty('manuallyHacked')) return this.props.loc.costMult;
const discount = (server as Server).manuallyHacked? 0.9 : 1;
return this.props.loc.costMult * discount;
} }
train(stat: string) { train(stat: string) {
const loc = this.props.loc; const loc = this.props.loc;
this.props.p.startClass(loc.costMult, loc.expMult, stat); this.props.p.startClass(this.calculateCost(), loc.expMult, stat);
} }
trainStrength() { trainStrength() {
@ -58,9 +72,7 @@ export class GymLocation extends React.Component<IProps, any> {
} }
render() { render() {
const costMult: number = this.props.loc.costMult; const cost = CONSTANTS.ClassGymBaseCost * this.calculateCost();
const cost = CONSTANTS.ClassGymBaseCost * costMult;
return ( return (
<div> <div>

@ -9,6 +9,9 @@ import { Location } from "../Location";
import { CONSTANTS } from "../../Constants"; import { CONSTANTS } from "../../Constants";
import { IPlayer } from "../../PersonObjects/IPlayer"; import { IPlayer } from "../../PersonObjects/IPlayer";
import { getServer } from "../../Server/ServerHelpers";
import { Server } from "../../Server/Server";
import { SpecialServerIps } from "../../Server/SpecialServerIps";
import { numeralWrapper } from "../../ui/numeralFormat"; import { numeralWrapper } from "../../ui/numeralFormat";
import { StdButton } from "../../ui/React/StdButton"; import { StdButton } from "../../ui/React/StdButton";
@ -37,11 +40,22 @@ export class UniversityLocation extends React.Component<IProps, any> {
this.algorithms = this.algorithms.bind(this); this.algorithms = this.algorithms.bind(this);
this.management = this.management.bind(this); this.management = this.management.bind(this);
this.leadership = this.leadership.bind(this); this.leadership = this.leadership.bind(this);
this.calculateCost = this.calculateCost.bind(this);
}
calculateCost(): number {
const ip = SpecialServerIps.getIp(this.props.loc.name);
console.log(`ip: ${ip}`);
const server = getServer(ip);
if(server == null || !server.hasOwnProperty('manuallyHacked')) return this.props.loc.costMult;
const discount = (server as Server).manuallyHacked? 0.9 : 1;
return this.props.loc.costMult * discount;
} }
take(stat: string) { take(stat: string) {
const loc = this.props.loc; const loc = this.props.loc;
this.props.p.startClass(loc.costMult, loc.expMult, stat); this.props.p.startClass(this.calculateCost(), loc.expMult, stat);
} }
study() { study() {
@ -69,7 +83,7 @@ export class UniversityLocation extends React.Component<IProps, any> {
} }
render() { render() {
const costMult: number = this.props.loc.costMult; const costMult: number = this.calculateCost();
const dataStructuresCost = CONSTANTS.ClassDataStructuresBaseCost * costMult; const dataStructuresCost = CONSTANTS.ClassDataStructuresBaseCost * costMult;
const networksCost = CONSTANTS.ClassNetworksBaseCost * costMult; const networksCost = CONSTANTS.ClassNetworksBaseCost * costMult;

@ -924,7 +924,7 @@ function NetscriptFunctions(workerScript) {
// Check argument validity // Check argument validity
const server = safeGetServer(ip, 'growthAnalyze'); const server = safeGetServer(ip, 'growthAnalyze');
if (typeof growth !== "number" || isNaN(growth) || growth < 1) { if (typeof growth !== "number" || isNaN(growth) || growth < 1 || !isFinite(growth)) {
throw makeRuntimeErrorMsg("growthAnalyze", `Invalid argument: growth must be numeric and >= 1, is ${growth}.`); throw makeRuntimeErrorMsg("growthAnalyze", `Invalid argument: growth must be numeric and >= 1, is ${growth}.`);
} }
@ -2037,7 +2037,7 @@ function NetscriptFunctions(workerScript) {
const cost = getPurchaseServerCost(ram); const cost = getPurchaseServerCost(ram);
if (cost === Infinity) { if (cost === Infinity) {
workerScript.log("purchaseServer", `Invalid argument: ram='${ram}'`); workerScript.log("purchaseServer", `Invalid argument: ram='${ram}'`);
return Infinity; return "";
} }
if (Player.money.lt(cost)) { if (Player.money.lt(cost)) {

@ -434,6 +434,8 @@ export function gainHackingExp(exp) {
if(this.hacking_exp < 0) { if(this.hacking_exp < 0) {
this.hacking_exp = 0; this.hacking_exp = 0;
} }
this.hacking_skill = calculateSkillF(this.hacking_exp, this.hacking_mult * BitNodeMultipliers.HackingLevelMultiplier);
} }
export function gainStrengthExp(exp) { export function gainStrengthExp(exp) {
@ -444,6 +446,8 @@ export function gainStrengthExp(exp) {
if(this.strength_exp < 0) { if(this.strength_exp < 0) {
this.strength_exp = 0; this.strength_exp = 0;
} }
this.strength = calculateSkillF(this.strength_exp, this.strength_mult * BitNodeMultipliers.StrengthLevelMultiplier);
} }
export function gainDefenseExp(exp) { export function gainDefenseExp(exp) {
@ -454,6 +458,8 @@ export function gainDefenseExp(exp) {
if(this.defense_exp < 0) { if(this.defense_exp < 0) {
this.defense_exp = 0; this.defense_exp = 0;
} }
this.defense = calculateSkillF(this.defense_exp, this.defense_mult * BitNodeMultipliers.DefenseLevelMultiplier);
} }
export function gainDexterityExp(exp) { export function gainDexterityExp(exp) {
@ -464,6 +470,8 @@ export function gainDexterityExp(exp) {
if(this.dexterity_exp < 0) { if(this.dexterity_exp < 0) {
this.dexterity_exp = 0; this.dexterity_exp = 0;
} }
this.dexterity = calculateSkillF(this.dexterity_exp, this.dexterity_mult * BitNodeMultipliers.DexterityLevelMultiplier);
} }
export function gainAgilityExp(exp) { export function gainAgilityExp(exp) {
@ -474,6 +482,8 @@ export function gainAgilityExp(exp) {
if(this.agility_exp < 0) { if(this.agility_exp < 0) {
this.agility_exp = 0; this.agility_exp = 0;
} }
this.agility = calculateSkillF(this.agility_exp, this.agility_mult * BitNodeMultipliers.AgilityLevelMultiplier);
} }
export function gainCharismaExp(exp) { export function gainCharismaExp(exp) {
@ -484,6 +494,8 @@ export function gainCharismaExp(exp) {
if(this.charisma_exp < 0) { if(this.charisma_exp < 0) {
this.charisma_exp = 0; this.charisma_exp = 0;
} }
this.charisma = calculateSkillF(this.charisma_exp, this.charisma_mult * BitNodeMultipliers.CharismaLevelMultiplier);
} }
export function gainIntelligenceExp(exp) { export function gainIntelligenceExp(exp) {
@ -601,6 +613,17 @@ export function startWork(companyName) {
Engine.loadWorkInProgressContent(); Engine.loadWorkInProgressContent();
} }
export function cancelationPenalty() {
const company = Companies[this.companyName];
const specialIp = SpecialServerIps[this.companyName];
if(specialIp) {
const server = AllServers[specialIp];
if(server && server.manuallyHacked) return 0.75;
}
return 0.5;
}
export function work(numCycles) { export function work(numCycles) {
// Cap the number of cycles being processed to whatever would put you at // Cap the number of cycles being processed to whatever would put you at
// the work time limit (8 hours) // the work time limit (8 hours)
@ -631,6 +654,10 @@ export function work(numCycles) {
const position = this.jobs[this.companyName]; const position = this.jobs[this.companyName];
const penalty = this.cancelationPenalty();
const penaltyString = penalty === 0.5 ? 'half' : 'three quarter'
var elem = document.getElementById("work-in-progress-text"); var elem = document.getElementById("work-in-progress-text");
ReactDOM.render(<> ReactDOM.render(<>
You are currently working as a {position} at {this.companyName} (Current Company Reputation: {Reputation(companyRep)})<br /><br /> You are currently working as a {position} at {this.companyName} (Current Company Reputation: {Reputation(companyRep)})<br /><br />
@ -645,17 +672,17 @@ export function work(numCycles) {
{numeralWrapper.formatExp(this.workAgiExpGained)} ({`${numeralWrapper.formatExp(this.workAgiExpGainRate * CYCLES_PER_SEC)} / sec`}) agility exp <br /><br /> {numeralWrapper.formatExp(this.workAgiExpGained)} ({`${numeralWrapper.formatExp(this.workAgiExpGainRate * CYCLES_PER_SEC)} / sec`}) agility exp <br /><br />
{numeralWrapper.formatExp(this.workChaExpGained)} ({`${numeralWrapper.formatExp(this.workChaExpGainRate * CYCLES_PER_SEC)} / sec`}) charisma exp <br /><br /> {numeralWrapper.formatExp(this.workChaExpGained)} ({`${numeralWrapper.formatExp(this.workChaExpGainRate * CYCLES_PER_SEC)} / sec`}) charisma exp <br /><br />
You will automatically finish after working for 8 hours. You can cancel earlier if you wish, You will automatically finish after working for 8 hours. You can cancel earlier if you wish,
but you will only gain half of the reputation you've earned so far. but you will only gain {penaltyString} of the reputation you've earned so far.
</>, elem); </>, elem);
} }
export function finishWork(cancelled, sing=false) { export function finishWork(cancelled, sing=false) {
//Since the work was cancelled early, player only gains half of what they've earned so far //Since the work was cancelled early, player only gains half of what they've earned so far
if (cancelled) { if (cancelled) {
this.workRepGained /= 2; this.workRepGained *= this.cancelationPenalty();
} }
var company = Companies[this.companyName]; const company = Companies[this.companyName];
company.playerReputation += (this.workRepGained); company.playerReputation += (this.workRepGained);
this.updateSkillLevels(); this.updateSkillLevels();

@ -16,6 +16,7 @@ import {
import { Player } from "../Player"; import { Player } from "../Player";
import { AceEditor } from "../ScriptEditor/Ace"; import { AceEditor } from "../ScriptEditor/Ace";
import { CodeMirrorEditor } from "../ScriptEditor/CodeMirror"; import { CodeMirrorEditor } from "../ScriptEditor/CodeMirror";
import { CursorPositions } from "../ScriptEditor/CursorPositions";
import { AllServers } from "../Server/AllServers"; import { AllServers } from "../Server/AllServers";
import { processSingleServerGrowth } from "../Server/ServerHelpers"; import { processSingleServerGrowth } from "../Server/ServerHelpers";
import { Settings } from "../Settings/Settings"; import { Settings } from "../Settings/Settings";
@ -224,11 +225,13 @@ $(document).keydown(function(e) {
function saveAndCloseScriptEditor() { function saveAndCloseScriptEditor() {
var filename = document.getElementById("script-editor-filename").value; var filename = document.getElementById("script-editor-filename").value;
let code; let code, cursor;
try { try {
code = getCurrentEditor().getCode(); code = getCurrentEditor().getCode();
cursor = getCurrentEditor().getCursor();
CursorPositions.saveCursor(filename, cursor);
} catch(e) { } catch(e) {
dialogBoxCreate("Something went wrong when trying to save (getCurrentEditor().getCode()). Please report to game developer with details"); dialogBoxCreate("Something went wrong when trying to save (getCurrentEditor().getCode() or getCurrentEditor().getCursor()). Please report to game developer with details");
return; return;
} }
@ -282,7 +285,7 @@ function saveAndCloseScriptEditor() {
} }
} else if (isScriptFilename(filename)) { } else if (isScriptFilename(filename)) {
//If the current script already exists on the server, overwrite it //If the current script already exists on the server, overwrite it
for (var i = 0; i < s.scripts.length; i++) { for (let i = 0; i < s.scripts.length; i++) {
if (filename == s.scripts[i].filename) { if (filename == s.scripts[i].filename) {
s.scripts[i].saveScript(getCurrentEditor().getCode(), Player.currentServer, Player.getCurrentServer().scripts); s.scripts[i].saveScript(getCurrentEditor().getCode(), Player.currentServer, Player.getCurrentServer().scripts);
Engine.loadTerminalContent(); Engine.loadTerminalContent();
@ -295,14 +298,14 @@ function saveAndCloseScriptEditor() {
script.saveScript(getCurrentEditor().getCode(), Player.currentServer, Player.getCurrentServer().scripts); script.saveScript(getCurrentEditor().getCode(), Player.currentServer, Player.getCurrentServer().scripts);
s.scripts.push(script); s.scripts.push(script);
} else if (filename.endsWith(".txt")) { } else if (filename.endsWith(".txt")) {
for (var i = 0; i < s.textFiles.length; ++i) { for (let i = 0; i < s.textFiles.length; ++i) {
if (s.textFiles[i].fn === filename) { if (s.textFiles[i].fn === filename) {
s.textFiles[i].write(code); s.textFiles[i].write(code);
Engine.loadTerminalContent(); Engine.loadTerminalContent();
return; return;
} }
} }
var textFile = new TextFile(filename, code); const textFile = new TextFile(filename, code);
s.textFiles.push(textFile); s.textFiles.push(textFile);
} else { } else {
dialogBoxCreate("Invalid filename. Must be either a script (.script) or " + dialogBoxCreate("Invalid filename. Must be either a script (.script) or " +

@ -314,6 +314,14 @@ class AceEditorWrapper extends ScriptEditor {
elem.style.display = "none"; elem.style.display = "none";
} }
} }
getCursor() {
return this.editor.getCursorPosition();
}
setCursor(pos) {
this.editor.gotoLine(pos.row+1, pos.column);
}
} }
export const AceEditor = new AceEditorWrapper(); export const AceEditor = new AceEditorWrapper();

@ -570,6 +570,15 @@ class CodeMirrorEditorWrapper extends ScriptEditor {
elem.style.display = "none"; elem.style.display = "none";
} }
} }
getCursor() {
const c = this.editor.getCursor(); //I need to get the cursor position
return {row: c.line, column: c.ch};
}
setCursor(pos) {
this.editor.setCursor({line: pos.row, ch: pos.column});
}
} }
export const CodeMirrorEditor = new CodeMirrorEditorWrapper(); export const CodeMirrorEditor = new CodeMirrorEditorWrapper();

@ -0,0 +1,29 @@
export type Position = {
row: number;
column: number;
};
export class PositionTracker {
positions: Map<string, Position>;
constructor() {
this.positions = new Map<string, Position>();
}
saveCursor(filename: string, pos: Position) {
this.positions.set(filename, pos);
}
getCursor(filename: string): Position {
const position = this.positions.get(filename);
if (!position) {
return {
row: 0,
column: 0,
};
}
return position;
}
};
export const CursorPositions: PositionTracker = new PositionTracker();

@ -1,3 +1,5 @@
import { CursorPositions } from './CursorPositions';
// Base Script Editor class for the Ace/CodeMirror/etc. wrappers // Base Script Editor class for the Ace/CodeMirror/etc. wrappers
const beautify = require('js-beautify').js_beautify; const beautify = require('js-beautify').js_beautify;
@ -33,6 +35,7 @@ export class ScriptEditor {
if (filename != "") { if (filename != "") {
this.filenameInput.value = filename; this.filenameInput.value = filename;
this.editor.setValue(code); this.editor.setValue(code);
this.setCursor(CursorPositions.getCursor(filename));
} }
this.editor.focus(); this.editor.focus();

@ -90,6 +90,7 @@ export const serverMetadata: IServerMetadata[] = [
min: 1050, min: 1050,
}, },
serverGrowth: 99, serverGrowth: 99,
specialName: LocationName.AevumECorp,
}, },
{ {
hackDifficulty: 99, hackDifficulty: 99,
@ -106,6 +107,7 @@ export const serverMetadata: IServerMetadata[] = [
min: 1100, min: 1100,
}, },
serverGrowth: 99, serverGrowth: 99,
specialName: LocationName.Sector12MegaCorp,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -128,6 +130,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 80, max: 80,
min: 60, min: 60,
}, },
specialName: LocationName.AevumBachmanAndAssociates,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -155,6 +158,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 85, max: 85,
min: 55, min: 55,
}, },
specialName: LocationName.Sector12BladeIndustries,
}, },
{ {
hackDifficulty: 99, hackDifficulty: 99,
@ -175,6 +179,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 95, max: 95,
min: 65, min: 65,
}, },
specialName: LocationName.VolhavenNWO,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -201,6 +206,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 75, max: 75,
min: 45, min: 45,
}, },
specialName: LocationName.AevumClarkeIncorporated,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -231,6 +237,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 99, max: 99,
min: 95, min: 95,
}, },
specialName: LocationName.VolhavenOmniTekIncorporated,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -253,6 +260,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 99, max: 99,
min: 75, min: 75,
}, },
specialName: LocationName.Sector12FourSigma,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -275,6 +283,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 99, max: 99,
min: 90, min: 90,
}, },
specialName: LocationName.ChongqingKuaiGongInternational,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -302,6 +311,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 99, max: 99,
min: 80, min: 80,
}, },
specialName: LocationName.AevumFulcrumTechnologies,
}, },
{ {
hackDifficulty: 99, hackDifficulty: 99,
@ -338,6 +348,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 92, max: 92,
min: 68, min: 68,
}, },
specialName: LocationName.IshimaStormTechnologies,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -360,6 +371,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 73, max: 73,
min: 47, min: 47,
}, },
specialName: LocationName.NewTokyoDefComm,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -409,6 +421,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 80, max: 80,
min: 70, min: 70,
}, },
specialName: LocationName.VolhavenHeliosLabs,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -436,6 +449,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 80, max: 80,
min: 60, min: 60,
}, },
specialName: LocationName.NewTokyoVitaLife,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -458,6 +472,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 95, max: 95,
min: 85, min: 85,
}, },
specialName: LocationName.Sector12IcarusMicrosystems,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -484,6 +499,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 90, max: 90,
min: 80, min: 80,
}, },
specialName: LocationName.Sector12UniversalEnergy,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -586,6 +602,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 90, max: 90,
min: 70, min: 70,
}, },
specialName: LocationName.AevumGalacticCybersystems,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -609,6 +626,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 65, max: 65,
min: 55, min: 55,
}, },
specialName: LocationName.AevumAeroCorp,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -636,6 +654,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 70, max: 70,
min: 60, min: 60,
}, },
specialName: LocationName.VolhavenOmniaCybersystems,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -711,6 +730,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 80, max: 80,
min: 70, min: 70,
}, },
specialName: LocationName.ChongqingSolarisSpaceSystems,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -733,6 +753,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 70, max: 70,
min: 50, min: 50,
}, },
specialName: LocationName.Sector12DeltaOne,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -760,6 +781,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 90, max: 90,
min: 80, min: 80,
}, },
specialName: LocationName.NewTokyoGlobalPharmaceuticals,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -782,6 +804,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 85, max: 85,
min: 65, min: 65,
}, },
specialName: LocationName.IshimaNovaMedical,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -856,6 +879,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 65, max: 65,
min: 55, min: 55,
}, },
specialName: LocationName.VolhavenLexoCorp,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -882,6 +906,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 60, max: 60,
min: 40, min: 40,
}, },
specialName: LocationName.AevumRhoConstruction,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -909,6 +934,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 60, max: 60,
min: 50, min: 50,
}, },
specialName: LocationName.Sector12AlphaEnterprises,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -935,6 +961,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 50, max: 50,
min: 30, min: 30,
}, },
specialName: LocationName.AevumPolice,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -966,6 +993,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 45, max: 45,
min: 35, min: 35,
}, },
specialName: LocationName.Sector12RothmanUniversity,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -992,6 +1020,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 85, max: 85,
min: 75, min: 75,
}, },
specialName: LocationName.VolhavenZBInstituteOfTechnology,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -1023,6 +1052,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 60, max: 60,
min: 40, min: 40,
}, },
specialName: LocationName.AevumSummitUniversity,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -1045,6 +1075,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 70, max: 70,
min: 60, min: 60,
}, },
specialName: LocationName.VolhavenSysCoreSecurities,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -1121,6 +1152,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 65, max: 65,
min: 45, min: 45,
}, },
specialName: LocationName.VolhavenCompuTek,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -1145,6 +1177,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 75, max: 75,
min: 45, min: 45,
}, },
specialName: LocationName.AevumNetLinkTechnologies,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -1179,6 +1212,7 @@ export const serverMetadata: IServerMetadata[] = [
organizationName: LocationName.Sector12FoodNStuff, organizationName: LocationName.Sector12FoodNStuff,
requiredHackingSkill: 1, requiredHackingSkill: 1,
serverGrowth: 5, serverGrowth: 5,
specialName: LocationName.Sector12FoodNStuff,
}, },
{ {
hackDifficulty: 10, hackDifficulty: 10,
@ -1198,9 +1232,10 @@ export const serverMetadata: IServerMetadata[] = [
moneyAvailable: 2500000, moneyAvailable: 2500000,
networkLayer: 1, networkLayer: 1,
numOpenPortsRequired: 0, numOpenPortsRequired: 0,
organizationName: "Joes Guns", organizationName: LocationName.Sector12JoesGuns,
requiredHackingSkill: 10, requiredHackingSkill: 10,
serverGrowth: 20, serverGrowth: 20,
specialName: LocationName.Sector12JoesGuns,
}, },
{ {
hackDifficulty: 25, hackDifficulty: 25,
@ -1316,6 +1351,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 40, max: 40,
min: 30, min: 30,
}, },
specialName: LocationName.IshimaOmegaSoftware,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -1338,6 +1374,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 33, max: 33,
min: 27, min: 27,
}, },
specialName: LocationName.AevumCrushFitnessGym,
}, },
{ {
hackDifficulty: 30, hackDifficulty: 30,
@ -1349,6 +1386,7 @@ export const serverMetadata: IServerMetadata[] = [
organizationName: "Iron Gym Network", organizationName: "Iron Gym Network",
requiredHackingSkill: 100, requiredHackingSkill: 100,
serverGrowth: 20, serverGrowth: 20,
specialName: LocationName.Sector12IronGym,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -1372,6 +1410,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 45, max: 45,
min: 25, min: 25,
}, },
specialName: LocationName.VolhavenMilleniumFitnessGym,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -1395,6 +1434,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 60, max: 60,
min: 50, min: 50,
}, },
specialName: LocationName.Sector12PowerhouseGym,
}, },
{ {
hackDifficulty: { hackDifficulty: {
@ -1414,6 +1454,7 @@ export const serverMetadata: IServerMetadata[] = [
max: 60, max: 60,
min: 40, min: 40,
}, },
specialName: LocationName.AevumSnapFitnessGym,
}, },
{ {
hackDifficulty: 0, hackDifficulty: 0,

@ -60,7 +60,7 @@ import { Player } from "./Player";
import { hackWorldDaemon } from "./RedPill"; import { hackWorldDaemon } from "./RedPill";
import { RunningScript } from "./Script/RunningScript"; import { RunningScript } from "./Script/RunningScript";
import { getRamUsageFromRunningScript } from "./Script/RunningScriptHelpers"; import { getRamUsageFromRunningScript } from "./Script/RunningScriptHelpers";
import { findRunningScript } from "./Script/ScriptHelpers"; import { getCurrentEditor, findRunningScript } from "./Script/ScriptHelpers";
import { isScriptFilename } from "./Script/ScriptHelpersTS"; import { isScriptFilename } from "./Script/ScriptHelpersTS";
import { AllServers } from "./Server/AllServers"; import { AllServers } from "./Server/AllServers";
import { Server } from "./Server/Server"; import { Server } from "./Server/Server";
@ -1789,6 +1789,7 @@ let Terminal = {
}`; }`;
} }
Engine.loadScriptEditorContent(filepath, code); Engine.loadScriptEditorContent(filepath, code);
getCurrentEditor().setCursor({row: 1, column: 4});
} else { } else {
Engine.loadScriptEditorContent(filepath, script.code); Engine.loadScriptEditorContent(filepath, script.code);
} }

@ -394,7 +394,7 @@ if (htmlWebpackPlugin.options.googleAnalytics.trackingId) { %>
<!-- Status text --> <!-- Status text -->
<div id="status-text-container"> <div id="status-text-container">
<p id="status-text"> </p> <p id="status-text"></p>
</div> </div>
<!-- Game Options --> <!-- Game Options -->