Added more error line numbers to JS Interpreter. Reputation needed for megacorp faction reduced from 250k -> 200k. Fixed bladeburner.getActionobject() bug with general actions

This commit is contained in:
danielyxie 2018-07-27 19:00:57 -05:00
parent 47134a9640
commit b34057f2d3
8 changed files with 63 additions and 31 deletions

File diff suppressed because one or more lines are too long

@ -166,7 +166,9 @@ getActionMaxLevel
:param string type: Type of action. See :ref:`bladeburner_action_types` :param string type: Type of action. See :ref:`bladeburner_action_types`
:param string name: Name of action. Must be an exact match :param string name: Name of action. Must be an exact match
Return the maximum level for this action. Returns the maximum level for this action.
Returns -1 if an invalid action is specified.
getActionCurrentLevel getActionCurrentLevel
--------------------- ---------------------
@ -176,7 +178,9 @@ getActionCurrentLevel
:param string type: Type of action. See :ref:`bladeburner_action_types` :param string type: Type of action. See :ref:`bladeburner_action_types`
:param string name: Name of action. Must be an exact match :param string name: Name of action. Must be an exact match
Return the current level of this action. Returns the current level of this action.
Returns -1 if an invalid action is specified.
getActionAutolevel getActionAutolevel
------------------ ------------------
@ -186,7 +190,9 @@ getActionAutolevel
:param string type: Type of action. See :ref:`bladeburner_action_types` :param string type: Type of action. See :ref:`bladeburner_action_types`
:param string name: Name of action. Must be an exact match :param string name: Name of action. Must be an exact match
Return wether of not this action is currently autoleveling. Return a boolean indicating whether or not this action is currently set to autolevel.
Returns false if an invalid action is specified.
setActionAutolevel setActionAutolevel
------------------ ------------------
@ -195,7 +201,9 @@ setActionAutolevel
:param string type: Type of action. See :ref:`bladeburner_action_types` :param string type: Type of action. See :ref:`bladeburner_action_types`
:param string name: Name of action. Must be an exact match :param string name: Name of action. Must be an exact match
:param boolean autoLevel: wether or not to autolevel this action :param boolean autoLevel: Whether or not to autolevel this action
Enable/disable autoleveling for the specified action.
setActionLevel setActionLevel
-------------- --------------
@ -204,7 +212,9 @@ setActionLevel
:param string type: Type of action. See :ref:`bladeburner_action_types` :param string type: Type of action. See :ref:`bladeburner_action_types`
:param string name: Name of action. Must be an exact match :param string name: Name of action. Must be an exact match
:param level int: the level to set this action to :param level int: Level to set this action to
Set the level for the specified action.
getRank getRank
------- -------

@ -814,7 +814,7 @@
<span class="tooltiptext"> <span class="tooltiptext">
The minimum number of milliseconds it takes to execute an operation in Netscript. The minimum number of milliseconds it takes to execute an operation in Netscript.
Setting this too low can result in poor performance if you have many scripts running. Setting this too low can result in poor performance if you have many scripts running.
The default value is 50ms. The default value is 25ms.
</span> </span>
</label> </label>

@ -96,6 +96,8 @@ let NetscriptFunctions =
"bladeburner|getContractNames|getOperationNames|getBlackOpNames|" + "bladeburner|getContractNames|getOperationNames|getBlackOpNames|" +
"getGeneralActionNames|getSkillNames|startAction|stopBladeburnerAction|" + "getGeneralActionNames|getSkillNames|startAction|stopBladeburnerAction|" +
"getActionTime|getActionEstimatedSuccessChance|getActionCountRemaining|" + "getActionTime|getActionEstimatedSuccessChance|getActionCountRemaining|" +
"getActionMaxLevel|getActionCurrentLevel|getActionAutolevel|" +
"setActionAutolevel|setActionLevel|" +
"getRank|getSkillPoints|getSkillLevel|upgradeSkill|getTeamSize|" + "getRank|getSkillPoints|getSkillLevel|upgradeSkill|getTeamSize|" +
"setTeamSize|getCityEstimatedPopulation|getCityEstimatedCommunities|" + "setTeamSize|getCityEstimatedPopulation|getCityEstimatedCommunities|" +
"getCityChaos|switchCity|getStamina|joinBladeburnerFaction"; "getCityChaos|switchCity|getStamina|joinBladeburnerFaction";

