Re-adjusted some stock market parameters. Improved Resleeving UI by allowing sort. Rebalanced Resleeve price. 0 is now a valid argument for number of threads when running scripts

This commit is contained in:
danielyxie
2019-01-28 16:17:04 -08:00
parent 8d2c007bcb
commit d54f0906f0
9 changed files with 325 additions and 83 deletions

View File

@@ -522,6 +522,11 @@ export let CONSTANTS: IMap<any> = {
** You can now hold multiple jobs at once. This means you no longer lose reputation when leaving a company
** Because of this change, the getCharacterInformation() Netscript function returns a slightly different value
* Script Editor Changes:
** Added new script editor: CodeMirror. You can choose between the old editor (Ace) or CodeMirror
** Navigation keyboard shortcuts no longer work on the script editor page
* Trying to programmatically run a script (run(), exec()) with a 'threads' argument of 0 will now cause the function to return false without running the script
* Home Computer RAM is now capped at 2 ^ 30 GB (1073741824 GB)
* Pop-up dialog boxes are a little bit bigger
* Bug Fix: When importing scripts, "./" will now be properly ignored (e.g. import { foo } from "./lib.script" )

View File

@@ -860,6 +860,7 @@ function runScriptFromScript(server, scriptname, args, workerScript, threads=1)
var script = server.scripts[i];
var ramUsage = script.ramUsage;
threads = Math.round(Number(threads)); //Convert to number and round
if (threads === 0) { return Promise.resolve(false); }
ramUsage = ramUsage * threads;
var ramAvailable = server.maxRam - server.ramUsed;

View File

@@ -821,7 +821,7 @@ function NetscriptFunctions(workerScript) {
if (scriptname === undefined) {
throw makeRuntimeRejectMsg(workerScript, "run() call has incorrect number of arguments. Usage: run(scriptname, [numThreads], [arg1], [arg2]...)");
}
if (isNaN(threads) || threads < 1) {
if (isNaN(threads) || threads < 0) {
throw makeRuntimeRejectMsg(workerScript, "Invalid argument for thread count passed into run(). Must be numeric and greater than 0");
}
var argsForNewScript = [];
@@ -843,7 +843,7 @@ function NetscriptFunctions(workerScript) {
if (scriptname === undefined || ip === undefined) {
throw makeRuntimeRejectMsg(workerScript, "exec() call has incorrect number of arguments. Usage: exec(scriptname, server, [numThreads], [arg1], [arg2]...)");
}
if (isNaN(threads) || threads < 1) {
if (isNaN(threads) || threads < 0) {
throw makeRuntimeRejectMsg(workerScript, "Invalid argument for thread count passed into exec(). Must be numeric and greater than 0");
}
var argsForNewScript = [];
@@ -868,7 +868,7 @@ function NetscriptFunctions(workerScript) {
if (scriptname === undefined) {
throw makeRuntimeRejectMsg(workerScript, "spawn() call has incorrect number of arguments. Usage: spawn(scriptname, numThreads, [arg1], [arg2]...)");
}
if (isNaN(threads) || threads < 1) {
if (isNaN(threads) || threads < 0) {
throw makeRuntimeRejectMsg(workerScript, "Invalid argument for thread count passed into run(). Must be numeric and greater than 0");
}
var argsForNewScript = [];

View File

@@ -23,10 +23,10 @@ export class Resleeve extends Person {
getCost(): number {
// Each experience point adds this to the cost
const CostPerExp: number = 10e3;
const CostPerExp: number = 25e3;
// Final cost is multiplied by this constant ^ # Augs
const NumAugsExponent: number = 1.12;
const NumAugsExponent: number = 1.2;
// Get total exp in this re-sleeve
let totalExp: number = this.hacking_exp +

View File

@@ -21,6 +21,7 @@ import { exceptionAlert } from "../../../utils/helpers/exceptionAlert";
import { createElement } from "../../../utils/uiHelpers/createElement";
import { createOptionElement } from "../../../utils/uiHelpers/createOptionElement";
import { getSelectValue } from "../../../utils/uiHelpers/getSelectData";
import { removeChildrenFromElement } from "../../../utils/uiHelpers/removeChildrenFromElement";
import { removeElement } from "../../../utils/uiHelpers/removeElement";
interface IResleeveUIElems {
@@ -39,6 +40,8 @@ interface IResleeveUIElems {
interface IPageUIElems {
container: HTMLElement | null;
info: HTMLElement | null;
sortTag: HTMLElement | null;
sortSelector: HTMLSelectElement | null;
resleeveList: HTMLElement | null;
resleeves: IResleeveUIElems[] | null;
}
@@ -46,6 +49,8 @@ interface IPageUIElems {
const UIElems: IPageUIElems = {
container: null,
info: null,
sortTag: null,
sortSelector: null,
resleeveList: null,
resleeves: null,
}
@@ -65,7 +70,7 @@ export function createResleevesPage(p: IPlayer) {
});
UIElems.info = createElement("p", {
display: "inline-block",
display: "block",
innerHTML: "Re-sleeving is the process of digitizing and transferring your consciousness " +
"into a new human body, or 'sleeve'. Here at VitaLife, you can purchase new " +
"specially-engineered bodies for the re-sleeve process. Many of these bodies " +
@@ -81,20 +86,131 @@ export function createResleevesPage(p: IPlayer) {
width: "75%",
});
UIElems.resleeveList = createElement("ul");
UIElems.resleeves = [];
// Randomly create all Resleeves if they dont already exist
if (p.resleeves.length === 0) {
p.resleeves = generateResleeves();
}
for (const resleeve of p.resleeves) {
const resleeveUi = createResleeveUi(resleeve);
UIElems.resleeveList.appendChild(resleeveUi.container!);
UIElems.resleeves.push(resleeveUi);
// Create a selector for sorting the list of Resleeves
UIElems.sortTag = createElement("p", {
display: "inline-block",
innerText: "Sort By: "
});
UIElems.sortSelector = createElement("select") as HTMLSelectElement;
enum SortOption {
Cost = "Cost",
Hacking = "Hacking",
Strength = "Strength",
Defense = "Defense",
Dexterity = "Dexterity",
Agility = "Agility",
Charisma = "Charisma",
AverageCombatStats = "AverageCombat",
AverageAllStats = "AverageAllStats",
TotalNumAugmentations = "TotalNumAugmentations",
}
UIElems.sortSelector!.add(createOptionElement("Cost", SortOption.Cost));
UIElems.sortSelector!.add(createOptionElement("Hacking Level", SortOption.Hacking));
UIElems.sortSelector!.add(createOptionElement("Strength Level", SortOption.Strength));
UIElems.sortSelector!.add(createOptionElement("Defense Level", SortOption.Defense));
UIElems.sortSelector!.add(createOptionElement("Dexterity Level", SortOption.Dexterity));
UIElems.sortSelector!.add(createOptionElement("Agility Level", SortOption.Agility));
UIElems.sortSelector!.add(createOptionElement("Charisma Level", SortOption.Charisma));
UIElems.sortSelector!.add(createOptionElement("Average Combat Stats", SortOption.AverageCombatStats));
UIElems.sortSelector!.add(createOptionElement("Average Stats", SortOption.AverageAllStats));
UIElems.sortSelector!.add(createOptionElement("Number of Augmentations", SortOption.TotalNumAugmentations));
UIElems.resleeveList = createElement("ul");
UIElems.sortSelector!.onchange = () => {
removeChildrenFromElement(UIElems.resleeveList);
UIElems.resleeves = [];
// Helper function for averaging
function getAverage(...values: number[]) {
let sum: number = 0;
for (let i = 0; i < values.length; ++i) {
sum += values[i];
}
return sum / values.length;
}
const sortOpt = getSelectValue(UIElems.sortSelector!);
switch (sortOpt) {
case SortOption.Hacking:
p.resleeves.sort((a, b) => {
return a.hacking_skill - b.hacking_skill;
});
break;
case SortOption.Strength:
p.resleeves.sort((a, b) => {
return a.strength - b.strength;
});
break;
case SortOption.Defense:
p.resleeves.sort((a, b) => {
return a.defense - b.defense;
});
break;
case SortOption.Dexterity:
p.resleeves.sort((a, b) => {
return a.dexterity - b.dexterity;
});
break;
case SortOption.Agility:
p.resleeves.sort((a, b) => {
return a.agility - b.agility;
});
break;
case SortOption.Charisma:
p.resleeves.sort((a, b) => {
return a.charisma - b.charisma;
});
break;
case SortOption.AverageCombatStats:
p.resleeves.sort((a, b) => {
let aAvg = getAverage(a.strength, a.defense, a.dexterity, a.agility);
let bAvg = getAverage(b.strength, b.defense, b.dexterity, b.agility);
return aAvg - bAvg;
});
break;
case SortOption.AverageAllStats:
p.resleeves.sort((a, b) => {
let aAvg = getAverage(a.hacking_skill, a.strength, a.defense, a.dexterity, a.agility, a.charisma);
let bAvg = getAverage(b.hacking_skill, b.strength, b.defense, b.dexterity, b.agility, b.charisma);
return aAvg - bAvg;
});
break;
case SortOption.TotalNumAugmentations:
p.resleeves.sort((a, b) => {
return a.augmentations.length - b.augmentations.length;
});
break;
case SortOption.Cost:
default:
p.resleeves.sort((a, b) => {
return a.getCost() - b.getCost();
});
break;
}
// Create UI for all Resleeves
for (const resleeve of p.resleeves) {
const resleeveUi = createResleeveUi(resleeve);
UIElems.resleeveList!.appendChild(resleeveUi.container!);
UIElems.resleeves!.push(resleeveUi);
}
}
UIElems.sortSelector!.dispatchEvent(new Event('change')); // Force onchange event
UIElems.container.appendChild(UIElems.info);
UIElems.container.appendChild(createElement("br"));
UIElems.container.appendChild(UIElems.sortTag);
UIElems.container.appendChild(UIElems.sortSelector);
UIElems.container.appendChild(UIElems.resleeveList);
document.getElementById("entire-game-container")!.appendChild(UIElems.container);
@@ -145,7 +261,8 @@ function createResleeveUi(resleeve: Resleeve): IResleeveUIElems {
`Defense: ${numeralWrapper.format(resleeve.defense, "0,0")} (${numeralWrapper.formatBigNumber(resleeve.defense_exp)} exp)<br>` +
`Dexterity: ${numeralWrapper.format(resleeve.dexterity, "0,0")} (${numeralWrapper.formatBigNumber(resleeve.dexterity_exp)} exp)<br>` +
`Agility: ${numeralWrapper.format(resleeve.agility, "0,0")} (${numeralWrapper.formatBigNumber(resleeve.agility_exp)} exp)<br>` +
`Charisma: ${numeralWrapper.format(resleeve.charisma, "0,0")} (${numeralWrapper.formatBigNumber(resleeve.charisma_exp)} exp)`,
`Charisma: ${numeralWrapper.format(resleeve.charisma, "0,0")} (${numeralWrapper.formatBigNumber(resleeve.charisma_exp)} exp)<br>` +
`# Augmentations: ${resleeve.augmentations.length}`,
});
elems.multipliersButton = createElement("button", {
class: "std-button",

View File

@@ -104,13 +104,13 @@ export class Stock {
this.otlkMag = otlkMag;
this.cap = getRandomInt(initPrice * 1e3, initPrice * 25e3);
// Total shares is determined by market cap, and is rounded to nearest millions
// Total shares is determined by market cap, and is rounded to nearest 100k
let totalSharesUnrounded: number = (marketCap / initPrice);
this.totalShares = Math.round(totalSharesUnrounded / 1e6) * 1e6;
this.totalShares = Math.round(totalSharesUnrounded / 1e5) * 1e5;
// Max Shares (Outstanding shares) is a percentage of total shares
const outstandingSharePercentage: number = 0.25;
this.maxShares = Math.round((this.totalShares * outstandingSharePercentage) / 1e6) * 1e6;
const outstandingSharePercentage: number = 0.2;
this.maxShares = Math.round((this.totalShares * outstandingSharePercentage) / 1e5) * 1e5;
this.posTxtEl = null;
}

View File

@@ -350,7 +350,7 @@ function initStockMarket() {
StockMarket[joesguns] = joesgunsStk;
var catalyst = "Catalyst Ventures";
var catalystStk = new Stock(catalyst, StockSymbols[catalyst], randInt(120, 175)/100, true, 13.5, randInt(250, 1.5e3), 120e9);
var catalystStk = new Stock(catalyst, StockSymbols[catalyst], randInt(120, 175)/100, true, 13.5, randInt(250, 1.5e3), 100e9);
StockMarket[catalyst] = catalystStk;
var microdyne = "Microdyne Technologies";