This commit is contained in:
danielyxie 2018-02-14 22:26:43 -06:00
parent dc26d831d6
commit f82d216e10
16 changed files with 2498 additions and 2266 deletions

@ -609,61 +609,6 @@ div.faction-clear {
padding: 6px; padding: 6px;
} }
.gang-member-header {
background-color: #444;
font-size: 20px;
color: white;
margin: 6px 6px 0px 6px;
padding: 6px;
cursor: pointer;
width: 80%;
text-align: left;
border: none;
outline: none;
}
.gang-member-header.active,
.gang-member-header:hover {
background-color: #555;
}
.gang-member-header.active:hover {
background-color: #666;
}
.gang-member-header:after {
content: '\02795'; /* "plus" sign (+) */
font-size: 13px;
color: white;
float: right;
margin-left: 5px;
}
.gang-member-header.active:after {
content: "\2796"; /* "minus" sign (-) */
font-size: 13px;
color: white;
float: right;
margin-left: 5px;
}
.gang-member-panel {
margin: 0px 6px 6px 6px;
padding: 0px 6px 6px 6px;
width: 75%;
margin-left: 5%;
display: none;
background-color: #555;
overflow:auto;
}
.gang-member-panel div,
.gang-member-panel ul,
.gang-member-panel p,
.gang-member-panel ul > li {
background-color: #555;
}
#gang-management-subpage > p { #gang-management-subpage > p {
padding: 4px; padding: 4px;
} }