@ -1042,22 +1042,23 @@ Bladeburner.prototype.upgradeSkill = function(skill) {
Bladeburner.prototype.getActionObject = function(actionId) { Bladeburner.prototype.getActionObject = function(actionId) {
//Given an ActionIdentifier object, returns the corresponding //Given an ActionIdentifier object, returns the corresponding
//Contract, Operation, or BlackOperation object //GeneralAction, Contract, Operation, or BlackOperation object
switch (actionId.type) { switch (actionId.type) {
case ActionTypes["Contract"]: case ActionTypes["Contract"]:
return this.contracts[actionId.name]; return this.contracts[actionId.name];
break;
case ActionTypes["Operation"]: case ActionTypes["Operation"]:
return this.operations[actionId.name]; return this.operations[actionId.name];
break;
case ActionTypes["BlackOp"]: case ActionTypes["BlackOp"]:
case ActionTypes["BlackOperation"]: case ActionTypes["BlackOperation"]:
return BlackOperations[actionId.name]; return BlackOperations[actionId.name];
break; case ActionTypes["Training"]:
return GeneralActions["Training"];
case ActionTypes["Field Analysis"]:
return GeneralActions["Field Analysis"];
case ActionTypes["Recruitment"]:
return GeneralActions["Recruitment"];
default: default:
return null; return null;
console.log("WARNING: Bladeburner.getActionObject() called with an unexpected " +
"ActionIdentifier type: " + actionId.type);
} }
} }
@ -3222,6 +3223,7 @@ Bladeburner.prototype.getActionIdFromTypeAndName = function(type="", name="") {
} else { } else {
return null; return null;
} }
break;
case "operation": case "operation":
case "operations": case "operations":
case "op": case "op":
@ -3233,6 +3235,7 @@ Bladeburner.prototype.getActionIdFromTypeAndName = function(type="", name="") {
} else { } else {
return null; return null;
} }
break;
case "blackoperation": case "blackoperation":
case "black operation": case "black operation":
case "black operations": case "black operations":
@ -3247,6 +3250,7 @@ Bladeburner.prototype.getActionIdFromTypeAndName = function(type="", name="") {
} else { } else {
return null; return null;
} }
break;
case "general": case "general":
case "general action": case "general action":
case "gen": case "gen":

