mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-19 04:35:46 +01:00
Implemented Coding Contracts
This commit is contained in:
parent
e714f1e6cd
commit
f78f0ec1a7
47
doc/source/codingcontracts.rst
Normal file
47
doc/source/codingcontracts.rst
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
.. _codingcontracts:
|
||||||
|
|
||||||
|
Coding Contracts
|
||||||
|
================
|
||||||
|
Coding Contracts are a mechanic that lets players earn rewards in
|
||||||
|
exchange for solving programming problems.
|
||||||
|
|
||||||
|
Coding Contracts are files with the ".cct" extensions. They can
|
||||||
|
be accessed through the :ref:`terminal` or through scripts using
|
||||||
|
the :ref:`netscriptcodingcontractapi`
|
||||||
|
|
||||||
|
Each contract has a limited number of attempts. If you
|
||||||
|
provide the wrong answer too many times and exceed the
|
||||||
|
number of attempts, the contract will self destruct (delete itself)
|
||||||
|
|
||||||
|
Currently, Coding Contracts are randomly generated and
|
||||||
|
spawned over time. They can appear on any server (including your
|
||||||
|
home computer), except for your purchased servers.
|
||||||
|
|
||||||
|
|
||||||
|
Running in Terminal
|
||||||
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
To run a Coding Contract in the Terminal, simply use the
|
||||||
|
:ref:`run_terminal_command` command::
|
||||||
|
|
||||||
|
$ run some-contract.cct
|
||||||
|
|
||||||
|
Doing this will bring up a popup. The popup will display
|
||||||
|
the contract's problem, the number of attempts remaining, and
|
||||||
|
an area to provide an answer.
|
||||||
|
|
||||||
|
Interacting through Scripts
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
See :ref:`netscriptcodingcontractapi`.
|
||||||
|
|
||||||
|
Rewards
|
||||||
|
^^^^^^^
|
||||||
|
There are currently four possible rewards for solving a Coding Contract:
|
||||||
|
|
||||||
|
* Faction Reputation for a specific Faction
|
||||||
|
* Faction Reputation for all Factions that you are a member of
|
||||||
|
* Company reputation for a specific Company
|
||||||
|
* Money
|
||||||
|
|
||||||
|
The 'amount' of reward varies based on the difficulty of the problem
|
||||||
|
posed by the Coding Contract. There is no way to know what a
|
||||||
|
Coding Contract's exact reward will be until it is solved.
|
@ -21,6 +21,7 @@ secrets that you've been searching for.
|
|||||||
|
|
||||||
Netscript <netscript>
|
Netscript <netscript>
|
||||||
Terminal <terminal>
|
Terminal <terminal>
|
||||||
|
Coding Contracts <codingcontracts>
|
||||||
Keyboard Shortcuts <shortcuts>
|
Keyboard Shortcuts <shortcuts>
|
||||||
Changelog <changelog>
|
Changelog <changelog>
|
||||||
|
|
||||||
|
@ -25,4 +25,5 @@ to reach out to the developer!
|
|||||||
Trade Information eXchange (TIX) API <netscriptixapi>
|
Trade Information eXchange (TIX) API <netscriptixapi>
|
||||||
Singularity Functions <netscriptsingularityfunctions>
|
Singularity Functions <netscriptsingularityfunctions>
|
||||||
Bladeburner API <netscriptbladeburnerapi>
|
Bladeburner API <netscriptbladeburnerapi>
|
||||||
|
Coding Contract API <netscriptcodingcontractapi>
|
||||||
Miscellaneous <netscriptmisc>
|
Miscellaneous <netscriptmisc>
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
Netscript Bladeburner API
|
Netscript Bladeburner API
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
Netscript provides the following API for interacting with the game's Bladeburner mechanic.
|
Netscript provides the following API for interacting with the game's Bladeburner mechanic.
|
||||||
|
|
||||||
The Bladeburner API is **not** immediately available to the palyer and must be unlocked
|
The Bladeburner API is **not** immediately available to the player and must be unlocked
|
||||||
later in the game
|
later in the game
|
||||||
|
|
||||||
**WARNING: This page contains spoilers for the game**
|
**WARNING: This page contains spoilers for the game**
|
||||||
@ -12,9 +11,9 @@ The Bladeburner API is unlocked in BitNode-7. If you are in BitNode-7, you will
|
|||||||
automatically gain access to this API. Otherwise, you must have Source-File 7 in
|
automatically gain access to this API. Otherwise, you must have Source-File 7 in
|
||||||
order to use this API in other BitNodes
|
order to use this API in other BitNodes
|
||||||
|
|
||||||
**Bladeburner API functions must be accessed through the bladeburner namespace**
|
**Bladeburner API functions must be accessed through the 'bladeburner' namespace**
|
||||||
|
|
||||||
In Netscript 1.0::
|
In :ref:`netscript1`::
|
||||||
|
|
||||||
bladeburner.getContractNames();
|
bladeburner.getContractNames();
|
||||||
bladeburner.startAction("general", "Training");
|
bladeburner.startAction("general", "Training");
|
||||||
|
74
doc/source/netscriptcodingcontractapi.rst
Normal file
74
doc/source/netscriptcodingcontractapi.rst
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
.. _netscriptcodingcontractapi:
|
||||||
|
|
||||||
|
Netscript Coding Contract API
|
||||||
|
=============================
|
||||||
|
Netscript provides the following API for interacting with
|
||||||
|
:ref:`codingcontracts`.
|
||||||
|
|
||||||
|
**The Coding Contract API must be accessed through the 'codingcontract' namespace**
|
||||||
|
|
||||||
|
In :ref:`netscript1`::
|
||||||
|
|
||||||
|
codingcontract.getDescription("foo.cct", "home");
|
||||||
|
codingcontract.attempt(1, "foo.cct", "foodnstuff");
|
||||||
|
|
||||||
|
In :ref:`netscriptjs`::
|
||||||
|
|
||||||
|
ns.codingcontract.getDescription("foo.cct", "home");
|
||||||
|
ns.codingcontract.attempt(1, "foo.cct", "foodnstuff");
|
||||||
|
|
||||||
|
attempt
|
||||||
|
-------
|
||||||
|
|
||||||
|
.. js:function:: attempt(answer, fn[, hostname/ip=current ip])
|
||||||
|
|
||||||
|
:param answer: Solution for the contract
|
||||||
|
:param string fn: Filename of the contract
|
||||||
|
:param string hostname/ip: Hostname or IP of the server containing the contract.
|
||||||
|
Optional. Defaults to current server if not provided
|
||||||
|
|
||||||
|
Attempts to solve the Coding Contract with the provided solution.
|
||||||
|
|
||||||
|
:returns: Boolean indicating whether the solution was correct
|
||||||
|
|
||||||
|
getDescription
|
||||||
|
--------------
|
||||||
|
|
||||||
|
.. js:function:: getDescription(fn[, hostname/ip=current ip])
|
||||||
|
|
||||||
|
:param string fn: Filename of the contract
|
||||||
|
:param string hostname/ip: Hostname or IP of the server containing the contract.
|
||||||
|
Optional. Defaults to current server if not provided
|
||||||
|
|
||||||
|
Get the full text description for the problem posed by the Coding Contract
|
||||||
|
|
||||||
|
:returns: A string with the contract's text description
|
||||||
|
|
||||||
|
getData
|
||||||
|
-------
|
||||||
|
|
||||||
|
.. js:function:: getData(fn[, hostname/ip=current ip])
|
||||||
|
|
||||||
|
:param string fn: Filename of the contract
|
||||||
|
:param string hostname/ip: Hostname or IP of the server containing the contract.
|
||||||
|
Optional. Defaults to current server if not provided
|
||||||
|
|
||||||
|
Get the data associated with the specific Coding Contract. Note that this is
|
||||||
|
not the same as the contract's description. This is just the data that
|
||||||
|
the contract wants you to act on in order to solve
|
||||||
|
|
||||||
|
:returns: The specified contract's data
|
||||||
|
|
||||||
|
getNumTriesRemaining
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
.. js:function:: getNumTriesRemaining(fn[, hostname/ip=current ip])
|
||||||
|
|
||||||
|
:param string fn: Filename of the contract
|
||||||
|
:param string hostname/ip: Hostname or IP of the server containing the contract.
|
||||||
|
Optional. Defaults to current server if not provided
|
||||||
|
|
||||||
|
Get the number of tries remaining on the contract before it
|
||||||
|
self-destructs.
|
||||||
|
|
||||||
|
:returns: Number indicating how many attempts are remaining
|
@ -154,7 +154,7 @@ getScriptLogs
|
|||||||
scan
|
scan
|
||||||
^^^^
|
^^^^
|
||||||
|
|
||||||
.. js:function:: scan(hostname/ip[, hostnames=true])
|
.. js:function:: scan(hostname/ip=current ip[, hostnames=true])
|
||||||
|
|
||||||
:param string hostname/ip: IP or hostname of the server to scan
|
:param string hostname/ip: IP or hostname of the server to scan
|
||||||
:param boolean: Optional boolean specifying whether the function should output hostnames (if true) or IP addresses (if false)
|
:param boolean: Optional boolean specifying whether the function should output hostnames (if true) or IP addresses (if false)
|
||||||
|
@ -285,12 +285,15 @@ except literature files (.lit).
|
|||||||
|
|
||||||
**WARNING: This is permanent and cannot be undone**
|
**WARNING: This is permanent and cannot be undone**
|
||||||
|
|
||||||
|
|
||||||
|
.. _run_terminal_command:
|
||||||
|
|
||||||
run
|
run
|
||||||
^^^
|
^^^
|
||||||
|
|
||||||
$ run [file name] [-t] [num threads] [args...]
|
$ run [file name] [-t] [num threads] [args...]
|
||||||
|
|
||||||
Execute a program or a script.
|
Execute a program, script, or :ref:`codingcontracts`.
|
||||||
|
|
||||||
The '[-t]', '[num threads]', and '[args...]' arguments are only valid when
|
The '[-t]', '[num threads]', and '[args...]' arguments are only valid when
|
||||||
running a script. The '-t' flag is used to indicate that the script should
|
running a script. The '-t' flag is used to indicate that the script should
|
||||||
@ -305,13 +308,17 @@ argument must be separated by a space.
|
|||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
|
||||||
Run a program:
|
Run a program::
|
||||||
|
|
||||||
run BruteSSH.exe
|
$ run BruteSSH.exe
|
||||||
|
|
||||||
Run *foo.script* with 50 threads and the arguments [1e3, 0.5, foodnstuff]::
|
Run *foo.script* with 50 threads and the arguments [1e3, 0.5, foodnstuff]::
|
||||||
|
|
||||||
run foo.script -t 50 1e3 0.5 foodnstuff
|
$ run foo.script -t 50 1e3 0.5 foodnstuff
|
||||||
|
|
||||||
|
Run a Coding Contract::
|
||||||
|
|
||||||
|
$ run foo-contract.cct
|
||||||
|
|
||||||
scan
|
scan
|
||||||
^^^^
|
^^^^
|
||||||
|
13
netscript.js
13
netscript.js
@ -78,7 +78,7 @@ let NetscriptFunctions =
|
|||||||
"getHackTime|getGrowTime|getWeakenTime|getScriptIncome|getScriptExpGain|" +
|
"getHackTime|getGrowTime|getWeakenTime|getScriptIncome|getScriptExpGain|" +
|
||||||
"getTimeSinceLastAug|prompt|" +
|
"getTimeSinceLastAug|prompt|" +
|
||||||
|
|
||||||
//Singularity Functions
|
// Singularity Functions
|
||||||
"universityCourse|getCharacterInformation|" +
|
"universityCourse|getCharacterInformation|" +
|
||||||
"gymWorkout|travelToCity|purchaseTor|purchaseProgram|upgradeHomeRam|" +
|
"gymWorkout|travelToCity|purchaseTor|purchaseProgram|upgradeHomeRam|" +
|
||||||
"getUpgradeHomeRamCost|workForCompany|applyToCompany|getCompanyRep|" +
|
"getUpgradeHomeRamCost|workForCompany|applyToCompany|getCompanyRep|" +
|
||||||
@ -91,16 +91,16 @@ let NetscriptFunctions =
|
|||||||
"getAugmentationCost|purchaseAugmentation|" +
|
"getAugmentationCost|purchaseAugmentation|" +
|
||||||
"installAugmentations|" +
|
"installAugmentations|" +
|
||||||
|
|
||||||
//TIX API
|
// TIX API
|
||||||
"getStockPrice|getStockPosition|buyStock|sellStock|shortStock|sellShort|" +
|
"getStockPrice|getStockPosition|buyStock|sellStock|shortStock|sellShort|" +
|
||||||
"placeOrder|cancelOrder|" +
|
"placeOrder|cancelOrder|" +
|
||||||
|
|
||||||
//Hacknet Node API
|
// Hacknet Node API
|
||||||
"hacknet|numNodes|purchaseNode|getPurchaseNodeCost|getNodeStats|" +
|
"hacknet|numNodes|purchaseNode|getPurchaseNodeCost|getNodeStats|" +
|
||||||
"upgradeLevel|upgradeRam|upgradeCore|getLevelUpgradeCost|" +
|
"upgradeLevel|upgradeRam|upgradeCore|getLevelUpgradeCost|" +
|
||||||
"getRamUpgradeCost|getCoreUpgradeCost|" +
|
"getRamUpgradeCost|getCoreUpgradeCost|" +
|
||||||
|
|
||||||
//Bladeburner functions
|
// Bladeburner functions
|
||||||
"bladeburner|getContractNames|getOperationNames|getBlackOpNames|" +
|
"bladeburner|getContractNames|getOperationNames|getBlackOpNames|" +
|
||||||
"getGeneralActionNames|getSkillNames|startAction|stopBladeburnerAction|" +
|
"getGeneralActionNames|getSkillNames|startAction|stopBladeburnerAction|" +
|
||||||
"getActionTime|getActionEstimatedSuccessChance|getActionCountRemaining|" +
|
"getActionTime|getActionEstimatedSuccessChance|getActionCountRemaining|" +
|
||||||
@ -109,7 +109,10 @@ let NetscriptFunctions =
|
|||||||
"getRank|getSkillPoints|getSkillLevel|getSkillUpgradeCost|" +
|
"getRank|getSkillPoints|getSkillLevel|getSkillUpgradeCost|" +
|
||||||
"upgradeSkill|getTeamSize|getCity|" +
|
"upgradeSkill|getTeamSize|getCity|" +
|
||||||
"setTeamSize|getCityEstimatedPopulation|getCityEstimatedCommunities|" +
|
"setTeamSize|getCityEstimatedPopulation|getCityEstimatedCommunities|" +
|
||||||
"getCityChaos|switchCity|getStamina|joinBladeburnerFaction|getBonusTime";
|
"getCityChaos|switchCity|getStamina|joinBladeburnerFaction|getBonusTime|" +
|
||||||
|
|
||||||
|
// Coding Contract API
|
||||||
|
"codingcontract|attempt|getData|getDescription|getNumTriesRemaining";
|
||||||
|
|
||||||
var NetscriptHighlightRules = function(options) {
|
var NetscriptHighlightRules = function(options) {
|
||||||
var keywordMapper = this.createKeywordMapper({
|
var keywordMapper = this.createKeywordMapper({
|
||||||
|
@ -70,7 +70,7 @@ export enum CodingContractRewardType {
|
|||||||
FactionReputation,
|
FactionReputation,
|
||||||
FactionReputationAll,
|
FactionReputationAll,
|
||||||
CompanyReputation,
|
CompanyReputation,
|
||||||
Money, // This must always be the last reward type
|
Money, // This must always be the last reward type
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -137,6 +137,14 @@ export class CodingContract {
|
|||||||
this.reward = reward;
|
this.reward = reward;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getData(): any {
|
||||||
|
return this.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
getDescription(): string {
|
||||||
|
return CodingContractTypes[this.type].desc(this.data);
|
||||||
|
}
|
||||||
|
|
||||||
getDifficulty(): number {
|
getDifficulty(): number {
|
||||||
return CodingContractTypes[this.type].difficulty;
|
return CodingContractTypes[this.type].difficulty;
|
||||||
}
|
}
|
||||||
@ -155,15 +163,21 @@ export class CodingContract {
|
|||||||
async prompt(): Promise<CodingContractResult> {
|
async prompt(): Promise<CodingContractResult> {
|
||||||
// tslint:disable-next-line
|
// tslint:disable-next-line
|
||||||
return new Promise<CodingContractResult>((resolve: Function, reject: Function) => {
|
return new Promise<CodingContractResult>((resolve: Function, reject: Function) => {
|
||||||
const contractType: ContractType = CodingContractTypes[this.type];
|
const contractType: CodingContractType = CodingContractTypes[this.type];
|
||||||
const popupId: string = `coding-contract-prompt-popup-${this.fn}`;
|
const popupId: string = `coding-contract-prompt-popup-${this.fn}`;
|
||||||
const txt: HTMLElement = createElement("p", {
|
const txt: HTMLElement = createElement("p", {
|
||||||
innerText: ["You are attempting to solve a Coding Contract. Note that",
|
innerText: ["You are attempting to solve a Coding Contract. You have",
|
||||||
"you only have one chance. Providing the wrong solution",
|
`${this.getMaxNumTries() - this.tries} tries remaining,`,
|
||||||
"will cause the contract to self-destruct.\n\n",
|
"after which the contract will self-destruct.\n\n",
|
||||||
`${contractType.desc(this.data)}`].join(" "),
|
`${contractType.desc(this.data)}`].join(" "),
|
||||||
});
|
});
|
||||||
const answerInput: HTMLInputElement = createElement("input", {
|
const answerInput: HTMLInputElement = createElement("input", {
|
||||||
|
onkeydown:(e)=>{
|
||||||
|
if (e.keyCode === 13 && answerInput.value !== "") {
|
||||||
|
e.preventDefault();
|
||||||
|
solveBtn.click();
|
||||||
|
}
|
||||||
|
},
|
||||||
placeholder: "Enter Solution here",
|
placeholder: "Enter Solution here",
|
||||||
}) as HTMLInputElement;
|
}) as HTMLInputElement;
|
||||||
const solveBtn: HTMLElement = createElement("a", {
|
const solveBtn: HTMLElement = createElement("a", {
|
||||||
@ -189,6 +203,7 @@ export class CodingContract {
|
|||||||
});
|
});
|
||||||
const lineBreak: HTMLElement = createElement("br");
|
const lineBreak: HTMLElement = createElement("br");
|
||||||
createPopup(popupId, [txt, lineBreak, lineBreak, answerInput, solveBtn, cancelBtn]);
|
createPopup(popupId, [txt, lineBreak, lineBreak, answerInput, solveBtn, cancelBtn]);
|
||||||
|
answerInput.focus();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,8 +85,7 @@ let CONSTANTS = {
|
|||||||
ScriptGetScriptRamCost: 0.1,
|
ScriptGetScriptRamCost: 0.1,
|
||||||
ScriptGetHackTimeRamCost: 0.05,
|
ScriptGetHackTimeRamCost: 0.05,
|
||||||
ScriptGetFavorToDonate: 0.10,
|
ScriptGetFavorToDonate: 0.10,
|
||||||
ScriptGetContractDataRamCost: 25,
|
ScriptCodingContractBaseRamCost:10,
|
||||||
ScriptAttemptContractRamCost: 25,
|
|
||||||
|
|
||||||
ScriptSingularityFn1RamCost: 1,
|
ScriptSingularityFn1RamCost: 1,
|
||||||
ScriptSingularityFn2RamCost: 2,
|
ScriptSingularityFn2RamCost: 2,
|
||||||
@ -274,7 +273,7 @@ let CONSTANTS = {
|
|||||||
/* Coding Contract Constants */
|
/* Coding Contract Constants */
|
||||||
CodingContractBaseFactionRepGain: 2500,
|
CodingContractBaseFactionRepGain: 2500,
|
||||||
CodingContractBaseCompanyRepGain: 4000,
|
CodingContractBaseCompanyRepGain: 4000,
|
||||||
CodingContractBaseMoneyGain: 10e6,
|
CodingContractBaseMoneyGain: 50e6,
|
||||||
|
|
||||||
/* Tutorial related things */
|
/* Tutorial related things */
|
||||||
TutorialNetworkingText: "Servers are a central part of the game. You start with a single personal server (your home computer) " +
|
TutorialNetworkingText: "Servers are a central part of the game. You start with a single personal server (your home computer) " +
|
||||||
@ -508,35 +507,13 @@ let CONSTANTS = {
|
|||||||
LatestUpdate:
|
LatestUpdate:
|
||||||
`
|
`
|
||||||
v0.40.4<br>
|
v0.40.4<br>
|
||||||
* (TODO NEEDS DOCUMENTATION) The write() and read() Netscript functions now work on scripts<br>
|
* Added new Coding Contracts mechanic. Solve programming problems to earn rewards
|
||||||
* It is now possible to use freely use angled bracket (<, >) and create DOM elements using tprint()<br>
|
* (TODO NEEDS DOCUMENTATION) The write() and read() Netscript functions now work on scripts
|
||||||
* Added Coding Contracts (not yet generated in game, but the data/implementation exists)<br>
|
* It is now possible to use freely use angled bracket (<, >) and create DOM elements using tprint()
|
||||||
|
* The game's theme colors can now be set through the Terminal configuration (.fconf).
|
||||||
|
* You can now switch to the old left-hand main menu bar through the Terminal configuration (.fconf)
|
||||||
|
`
|
||||||
|
|
||||||
v0.40.3<br>
|
|
||||||
-----------------------------------------------<br>
|
|
||||||
* Bladeburner Changes:<br>
|
|
||||||
*** Increased the effect that agi and dexterity have on action time<br>
|
|
||||||
*** Starting number of contracts/operations available will be slightly lower<br>
|
|
||||||
*** Random events will now happen slightly more often<br>
|
|
||||||
*** Slightly increased the rate at which the Overclock skill point cost increases<br>
|
|
||||||
-----------------------------------------------<br>
|
|
||||||
* The maximum volatility of stocks is now randomized (randomly generated within a certain range every time the game resets)<br>
|
|
||||||
* Increased the range of possible values for initial stock prices<br>
|
|
||||||
* b1t_flum3.exe program can now be created immediately at Hacking level 1 (rather than hacking level 5)<br>
|
|
||||||
* UI improvements for the character overview panel and the left-hand menu (by mat-jaworski)<br>
|
|
||||||
* General UI improvements for displays and Terminal (by mat-jaworski)<br>
|
|
||||||
* Added optional parameters to the getHackTime(), getGrowTime(), and getWeakenTime() Netscript functions<br>
|
|
||||||
* Added isLogEnabled() and getScriptLogs() Netscript functions<br>
|
|
||||||
* Added donateToFaction() Singularity function<br>
|
|
||||||
* Updated documentation to reflect the fact that Netscript port handles (getPortHandle()) only works in NetscriptJS (2.0), NOT Netscript 1.0<br>
|
|
||||||
* Added tryWrite() Netscript function<br>
|
|
||||||
* When working (for a company/faction), experience is gained immediately/continuously rather than all at once when the work is finished<br>
|
|
||||||
* Added a setting in .fconf for enabling line-wrap in the Terminal input<br>
|
|
||||||
* Adding a game option for changing the locale that most numbers are displayed in (this mostly applies for whenever money is displayed)<br>
|
|
||||||
* The randomized parameters of many high-level servers can now take on a higher range of values<br>
|
|
||||||
* Many 'foreign' servers (hackable servers that you don't own) now have a randomized amount of RAM<br>
|
|
||||||
* Added 'wget' Terminal command<br>
|
|
||||||
* Improved the introductory tutorial`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export {CONSTANTS};
|
export {CONSTANTS};
|
||||||
|
@ -175,7 +175,21 @@ function NetscriptFunctions(workerScript) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//Utility function to get Hacknet Node object
|
/**
|
||||||
|
* Gets the Server for a specific hostname/ip, throwing an error
|
||||||
|
* if the server doesn't exist.
|
||||||
|
* @param {string} Hostname or IP of the server
|
||||||
|
* @returns {Server} The specified Server
|
||||||
|
*/
|
||||||
|
var safeGetServer = function(ip, callingFnName="") {
|
||||||
|
var server = getServer(ip);
|
||||||
|
if (server == null) {
|
||||||
|
throw makeRuntimeRejectMsg(workerScript, `Invalid IP or hostname passed into ${callingFnName}() function`);
|
||||||
|
}
|
||||||
|
return server;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Utility function to get Hacknet Node object
|
||||||
var getHacknetNode = function(i) {
|
var getHacknetNode = function(i) {
|
||||||
if (isNaN(i)) {
|
if (isNaN(i)) {
|
||||||
throw makeRuntimeRejectMsg(workerScript, "Invalid index specified for Hacknet Node: " + i);
|
throw makeRuntimeRejectMsg(workerScript, "Invalid index specified for Hacknet Node: " + i);
|
||||||
@ -186,6 +200,11 @@ function NetscriptFunctions(workerScript) {
|
|||||||
return Player.hacknetNodes[i];
|
return Player.hacknetNodes[i];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var getCodingContract = function(fn, ip) {
|
||||||
|
var server = safeGetServer(ip, "getCodingContract");
|
||||||
|
return server.getContract(fn);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {number} ram The amount of server RAM to calculate cost of.
|
* @param {number} ram The amount of server RAM to calculate cost of.
|
||||||
* @exception {Error} If the value passed in is not numeric, out of range, or too large of a value.
|
* @exception {Error} If the value passed in is not numeric, out of range, or too large of a value.
|
||||||
@ -1057,6 +1076,16 @@ function NetscriptFunctions(workerScript) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < server.contracts.length; ++i) {
|
||||||
|
if (filter) {
|
||||||
|
if (server.contracts[i].fn.includes(filter)) {
|
||||||
|
allFiles.push(server.contracts[i].fn);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
allFiles.push(server.contracts[i].fn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Sort the files alphabetically then print each
|
//Sort the files alphabetically then print each
|
||||||
allFiles.sort();
|
allFiles.sort();
|
||||||
return allFiles;
|
return allFiles;
|
||||||
@ -2040,6 +2069,13 @@ function NetscriptFunctions(workerScript) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (fn.endsWith(".cct")) {
|
||||||
|
for (var i = 0; i < s.contracts.length; ++i) {
|
||||||
|
if (s.contracts[i].fn === fn) {
|
||||||
|
s.contracts.splice(i, 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
@ -3947,6 +3983,72 @@ function NetscriptFunctions(workerScript) {
|
|||||||
throw makeRuntimeRejectMsg(workerScript, "getBonusTime() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
|
throw makeRuntimeRejectMsg(workerScript, "getBonusTime() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
|
||||||
"at the Bladeburner division or because you do not have Source-File 7");
|
"at the Bladeburner division or because you do not have Source-File 7");
|
||||||
}
|
}
|
||||||
|
}, // End Bladeburner
|
||||||
|
codingcontract : {
|
||||||
|
attempt : function(answer, fn, ip=workerScript.serverIp) {
|
||||||
|
if (workerScript.checkingRam) {
|
||||||
|
return updateStaticRam("attempt", CONSTANTS.ScriptCodingContractBaseRamCost);
|
||||||
|
}
|
||||||
|
updateDynamicRam("attempt", CONSTANTS.ScriptCodingContractBaseRamCost);
|
||||||
|
const contract = getCodingContract(fn, ip);
|
||||||
|
if (contract == null) {
|
||||||
|
workerScript.log(`ERROR: codingcontract.getData() failed because it could find the specified contract ${fn} on server ${ip}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
answer = String(answer);
|
||||||
|
const serv = safeGetServer(ip, "codingcontract.attempt()");
|
||||||
|
if (contract.isSolution(answer)) {
|
||||||
|
const reward = Player.gainCodingContractReward(contract.reward, contract.getDifficulty());
|
||||||
|
workerScript.log(`Successfully completed Coding Contract ${fn}. Reward: ${reward}`);
|
||||||
|
serv.removeContract(fn);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
++contract.tries;
|
||||||
|
if (contract.tries >= contract.getMaxNumTries()) {
|
||||||
|
workerScript.log(`Coding Contract ${fn} failed. Contract is now self-destructing`);
|
||||||
|
serv.removeContract(fn);
|
||||||
|
} else {
|
||||||
|
workerScript.log(`Coding Contract ${fn} failed. ${contract.getMaxNumTries() - contract.tries} attempts remaining`);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getData : function(fn, ip=workerScript.serverIp) {
|
||||||
|
if (workerScript.checkingRam) {
|
||||||
|
return updateStaticRam("getData", CONSTANTS.ScriptCodingContractBaseRamCost / 2);
|
||||||
|
}
|
||||||
|
updateDynamicRam("getData", CONSTANTS.ScriptCodingContractBaseRamCost / 2);
|
||||||
|
var contract = getCodingContract(fn, ip);
|
||||||
|
if (contract == null) {
|
||||||
|
workerScript.log(`ERROR: codingcontract.getData() failed because it could find the specified contract ${fn} on server ${ip}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return contract.getData();
|
||||||
|
},
|
||||||
|
getDescription : function(fn, ip=workerScript.serverIp) {
|
||||||
|
if (workerScript.checkingRam) {
|
||||||
|
return updateStaticRam("getDescription", CONSTANTS.ScriptCodingContractBaseRamCost / 2);
|
||||||
|
}
|
||||||
|
updateDynamicRam("getDescription", CONSTANTS.ScriptCodingContractBaseRamCost / 2);
|
||||||
|
var contract = getCodingContract(fn, ip);
|
||||||
|
if (contract == null) {
|
||||||
|
workerScript.log(`ERROR: codingcontract.getDescription() failed because it could find the specified contract ${fn} on server ${ip}`);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return contract.getDescription();
|
||||||
|
},
|
||||||
|
getNumTriesRemaining : function(fn, ip=workerScript.serverIp) {
|
||||||
|
if (workerScript.checkingRam) {
|
||||||
|
return updateStaticRam("getNumTriesRemaining", CONSTANTS.ScriptCodingContractBaseRamCost / 2);
|
||||||
|
}
|
||||||
|
updateDynamicRam("getNumTriesRemaining", CONSTANTS.ScriptCodingContractBaseRamCost / 2);
|
||||||
|
var contract = getCodingContract(fn, ip);
|
||||||
|
if (contract == null) {
|
||||||
|
workerScript.log(`ERROR: codingcontract.getNumTriesRemaining() failed because it could find the specified contract ${fn} on server ${ip}`);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return contract.getMaxNumTries() - contract.tries;
|
||||||
|
},
|
||||||
}
|
}
|
||||||
} //End return
|
} //End return
|
||||||
} //End NetscriptFunction()
|
} //End NetscriptFunction()
|
||||||
|
@ -2298,12 +2298,26 @@ PlayerObject.prototype.gainCodingContractReward = function(reward, difficulty=1)
|
|||||||
return `Gained ${repGain} faction reputation for ${reward.name}`;
|
return `Gained ${repGain} faction reputation for ${reward.name}`;
|
||||||
case CodingContractRewardType.FactionReputationAll:
|
case CodingContractRewardType.FactionReputationAll:
|
||||||
const totalGain = CONSTANTS.CodingContractBaseFactionRepGain * difficulty;
|
const totalGain = CONSTANTS.CodingContractBaseFactionRepGain * difficulty;
|
||||||
const gainPerFaction = Math.floor(totalGain / this.factions.length);
|
|
||||||
for (const facName of this.factions) {
|
// Ignore Bladeburners and other special factions for this calculation
|
||||||
|
const specialFactions = ["Bladeburners"];
|
||||||
|
var factions = this.factions.slice();
|
||||||
|
factions = factions.filter((f) => {
|
||||||
|
return !specialFactions.includes(f);
|
||||||
|
});
|
||||||
|
|
||||||
|
// If the player was only part of the special factions, we'll just give money
|
||||||
|
if (factions.length == 0) {
|
||||||
|
reward.type = CodingContractRewardType.Money;
|
||||||
|
return this.gainCodingContractReward(reward, difficulty);
|
||||||
|
}
|
||||||
|
|
||||||
|
const gainPerFaction = Math.floor(totalGain / factions.length);
|
||||||
|
for (const facName of factions) {
|
||||||
if (!(Factions[facName] instanceof Faction)) { continue; }
|
if (!(Factions[facName] instanceof Faction)) { continue; }
|
||||||
Factions[facName].playerReputation += gainPerFaction;
|
Factions[facName].playerReputation += gainPerFaction;
|
||||||
}
|
}
|
||||||
return `Gained ${gainPerFaction} reputation for each faction you are a member of`;
|
return `Gained ${gainPerFaction} reputation for each of the following factions: ${factions.toString()}`;
|
||||||
break;
|
break;
|
||||||
case CodingContractRewardType.CompanyReputation:
|
case CodingContractRewardType.CompanyReputation:
|
||||||
if (reward.name == null || !(Companies[reward.name] instanceof Company)) {
|
if (reward.name == null || !(Companies[reward.name] instanceof Company)) {
|
||||||
|
@ -531,10 +531,12 @@ function parseOnlyRamCalculate(server, code, workerScript) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Special logic for Bladeburner
|
//Special logic for namespaces (Bladeburner, CodingCOntract)
|
||||||
var func;
|
var func;
|
||||||
if (ref in workerScript.env.vars.bladeburner) {
|
if (ref in workerScript.env.vars.bladeburner) {
|
||||||
func = workerScript.env.vars.bladeburner[ref];
|
func = workerScript.env.vars.bladeburner[ref];
|
||||||
|
} else if (ref in workerScript.env.vars.codingcontract) {
|
||||||
|
func = workerScript.env.vars.codingcontract[ref];
|
||||||
} else {
|
} else {
|
||||||
func = workerScript.env.get(ref);
|
func = workerScript.env.get(ref);
|
||||||
}
|
}
|
||||||
|
@ -458,35 +458,42 @@ function determineAllPossibilitiesForTabCompletion(input, index=0) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (input.startsWith("rm ")) {
|
if (input.startsWith("rm ")) {
|
||||||
for (var i = 0; i < currServ.scripts.length; ++i) {
|
for (let i = 0; i < currServ.scripts.length; ++i) {
|
||||||
allPos.push(currServ.scripts[i].filename);
|
allPos.push(currServ.scripts[i].filename);
|
||||||
}
|
}
|
||||||
for (var i = 0; i < currServ.programs.length; ++i) {
|
for (let i = 0; i < currServ.programs.length; ++i) {
|
||||||
allPos.push(currServ.programs[i]);
|
allPos.push(currServ.programs[i]);
|
||||||
}
|
}
|
||||||
for (var i = 0; i < currServ.messages.length; ++i) {
|
for (let i = 0; i < currServ.messages.length; ++i) {
|
||||||
if (!(currServ.messages[i] instanceof Message) && isString(currServ.messages[i]) &&
|
if (!(currServ.messages[i] instanceof Message) && isString(currServ.messages[i]) &&
|
||||||
currServ.messages[i].endsWith(".lit")) {
|
currServ.messages[i].endsWith(".lit")) {
|
||||||
allPos.push(currServ.messages[i]);
|
allPos.push(currServ.messages[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (var i = 0; i < currServ.textFiles.length; ++i) {
|
for (let i = 0; i < currServ.textFiles.length; ++i) {
|
||||||
allPos.push(currServ.textFiles[i].fn);
|
allPos.push(currServ.textFiles[i].fn);
|
||||||
}
|
}
|
||||||
|
for (let i = 0; i < currServ.contracts.length; ++i) {
|
||||||
|
allPos.push(currServ.contracts[i].fn);
|
||||||
|
}
|
||||||
return allPos;
|
return allPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input.startsWith("run ")) {
|
if (input.startsWith("run ")) {
|
||||||
//All programs and scripts
|
//All programs, scripts, and contracts
|
||||||
for (var i = 0; i < currServ.scripts.length; ++i) {
|
for (let i = 0; i < currServ.scripts.length; ++i) {
|
||||||
allPos.push(currServ.scripts[i].filename);
|
allPos.push(currServ.scripts[i].filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Programs are on home computer
|
//Programs are on home computer
|
||||||
var homeComputer = Player.getHomeComputer();
|
var homeComputer = Player.getHomeComputer();
|
||||||
for(var i = 0; i < homeComputer.programs.length; ++i) {
|
for (let i = 0; i < homeComputer.programs.length; ++i) {
|
||||||
allPos.push(homeComputer.programs[i]);
|
allPos.push(homeComputer.programs[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < currServ.contracts.length; ++i) {
|
||||||
|
allPos.push(currServ.contracts[i].fn);
|
||||||
|
}
|
||||||
return allPos;
|
return allPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1341,6 +1348,13 @@ let Terminal = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (delTarget.endsWith(".cct")) {
|
||||||
|
for (var i = 0; i < s.contracts.length; ++i) {
|
||||||
|
if (s.contracts[i].fn === delTarget) {
|
||||||
|
s.contracts.splice(i, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
post("Error: No such file exists");
|
post("Error: No such file exists");
|
||||||
break;
|
break;
|
||||||
@ -2154,13 +2168,14 @@ let Terminal = {
|
|||||||
if (Terminal.contractOpen) {
|
if (Terminal.contractOpen) {
|
||||||
return post("ERROR: There's already a Coding Contract in Progress");
|
return post("ERROR: There's already a Coding Contract in Progress");
|
||||||
}
|
}
|
||||||
Terminal.contractOpen = true;
|
|
||||||
|
|
||||||
const serv = Player.getCurrentServer();
|
const serv = Player.getCurrentServer();
|
||||||
const contract = serv.getContract(contractName);
|
const contract = serv.getContract(contractName);
|
||||||
if (contract == null) {
|
if (contract == null) {
|
||||||
return post("ERROR: No such contract");
|
return post("ERROR: No such contract");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Terminal.contractOpen = true;
|
||||||
const res = await contract.prompt();
|
const res = await contract.prompt();
|
||||||
|
|
||||||
switch (res) {
|
switch (res) {
|
||||||
@ -2170,10 +2185,12 @@ let Terminal = {
|
|||||||
serv.removeContract(contract);
|
serv.removeContract(contract);
|
||||||
break;
|
break;
|
||||||
case CodingContractResult.Failure:
|
case CodingContractResult.Failure:
|
||||||
post("Contract <p style='color:red;display:inline'>FAILED</p> - Contract is now self-destructing");
|
|
||||||
++contract.tries;
|
++contract.tries;
|
||||||
if (contract.tries >= contract.getMaxNumTries()) {
|
if (contract.tries >= contract.getMaxNumTries()) {
|
||||||
|
post("Contract <p style='color:red;display:inline'>FAILED</p> - Contract is now self-destructing");
|
||||||
serv.removeContract(contract);
|
serv.removeContract(contract);
|
||||||
|
} else {
|
||||||
|
post(`Contract <p style='color:red;display:inline'>FAILED</p> - ${contract.getMaxNumTries() - contract.tries} tries remaining`);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CodingContractResult.Cancelled:
|
case CodingContractResult.Cancelled:
|
||||||
@ -2182,6 +2199,7 @@ let Terminal = {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Terminal.contractOpen = false;
|
Terminal.contractOpen = false;
|
||||||
|
console.log(Terminal.contractOpen);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -21,6 +21,28 @@ export interface ICodingContractTypeMetadata {
|
|||||||
solver: SolverFunc;
|
solver: SolverFunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Helper functions for Coding Contract implementations */
|
||||||
|
function removeBracketsFromArrayString(str: string) {
|
||||||
|
let strCpy: string = str;
|
||||||
|
if (strCpy.startsWith("[")) { strCpy = strCpy.slice(1); }
|
||||||
|
if (strCpy.endsWith("]")) { strCpy = strCpy.slice(-1); }
|
||||||
|
|
||||||
|
return strCpy;
|
||||||
|
}
|
||||||
|
|
||||||
|
function convert2DArrayToString(arr: any[][]) {
|
||||||
|
let res = "";
|
||||||
|
const components: string[] = [];
|
||||||
|
arr.forEach((e) => {
|
||||||
|
let s = e.toString();
|
||||||
|
s = ["[", s, "]"].join("");
|
||||||
|
components.push(s);
|
||||||
|
});
|
||||||
|
|
||||||
|
res = components.join(",");
|
||||||
|
return res.replace(/\s/g, "");
|
||||||
|
}
|
||||||
|
|
||||||
export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
|
export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
|
||||||
{
|
{
|
||||||
desc: (n: number) => {
|
desc: (n: number) => {
|
||||||
@ -136,6 +158,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
|
|||||||
const matrix: number[][] = [];
|
const matrix: number[][] = [];
|
||||||
matrix.length = m;
|
matrix.length = m;
|
||||||
for (let i: number = 0; i < m; ++i) {
|
for (let i: number = 0; i < m; ++i) {
|
||||||
|
matrix[i] = [];
|
||||||
matrix[i].length = n;
|
matrix[i].length = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,7 +210,9 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
|
|||||||
}
|
}
|
||||||
if (++l > r) { break; }
|
if (++l > r) { break; }
|
||||||
}
|
}
|
||||||
const playerAns: any[] = ans.split(",");
|
|
||||||
|
const sanitizedPlayerAns: string = removeBracketsFromArrayString(ans);
|
||||||
|
const playerAns: any[] = sanitizedPlayerAns.split(",");
|
||||||
for (let i: number = 0; i < playerAns.length; ++i) {
|
for (let i: number = 0; i < playerAns.length; ++i) {
|
||||||
playerAns[i] = parseInt(playerAns[i], 10);
|
playerAns[i] = parseInt(playerAns[i], 10);
|
||||||
}
|
}
|
||||||
@ -282,22 +307,21 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
|
|||||||
}
|
}
|
||||||
result.push([start, end]);
|
result.push([start, end]);
|
||||||
|
|
||||||
const sanitizedResult: string = result
|
const sanitizedResult: string = convert2DArrayToString(result);
|
||||||
.toString()
|
|
||||||
.replace(/\s/g, "");
|
|
||||||
const sanitizedAns: string = ans.replace(/\s/g, "");
|
const sanitizedAns: string = ans.replace(/\s/g, "");
|
||||||
|
|
||||||
return sanitizedResult === sanitizedAns;
|
return (sanitizedResult === sanitizedAns ||
|
||||||
|
sanitizedResult === removeBracketsFromArrayString(sanitizedAns));
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: (data: string) => {
|
desc: (data: string) => {
|
||||||
return ["Given the following string containing only digits, determine",
|
return ["Given the following string containing only digits, return",
|
||||||
"an array with all possible valid IP address combinations",
|
"an array with all possible valid IP address combinations",
|
||||||
"that can be created from the string:\n\n",
|
"that can be created from the string:\n\n",
|
||||||
`${data}\n\n`,
|
`${data}\n\n`,
|
||||||
"Example:\n\n",
|
"Example:\n\n",
|
||||||
"'25525511135' -> ['255.255.11.135', '255.255.111.35']"].join(" ");
|
"25525511135 -> [255.255.11.135, 255.255.111.35]"].join(" ");
|
||||||
},
|
},
|
||||||
difficulty: 3,
|
difficulty: 3,
|
||||||
gen: () => {
|
gen: () => {
|
||||||
@ -425,7 +449,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
|
|||||||
return ["You are given the following array of stock prices where the i-th element",
|
return ["You are given the following array of stock prices where the i-th element",
|
||||||
"represents the stock price on day i:\n\n",
|
"represents the stock price on day i:\n\n",
|
||||||
`${data}\n\n`,
|
`${data}\n\n`,
|
||||||
"Determine the maximum possible profit you can earn using at most ",
|
"Determine the maximum possible profit you can earn using at most",
|
||||||
"two transactions. A transaction is defined as buying",
|
"two transactions. A transaction is defined as buying",
|
||||||
"and then selling one share of the stock. Note that you cannot",
|
"and then selling one share of the stock. Note that you cannot",
|
||||||
"engage in multiple transactions at once. In other words, you",
|
"engage in multiple transactions at once. In other words, you",
|
||||||
|
@ -917,7 +917,6 @@ const Engine = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
updateGame: function(numCycles = 1) {
|
updateGame: function(numCycles = 1) {
|
||||||
//Update total playtime
|
|
||||||
var time = numCycles * Engine._idleSpeed;
|
var time = numCycles * Engine._idleSpeed;
|
||||||
if (Player.totalPlaytime == null) {Player.totalPlaytime = 0;}
|
if (Player.totalPlaytime == null) {Player.totalPlaytime = 0;}
|
||||||
if (Player.playtimeSinceLastAug == null) {Player.playtimeSinceLastAug = 0;}
|
if (Player.playtimeSinceLastAug == null) {Player.playtimeSinceLastAug = 0;}
|
||||||
@ -1155,20 +1154,66 @@ const Engine = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Engine.Counters.contractGeneration <= 0) {
|
if (Engine.Counters.contractGeneration <= 0) {
|
||||||
// 5% chance of a contract being generated
|
// 20% chance of a contract being generated
|
||||||
if (Math.random() <= 0.05) {
|
if (Math.random() < 0.2) {
|
||||||
// First select a random problem type
|
// First select a random problem type
|
||||||
let problemTypes = Object.keys(CodingContractTypes);
|
const problemTypes = Object.keys(CodingContractTypes);
|
||||||
let randIndex = getRandomInt(0, problemTypes.length - 1);
|
let randIndex = getRandomInt(0, problemTypes.length - 1);
|
||||||
let problemType = CodingContractTypes[problemTypes[randIndex]];
|
let problemType = problemTypes[randIndex];
|
||||||
|
|
||||||
// Then select a random reward type. 'Money' will always be the last reward type
|
// Then select a random reward type. 'Money' will always be the last reward type
|
||||||
let rewardType = getRandomInt(1, CodingContractRewardType.Money);
|
var reward = {};
|
||||||
|
reward.type = getRandomInt(0, CodingContractRewardType.Money);
|
||||||
|
|
||||||
|
// Change type based on certain conditions
|
||||||
|
if (Player.factions.length === 0) { reward.type = CodingContractRewardType.CompanyReputation; }
|
||||||
|
if (Player.companyName === "") { reward.type = CodingContractRewardType.Money; }
|
||||||
|
|
||||||
// Add additional information based on the reward type
|
// Add additional information based on the reward type
|
||||||
switch (rewardType) {
|
switch (reward.type) {
|
||||||
case CodingContractRewardType
|
case CodingContractRewardType.FactionReputation:
|
||||||
|
// Get a random faction that player is a part of. That
|
||||||
|
//faction must allow hacking contracts
|
||||||
|
var numFactions = Player.factions.length;
|
||||||
|
var randFaction = Player.factions[getRandomInt(0, numFactions - 1)];
|
||||||
|
try {
|
||||||
|
while(Factions[randFaction].getInfo().offerHackingWork !== true) {
|
||||||
|
randFaction = Player.factions[getRandomInt(0, numFactions - 1)];
|
||||||
|
}
|
||||||
|
reward.name = randFaction;
|
||||||
|
} catch (e) {
|
||||||
|
exceptionAlert("Failed to find a faction for Coding Contract Generation: " + e);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case CodingContractRewardType.CompanyReputation:
|
||||||
|
if (Player.companyName !== "") {
|
||||||
|
reward.name = Player.companyName;
|
||||||
|
} else {
|
||||||
|
reward.type = CodingContractRewardType.Money;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Choose random server
|
||||||
|
const servers = Object.keys(AllServers);
|
||||||
|
randIndex = getRandomInt(0, servers.length - 1);
|
||||||
|
var randServer = AllServers[servers[randIndex]];
|
||||||
|
while (randServer.purchasedByPlayer === true) {
|
||||||
|
randIndex = getRandomInt(0, servers.length - 1);
|
||||||
|
randServer = AllServers[servers[randIndex]];
|
||||||
|
}
|
||||||
|
|
||||||
|
let contractFn = `contract-${getRandomInt(0, 1e6)}`;
|
||||||
|
while (randServer.contracts.filter((c) => {return c.fn === contractFn}).length > 0) {
|
||||||
|
contractFn = `contract-${getRandomInt(0, 1e6)}`;
|
||||||
|
}
|
||||||
|
if (reward.name) { contractFn += `-${reward.name.replace(/\s/g, "")}`; }
|
||||||
|
let contract = new CodingContract(contractFn, problemType, reward);
|
||||||
|
|
||||||
|
randServer.addContract(contract);
|
||||||
}
|
}
|
||||||
Engine.Counters.contractGeneration = 3000;
|
Engine.Counters.contractGeneration = 3000;
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ interface ICreateElementListenerOptions {
|
|||||||
clickListener?(this: HTMLElement, ev: MouseEvent): any;
|
clickListener?(this: HTMLElement, ev: MouseEvent): any;
|
||||||
inputListener?(this: HTMLElement, ev: Event): any;
|
inputListener?(this: HTMLElement, ev: Event): any;
|
||||||
onfocus?(this: HTMLElement, ev: FocusEvent): any;
|
onfocus?(this: HTMLElement, ev: FocusEvent): any;
|
||||||
|
onkeydown?(this: HTMLElement, ev: KeyboardEvent): any;
|
||||||
onkeyup?(this: HTMLElement, ev: KeyboardEvent): any;
|
onkeyup?(this: HTMLElement, ev: KeyboardEvent): any;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,6 +149,9 @@ function setElementListeners(el: HTMLElement, params: ICreateElementListenerOpti
|
|||||||
if (params.onkeyup !== undefined) {
|
if (params.onkeyup !== undefined) {
|
||||||
el.addEventListener("keyup", params.onkeyup);
|
el.addEventListener("keyup", params.onkeyup);
|
||||||
}
|
}
|
||||||
|
if (params.onkeydown !== undefined) {
|
||||||
|
el.addEventListener("keydown", params.onkeydown);
|
||||||
|
}
|
||||||
if (params.onfocus !== undefined) {
|
if (params.onfocus !== undefined) {
|
||||||
el.addEventListener("focus", params.onfocus);
|
el.addEventListener("focus", params.onfocus);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user