@ -1,6 +1,3 @@
/** This removes all padding and margins as well as
setting a default font size and family for the page **/
:root{ :root{
--my-font-color: #66ff33; --my-font-color: #66ff33;
--my-background-color: #000000; --my-background-color: #000000;

2404
dist/bundle.js vendored

File diff suppressed because one or more lines are too long

@ -248,6 +248,26 @@ exec
exec("foo.script", "foodnstuff", 5, 1, "test"); exec("foo.script", "foodnstuff", 5, 1, "test");
spawn
^^^^^
.. js:function:: spawn(script, numThreads, [args...])
:param string script: Filename of script to execute
:param number numThreads: Number of threads to spawn new script with. Will be rounded to nearest integer
:param args...:
Additional arguments to pass into the new script that is being run.
Terminates the current script, and then after a delay of about 20 seconds it will execute the newly-specified script.
The purpose of this function is to execute a new script without being constrained by the RAM usage of the current one.
This function can only be used to run scripts on the local server.
Because this function immediately terminates the script, it does not have a return value.
The following example will execute the script 'foo.script' with 10 threads and the arguments 'foodnstuff' and 90::
spawn('foo.script', 10, 'foodnstuff', 90);
kill kill
^^^^ ^^^^

@ -162,6 +162,25 @@ isBusy
Returns a boolean indicating whether or not the player is currently performing an 'action'. These actions include Returns a boolean indicating whether or not the player is currently performing an 'action'. These actions include
working for a company/faction, studying at a univeristy, working out at a gym, creating a program, or committing a crime. working for a company/faction, studying at a univeristy, working out at a gym, creating a program, or committing a crime.
stopAction
----------
.. js:function:: stopAction()
If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to run this function.
This function is used to end whatever 'action' the player is currently performing. The player
will receive whatever money/experience/etc. he has earned from that action.
The actions that can be stopped with this function are:
* Studying at a university
* Working for a company/faction
* Creating a program
* Committing a Crime
This function will return true if the player's action was ended. It will return false if the player was not
performing an action when this function was called.
upgradeHomeRam upgradeHomeRam
-------------- --------------

@ -135,14 +135,22 @@
</fieldset> </fieldset>
<fieldset> <fieldset>
<label for="script-editor-option-showinvisibles">Show Invisibles</label></td> <label for="script-editor-option-showinvisibles">Show Invisibles</label>
<input type="checkbox" name="script-editor-option-showinvisibles" id="script-editor-option-showinvisibles"> <input type="checkbox" name="script-editor-option-showinvisibles" id="script-editor-option-showinvisibles">
</fieldset> </fieldset>
<fieldset> <fieldset>
<label for="script-editor-option-usesofttab">Use Soft Tab</label></td> <label for="script-editor-option-usesofttab">Use Soft Tab</label>
<input type="checkbox" name="script-editor-option-usesofttab" id="script-editor-option-usesofttab" checked> <input type="checkbox" name="script-editor-option-usesofttab" id="script-editor-option-usesofttab" checked>
</fieldset> </fieldset>
<fieldset>
<label for="script-editor-option-maxerr" class="tooltip">Max Error Count</label>
<input type="range" max="1000" min="50" value="200"
step="1" name="script-editor-option-maxerr" id="script-editor-option-maxerr"
</input>
<em id="script-editor-option-maxerror-value-label" style="font-style: normal;"></em>
</fieldset>
</div> <!-- End script editor options panel --> </div> <!-- End script editor options panel -->
</div> </div>

File diff suppressed because it is too large Load Diff

@ -1,5 +1,5 @@
let CONSTANTS = { let CONSTANTS = {
Version: "0.34.3", Version: "0.34.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
@ -49,6 +49,7 @@ let CONSTANTS = {
ScriptPortProgramRamCost: 0.05, ScriptPortProgramRamCost: 0.05,
ScriptRunRamCost: 1.0, ScriptRunRamCost: 1.0,
ScriptExecRamCost: 1.3, ScriptExecRamCost: 1.3,
ScriptSpawnRamCost: 2.0,
ScriptScpRamCost: 0.6, ScriptScpRamCost: 0.6,
ScriptKillRamCost: 0.5, //Kill and killall ScriptKillRamCost: 0.5, //Kill and killall
ScriptHasRootAccessRamCost: 0.05, ScriptHasRootAccessRamCost: 0.05,
@ -502,7 +503,15 @@ let CONSTANTS = {
"The following example will try to run the script 'foo.script' on the 'foodnstuff' server with 5 threads. It will also pass the number 1 and the string 'test' in as arguments " + "The following example will try to run the script 'foo.script' on the 'foodnstuff' server with 5 threads. It will also pass the number 1 and the string 'test' in as arguments " +
"to the script.<br><br>" + "to the script.<br><br>" +
"exec('foo.script', 'foodnstuff', 5, 1, 'test');<br><br>" + "exec('foo.script', 'foodnstuff', 5, 1, 'test');<br><br>" +
"<i><u>kill(script, hostname/ip, [args...])</u></i><br> Kills the script on the target server specified by the script's name and arguments. Remember that " + "<i><u>spawn(script, numThreads, [args...])</u></i><br>Terminates the current script, and then after a delay of about 20 seconds " +
"it will execute the newly specified script. The purpose of this function is to execute a new script without being constrained " +
"by the RAM usage of the current one. This function can only be used to run scripts on the local server.<br><br>" +
"The first argument must be a string with the name of the script. The second argument must be an integer specifying the number " +
"of threads to run the script with. Any additional arguments will specify arguments to pass into the 'newly-spawned' script." +
"Because this function immediately terminates the script, it does not have a return value.<br><br>" +
"The following example will execute the script 'foo.script' with 10 threads and the arguments 'foodnstuff' and 90:<br><br>" +
"spawn('foo.script', 10, 'foodnstuff', 90);<br><br>" +
"<i><u>kill(script, hostname/ip, [args...])</u></i><br>Kills the script on the target server specified by the script's name and arguments. Remember that " +
"scripts are uniquely identified by both their name and arguments. For example, if 'foo.script' is run with the argument 1, then this is not the " + "scripts are uniquely identified by both their name and arguments. For example, if 'foo.script' is run with the argument 1, then this is not the " +
"same as 'foo.script' run with the argument 2, even though they have the same code. <br><br>" + "same as 'foo.script' run with the argument 2, even though they have the same code. <br><br>" +
"The first argument must be a string with the name of the script. The name is case-sensitive. " + "The first argument must be a string with the name of the script. The name is case-sensitive. " +
@ -902,6 +911,13 @@ let CONSTANTS = {
"function.<br><br>Returns a boolean indicating whether or not the player is currently performing an 'action'. " + "function.<br><br>Returns a boolean indicating whether or not the player is currently performing an 'action'. " +
"These actions include working for a company/faction, studying at a univeristy, working out at a gym, " + "These actions include working for a company/faction, studying at a univeristy, working out at a gym, " +
"creating a program, or committing a crime.<br><br>" + "creating a program, or committing a crime.<br><br>" +
"<i><u>stopAction()</u></i><br>If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to " +
"run this function.<br><br>This function is used to end whatever 'action' the player is currently performing. The player " +
"will receive whatever money/experience/etc. he has earned from that action. The actions that can be stopped with this function " +
"are:<br><br> " +
"-Studying at a university<br>-Working for a company/faction<br>-Creating a program<br>-Committing a Crime<br><br> " +
"This function will return true if the player's action was ended. It will return false if the player was not " +
"performing an action when this function was called.<br><br>" +
"<i><u>upgradeHomeRam()</u></i><br>" + "<i><u>upgradeHomeRam()</u></i><br>" +
"If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.<br><br>" + "If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.<br><br>" +
"This function will upgrade amount of RAM on the player's home computer. The cost is the same as if you were to do it manually.<br><br>" + "This function will upgrade amount of RAM on the player's home computer. The cost is the same as if you were to do it manually.<br><br>" +
@ -1113,39 +1129,20 @@ let CONSTANTS = {
"World Stock Exchange account and TIX API Access<br>", "World Stock Exchange account and TIX API Access<br>",
LatestUpdate: LatestUpdate:
"v0.34.2<br>" + "v0.34.4<br>" +
"-Corporation Management Changes:<br>" + "-Added several new features to Gang UI to make it easier to manage your Gang.<br>" +
"---Added advertising mechanics<br>" + "-Changed the Gang Member upgrade mechanic. Now, rather than only being able to have " +
"---Added Industry-specific purchases<br>" + "one weapon/armor/vehicle/etc., you can purchase all the upgrades for each Gang member " +
"---Re-designed employee management UI<br>" + "and their multipliers will stack. To balance this out, the effects (AKA multipliers) of each Gang member upgrade " +
"---Rebalancing: Made many upgrades/purchases cheaper. Receive more money from investors in early stage. Company valuation is higher after going public<br>" + "were reduced.<br>" +
"---Multiple bug fixes<br>" + "-Added a new script editor option: Max Error Count. This affects how many approximate lines the script editor will " +
"-Added rm() Netscript function<br>" + "process (JSHint) for common errors. Increase this option can affect performance<br>" +
"-Updated the way script RAM usage is calculated. Now, a function only increases RAM usage the first time it is called. i.e. even if you call hack() multiple times in a script, it only counts against RAM usage once. The same change applies for while/for loops and if conditionals.<br>" + "-Game theme colors (set using 'theme' Terminal command) are now saved when re-opening the game<br>" +
"-The RAM cost of the following were increased:<br>" + "-'download' Terminal command now works on scripts<br>" +
"---If statements: increased by 0.05GB<br>" + "-Added stopAction() Singularity function and the spawn() Netscript function<br>" +
"---run() and exec(): increased by 0.2GB<br>" + "-The 'Purchase Augmentations' UI screen will now tell you if you need a certain prerequisite for Augmentations.<br>" +
"---scp(): increased by 0.1GB<br>" + "-Augmentations with prerequisites can now be purchased as long as their prerequisites are puchased (" +
"---purchaseServer(): increased by 0.25GB<br>" + "before, you had to actually install the prerequisites before being able to purchase)<br>"
"-Note: You may need to re-save all of your scripts in order to re-calculate their RAM usages. Otherwise, it should automatically be re-calculated when you reset/prestige<br>" +
"-The cost to upgrade your home computer's RAM has been increased (both the base cost and the exponential upgrade multiplier)<br>" +
"-The cost of purchasing a server was increased by 10% (it is now $55k per RAM)<br>" +
"-Bug fix: (Hopefully) removed an exploit where you could avoid RAM usage for Netscript function calls by assigning functions to a variable (foo = hack(); foo('helios');)<br>" +
"-Bug fix: (Hopefully) removed an exploit where you could run arbitrary Javascript code using the constructor() method<br>" +
"-Thanks to Github user mateon1 and Reddit users havoc_mayhem and spaceglace for notifying me of the above exploits<br>" +
"-The fileExists() Netscript function now works on text files (.txt). Thanks to Github user devoidfury for this<br><br>" +
"v0.34.3<br>" +
"-Minor balance changes to Corporations: <br>" +
"---Upgrades are generally cheaper and/or have more powerful effects.<br>" +
"---You will receive more funding while your are a private company.<br>" +
"---Product demand decreases at a slower rate.<br>" +
"---Production multiplier for Industries (receives for owning real estate/hardware/robots/etc.) is slightly higher<br>" +
"-Accessing the hacknetnodes array in Netscript now costs 4.0GB of RAM (only counts against RAM usage once)<br>" +
"-Bug Fix: Corporation oustanding shares should now be numeric rather than a string<br>" +
"-Bug Fix: Corporation production now properly calculated for industries that dont produce materials.<br>" +
"-Bug Fix: Gangs should now properly reset when switching BitNodes<br>" +
"-Bug Fix: Corporation UI should now properly reset when you go public<br>"
} }
export {CONSTANTS}; export {CONSTANTS};

@ -846,7 +846,12 @@ function displayFactionAugmentations(factionName) {
var pElem = document.createElement("p"); var pElem = document.createElement("p");
aElem.setAttribute("href", "#"); aElem.setAttribute("href", "#");
var req = aug.baseRepRequirement * faction.augmentationRepRequirementMult; var req = aug.baseRepRequirement * faction.augmentationRepRequirementMult;
if (aug.name != AugmentationNames.NeuroFluxGovernor && (aug.owned || owned)) { var hasPrereqs = hasAugmentationPrereqs(aug);
if (!hasPrereqs) {
aElem.setAttribute("class", "a-link-button-inactive");
pElem.innerHTML = "LOCKED (Requires " + aug.prereqs.join(",") + " as prerequisite(s))";
pElem.style.color = "red";
} else if (aug.name != AugmentationNames.NeuroFluxGovernor && (aug.owned || owned)) {
aElem.setAttribute("class", "a-link-button-inactive"); aElem.setAttribute("class", "a-link-button-inactive");
pElem.innerHTML = "ALREADY OWNED"; pElem.innerHTML = "ALREADY OWNED";
} else if (faction.playerReputation >= req) { } else if (faction.playerReputation >= req) {
@ -901,57 +906,38 @@ function purchaseAugmentationBoxCreate(aug, fac) {
formatNumber(aug.baseCost * fac.augmentationPriceMult, 2) + "?"); formatNumber(aug.baseCost * fac.augmentationPriceMult, 2) + "?");
} }
//Returns a boolean indicating whether the player has the prerequisites for the
//specified Augmentation
function hasAugmentationPrereqs(aug) {
var hasPrereqs = true;
if (aug.prereqs && aug.prereqs.length > 0) {
for (var i = 0; i < aug.prereqs.length; ++i) {
var prereqAug = Augmentations[aug.prereqs[i]];
if (prereqAug == null) {
console.log("ERROR: Invalid prereq Augmentation: " + aug.prereqs[i]);
continue;
}
if (prereqAug.owned === false) {
hasPrereqs = false;
//Check if the aug is purchased
for (var j = 0; j < Player.queuedAugmentations.length; ++j) {
if (Player.queuedAugmentations[j].name === prereqAug.name) {
hasPrereqs = true;
break;
}
}
}
}
}
return hasPrereqs;
}
function purchaseAugmentation(aug, fac, sing=false) { function purchaseAugmentation(aug, fac, sing=false) {
if (aug.name == AugmentationNames.Targeting2 && var hasPrereqs = hasAugmentationPrereqs(aug);
Augmentations[AugmentationNames.Targeting1].owned == false) { if (!hasPrereqs) {
var txt = "You must first install Augmented Targeting I before you can upgrade it to Augmented Targeting II"; var txt = "You must first purchase or install " + aug.prereqs.join(",") + " before you can " +
if (sing) {return txt;} else {dialogBoxCreate(txt);} "purchase this one.";
} else if (aug.name == AugmentationNames.Targeting3 &&
Augmentations[AugmentationNames.Targeting2].owned == false) {
var txt = "You must first install Augmented Targeting II before you can upgrade it to Augmented Targeting III";
if (sing) {return txt;} else {dialogBoxCreate(txt);}
} else if (aug.name == AugmentationNames.CombatRib2 &&
Augmentations[AugmentationNames.CombatRib1].owned == false) {
var txt = "You must first install Combat Rib I before you can upgrade it to Combat Rib II";
if (sing) {return txt;} else {dialogBoxCreate(txt);}
} else if (aug.name == AugmentationNames.CombatRib3 &&
Augmentations[AugmentationNames.CombatRib2].owned == false) {
var txt = "You must first install Combat Rib II before you can upgrade it to Combat Rib III";
if (sing) {return txt;} else {dialogBoxCreate(txt);}
} else if (aug.name == AugmentationNames.GrapheneBionicSpine &&
Augmentations[AugmentationNames.BionicSpine].owned == false) {
var txt = "You must first install a Bionic Spine before you can upgrade it to a Graphene Bionic Spine";
if (sing) {return txt;} else {dialogBoxCreate(txt);}
} else if (aug.name == AugmentationNames.GrapheneBionicLegs &&
Augmentations[AugmentationNames.BionicLegs].owned == false) {
var txt = "You must first install Bionic Legs before you can upgrade it to Graphene Bionic Legs";
if (sing) {return txt;} else {dialogBoxCreate(txt);}
} else if (aug.name == AugmentationNames.ENMCoreV2 &&
Augmentations[AugmentationNames.ENMCore].owned == false) {
var txt = "You must first install Embedded Netburner Module Core Implant before you can upgrade it to V2";
if (sing) {return txt;} else {dialogBoxCreate(txt);}
} else if (aug.name == AugmentationNames.ENMCoreV3 &&
Augmentations[AugmentationNames.ENMCoreV2].owned == false) {
var txt = "You must first install Embedded Netburner Module Core V2 Upgrade before you can upgrade it to V3";
if (sing) {return txt;} else {dialogBoxCreate(txt);}
} else if ((aug.name == AugmentationNames.ENMCore ||
aug.name == AugmentationNames.ENMAnalyzeEngine ||
aug.name == AugmentationNames.ENMDMA) &&
Augmentations[AugmentationNames.ENM].owned == false) {
var txt = "You must first install the Embedded Netburner Module before installing any upgrades to it";
if (sing) {return txt;} else {dialogBoxCreate(txt);}
} else if ((aug.name == AugmentationNames.PCDNIOptimizer ||
aug.name == AugmentationNames.PCDNINeuralNetwork) &&
Augmentations[AugmentationNames.PCDNI].owned == false) {
var txt = "You must first install the Pc Direct-Neural Interface before installing this upgrade";
if (sing) {return txt;} else {dialogBoxCreate(txt);}
} else if (aug.name == AugmentationNames.GrapheneBrachiBlades &&
Augmentations[AugmentationNames.BrachiBlades].owned == false) {
var txt = "You must first install the Brachi Blades augmentation before installing this upgrade";
if (sing) {return txt;} else {dialogBoxCreate(txt);}
} else if (aug.name == AugmentationNames.GrapheneBionicArms &&
Augmentations[AugmentationNames.BionicArms].owned == false) {
var txt = "You must first install the Bionic Arms augmentation before installing this upgrade";
if (sing) {return txt;} else {dialogBoxCreate(txt);} if (sing) {return txt;} else {dialogBoxCreate(txt);}
} else if (Player.money.gte(aug.baseCost * fac.augmentationPriceMult)) { } else if (Player.money.gte(aug.baseCost * fac.augmentationPriceMult)) {
if (Player.firstAugPurchased === false) { if (Player.firstAugPurchased === false) {
@ -974,7 +960,8 @@ function purchaseAugmentation(aug, fac, sing=false) {
var nextLevel = getNextNeurofluxLevel(); var nextLevel = getNextNeurofluxLevel();
--nextLevel; --nextLevel;
var mult = Math.pow(CONSTANTS.NeuroFluxGovernorLevelMult, nextLevel); var mult = Math.pow(CONSTANTS.NeuroFluxGovernorLevelMult, nextLevel);
aug.setRequirements(500 * mult, 750000 * mult); aug.baseRepRequirement = 500 * mult * CONSTANTS.AugmentationRepMultiplier * BitNodeMultipliers.AugmentationRepCost;
aug.baseCost = 750e3 * mult * CONSTANTS.AugmentationCostMultiplier * BitNodeMultipliers.AugmentationMoneyCost;
for (var i = 0; i < Player.queuedAugmentations.length-1; ++i) { for (var i = 0; i < Player.queuedAugmentations.length-1; ++i) {
aug.baseCost *= CONSTANTS.MultipleAugMultiplier; aug.baseCost *= CONSTANTS.MultipleAugMultiplier;

@ -8,7 +8,8 @@ import {Reviver, Generic_toJSON,
Generic_fromJSON} from "../utils/JSONReviver.js"; Generic_fromJSON} from "../utils/JSONReviver.js";
import {getRandomInt, createElement, import {getRandomInt, createElement,
removeChildrenFromElement, removeChildrenFromElement,
createAccordionElement} from "../utils/HelperFunctions.js"; createAccordionElement, createPopup,
removeElementById, removeElement} from "../utils/HelperFunctions.js";
import numeral from "../utils/numeral.min.js"; import numeral from "../utils/numeral.min.js";
import {formatNumber} from "../utils/StringHelperFunctions.js"; import {formatNumber} from "../utils/StringHelperFunctions.js";
import {yesNoBoxCreate, yesNoTxtInpBoxCreate, import {yesNoBoxCreate, yesNoTxtInpBoxCreate,
@ -21,13 +22,14 @@ import {yesNoBoxCreate, yesNoTxtInpBoxCreate,
//Switch between territory and management screen with 1 and 2 //Switch between territory and management screen with 1 and 2
$(document).keydown(function(event) { $(document).keydown(function(event) {
if (Engine.currentPage == Engine.Page.Gang && !yesNoBoxOpen) { if (Engine.currentPage == Engine.Page.Gang && !yesNoBoxOpen) {
if (gangMemberFilter != null && gangMemberFilter === document.activeElement) {return;}
if (event.keyCode === 49) { if (event.keyCode === 49) {
if(document.getElementById("gang-territory-subpage").style.display === "block") { if(gangTerritorySubpage.style.display === "block") {
document.getElementById("gang-management-subpage-button").click(); managementButton.click();
} }
} else if (event.keyCode === 50) { } else if (event.keyCode === 50) {
if (document.getElementById("gang-management-subpage").style.display === "block") { if (gangManagementSubpage.style.display === "block") {
document.getElementById("gang-territory-subpage-button").click(); territoryButton.click();
} }
} }
} }
@ -35,15 +37,16 @@ $(document).keydown(function(event) {
//Delete upgrade box when clicking outside //Delete upgrade box when clicking outside
$(document).mousedown(function(event) { $(document).mousedown(function(event) {
var boxId = "gang-member-upgrade-popup-box";
var contentId = "gang-member-upgrade-popup-box-content";
if (gangMemberUpgradeBoxOpened) { if (gangMemberUpgradeBoxOpened) {
if ( $(event.target).closest("#gang-purchase-upgrade-container").get(0) == null ) { if ( $(event.target).closest("#" + contentId).get(0) == null ) {
//Delete the box //Delete the box
var container = document.getElementById("gang-purchase-upgrade-container"); removeElement(gangMemberUpgradeBox);
while(container.firstChild) { gangMemberUpgradeBox = null;
container.removeChild(container.firstChild); gangMemberUpgradeBoxContent = null;
}
container.parentNode.removeChild(container);
gangMemberUpgradeBoxOpened = false; gangMemberUpgradeBoxOpened = false;
gangMemberUpgradeBoxElements = null;
} }
} }
}); });
@ -310,12 +313,6 @@ function GangMember(name) {
this.task = GangMemberTasks["Unassigned"]; //GangMemberTask object this.task = GangMemberTasks["Unassigned"]; //GangMemberTask object
this.city = Player.city; this.city = Player.city;
//Name of upgrade only
this.weaponUpgrade = null;
this.armorUpgrade = null;
this.vehicleUpgrade = null;
this.hackingUpgrade = null;
this.hack = 1; this.hack = 1;
this.str = 1; this.str = 1;
this.def = 1; this.def = 1;
@ -363,7 +360,7 @@ GangMember.prototype.assignToTask = function(taskName) {
if (GangMemberTasks.hasOwnProperty(taskName)) { if (GangMemberTasks.hasOwnProperty(taskName)) {
this.task = GangMemberTasks[taskName]; this.task = GangMemberTasks[taskName];
} else { } else {
console.log("ERROR: Invalid task " + taskName); this.task = GangMemberTasks["Unassigned"];
this.task = null; this.task = null;
} }
} }
@ -490,7 +487,7 @@ Reviver.constructors.GangMemberTask = GangMemberTask;
//TODO Human trafficking and an equivalent hacking crime //TODO Human trafficking and an equivalent hacking crime
let GangMemberTasks = { let GangMemberTasks = {
"Unassigned" : new GangMemebrTask( "Unassigned" : new GangMemberTask(
"Unassigned", "Unassigned",
"This gang member is currently idle"), "This gang member is currently idle"),
"Ransomware" : new GangMemberTask( "Ransomware" : new GangMemberTask(
@ -617,10 +614,11 @@ let GangMemberTasks = {
} }
function GangMemberUpgrade(name="", desc="", cost=0) { function GangMemberUpgrade(name="", desc="", cost=0, type="w") {
this.name = name; this.name = name;
this.desc = desc; this.desc = desc;
this.cost = cost; this.cost = cost;
this.type = type; //w, a, v, r
} }
//Passes in a GangMember object //Passes in a GangMember object
@ -641,7 +639,7 @@ GangMemberUpgrade.prototype.apply = function(member) {
member.dex_mult *= 1.15; member.dex_mult *= 1.15;
member.agi_mult *= 1.15; member.agi_mult *= 1.15;
break; break;
case "P90": case "P90C":
member.str_mult *= 1.2; member.str_mult *= 1.2;
member.def_mult *= 1.2; member.def_mult *= 1.2;
member.agi_mult *= 1.1; member.agi_mult *= 1.1;
@ -674,7 +672,7 @@ GangMemberUpgrade.prototype.apply = function(member) {
member.agi_mult *= 1.25; member.agi_mult *= 1.25;
break; break;
case "Graphene Plating Armor": case "Graphene Plating Armor":
member.def_mult *= 5; member.def_mult *= 1.5;
break; break;
case "Ford Flex V20": case "Ford Flex V20":
member.agi_mult *= 1.1; member.agi_mult *= 1.1;
@ -707,49 +705,6 @@ GangMemberUpgrade.prototype.apply = function(member) {
} }
} }
//Purchases for given member
GangMemberUpgrade.prototype.purchase = function(memberObj) {
if (Player.money.lt(this.cost)) {
dialogBoxCreate("You do not have enough money to purchase this upgrade");
return;
}
Player.loseMoney(this.cost);
switch (this.type) {
case "w":
if (memberObj.weaponUpgrade instanceof GangMemberUpgrade) {
memberObj.weaponUpgrade.apply(memberObj, true); //Unapply old upgrade
}
this.apply(memberObj, false);
memberObj.weaponUpgrade = this;
break;
case "a":
if (memberObj.armorUpgrade instanceof GangMemberUpgrade) {
memberObj.armorUpgrade.apply(memberObj, true); //Unapply old upgrade
}
this.apply(memberObj, false);
memberObj.armorUpgrade = this;
break;
case "v":
if (memberObj.vehicleUpgrade instanceof GangMemberUpgrade) {
memberObj.vehicleUpgrade.apply(memberObj, true); //Unapply old upgrade
}
this.apply(memberObj, false);
memberObj.vehicleUpgrade = this;
break;
case "r":
if (memberObj.hackingUpgrade instanceof GangMemberUpgrade) {
memberObj.hackingUpgrade.apply(memberObj, true); //Unapply old upgrade
}
this.apply(memberObj, false);
memberObj.hackingUpgrade = this;
break;
default:
console.log("ERROR: GangMemberUpgrade has invalid type: " + this.type);
break;
}
createGangMemberUpgradeBox(memberObj);
}
GangMemberUpgrade.prototype.toJSON = function() { GangMemberUpgrade.prototype.toJSON = function() {
return Generic_toJSON("GangMemberUpgrade", this); return Generic_toJSON("GangMemberUpgrade", this);
} }
@ -762,166 +717,203 @@ Reviver.constructors.GangMemberUpgrade = GangMemberUpgrade;
let GangMemberUpgrades = { let GangMemberUpgrades = {
"Baseball Bat" : new GangMemberUpgrade("Baseball Bat", "Baseball Bat" : new GangMemberUpgrade("Baseball Bat",
"Increases strength and defense by 5%", 1e6), "Increases strength and defense by 5%", 1e6, "w"),
"Katana" : new GangMemberUpgrade("Katana", "Katana" : new GangMemberUpgrade("Katana",
"Increases strength, defense, and dexterity by 10%", 12e6), "Increases strength, defense, and dexterity by 10%", 12e6, "w"),
"Glock 18C" : new GangMemberUpgrade("Glock 18C", "Glock 18C" : new GangMemberUpgrade("Glock 18C",
"Increases strength, defense, dexterity, and agility by 15%", 25e6), "Increases strength, defense, dexterity, and agility by 15%", 25e6, "w"),
"P90" : new GangMemberUpgrade("P90C", "P90C" : new GangMemberUpgrade("P90C",
"Increases strength and defense by 20%. Increases agility by 10%", 50e6), "Increases strength and defense by 20%. Increases agility by 10%", 50e6, "w"),
"Steyr AUG" : new GangMemberUpgrade("Steyr AUG", "Steyr AUG" : new GangMemberUpgrade("Steyr AUG",
"Increases strength and defense by 25%", 60e6), "Increases strength and defense by 25%", 60e6, "w"),
"AK-47" : new GangMemberUpgrade("AK-47", "AK-47" : new GangMemberUpgrade("AK-47",
"Increases strength and defense by 50%", 100e6), "Increases strength and defense by 50%", 100e6, "w"),
"M15A10 Assault Rifle" : new GangMemberUpgrade("M15A10 Assault Rifle", "M15A10 Assault Rifle" : new GangMemberUpgrade("M15A10 Assault Rifle",
"Increases strength and defense by 60%", 150e6), "Increases strength and defense by 60%", 150e6, "w"),
"AWM Sniper Rifle" : new GangMemberUpgrade("AWM Sniper Rifle", "AWM Sniper Rifle" : new GangMemberUpgrade("AWM Sniper Rifle",
"Increases strength, dexterity, and agility by 50%", 225e6), "Increases strength, dexterity, and agility by 50%", 225e6, "w"),
"Bulletproof Vest" : new GangMemberUpgrade("Bulletproof Vest", "Bulletproof Vest" : new GangMemberUpgrade("Bulletproof Vest",
"Increases defense by 5%", 2e6), "Increases defense by 5%", 2e6, "a"),
"Full Body Armor" : new GangMemberUpgrade("Full Body Armor", "Full Body Armor" : new GangMemberUpgrade("Full Body Armor",
"Increases defense by 10%", 5e6), "Increases defense by 10%", 5e6, "a"),
"Liquid Body Armor" : new GangMemberUpgrade("Liquid Body Armor", "Liquid Body Armor" : new GangMemberUpgrade("Liquid Body Armor",
"Increases defense and agility by 25%", 25e6), "Increases defense and agility by 25%", 25e6, "a"),
"Graphene Plating Armor" : new GangMemberUpgrade("Graphene Plating Armor", "Graphene Plating Armor" : new GangMemberUpgrade("Graphene Plating Armor",
"Increases defense by 50%", 40e6), "Increases defense by 50%", 40e6, "a"),
"Ford Flex V20" : new GangMemberUpgrade("Ford Flex V20", "Ford Flex V20" : new GangMemberUpgrade("Ford Flex V20",
"Increases agility and charisma by 10%", 3e6), "Increases agility and charisma by 10%", 3e6, "v"),
"ATX1070 Superbike" : new GangMemberUpgrade("ATX1070 Superbike", "ATX1070 Superbike" : new GangMemberUpgrade("ATX1070 Superbike",
"Increases agility and charisma by 15%", 9e6), "Increases agility and charisma by 15%", 9e6, "v"),
"Mercedes-Benz S9001" : new GangMemberUpgrade("Mercedes-Benz S9001", "Mercedes-Benz S9001" : new GangMemberUpgrade("Mercedes-Benz S9001",
"Increases agility and charisma by 20%", 18e6), "Increases agility and charisma by 20%", 18e6, "v"),
"White Ferrari" : new GangMemberUpgrade("White Ferrari", "White Ferrari" : new GangMemberUpgrade("White Ferrari",
"Increases agility and charisma by 25%", 30e6), "Increases agility and charisma by 25%", 30e6, "v"),
"NUKE Rootkit" : new GangMemberUpgrade("NUKE Rootkit", "NUKE Rootkit" : new GangMemberUpgrade("NUKE Rootkit",
"Increases hacking by 10%", 5e6), "Increases hacking by 10%", 5e6, "r"),
"Soulstealer Rootkit" : new GangMemberUpgrade("Soulstealer Rootkit", "Soulstealer Rootkit" : new GangMemberUpgrade("Soulstealer Rootkit",
"Increases hacking by 20%", 15e6), "Increases hacking by 20%", 15e6, "r"),
"Demon Rootkit" : new GangMemberUpgrade("Demon Rootkit", "Demon Rootkit" : new GangMemberUpgrade("Demon Rootkit",
"Increases hacking by 30%", 50e6), "Increases hacking by 30%", 50e6, "r"),
} }
//Create a pop-up box that lets player purchase upgrades //Create a pop-up box that lets player purchase upgrades
let gangMemberUpgradeBoxOpened = false; let gangMemberUpgradeBoxOpened = false;
function createGangMemberUpgradeBox(memberObj) { function createGangMemberUpgradeBox(initialFilter="") {
console.log("Creating gang member upgrade box for " + memberObj.name); var boxId = "gang-member-upgrade-popup-box";
var container = document.getElementById("gang-purchase-upgrade-container"); if (gangMemberUpgradeBoxOpened) {
if (container) { //Already opened, refreshing
while (container.firstChild) { if (gangMemberUpgradeBoxElements == null || gangMemberUpgradeBox == null || gangMemberUpgradeBoxContent == null) {
container.removeChild(container.firstChild); console.log("ERROR: Refreshing Gang member upgrade box throws error because required elements are null");
return;
}
for (var i = 1; i < gangMemberUpgradeBoxElements.length; ++i) {
removeElement(gangMemberUpgradeBoxElements[i]);
}
gangMemberUpgradeBoxElements = [gangMemberUpgradeBoxFilter];
var filter = gangMemberUpgradeBoxFilter.value.toString();
for (var i = 0; i < Player.gang.members.length; ++i) {
if (Player.gang.members[i].name.indexOf(filter) > -1 || Player.gang.members[i].task.name.indexOf(filter) > -1) {
var newPanel = createGangMemberUpgradePanel(Player.gang.members[i]);
gangMemberUpgradeBoxContent.appendChild(newPanel);
gangMemberUpgradeBoxElements.push(newPanel);
}
} }
} else { } else {
var container = document.createElement("div"); //New popup
container.setAttribute("id", "gang-purchase-upgrade-container"); gangMemberUpgradeBoxFilter = createElement("input", {
document.getElementById("entire-game-container").appendChild(container); type:"text", placeholder:"Filter gang members",
container.setAttribute("class", "dialog-box-container"); value:initialFilter,
container.style.display = "block"; onkeyup:()=>{
var filterValue = gangMemberUpgradeBoxFilter.value.toString();
createGangMemberUpgradeBox(filterValue);
}
});
gangMemberUpgradeBoxElements = [gangMemberUpgradeBoxFilter];
var filter = gangMemberUpgradeBoxFilter.value.toString();
for (var i = 0; i < Player.gang.members.length; ++i) {
if (Player.gang.members[i].name.indexOf(filter) > -1 || Player.gang.members[i].task.name.indexOf(filter) > -1) {
gangMemberUpgradeBoxElements.push(createGangMemberUpgradePanel(Player.gang.members[i]));
}
}
gangMemberUpgradeBox = createPopup(boxId, gangMemberUpgradeBoxElements);
gangMemberUpgradeBoxContent = document.getElementById(boxId + "-content");
gangMemberUpgradeBoxOpened = true;
} }
var content = document.createElement("div");
content.setAttribute("class", "dialog-box-content");
content.setAttribute("id", "gang-purchase-upgrade-content");
container.appendChild(content);
var intro = document.createElement("p");
content.appendChild(intro);
intro.innerHTML =
memberObj.name + "<br><br>" +
"A gang member can be upgraded with a weapon, armor, a vehicle, and a hacking rootkit. " +
"For each of these pieces of equipment, a gang member can only have one at a time (i.e " +
"a member cannot have two weapons or two vehicles). Purchasing an upgrade will automatically " +
"replace the member's existing upgrade, if he/she is equipped with one. The existing upgrade " +
"will be lost and will have to be re-purchased if you want to switch back.<br><br>";
//Weapons
var weaponTxt = document.createElement("p");
weaponTxt.style.display = "block";
content.appendChild(weaponTxt);
if (memberObj.weaponUpgrade instanceof GangMemberUpgrade) {
weaponTxt.innerHTML = "Weapons (Current Equip: " + memberObj.weaponUpgrade.name + ")";
} else {
weaponTxt.innerHTML = "Weapons (Current Equip: NONE)";
}
var weaponNames = ["Baseball Bat", "Katana", "Glock 18C", "P90", "Steyr AUG",
"AK-47", "M15A10 Assault Rifle", "AWM Sniper Rifle"];
createGangMemberUpgradeButtons(memberObj, weaponNames, memberObj.weaponUpgrade, content);
content.appendChild(document.createElement("br"));
var armorTxt = document.createElement("p");
armorTxt.style.display = "block";
content.appendChild(armorTxt);
if (memberObj.armorUpgrade instanceof GangMemberUpgrade) {
armorTxt.innerHTML = "Armor (Current Equip: " + memberObj.armorUpgrade.name + ")";
} else {
armorTxt.innerHTML = "Armor (Current Equip: NONE)";
}
var armorNames = ["Bulletproof Vest", "Full Body Armor", "Liquid Body Armor",
"Graphene Plating Armor"];
createGangMemberUpgradeButtons(memberObj, armorNames, memberObj.armorUpgrade, content);
var vehicleTxt = document.createElement("p");
vehicleTxt.style.display = "block";
content.appendChild(vehicleTxt);
if (memberObj.vehicleUpgrade instanceof GangMemberUpgrade) {
vehicleTxt.innerHTML = "Vehicles (Current Equip: " + memberObj.vehicleUpgrade.name + ")";
} else {
vehicleTxt.innerHTML = "Vehicles (Current Equip: NONE)";
}
var vehicleNames = ["Ford Flex V20", "ATX1070 Superbike", "Mercedes-Benz S9001",
"White Ferrari"];
createGangMemberUpgradeButtons(memberObj, vehicleNames, memberObj.vehicleUpgrade, content);
var rootkitTxt = document.createElement("p");
rootkitTxt.style.display = "block";
content.appendChild(rootkitTxt);
if (memberObj.hackingUpgrade instanceof GangMemberUpgrade) {
rootkitTxt.innerHTML = "Rootkits (Current Equip: " + memberObj.hackingUpgrade.name + ")";
} else {
rootkitTxt.innerHTML = "Rootkits (Current Equip: NONE)";
}
var rootkitNames = ["NUKE Rootkit", "Soulstealer Rootkit", "Demon Rootkit"];
createGangMemberUpgradeButtons(memberObj, rootkitNames, memberObj.hackingUpgrade, content);
gangMemberUpgradeBoxOpened = true;
} }
function createGangMemberUpgradeButtons(memberObj, upgNames, memberUpgrade, content) { //Create upgrade panels for each individual Gang Member
for (var i = 0; i < upgNames.length; ++i) { function createGangMemberUpgradePanel(memberObj) {
(function() { var container = createElement("div", {
var upgrade = GangMemberUpgrades[upgNames[i]]; border:"1px solid white",
if (upgrade == null) { });
console.log("ERROR: Could not find GangMemberUpgrade object for" + upgNames[i]);
return; //Return inside closure var header = createElement("h1", {
innerText:memberObj.name + " (" + memberObj.task.name + ")"
});
container.appendChild(header);
var text = createElement("pre", {
fontSize:"14px", display: "inline-block", width:"20%",
innerText:
"Hack: " + memberObj.hack + " (x" + formatNumber(memberObj.hack_mult, 2) + ")\n" +
"Str: " + memberObj.str + " (x" + formatNumber(memberObj.str_mult, 2) + ")\n" +
"Def: " + memberObj.def + " (x" + formatNumber(memberObj.def_mult, 2) + ")\n" +
"Dex: " + memberObj.dex + " (x" + formatNumber(memberObj.dex_mult, 2) + ")\n" +
"Agi: " + memberObj.agi + " (x" + formatNumber(memberObj.agi_mult, 2) + ")\n" +
"Cha: " + memberObj.cha + " (x" + formatNumber(memberObj.cha_mult, 2) + ")\n",
});
//Already purchased upgrades
var ownedUpgradesElements = [];
for (var i = 0; i < memberObj.upgrades.length; ++i) {
var upg = GangMemberUpgrades[memberObj.upgrades[i]];
if (upg == null) {
console.log("ERR: Could not find this upgrade: " + memberObj.upgrades[i]);
continue;
} }
//Skip the currently owned upgrade var e = createElement("div", {
if (memberUpgrade instanceof GangMemberUpgrade && border:"1px solid white", innerText:memberObj.upgrades[i],
memberUpgrade.name == upgrade.name) {return;} margin:"1px", padding:"1px", tooltip:upg.desc, fontSize:"12px",
//Create button
var btn = document.createElement("a");
btn.innerHTML = upgrade.name + " - $" + numeral(upgrade.cost).format('(0.00a)');
if (Player.money.gte(upgrade.cost)) {
btn.setAttribute("class", "popup-box-button tooltip")
} else {
btn.setAttribute("class", "popup-box-button-inactive tooltip");
}
btn.style.cssFloat = "none";
btn.style.display = "block";
btn.style.margin = "8px";
btn.style.width = "40%";
//Tooltip for upgrade
var tooltip = document.createElement("span");
tooltip.setAttribute("class", "tooltiptext");
tooltip.innerHTML = upgrade.desc;
btn.appendChild(tooltip);
content.appendChild(btn);
btn.addEventListener("click", function() {
upgrade.purchase(memberObj);
}); });
}()); // Immediate invocation ownedUpgradesElements.push(e);
} }
var ownedUpgrades = createElement("div", {
display:"inline-block", marginLeft:"6px", width:"75%", innerText:"Purchased Upgrades:",
});
for (var i = 0; i < ownedUpgradesElements.length; ++i) {
ownedUpgrades.appendChild(ownedUpgradesElements[i]);
}
container.appendChild(text);
container.appendChild(ownedUpgrades);
container.appendChild(createElement("br", {}));
//Upgrade buttons. Only show upgrades that can be afforded
var weaponUpgrades = [], armorUpgrades = [], vehicleUpgrades = [], rootkitUpgrades = [];
for (var upgName in GangMemberUpgrades) {
if (GangMemberUpgrades.hasOwnProperty(upgName)) {
var upg = GangMemberUpgrades[upgName];
if (Player.money.lt(upg.cost) || memberObj.upgrades.includes(upgName)) {continue;}
switch (upg.type) {
case "w":
weaponUpgrades.push(upg);
break;
case "a":
armorUpgrades.push(upg);
break;
case "v":
vehicleUpgrades.push(upg);
break;
case "r":
rootkitUpgrades.push(upg);
break;
default:
console.log("ERROR: Invalid Gang Member Upgrade Type: " + upg.type);
}
}
}
var weaponDiv = createElement("div", {width:"20%", display:"inline-block",});
var armorDiv = createElement("div", {width:"20%", display:"inline-block",});
var vehicleDiv = createElement("div", {width:"20%", display:"inline-block",});
var rootkitDiv = createElement("div", {width:"20%", display:"inline-block",});
var upgrades = [weaponUpgrades, armorUpgrades, vehicleUpgrades, rootkitUpgrades];
var divs = [weaponDiv, armorDiv, vehicleDiv, rootkitDiv];
for (var i = 0; i < upgrades.length; ++i) {
var upgradeArray = upgrades[i];
var div = divs[i];
for (var j = 0; j < upgradeArray.length; ++j) {
var upg = upgradeArray[j];
(function (upg, div, memberObj) {
div.appendChild(createElement("a", {
innerText:upg.name + " - " + numeral(upg.cost).format("$0.000a"),
class:"a-link-button", margin:"2px", padding:"2px", display:"block",
fontSize:"12px",
tooltip:upg.desc,
clickListener:()=>{
if (Player.money.lt(upg.cost)) {return false;}
Player.loseMoney(upg.cost);
memberObj.upgrades.push(upg.name);
upg.apply(memberObj);
var initFilterValue = gangMemberUpgradeBoxFilter.value.toString();
createGangMemberUpgradeBox(initFilterValue);
return false;
}
}));
})(upg, div, memberObj);
}
}
container.appendChild(weaponDiv);
container.appendChild(armorDiv);
container.appendChild(vehicleDiv);
container.appendChild(rootkitDiv);
return container;
} }
//Gang DOM elements //Gang DOM elements
@ -935,8 +927,13 @@ let gangManagementSubpage = null, gangTerritorySubpage = null;
let gangDesc = null, gangInfo = null, let gangDesc = null, gangInfo = null,
gangRecruitMemberButton = null, gangRecruitRequirementText = null, gangRecruitMemberButton = null, gangRecruitRequirementText = null,
gangExpandAllButton = null, gangCollapseAllButton, gangMemberFilter = null, gangExpandAllButton = null, gangCollapseAllButton, gangMemberFilter = null,
gangManageEquipmentButton = null,
gangMemberList = null; gangMemberList = null;
//Gang Equipment Upgrade Elements
let gangMemberUpgradeBox = null, gangMemberUpgradeBoxContent = null,
gangMemberUpgradeBoxFilter = null, gangMemberUpgradeBoxElements = null;
//Gang Territory Elements //Gang Territory Elements
let gangTerritoryDescText = null, gangTerritoryInfoText = null; let gangTerritoryDescText = null, gangTerritoryInfoText = null;
@ -1051,7 +1048,7 @@ function displayGangContent() {
return false; return false;
} }
}); });
gangManagementSubpage.appendChild(recruitGangMemberBtn); gangManagementSubpage.appendChild(gangRecruitMemberButton);
//Text for how much reputation is required for recruiting next memberList //Text for how much reputation is required for recruiting next memberList
gangRecruitRequirementText = createElement("p", {color:"red", id:"gang-recruit-requirement-text"}); gangRecruitRequirementText = createElement("p", {color:"red", id:"gang-recruit-requirement-text"});
@ -1060,38 +1057,50 @@ function displayGangContent() {
//Gang Member List management buttons (Expand/Collapse All, select a single member) //Gang Member List management buttons (Expand/Collapse All, select a single member)
gangManagementSubpage.appendChild(createElement("br", {})); gangManagementSubpage.appendChild(createElement("br", {}));
gangExpandAllButton = createElement("a", { gangExpandAllButton = createElement("a", {
class:"a-link-button", display:"inline-block", margin:"4px", padding:"2px", class:"a-link-button", display:"inline-block",
innerHTML:"Expand All", innerHTML:"Expand All",
clickListener:()=>{ clickListener:()=>{
var allHeaders = gangManagementSubpage.getElementsByClassName("accordion-header"); var allHeaders = gangManagementSubpage.getElementsByClassName("accordion-header");
allHeaders.forEach((hdr)=>{ for (var i = 0; i < allHeaders.length; ++i) {
var hdr = allHeaders[i];
if (!hdr.classList.contains("active")) { if (!hdr.classList.contains("active")) {
hdr.click(); hdr.click();
} }
}) }
return false;
} }
}); });
gangCollapseAllButton = createElement("a", { gangCollapseAllButton = createElement("a", {
class:"a-link-button", display:"inline-block", margin:"4px", padding:"2px", class:"a-link-button", display:"inline-block",
innerHTML:"Collapse All", innerHTML:"Collapse All",
clickListener:()=>{ clickListener:()=>{
var allHeaders = gangManagementSubpage.getElementsByClassName("accordion-header"); var allHeaders = gangManagementSubpage.getElementsByClassName("accordion-header");
allHeaders.forEach((hdr)=>{ for (var i = 0; i < allHeaders.length; ++i) {
var hdr = allHeaders[i];
if (hdr.classList.contains("active")) { if (hdr.classList.contains("active")) {
hdr.click(); hdr.click();
} }
}) }
return false;
} }
}); });
gangMemberFilter = createElement("input", { gangMemberFilter = createElement("input", {
type:"text", placeholder:"Filter gang members", type:"text", placeholder:"Filter gang members", margin:"5px", padding:"5px",
onkeyup:()=>{ onkeyup:()=>{
displayGangMemberList(); displayGangMemberList();
} }
}); });
gangManageEquipmentButton = createElement("a", {
class:"a-link-button", display:"inline-block",
innerHTML:"Manage Equipment",
clickListener:()=>{
createGangMemberUpgradeBox();
}
});
gangManagementSubpage.appendChild(gangExpandAllButton); gangManagementSubpage.appendChild(gangExpandAllButton);
gangManagementSubpage.appendChild(gangCollapseAllButton); gangManagementSubpage.appendChild(gangCollapseAllButton);
gangManagementSubpage.appendChild(gangMemberFilter); gangManagementSubpage.appendChild(gangMemberFilter);
gangManagementSubpage.appendChild(gangManageEquipmentButton);
//Gang Member list //Gang Member list
gangMemberList = createElement("ul", {id:"gang-member-list"}); gangMemberList = createElement("ul", {id:"gang-member-list"});
@ -1125,7 +1134,7 @@ function displayGangContent() {
territoryBorder.appendChild(gangTerritoryInfoText); territoryBorder.appendChild(gangTerritoryInfoText);
gangTerritorySubpage.appendChild(territoryBorder); gangTerritorySubpage.appendChild(territoryBorder);
gangContainer.appendChild(territorySubpage); gangContainer.appendChild(gangTerritorySubpage);
gangContainer.appendChild(gangManagementSubpage); gangContainer.appendChild(gangManagementSubpage);
document.getElementById("entire-game-container").appendChild(gangContainer); document.getElementById("entire-game-container").appendChild(gangContainer);
} }
@ -1135,9 +1144,10 @@ function displayGangContent() {
function displayGangMemberList() { function displayGangMemberList() {
removeChildrenFromElement(gangMemberList); removeChildrenFromElement(gangMemberList);
var members = Player.gang.members;
var filter = gangMemberFilter.value.toString(); var filter = gangMemberFilter.value.toString();
for (var i = 0; i < members.length; ++i) { for (var i = 0; i < members.length; ++i) {
if (members[i].name.indexOf(filter) > -1) { if (members[i].name.indexOf(filter) > -1 || members[i].task.name.indexOf(filter) > -1) {
createGangMemberDisplayElement(members[i]); createGangMemberDisplayElement(members[i]);
} }
} }
@ -1152,19 +1162,19 @@ function updateGangContent() {
gangTerritoryInfoText.innerHTML = ""; gangTerritoryInfoText.innerHTML = "";
for (var gangname in AllGangs) { for (var gangname in AllGangs) {
if (AllGangs.hasOwnProperty(gangname)) { if (AllGangs.hasOwnProperty(gangname)) {
var gangInfo = AllGangs[gangname]; var gangTerritoryInfo = AllGangs[gangname];
if (gangname == Player.gang.facName) { if (gangname == Player.gang.facName) {
gangTerritoryInfoText.innerHTML += ("<b>" + gangname + "</b><br>(Power: " + formatNumber(gangInfo.power, 6) + "): " + gangTerritoryInfoText.innerHTML += ("<b>" + gangname + "</b><br>(Power: " + formatNumber(gangTerritoryInfo.power, 6) + "): " +
formatNumber(100*gangInfo.territory, 2) + "%<br><br>"); formatNumber(100*gangTerritoryInfo.territory, 2) + "%<br><br>");
} else { } else {
gangTerritoryInfoText.innerHTML += (gangname + "<br>(Power: " + formatNumber(gangInfo.power, 6) + "): " + gangTerritoryInfoText.innerHTML += (gangname + "<br>(Power: " + formatNumber(gangTerritoryInfo.power, 6) + "): " +
formatNumber(100*gangInfo.territory, 2) + "%<br><br>"); formatNumber(100*gangTerritoryInfo.territory, 2) + "%<br><br>");
} }
} }
} }
} else { } else {
//Update information for overall gang //Update information for overall gang
if (gangInfo) { if (gangInfo instanceof Element) {
var faction = Factions[Player.gang.facName]; var faction = Factions[Player.gang.facName];
var rep; var rep;
if (!(faction instanceof Faction)) { if (!(faction instanceof Faction)) {
@ -1174,7 +1184,7 @@ function updateGangContent() {
} }
removeChildrenFromElement(gangInfo); removeChildrenFromElement(gangInfo);
gangInfo.appendChild(createElement("p", { //Respect gangInfo.appendChild(createElement("p", { //Respect
display:"block", display:"inline-block",
innerText:"Respect: " + formatNumber(Player.gang.respect, 6) + innerText:"Respect: " + formatNumber(Player.gang.respect, 6) +
" (" + formatNumber(5*Player.gang.respectGainRate, 6) + " / sec)", " (" + formatNumber(5*Player.gang.respectGainRate, 6) + " / sec)",
tooltip:"Represents the amount of respect your gang has from other gangs and criminal " + tooltip:"Represents the amount of respect your gang has from other gangs and criminal " +
@ -1182,38 +1192,47 @@ function updateGangContent() {
"your gang members will earn, and also determines how much " + "your gang members will earn, and also determines how much " +
"reputation you are earning with your gang's corresponding Faction." "reputation you are earning with your gang's corresponding Faction."
})); }));
gangInfo.appendChild(createElement("br", {}));
gangInfo.appendChild(createElement("p", { //Wanted level gangInfo.appendChild(createElement("p", { //Wanted level
display:"block", display:"inline-block",
innerText:"Wanted Level: " + formatNumber(Player.gang.wanted, 6) + innerText:"Wanted Level: " + formatNumber(Player.gang.wanted, 6) +
" (" + formatNumber(5*Player.gang.wantedGainRate, 6) + " / sec)", " (" + formatNumber(5*Player.gang.wantedGainRate, 6) + " / sec)",
tooltip:"Represents how much the gang is wanted by law enforcement. The higher " + tooltip:"Represents how much the gang is wanted by law enforcement. The higher " +
"your gang's wanted level, the harder it will be for your gang members " + "your gang's wanted level, the harder it will be for your gang members " +
"to make money and earn respect. Note that the minimum wanted level is 1." "to make money and earn respect. Note that the minimum wanted level is 1."
})); }));
gangInfo.appendChild(createElement("br", {}));
var wantedPenalty = (Player.gang.respect) / (Player.gang.respect + Player.gang.wanted); var wantedPenalty = (Player.gang.respect) / (Player.gang.respect + Player.gang.wanted);
wantedPenalty = (1 - wantedPenalty) * 100; wantedPenalty = (1 - wantedPenalty) * 100;
gangInfo.appendChild(createElement("p", { //Wanted Level multiplier gangInfo.appendChild(createElement("p", { //Wanted Level multiplier
display:"block", display:"inline-block",
innerText:"Wanted Level Penalty: -" + formatNumber(wantedPenalty, 2) + "%", innerText:"Wanted Level Penalty: -" + formatNumber(wantedPenalty, 2) + "%",
tooltip:"Penalty for respect and money gain rates due to Wanted Level" tooltip:"Penalty for respect and money gain rates due to Wanted Level"
})); }));
gangInfo.appendChild(createElement("br", {}));
gangInfo.appendChild(createElement("p", { //Money gain rate gangInfo.appendChild(createElement("p", { //Money gain rate
display:"block", display:"inline-block",
innerText:"Money gain rate: $" + formatNumber(5*Player.gang.moneyGainRate, 2) + innerText:"Money gain rate: $" + formatNumber(5*Player.gang.moneyGainRate, 2) +
" / sec", " / sec",
})); }));
gangInfo.appendChild(createElement("br", {}));
var territoryMult = AllGangs[Player.gang.facName].territory; var territoryMult = AllGangs[Player.gang.facName].territory;
gangInfo.appendChild(createElement("p", { //Territory multiplier gangInfo.appendChild(createElement("p", { //Territory multiplier
display:"block", display:"inline-block",
innerText:"Territory: " + formatNumber(territoryMult * 100, 3), innerText:"Territory: " + formatNumber(territoryMult * 100, 3) + "%",
tooltip:"The percentage of total territory your Gang controls" tooltip:"The percentage of total territory your Gang controls"
})); }));
gangInfo.appendChild(createElement("br", {}));
gangInfo.appendChild(createElement("p", { //Faction reputation gangInfo.appendChild(createElement("p", { //Faction reputation
display:"block", display:"inline-block",
innerText:"Faction reputation: " + formatNumber(rep, 3) innerText:"Faction reputation: " + formatNumber(rep, 3)
})); }));
gangInfo.appendChild(createElement("br", {}));
} else { } else {
console.log("ERROR: gang-info DOM element DNE"); console.log("ERROR: gang-info DOM element DNE");
} }
@ -1252,29 +1271,6 @@ function updateGangContent() {
} }
} }
/*
function setGangMemberClickHandlers() {
//Server panel click handlers
var gangMemberHdrs = document.getElementsByClassName("gang-member-header");
if (gangMemberHdrs == null) {
console.log("ERROR: Could not find Gang Member Headers");
return;
}
for (let i = 0; i < gangMemberHdrs.length; ++i) {
gangMemberHdrs[i].onclick = function() {
this.classList.toggle("active");
var panel = this.nextElementSibling;
if (panel.style.display === "block") {
panel.style.display = "none";
} else {
panel.style.display = "block";
}
}
}
}
*/
//Takes in a GangMember object //Takes in a GangMember object
function createGangMemberDisplayElement(memberObj) { function createGangMemberDisplayElement(memberObj) {
if (!gangContentCreated || !Player.inGang()) {return;} if (!gangContentCreated || !Player.inGang()) {return;}
@ -1285,20 +1281,8 @@ function createGangMemberDisplayElement(memberObj) {
hdrText:name, hdrText:name,
}); });
var li = accordion[0]; var li = accordion[0];
var hdr = accordion[2]; var hdr = accordion[1];
var gangMemberDiv = accordion[3]; var gangMemberDiv = accordion[2];
/*
var li = document.createElement("li");
var hdr = document.createElement("button");
hdr.setAttribute("class", "gang-member-header");
hdr.setAttribute("id", name + "-gang-member-hdr");
hdr.innerHTML = name;
//Div for entire panel
var gangMemberDiv = document.createElement("div");
gangMemberDiv.setAttribute("class", "gang-member-panel");
*/
//Gang member content divided into 3 panels: //Gang member content divided into 3 panels:
//Stats Panel //Stats Panel
@ -1310,22 +1294,6 @@ function createGangMemberDisplayElement(memberObj) {
id:name + "gang-member-stats-text", display:"inline" id:name + "gang-member-stats-text", display:"inline"
}); });
/*
var statsDiv = document.createElement("div");
statsDiv.setAttribute("id", );
statsDiv.setAttribute("class", "gang-member-info-div");
var statsP = document.createElement("p");
statsP.setAttribute("id", name + "gang-member-stats-text");
statsP.style.display = "inline";
var upgradeButton = document.createElement("a");
upgradeButton.setAttribute("id", name + "gang-member-upgrade-btn");
upgradeButton.setAttribute("class", "popup-box-button");
upgradeButton.style.cssFloat = "left";
upgradeButton.innerHTML = "Purchase Upgrades";
upgradeButton.addEventListener("click", function() {
createGangMemberUpgradeBox(memberObj);
});
*/
statsDiv.appendChild(statsP); statsDiv.appendChild(statsP);
//statsDiv.appendChild(upgradeButton); //statsDiv.appendChild(upgradeButton);
@ -1338,15 +1306,7 @@ function createGangMemberDisplayElement(memberObj) {
color:"white", backgroundColor:"black", color:"white", backgroundColor:"black",
id:name + "gang-member-task-selector" id:name + "gang-member-task-selector"
}); });
/*
var taskDiv = document.createElement("div");
taskDiv.setAttribute("id", name + "gang-member-task");
taskDiv.setAttribute("class", "gang-member-info-div");
var taskSelector = document.createElement("select");
taskSelector.style.color = "white";
taskSelector.style.backgroundColor = "black";
taskSelector.setAttribute("id", name + "gang-member-task-selector");
*/
var tasks = null; var tasks = null;
if (Player.gang.isHackingGang) { if (Player.gang.isHackingGang) {
tasks = ["---", "Ransomware", "Phishing", "Identity Theft", "DDoS Attacks", tasks = ["---", "Ransomware", "Phishing", "Identity Theft", "DDoS Attacks",
@ -1384,8 +1344,6 @@ function createGangMemberDisplayElement(memberObj) {
} }
var gainInfo = createElement("p", {id:name + "gang-member-gain-info"}); var gainInfo = createElement("p", {id:name + "gang-member-gain-info"});
/*var gainInfo = document.createElement("p"); //Wanted, respect, reputation, and money gain
gainInfo.setAttribute("id", name + "gang-member-gain-info");*/
taskDiv.appendChild(taskSelector); taskDiv.appendChild(taskSelector);
taskDiv.appendChild(gainInfo); taskDiv.appendChild(gainInfo);
@ -1394,18 +1352,8 @@ function createGangMemberDisplayElement(memberObj) {
id:name + "gang-member-task-desc", class:"gang-member-info-div", id:name + "gang-member-task-desc", class:"gang-member-info-div",
width:"30%", display:"inline" width:"30%", display:"inline"
}); });
/*
var taskDescDiv = document.createElement("div");
taskDescDiv.setAttribute("id", name + "gang-member-task-desc");
taskDescDiv.setAttribute("class", "gang-member-info-div");
*/
var taskDescP = createElement("p", {id: name + "gang-member-task-description", display:"inline"}); var taskDescP = createElement("p", {id: name + "gang-member-task-description", display:"inline"});
/*
var taskDescP = document.createElement("p");
taskDescP.setAttribute("id", name + "gang-member-task-description");
taskDescP.style.display = "inline";
*/
taskDescDiv.appendChild(taskDescP); taskDescDiv.appendChild(taskDescP);
statsDiv.style.width = "30%"; statsDiv.style.width = "30%";
@ -1418,12 +1366,8 @@ function createGangMemberDisplayElement(memberObj) {
gangMemberDiv.appendChild(taskDiv); gangMemberDiv.appendChild(taskDiv);
gangMemberDiv.appendChild(taskDescDiv); gangMemberDiv.appendChild(taskDescDiv);
//li.appendChild(hdr); gangMemberList.appendChild(li);
//li.appendChild(gangMemberDiv);
document.getElementById("gang-member-list").appendChild(li);
setGangMemberTaskDescription(memberObj, taskName); //Initialize description setGangMemberTaskDescription(memberObj, taskName); //Initialize description
setGangMemberClickHandlers(); //Reset click handlers
updateGangMemberDisplayElement(memberObj); updateGangMemberDisplayElement(memberObj);
} }