@ -7,7 +7,7 @@ let CONSTANTS = {
MaxSkillLevel: 975, MaxSkillLevel: 975,
//How much reputation is needed to join a megacorporation's faction //How much reputation is needed to join a megacorporation's faction
CorpFactionRepRequirement: 250000, CorpFactionRepRequirement: 200e3,
/* Base costs */ /* Base costs */
BaseCostFor1GBOfRamHome: 32000, BaseCostFor1GBOfRamHome: 32000,
@ -502,6 +502,7 @@ let CONSTANTS = {
"* Completely re-designed the Hacknet Node API<br>" + "* Completely re-designed the Hacknet Node API<br>" +
"* getSkillLevel() in Bladeburner API now returns an error if no argument is passed in (as opposed to an object with all skill levels). This may break scripts<br>" + "* getSkillLevel() in Bladeburner API now returns an error if no argument is passed in (as opposed to an object with all skill levels). This may break scripts<br>" +
"* Minimum Netscript execution time reduced from 15ms to 10ms (configurable in Options)<br>" + "* Minimum Netscript execution time reduced from 15ms to 10ms (configurable in Options)<br>" +
"* Company reputation needed to get invited to Megacorporation factions decreased from 250k to 200k<br>" +
"* HP is now reset (restored) when Augmenting<br>" + "* HP is now reset (restored) when Augmenting<br>" +
"* Source-File 6 now increases both the level and experience gain of all combat stats (it was only experience gain previously)<br>" + "* Source-File 6 now increases both the level and experience gain of all combat stats (it was only experience gain previously)<br>" +
"* Reverted a previous change for Source-File 12. It's benefits are now multiplicative rather than additive<br>" + "* Reverted a previous change for Source-File 12. It's benefits are now multiplicative rather than additive<br>" +

@ -84,7 +84,8 @@ var Interpreter = function(code, opt_initFunc, lineOffset=0) {
* @const {!Object} Configuration used for all Acorn parsing. * @const {!Object} Configuration used for all Acorn parsing.
*/ */
Interpreter.PARSE_OPTIONS = { Interpreter.PARSE_OPTIONS = {
ecmaVersion: 5 ecmaVersion: 5,
locations: true
}; };
/** /**
@ -2125,13 +2126,18 @@ Interpreter.prototype.getPrototype = function(value) {
* Fetch a property value from a data object. * Fetch a property value from a data object.
* @param {Interpreter.Value} obj Data object. * @param {Interpreter.Value} obj Data object.
* @param {Interpreter.Value} name Name of property. * @param {Interpreter.Value} name Name of property.
* @param {Acorn AST Node} node Node that triggered this function. Used by Bitburner for getting error line numbers
* @return {Interpreter.Value} Property value (may be undefined). * @return {Interpreter.Value} Property value (may be undefined).
*/ */
Interpreter.prototype.getProperty = function(obj, name) { Interpreter.prototype.getProperty = function(obj, name, node) {
name = String(name); name = String(name);
if (obj === undefined || obj === null) { if (obj === undefined || obj === null) {
let lineNum;
if (node != null && node.loc != null && node.loc.start != null) {
lineNum = node.loc.start.line;
}
this.throwException(this.TYPE_ERROR, this.throwException(this.TYPE_ERROR,
"Cannot read property '" + name + "' of " + obj); "Cannot read property '" + name + "' of " + obj, lineNum);
} }
if (name === 'length') { if (name === 'length') {
// Special cases for magic length property. // Special cases for magic length property.
@ -2425,11 +2431,12 @@ Interpreter.prototype.createSpecialScope = function(parentScope, opt_scope) {
/** /**
* Retrieves a value from the scope chain. * Retrieves a value from the scope chain.
* @param {string} name Name of variable. * @param {string} name Name of variable.
* @param {Acorn AST Node} node Node that triggered this function. Used by Bitburner for getting error line number
* @return {Interpreter.Value} Any value. * @return {Interpreter.Value} Any value.
* May be flagged as being a getter and thus needing immediate execution * May be flagged as being a getter and thus needing immediate execution
* (rather than being the value of the property). * (rather than being the value of the property).
*/ */
Interpreter.prototype.getValueFromScope = function(name) { Interpreter.prototype.getValueFromScope = function(name, node) {
var scope = this.getScope(); var scope = this.getScope();
while (scope && scope !== this.global) { while (scope && scope !== this.global) {
if (name in scope.properties) { if (name in scope.properties) {
@ -2448,7 +2455,12 @@ Interpreter.prototype.getValueFromScope = function(name) {
prevNode['operator'] === 'typeof') { prevNode['operator'] === 'typeof') {
return undefined; return undefined;
} }
this.throwException(this.REFERENCE_ERROR, name + ' is not defined');
var lineNum;
if (node != null && node.loc != null && node.loc.start != null) {
lineNum = node.loc.start.line;
}
this.throwException(this.REFERENCE_ERROR, name + ' is not defined', lineNum);
}; };
/** /**
@ -2557,17 +2569,18 @@ Interpreter.prototype.calledWithNew = function() {
/** /**
* Gets a value from the scope chain or from an object property. * Gets a value from the scope chain or from an object property.
* @param {!Array} ref Name of variable or object/propname tuple. * @param {!Array} ref Name of variable or object/propname tuple.
* @param {Acorn AST Node} node Node that triggered this function. Used by Bitburner for getting error line number
* @return {Interpreter.Value} Any value. * @return {Interpreter.Value} Any value.
* May be flagged as being a getter and thus needing immediate execution * May be flagged as being a getter and thus needing immediate execution
* (rather than being the value of the property). * (rather than being the value of the property).
*/ */
Interpreter.prototype.getValue = function(ref) { Interpreter.prototype.getValue = function(ref, node) {
if (ref[0] === Interpreter.SCOPE_REFERENCE) { if (ref[0] === Interpreter.SCOPE_REFERENCE) {
// A null/varname variable lookup. // A null/varname variable lookup.
return this.getValueFromScope(ref[1]); return this.getValueFromScope(ref[1], node);
} else { } else {
// An obj/prop components tuple (foo.bar). // An obj/prop components tuple (foo.bar).
return this.getProperty(ref[0], ref[1]); return this.getProperty(ref[0], ref[1], node);
} }
}; };
@ -2685,7 +2698,7 @@ Interpreter.prototype.unwind = function(type, value, label, lineNumberMsg="") {
var type = errorTable[name] || Error; var type = errorTable[name] || Error;
realError = type(message + lineNumberMsg); realError = type(message + lineNumberMsg);
} else { } else {
realError = String(value + lineNumberMsg); realError = String(value) + lineNumberMsg;
} }
throw realError; throw realError;
}; };
@ -2791,7 +2804,7 @@ Interpreter.prototype['stepAssignmentExpression'] =
state.leftValue_ = state.value; state.leftValue_ = state.value;
} }
if (!state.doneGetter_ && node['operator'] !== '=') { if (!state.doneGetter_ && node['operator'] !== '=') {
var leftValue = this.getValue(state.leftReference_); var leftValue = this.getValue(state.leftReference_, node);
state.leftValue_ = leftValue; state.leftValue_ = leftValue;
if (leftValue && typeof leftValue === 'object' && leftValue.isGetter) { if (leftValue && typeof leftValue === 'object' && leftValue.isGetter) {
// Clear the getter flag and call the getter function. // Clear the getter flag and call the getter function.
@ -2925,7 +2938,7 @@ Interpreter.prototype['stepCallExpression'] = function(stack, state, node) {
state.doneCallee_ = 2; state.doneCallee_ = 2;
var func = state.value; var func = state.value;
if (Array.isArray(func)) { if (Array.isArray(func)) {
state.func_ = this.getValue(func); state.func_ = this.getValue(func, node);
if (func[0] === Interpreter.SCOPE_REFERENCE) { if (func[0] === Interpreter.SCOPE_REFERENCE) {
// (Globally or locally) named function. Is it named 'eval'? // (Globally or locally) named function. Is it named 'eval'?
state.directEval_ = (func[1] === 'eval'); state.directEval_ = (func[1] === 'eval');
@ -3335,7 +3348,7 @@ Interpreter.prototype['stepIdentifier'] = function(stack, state, node) {
stack[stack.length - 1].value = [Interpreter.SCOPE_REFERENCE, node['name']]; stack[stack.length - 1].value = [Interpreter.SCOPE_REFERENCE, node['name']];
return; return;
} }
var value = this.getValueFromScope(node['name']); var value = this.getValueFromScope(node['name'], node);
// An identifier could be a getter if it's a property on the global object. // An identifier could be a getter if it's a property on the global object.
if (value && typeof value === 'object' && value.isGetter) { if (value && typeof value === 'object' && value.isGetter) {
// Clear the getter flag and call the getter function. // Clear the getter flag and call the getter function.
@ -3570,7 +3583,7 @@ Interpreter.prototype['stepSwitchStatement'] = function(stack, state, node) {
Interpreter.prototype['stepThisExpression'] = function(stack, state, node) { Interpreter.prototype['stepThisExpression'] = function(stack, state, node) {
stack.pop(); stack.pop();
stack[stack.length - 1].value = this.getValueFromScope('this'); stack[stack.length - 1].value = this.getValueFromScope('this', node);
}; };
Interpreter.prototype['stepThrowStatement'] = function(stack, state, node) { Interpreter.prototype['stepThrowStatement'] = function(stack, state, node) {
@ -3671,7 +3684,7 @@ Interpreter.prototype['stepUpdateExpression'] = function(stack, state, node) {
state.leftValue_ = state.value; state.leftValue_ = state.value;
} }
if (!state.doneGetter_) { if (!state.doneGetter_) {
var leftValue = this.getValue(state.leftSide_); var leftValue = this.getValue(state.leftSide_, node);
state.leftValue_ = leftValue; state.leftValue_ = leftValue;
if (leftValue && typeof leftValue === 'object' && leftValue.isGetter) { if (leftValue && typeof leftValue === 'object' && leftValue.isGetter) {
// Clear the getter flag and call the getter function. // Clear the getter flag and call the getter function.

@ -300,7 +300,9 @@ function NetscriptFunctions(workerScript) {
const percentHacked = scriptCalculatePercentMoneyHacked(server); const percentHacked = scriptCalculatePercentMoneyHacked(server);
let maxThreadNeeded = Math.ceil(1/percentHacked*(server.moneyAvailable/server.moneyMax)); let maxThreadNeeded = Math.ceil(1/percentHacked*(server.moneyAvailable/server.moneyMax));
if (isNaN(maxThreadNeeded)) { if (isNaN(maxThreadNeeded)) {
maxThreadNeeded = 1e6; //Server has a 'max money' of 0 (probably) //Server has a 'max money' of 0 (probably).
//We'll set this to an arbitrarily large value
maxThreadNeeded = 1e6;
} }
let moneyGained = Math.floor(server.moneyAvailable * percentHacked) * threads; let moneyGained = Math.floor(server.moneyAvailable * percentHacked) * threads;
@ -3046,7 +3048,7 @@ function NetscriptFunctions(workerScript) {
const crime = findCrime(crimeRoughName.toLowerCase()); const crime = findCrime(crimeRoughName.toLowerCase());
if(crime == null) { // couldn't find crime if(crime == null) { // couldn't find crime
throw makeRuntimeRejectMsg(workerScript, "Invalid crime passed into commitCrime(): " + crime); throw makeRuntimeRejectMsg(workerScript, "Invalid crime passed into commitCrime(): " + crimeRoughName);
} }
if(workerScript.disableLogs.ALL == null && workerScript.disableLogs.commitCrime == null) { if(workerScript.disableLogs.ALL == null && workerScript.disableLogs.commitCrime == null) {
workerScript.scriptRef.log("Attempting to commit crime: "+crime.name+"..."); workerScript.scriptRef.log("Attempting to commit crime: "+crime.name+"...");