@ -9,7 +9,7 @@ let TerminalHelpText =
"clear Clear all text on the terminal <br>" + "clear Clear all text on the terminal <br>" +
"cls See 'clear' command <br>" + "cls See 'clear' command <br>" +
"connect [ip/hostname] Connects to a remote server<br>" + "connect [ip/hostname] Connects to a remote server<br>" +
"download [text file] Downloads a text (.txt) file to your computer<br>" + "download [script/text file] Downloads a script or text file to your computer<br>" +
"free Check the machine's memory (RAM) usage<br>" + "free Check the machine's memory (RAM) usage<br>" +
"hack Hack the current machine<br>" + "hack Hack the current machine<br>" +
"help [command] Display this help text, or the help text for a command<br>" + "help [command] Display this help text, or the help text for a command<br>" +
@ -86,9 +86,8 @@ let HelpTexts = {
"Connect to a remote server. The hostname or IP address of the remote server must be given as the argument " + "Connect to a remote server. The hostname or IP address of the remote server must be given as the argument " +
"to this command. Note that only servers that are immediately adjacent to the current server in the network can be connected to. To " + "to this command. Note that only servers that are immediately adjacent to the current server in the network can be connected to. To " +
"see which servers can be connected to, use the 'scan' command.", "see which servers can be connected to, use the 'scan' command.",
download: "download [text file]<br>" + download: "download [script/text file]<br>" +
"Downloads a text file to your computer (like your real life computer). Only works on text files, " + "Downloads a script or text file to your computer (like your real life computer).",
"which are the ones with a .txt extension.",
free: "free<br>" + free: "free<br>" +
"Display's the memory usage on the current machine. Print the amount of RAM that is available on the current server as well as " + "Display's the memory usage on the current machine. Print the amount of RAM that is available on the current server as well as " +
"how much of it is being used.", "how much of it is being used.",

@ -559,6 +559,24 @@ function NetscriptFunctions(workerScript) {
} }
return runScriptFromScript(server, scriptname, argsForNewScript, workerScript, threads); return runScriptFromScript(server, scriptname, argsForNewScript, workerScript, threads);
}, },
spawn : function(scriptname, threads) {
if (workerScript.checkingRam) {
if (workerScript.loadedFns.spawn) {
return 0;
} else {
workerScript.loadedFns.spawn = true;
return CONSTANTS.ScriptSpawnRamCost;
}
}
if (scriptname == null || threads == 1) {
throw makeRuntimeRejectMsg(workerScript, "Invalid scriptname or numThreads argument passed to spawn()");
}
setTimeout(()=>{
NetscriptFunctions(workerScript).run.apply(this, arguments);
}, 20000);
workerScript.scriptRef.log("spawn() will execute " + scriptname + " in 20 seconds");
NetscriptFunctions(workerScript).exit();
},
kill : function(filename,ip) { kill : function(filename,ip) {
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
if (workerScript.loadedFns.kill) { if (workerScript.loadedFns.kill) {
@ -2398,6 +2416,24 @@ function NetscriptFunctions(workerScript) {
} }
return Player.isWorking; return Player.isWorking;
}, },
stopAction : function() {
if (workerScript.checkingRam) {
if (workerScript.loadedFns.stopAction) {
return 0;
} else {
workerScript.loadedFns.stopAction = true;
var ramCost = CONSTANTS.ScriptSingularityFn1RamCost;
if (Player.bitNodeN !== 4) {ramCost *= 10;}
return ramCost;
}
}
if (Player.isWorking) {
var txt = Player.singularityStopWork();
workerScript.scriptRef.log(txt);
return true;
}
return false;
},
upgradeHomeRam() { upgradeHomeRam() {
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
if (workerScript.loadedFns.upgradeHomeRam) { if (workerScript.loadedFns.upgradeHomeRam) {

@ -128,6 +128,15 @@ function scriptEditorInit() {
editor.getSession().setUseSoftTabs(softTabChkBox.checked); editor.getSession().setUseSoftTabs(softTabChkBox.checked);
}; };
//Jshint Maxerr
var maxerr = document.getElementById("script-editor-option-maxerr");
var maxerrLabel = document.getElementById("script-editor-option-maxerror-value-label");
maxerrLabel.innerHTML = maxerr.value;
maxerr.onchange = function() {
editor.getSession().$worker.send("changeOptions", [{maxerr:maxerr.value}]);
maxerrLabel.innerHTML = maxerr.value;
}
//Configure some of the VIM keybindings //Configure some of the VIM keybindings
ace.config.loadModule('ace/keyboard/vim', function(module) { ace.config.loadModule('ace/keyboard/vim', function(module) {
var VimApi = module.CodeMirror.Vim; var VimApi = module.CodeMirror.Vim;
@ -367,6 +376,25 @@ function calculateRamUsage(codeCopy) {
return ramUsage; return ramUsage;
} }
Script.prototype.download = function() {
var filename = this.filename;
var file = new Blob([this.code], {type: 'text/plain'});
if (window.navigator.msSaveOrOpenBlob) {// IE10+
window.navigator.msSaveOrOpenBlob(file, filename);
} else { // Others
var a = document.createElement("a"),
url = URL.createObjectURL(file);
a.href = url;
a.download = this.filename;
document.body.appendChild(a);
a.click();
setTimeout(function() {
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 0);
}
}
Script.prototype.toJSON = function() { Script.prototype.toJSON = function() {
return Generic_toJSON("Script", this); return Generic_toJSON("Script", this);
} }

@ -8,6 +8,9 @@ let Settings = {
SuppressMessages: false, SuppressMessages: false,
SuppressFactionInvites: false, SuppressFactionInvites: false,
AutosaveInterval: 60, AutosaveInterval: 60,
ThemeHighlightColor: "#ffffff",
ThemeFontColor: "#66ff33",
ThemeBackgroundColor: "#000000",
} }
function loadSettings(saveString) { function loadSettings(saveString) {
@ -81,6 +84,19 @@ function setSettingsLabels() {
document.getElementById("settingsSuppressFactionInvites").onclick = function() { document.getElementById("settingsSuppressFactionInvites").onclick = function() {
Settings.SuppressFactionInvites = this.checked; Settings.SuppressFactionInvites = this.checked;
}; };
//Theme
if (Settings.ThemeHighlightColor == null || Settings.ThemeFontColor == null || Settings.ThemeBackgroundColor == null) {
console.log("ERROR: Cannot find Theme Settings");
return;
}
if (/^#[0-9a-f]{3}(?:[0-9a-f]{3})?$/i.test(Settings.ThemeHighlightColor) &&
/^#[0-9a-f]{3}(?:[0-9a-f]{3})?$/i.test(Settings.ThemeFontColor) &&
/^#[0-9a-f]{3}(?:[0-9a-f]{3})?$/i.test(Settings.ThemeBackgroundColor)) {
document.body.style.setProperty('--my-highlight-color', Settings.ThemeHighlightColor);
document.body.style.setProperty('--my-font-color', Settings.ThemeFontColor);
document.body.style.setProperty('--my-background-color', Settings.ThemeBackgroundColor);
}
} }
export {Settings, initSettings, setSettingsLabels, loadSettings}; export {Settings, initSettings, setSettingsLabels, loadSettings};

@ -23,6 +23,7 @@ import {findRunningScript, RunningScript,
AllServersMap, Script} from "./Script.js"; AllServersMap, Script} from "./Script.js";
import {AllServers, GetServerByHostname, import {AllServers, GetServerByHostname,
getServer, Server} from "./Server.js"; getServer, Server} from "./Server.js";
import {Settings} from "./Settings.js";
import {SpecialServerIps, import {SpecialServerIps,
SpecialServerNames} from "./SpecialServerIps.js"; SpecialServerNames} from "./SpecialServerIps.js";
import {TextFile, getTextFile, import {TextFile, getTextFile,
@ -401,6 +402,9 @@ function determineAllPossibilitiesForTabCompletion(input, index=0) {
for (var i = 0; i < currServ.textFiles.length; ++i) { for (var i = 0; i < currServ.textFiles.length; ++i) {
allPos.push(currServ.textFiles[i].fn); allPos.push(currServ.textFiles[i].fn);
} }
for (var i = 0; i < currServ.scripts.length; ++i) {
allPos.push(currServ.scripts[i].filename);
}
} }
return allPos; return allPos;
} }
@ -828,12 +832,19 @@ let Terminal = {
return; return;
} }
var fn = commandArray[1]; var fn = commandArray[1];
var txtFile = getTextFile(fn, s); if (fn.endsWith(".script")) {
if (txtFile !== null) { for (var i = 0; i < s.scripts.length; ++i) {
txtFile.download(); if (s.scripts[i].filename === fn) {
} else { return s.scripts[i].download();
post("Error: " + fn + " does not exist"); }
}
} else if (fn.endsWith(".txt")) {
var txtFile = getTextFile(fn, s);
if (txtFile !== null) {
return txtFile.download();
}
} }
post("Error: " + fn + " does not exist");
break; break;
case "free": case "free":
Terminal.executeFreeCommand(commandArray); Terminal.executeFreeCommand(commandArray);
@ -1055,7 +1066,7 @@ let Terminal = {
} else { } else {
var executableName = commandArray[1]; var executableName = commandArray[1];
//Music player! //Secret Music player!
if (executableName === "musicplayer") { if (executableName === "musicplayer") {
post('<iframe src="https://open.spotify.com/embed/user/danielyxie/playlist/1ORnnL6YNvXOracUaUV2kh" width="300" height="380" frameborder="0" allowtransparency="true"></iframe>', false); post('<iframe src="https://open.spotify.com/embed/user/danielyxie/playlist/1ORnnL6YNvXOracUaUV2kh" width="300" height="380" frameborder="0" allowtransparency="true"></iframe>', false);
return; return;
@ -1231,38 +1242,44 @@ let Terminal = {
case "theme": case "theme":
//todo support theme saving //todo support theme saving
var args = commandArray[1] ? commandArray[1].split(" ") : []; var args = commandArray[1] ? commandArray[1].split(" ") : [];
if(args.length != 1 && args.length != 3) { if (args.length != 1 && args.length != 3) {
post("Incorrect number of arguments."); post("Incorrect number of arguments.");
post("Usage: theme [default|muted|solarized] | #[background color hex] #[text color hex] #[highlight color hex]"); post("Usage: theme [default|muted|solarized] | #[background color hex] #[text color hex] #[highlight color hex]");
}else if(args.length == 1){ } else if(args.length == 1){
var themeName = args[0]; var themeName = args[0];
if(themeName == "default"){ if (themeName == "default"){
document.body.style.setProperty('--my-highlight-color',"#ffffff"); document.body.style.setProperty('--my-highlight-color',"#ffffff");
document.body.style.setProperty('--my-font-color',"#66ff33"); document.body.style.setProperty('--my-font-color',"#66ff33");
document.body.style.setProperty('--my-background-color',"#000000"); document.body.style.setProperty('--my-background-color',"#000000");
}else if(themeName == "muted"){ } else if (themeName == "muted"){
document.body.style.setProperty('--my-highlight-color',"#ffffff"); document.body.style.setProperty('--my-highlight-color',"#ffffff");
document.body.style.setProperty('--my-font-color',"#66ff33"); document.body.style.setProperty('--my-font-color',"#66ff33");
document.body.style.setProperty('--my-background-color',"#252527"); document.body.style.setProperty('--my-background-color',"#252527");
}else if(themeName == "solarized"){ } else if (themeName == "solarized"){
document.body.style.setProperty('--my-highlight-color',"#6c71c4"); document.body.style.setProperty('--my-highlight-color',"#6c71c4");
document.body.style.setProperty('--my-font-color',"#839496"); document.body.style.setProperty('--my-font-color',"#839496");
document.body.style.setProperty('--my-background-color',"#002b36"); document.body.style.setProperty('--my-background-color',"#002b36");
}else{ } else {
post("Theme not found"); return post("Theme not found");
} }
}else{ Settings.ThemeHighlightColor = document.body.style.getPropertyValue("--my-highlight-color");
Settings.ThemeFontColor = document.body.style.getPropertyValue("--my-font-color");
Settings.ThemeBackgroundColor = document.body.style.getPropertyValue("--my-background-color");
} else {
var inputBackgroundHex = args[0]; var inputBackgroundHex = args[0];
var inputTextHex = args[1]; var inputTextHex = args[1];
var inputHighlightHex = args[2]; var inputHighlightHex = args[2];
if(/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(inputBackgroundHex) && if (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(inputBackgroundHex) &&
/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(inputTextHex) && /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(inputTextHex) &&
/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(inputHighlightHex)){ /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(inputHighlightHex)){
document.body.style.setProperty('--my-highlight-color',inputHighlightHex); document.body.style.setProperty('--my-highlight-color',inputHighlightHex);
document.body.style.setProperty('--my-font-color',inputTextHex); document.body.style.setProperty('--my-font-color',inputTextHex);
document.body.style.setProperty('--my-background-color',inputBackgroundHex); document.body.style.setProperty('--my-background-color',inputBackgroundHex);
}else{ Settings.ThemeHighlightColor = document.body.style.getPropertyValue("--my-highlight-color");
post("Invalid Hex Input for theme"); Settings.ThemeFontColor = document.body.style.getPropertyValue("--my-font-color");
Settings.ThemeBackgroundColor = document.body.style.getPropertyValue("--my-background-color");
} else {
return post("Invalid Hex Input for theme");
} }
} }
break; break;

@ -126,6 +126,7 @@ function createPopup(id, elems) {
}), }),
content = createElement("div", { content = createElement("div", {
class:"popup-box-content", class:"popup-box-content",
id:id + "-content",
}); });
for (var i = 0; i < elems.length; ++i) { for (var i = 0; i < elems.length; ++i) {
@ -133,6 +134,7 @@ function createPopup(id, elems) {
} }
container.appendChild(content); container.appendChild(content);
document.getElementById("entire-game-container").appendChild(container); document.getElementById("entire-game-container").appendChild(container);
return container;
} }
//Creates both the header and panel element of an accordion and sets the click handler //Creates both the header and panel element of an accordion and sets the click handler