Bitburner – All-In-One 3GB: Gang Script with HUD
This is a 500+ line, all-in-one Gang script that I created. Here are the main features
- Only 3 GB memory footprint
- SINGLE script contained (no additional scripts necessary)
- All Gang actions handled (comment me to get more details).
- Great HUD to quickly see the status of gang stuff
- Assists with recruitment, ascension, and other tasks
- Automated Equipment Purchases with a Budget
- Territorial warfare is handled using custom parameters
- You can make your play-style completely customizable
The comments should make it clear how the code works. You can also see the DEBUG lines in the comments. Feel free to delete them. All comments are welcome
Table of Contents
Introduction
To maintain a 3.0 GB memory footprint, the latest update uses external script-running code (adapted by Alain Bryden). Gang Ops can now be run quickly!
* Gang members are automatically named from 0 to 11. This is for ease of programming, reference, and listing. However, you can program in custom names if desired.
* I have also tried the concept of
‘ranks’
It allows you to determine when your members should ascend. This is done by tracking their stats levels (even after factoring).
* Warfare can be managed automatically and will stop when territory reaches 100 percent (don’t underestimate warfare, as the cashflow gains are very exponential).
*
There are many theories, discussions, and ideas about how to manage gang members
. I hope you find the code useful and flexible enough to allow you to customize it.
Log Window can be used to view the current events in a small HUD. You don’t have to scroll through Gang menus all the time. The log HUD can be minimized and moved to the corner of your screen when it is not being used.
Personally, I like to keep the log window that covers the Health status line (as it isn’t important, healing costs scale linearly). You can expand it whenever you need it.
The HUD displays:
1. Each
member number
What and how?
current task
They are engaged in
2.
Member stats
For Strength, Defense, Dexterity and Agility. Ascension rank
3. #
Times looped
,
Buy stuff setting
, $
Money spent on equipment
,
Current money
4.
Minimum money setting
,
Respected
,
Needed level
5. W
Penalty percentage
, Wan/Resp:
Respect ratio
6.
Involved in war?
Members in war
,
Territory % Owned + History
Code Part 1: Settings
//=============================================================================
// GANG V5 Requires 3GB RAM by Troff//Note : This is NOT a hack (i.e. combat gang) gang script.
//Version 5 – Added automated config file handling (no manual stuff!)
// Minor improvements made, including better war management and also
// Excluding non-combat equipment in order to save money
Dinkum – How to Move Farm Animals to Another Location
//To get more information or to turn ON lines marked with “DEBUG”, you can either
// to troubleshoot. You can delete them if they aren’t needed.
/** @param “NS” ns **/
export async function main(ns) {
// ===============================================
// SETTINGS START (changes as needed)
//Text length for gang member’s task displayed. var lenCom = 21
let buyStuff = 1; //Can gang members buy equipment? 1=Yes, 0=No
Let minCash=50111222; //Minim cash to keep (gang equipment can be expensive)
//let minCash=52333111222 //Min cash (25/50B Stock market API)
//let minCash=150333111222 //Min cash (150B for a corporation to be started)
Let maxrank = 7. // Maximum rank for each member of the gang
Let equiprank = 2 // The rank at which members can purchase equipment (default: 2)
let defaulttask = Trafick Illegal Arms; //Default task if there are no criteria
Let sleepdelay = 16000 // Pause in milliseconds after each loop
// War team (e.g. The first 6 stop automatically when we reach 100% territory
Let warguys = 6. // The number of gang members that can engage in territory warfare
Let warchance = 0.97 // Minimum win chance before starting war with gangs
// ### Ascension Level Settings (adjust as necessary) //
// Read up on gang level progression. Do a clean sweep & take a note
// Your own rules/levels, etc. We use rank numbers for tracking ascension levels.
// e.g. 4=934 stats, 5=56k. You can add more, but you may need to adjust some code
let ascend = true // Do we check ascensions
Let rnk1 equal 98; // Rank 1. (gives you a x2 multiplier).
// Let rnk2 equal 274; //Rank 2 (gives an x4 multiplier and +0.25 rate).
Let rnk3 equal 550 // Rank 3 (gives an x6 multiplier).
Let rnk4= 934; // Rank 4. (x8 multiplier).
Let rnk5 equal 56000 // Rank 5 (x19 multiplier combined with mods).
Let rnk6 equal 145111 // Rank 6 (6 x 36 multiplier with mods).
Let rnk7 equal 380111 // Rank 7. (x80-82 multiplier combined with mods).
//let rnk8= 1256111 // Rank 8 (roughly 1 billion/second income).
//TO DO in V6 – Automate rank 8 to accommodate higher levels
// When Vigilante work can be started to lower Wanted levels
Let minVResp = 1. // Minimum respect for vigilante work
Let minVPen equal 10; // If Penalty is above this, then do Vigi work
Let minVWant equal 5; // If desired level is higher than this, then do vigi
Let minVRank = (rnk2); // Minimum member rank for vigi
// SETTINGS EXTEND
// ===============================================
// Set DEFAULT VARIEABLES (don’t change anything).
loops = 0, // Keeps track of loops
// lets you keep track of when to check ascensionCounter = 0.
// Set default ascension ranks for members. Name members 0, 1, 2, etc
let ascmem = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
Let lengthdump = 0. // Gang size default read from cfg.
Let war = false // Make territory warfare false
// Define default territory for gangs (more variables are needed as turnover is greater)
var gangt0 = 0; var gangt1 = 0; var gangt2 = 0; let gangtx = 0;
Let ganginwar = 0. // Add counter to number of members in territory warfare
// Disable logs
ns.disableLog(“disableLog”); ns.disableLog(“sleep”); ns.disableLog(“exec”);
ns.disableLog(“getServerMoneyAvailable”);ns.disableLog(“gang.ascendMember”);
ns.disableLog(“gang.setMemberTask”);ns.disableLog(“gang.purchaseEquipment”);
ns.disableLog(“gang.recruitMember”);ns.disableLog(“gang.setTerritoryWarfare”);
// Show log start in logs by opening a log window
ns.tail();
ns.print (” GANG SCRIPT START”)
// Try to find the current ranks of gang members from text configuration file
//ns.print(“Starting to read gang txt file… “); // DEBUG
if ( ns.fileExists(“/Temp/gang-cfg.txt”, “home”) ){
ns.print(“INFO ## Gang txt file EXISTS ##”)
let listnames = [];
var datadump = JSON.parse(ns.read(“/Temp/gang-cfg.txt”));
{ if (datadump.length > 0) If (datadump.length> 0),
lengthdump = datadump.length // Transfer value to check later
for (var ij = 0; ij < datadump.length; ij++) {
listnames[ij] = datadump[ij].name;
ascmem[ij] = datadump[ij].ascmem;
ns.print(“N: “, listnames[ij], ” Asc: “, ascmem[ij])
}
}
}
// If the number of gang members are too low, it is necessary to reset your config file
// This assumes that you will have more than three guys for subsequent launches.
// This is not something to do once you have more than three guys.
// subsequent stops and restarting this script.
{ if (lengthdump < 4) If (lengthdump > 4)
const resetconfig = await setGangFile (ns);
//ns.sleep (100); // Be safe.
ns.print (“Resetting gang file: “, resetconfig);
// In the meantime, load the reset variables into your memory.
ascmem = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
}
// ###################################
// MAIN WHILE START
{ while (true) While (true).
// To make sure the log window is perfect, resize it to the size of the red dots
// Blank line to separate loops
ns.print (” G A N T “);
// Get information about Gangs, Cash and Equipment
let myGang = await runCom1(ns, ‘ns.gang.getGangInformation()’, ‘getGangInfo’);
let curCash=await runCom1(ns, ‘ns.getServerMoneyAvailable(ns.args[0])’,’getSerMon’, [“home”]);
let allEquipment = await runCom1(ns, ‘ns.gang.getEquipmentNames()’, ‘getEqName’);
var curResp = ns.nFormat(myGang.respect, “0,0.a”);
var curResp2 = myGang.respect
//DEBUG
// Recruit members if possible
var canrecruit = await runCom1(ns, ‘ns.gang.canRecruitMember()’, ‘canRecr’);
//ns.print(“INFO Can recruit: ” + canrecruit); // DEBUG
{ while ( canrecruit == true ) While ( canrecruit == true)
for (let ij = 0; ij < 30; ++ij) {
var canrecruit=await runCom1(ns,’ns.gang.canRecruitMember()’,’canRecr’);
//ns.print(“INFO Can recruit: ” + canrecruit); // DEBUG
if (canrecruit == true) {
ns.print(“RECRUITED: ” + ij + “”);
}
}
}
// Get gang member names
let members = await runCom1(ns, ‘ns.gang.getMemberNames()’,’getMemNam’);
// Get Territory % to get the ‘wanted more respect’ level
var ganginfo = await runCom1(ns,’ns.gang.getGangInformation()’,’getGangInfo’);
gangtx = ganginfo.territory;
var curResp = ganginfo.respect;
var curWant = ganginfo.wantedLevel;
var curPena2b = ganginfo.wantedLevel/ganginfo.respect * 100;
//ns.print(“Want/Respect: ” + ns.nFormat(curPena2b, “0,0.00”) +” %” );
// //Reset check to reset status for territory warfare and gang members
ganginwar = 0;
False warfare
Code Part 2: Main Loop
// ###### MAIN TO LOOP START #####
for (let ij = 0; ij < members.length; ++ij) {
var member = members[ij];
var memberInfo = await runCom1(ns, ‘ns.gang.getMemberInformation(ns.args[0])’,’getMemInf’, [member]);// @@@@@@@@ Check Equipment START @@@@@@@@@@@
// Track cash spent within loop
//ns.print(“BUYSTUFF: ” + buyStuff); // DEBUG
//ns.print(“*members.length: ” + members.length); // DEBUG
if (buyStuff==1) {
{ for (var j = 0; j < allEquipment.length; ++j) for (var.j = 0;j allEquipment.length, ++j);
var equipment = allEquipment[j]
//var eqdebug=equipment.toString(); ns.print(eqdebug); //DEBUG
//ns.print(“Chk”,equipment,memberInfo.upgrades.indexOf(equipment));
//Above returns AWM Sniper Rifle 12, Graphene Armor -1 etc //DEBUG
//ns.print(“Checking: “,equipment); // DEBUG
//A guy of a certain rank who doesn’t have non-hacking stuff should buy it
if ( (memberInfo.upgrades.indexOf(equipment) == -1) && (memberInfo.augmentations.indexOf(equipment) == -1) && ascmem[ij] >= equiprank && equipment != “NUKE Rootkit” && equipment != “Soulstealer Rootkit” && equipment != “Demon Rootkit” && equipment != “Hmap Node” && equipment != “Jack the Ripper” && equipment != “DataJack” && equipment != “Neuralstimulator” && equipment != “BitWire”) {
var cost = await runCom1(ns, ‘ns.gang.getEquipmentCost(ns.args[0])’,’getEqCost’, [equipment]);
{ if ( (cost + minCash) < curCash ) If ((cost + minCash), curCash )
var gangbuy = await runCom1(ns, ‘ns.gang.purchaseEquipment(ns.args[0], ns.args[1])’,’getEqCost’, [member, equipment]);
//ns.print(“gangbuy: ” + gangbuy); // DEBUG
if (gangbuy == true) {
CashSpen = cashSpen + cost
ns.print (“: “+ equipment + “@” + member);
curCash=await runCom1(ns, ‘ns.getServerMoneyAvailable(ns.args[0])’,’getSerMon’, [“home”]);
}
}
}
}
}
// @@@@@@@@@@ Check Equipment. END @@@@@@@@@@@
// Get member variables
// Strength
// Defence
var memdex = membersInfo.dex, // Dexterity
// Agility
//##############################################################
//ASSIGN Tasks (series “if else” statements that can be edited as needed)
//#Wanted Status: If it is too high, be vigilant to lower it
{ if (curResp>minVResp && curPena2b>minVPen && curWant>minVWant && memstr>minVRank) If (curResp>minVResp and& curPena2b>minVPen and& curWant>minVWant&& memstr>minVRank),
var gangtask = “Vigilante Justice”;
await runCom1(ns,’ns.gang.setMemberTask(ns.args[0], ns.args[1])’,’setGnTask’, [member, gangtask]);
ns.print(“”+ij +”. r0:”+member+” >”+gangtask.substring(0,lenCom) );
}
//#Rank 1: Train Combat until all stats are Ranked 2
Other if (memstr) var gangtask = “Train Combat”;
__S.303__
__S.304__ __S.305__
__S.306__
//#Rank 3: If ranked 1-4, train Combat until combat stats Ranked 4
Other if ((memstr) var gangtask = “Train Combat”;
__S.321__
__S.322__ __S.323__
}
//EXAMPLE: Additional criteria that can easily be added using if’s
//#Rank5: Train Combat to rank 6, and members 3-11
/* other if ( (memstr 3 && members.length < 12 && maxrank == 3 ){
__S.342__
__S.343__
__S.344__ __S.345__
__S.346__
//#Terrorism – Do until Respect reaches 10,000,000 (for ascension usage)
{ else if (curResp2 < 10111222) Other if (curResp2 > 10111222)
var gangtask = “Terrorism”;
await runCom1(ns,’ns.gang.setMemberTask(ns.args[0], ns.args[1])’,’setGnTask’, [member, gangtask]);
ns.print(“”+ij +”. r3:”+member+” >”+gangtask.substring(0,lenCom) );
}
//#TERRORITY WARREN: Give a task to a guy who is above rank 2. Members must be at least 9.
// is part war team (warguys), and territory 100% conquered. (gangtx).
else if(ascmem[ij]>2 && members.length>9 && (ij>=0 && ij ganginwar = ganginwar + 1; // Increment counter for gangs in warfare
__S.374__
__S.375__
__S.376__
__S.377__
__S.378__ __S.379__
//Check war potential against clans
const dowewar=await checkgangwar(ns, warchance);//Warcheck function
if (dowewar == true) {
Warfare = True
await runCom1(ns, ‘ns.gang.setTerritoryWarfare(ns.args[0])’,’setWar’, [true]);
//DEBUG
else or else
await runCom1(ns, ‘ns.gang.setTerritoryWarfare(ns.args[0])’,’setWar’, [false]);
}
}
//#Trafficking/Illegal Arms: (money making actions here!)
//If you have enough respect, money-gathering task
{ else if (curResp2 > 10111222) Other than that, if (curResp2> 10111222)
var gangtask = “Traffick Illegal Arms”;
//var Gangtask = “Human Trafficking” // Modify if you wish
await runCom1(ns,’ns.gang.setMemberTask(ns.args[0], ns.args[1])’,’setGnTask’, [member, gangtask]);
ns.print(“”+ij +”. r4:”+member+” > “+gangtask.substring(0,lenCom) );
}
//#DEFAULT – If all else fails, assign the guy the default task
{ else Other information
var gangtask = defaulttask; // Default task
await runCom1(ns,’ns.gang.setMemberTask(ns.args[0], ns.args[1])’,’setGnTask’, [member, gangtask]);
ns.print(“”+ij +”. :”+member+” > “+gangtask.substring(0,lenCom) );
}
// Print Statistics and Rank (brain icon).
//A fixed length of 5 looks nicer than leading 0s, which makes comparison easier
var mstr = ns.nFormat(memstr, “00000”); // Strength (muscle icon)
var mdef = ns.nFormat(memdef, “00000”); // Defense (bone emoji)
var mdex = “00000”, memdex; // Dexterity (eyes with emoji).
var magi = @ns.nFormat (memagi, “00000”) // Agility (feet icons)
ns.print(” “+mstr+” “+mdef+” “+mdex+” “+magi+” ” +ascmem[ij]);
}
// ###### MAIN END #####
Code Part 3: Ascension and Misc
// @@@@@@@@@ START
If (ascensionCounter!= 50) // Check every 50 loops//Note: We need to verify current rankings (ascmem[ij] every time).
//to avoid duplications in rulesets
{ if (ascend == true) If (ascend == true),
for (let ij = 0; ij < members.length; ++ij) {
let member = members[ij];
//// Refresh your member statistics
var memberInfo = await runCom1(ns, ‘ns.gang.getMemberInformation(ns.args[0])’,’getMemInf’, [member]);
var memstr = memberstr; var mymdef = membersInfo.def.
var memdex = membersInfo.dex; and var memagi = membersInfo.agi
/*
//# Ascend to rank 8. [EXAMPLE OF THE Custom Ascension Rule]
if (memstr>=rnk8 && ascmem[ij]==7 && maxrank >= 8 ){
ns.gang.ascendMember(member);
ns.print (“Rank 4>5, + member + ” ascended!” “);
ascmem[ij] = 5. // Change ascension status rank from 5 to 5.
}
*/
//# Ascend to rank 7.
if (memstr>=rnk7 && ascmem[ij]==6 && maxrank >=7 ){
await runCom1(ns,’ns.gang.ascendMember(ns.args[0])’,’ascMem’, [member]);
ns.print (“Rank 6>7”, “+ member + ” ascended!” “);
ascmem[ij] = 7. // Change ascension status rank from 5 to 7
}
//# Ascend to rank 6
if (memstr>=rnk6 && ascmem[ij]==5 && maxrank >=6 ){
await runCom1(ns,’ns.gang.ascendMember(ns.args[0])’,’ascMem’, [member]);
ns.print (“Rank 5>6, + member +, ” ascended!” “);
ascmem[ij] = 6. // Change ascension status rank from 6 to 4.
//countrank2 = countrank2 + 1;
}
//# Ascend to rank 5.
if (memstr>=rnk5 && ascmem[ij]==4 && maxrank >=5 ){
await runCom1(ns,’ns.gang.ascendMember(ns.args[0])’,’ascMem’, [member]);
ns.print (“Rank 4>5, + member + ” ascended!” “);
ascmem[ij] = 5. // Change ascension status rank from 5 to 3.
}
//# Ascend to rank #4
else if (memstr>=rnk4 && ascmem[ij]==3 && maxrank >= 4 ){
await runCom1(ns,’ns.gang.ascendMember(ns.args[0])’,’ascMem’, [member]);
ns.print (“Rank 3>4, + member +, “ascended!” “);
ascmem[ij] = 4. // Change ascension status rank from 4 to 4.
}
//# Ascend To Rank 3 To Boost XP On The Way to Rank 4, Approx 25 Mins
else if (memstr>=rnk3 && memagi>=rnk3 && ascmem[ij]==2){
await runCom1(ns,’ns.gang.ascendMember(ns.args[0])’,’ascMem’, [member]);
ns.print (“Rank 2>3, + member +, “ascended!” “);
ascmem[ij] = 3. // Change ascension status rank from 3 to 4.
}
//# Ascend to rank 2.
else if(memstr>=rnk2 && memagi>=rnk2 && ascmem[ij]==1) {
await runCom1(ns,’ns.gang.ascendMember(ns.args[0])’,’ascMem’, [member]);
ns.print (“Rank 1>2, + member +, “ascended!” “);
ascmem[ij] = 2. // Change ascension status rank from 1 to 2.
}
//# Ascend rank 1 early to ‘boost xp gain, approximately 25 minutes
else if (memstr>=rnk1 && memagi>=rnk1 && ascmem[ij]==0){
await runCom1(ns,’ns.gang.ascendMember(ns.args[0])’,’ascMem’, [member]);
ns.print (“Rank 0>1, + member +, “ascended!” “);
ascmem[ij] = 1. // Change ascension status rank from 1 to 1.
}
}
}
// @@@@@@@@@ ASCEND SECTION @@@@@@@@
loops++; // Increment loop counter
// #### START Write status in txt file ####
var txtstring = “[“;
let members3 = await runCom1(ns, ‘ns.gang.getMemberNames()’,’getMemNam’);
for (let ij = 0; ij < members3.length; ++ij) {
var member = members3[ij];
var myGang2 = await runCom1(ns, ‘ns.gang.getMemberInformation(ns.args[0])’,’getMemInf’, [member]);
txtstring = txtstring + ‘{\”name\”:\”‘ + myGang2.name + ‘\”, ‘;
txtstring = txtstring + ‘\”ascmem\”:’ + ascmem[ij] + ‘}’;
if (ij!=members3.length-1) txtstring = txtstring + ‘,’
}
txtstring = txtstring + ‘]’;
var filewrite = await ns.write(“/Temp/gang-cfg.txt”, txtstring, “w”);
// #### Write status to txt ####
// SHOW STATUS
var money = $ns.nFormat (curCash, “0.0.0a”)); //Money in Hand: Cur
var minCash2 = ns.nFormat(minCash, “0,0.0a”); //Minimum cash level: Min
var getGang = await runCom1(ns, ‘ns.gang.getGangInformation()’, ‘getGangInfo’);
var curResp = ns.nFormat(getGang.respect, “0,0.0a”); // Respect: Res
var curWant =ns.nFormat(getGang.wantedLevel, “0,0.0a”);//Wanted level: W
var curPena =ns.nFormat(myGang.wantedPenalty,”0.00a”);//Penalty level: W
var curPenaRatio =getGang.wantedLevel/getGang.respect *100;//Penalty ratio
var curPenaRatio2 = ns.nFormat( curPenaRatio , “0.00a”) ; //Nicer format
gangt2 = gangt1; gangt1 = gangt0; gangt0 = gangtx;//Add territory history
gangtx = getGang.territory; // Get current territory history
gangt2 = (ns.nFormat)gangt2, “0.00 %”); // Convert into percentage
gangtx = (ns.nFormat,gangtx), “0.00 %”); // Convert into percentage
ns.print(“#: “+loops+” :” +buyStuff+” :$” +cashSpen+” Cur $” +money);
ns.print(“Min: $” + minCash2 +” Res: ” +curResp + ” W: ” +curWant);
ns.print(“W Pen:” +curPena +”%” +” Wan/Resp:” +curPenaRatio2 +”%”);
ns.print(“:”+warfare+” :”+warguys +” : “+gangt2 +” > “+ gangtx);
ns.print(“”);//Bottom footer
await sleep(sleepdelay);
//Check to see if the gang has 3+ guys ranked too high. If so, reset the config file
//This flag identifies a bug in the gang script if it crashes/ends unexpectedly
{ if (members3.length < 4 && ascmem[0]>2 && ascmem[1]>2 && ascmem[2]>2) If (members3.length > 4 && Ascmem[0]>2 and& Ascmem[1]>2&& Ascmem[2]>2&& Ascmem[2]>2)
const resetconfig = await setGangFile (ns);
ns.print (“Resetting gang file: “, resetconfig);
ascmem=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
}
}
// MAIN WHILE LOOKING END
// ###################################
}
Code Part 4: Functions
// Function: Sleep
{ function sleep(ms) Function sleep (ms)
return new Promise(resolve => setTimeout(resolve, ms));
// Function: Check chances of war against other gangs|// Funktion: Verify war chances against other gangs}
{ export async function checkgangwar(ns, winchance) Export async function checkgangwar (ns, winchance),
var gangresult = true; // By default we CAN engage in warfare
// Gang names for reference:
// Tetrads. The Syndicate. Speakers for the dead
// The Black Hand, The Dark Army and NiteSec
//const othergang = ns.gang.getOtherGangInformation(); // DEBUG
//ns.print(“Name : “+JSON.stringify(othergang[‘Tetrads’]) ); //DEBUG
//ns.print(“Power: “+JSON.stringify(othergang[‘Tetrads’].power) ); //DEBUG
//ns.print(“Terro: “+JSON.stringify(othergang[‘Tetrads’].territory));//DEB
//ns.print(“Clash: “+ns.gang.getChanceToWinClash(‘Tetrads’) ); //DEBUG
// Win wars for all other gangs
var chantetr = await runCom1(ns, ‘ns.gang.getChanceToWinClash(ns.args[0])’,’getChanWin’, [“Tetrads”]);
var chansynd = await runCom1(ns, ‘ns.gang.getChanceToWinClash(ns.args[0])’,’getChanWin’, [“The Syndicate”]);
var chanspea = await runCom1(ns, ‘ns.gang.getChanceToWinClash(ns.args[0])’,’getChanWin’, [“Speakers for the Dead”]);
var chanblac = await runCom1(ns, ‘ns.gang.getChanceToWinClash(ns.args[0])’,’getChanWin’, [“The Black Hand”]);
var chandark = await runCom1(ns, ‘ns.gang.getChanceToWinClash(ns.args[0])’,’getChanWin’, [“The Dark Army”]);
var channite = await runCom1(ns, ‘ns.gang.getChanceToWinClash(ns.args[0])’,’getChanWin’, [“NiteSec”]);
//ns.print(“Tetrads %: ” + ns.nFormat(chantetr, “0.00%”)); //DEBUG
//ns.print(“Syndicate %: ” + ns.nFormat(chansynd, “0.00%”)); //DEBUG
//ns.print(“Speakers %: ” + ns.nFormat(chanspea, “0.00%”)); //DEBUG
//ns.print(“Black Hand%: ” + ns.nFormat(chanblac, “0.00%”)); //DEBUG
//ns.print (“Dark Army%: ” +.ns.nFormat[chandark, “0.00 %”)); //DEBUG
//ns.print(“NiteSec %: ” + ns.nFormat(channite, “0.00%”)); //DEBUG
// Make sure you are able to engage in war if the chances are not.
if (chantetr < winchance) gangresult = false;
if (chansynd < winchance) gangresult = false;
if (chanspea < winchance) gangresult = false;
if (chanblac < winchance) gangresult = false;
if (chandark < winchance) gangresult = false;
if (channite < winchance) gangresult = false;
//ns.print(“INFO GangResult : ” + gangresult ); //DEBUG
if (gangresult == true) return true;
if (gangresult == false) return false;
}
// Function: Reset Gang File
// The contents of the new default Gang-Cfg.txt files are as follows:
// [“name”:”0”,”ascmem”:0,”name”:”1”,”ascmem”:0,”name”:”2”,”ascmem”:0]
function resetGangFile(ns) {
ns.print(“WARN Writing new gang config file…”);
const cfgScriptContent = “[\”name\”:\”0\”, \”ascmem\”:0,\”name\”:\”1\”, \”ascmem\”:0,\”name\”:\”2\”, \”ascmem\”:0]”;
const cfgScript = “/Temp/gang-cfg.txt”;
ns.write(cfgScript, cfgScriptContent, “w”);
Return true
}
//=============================================================================
// External SCRIPT RUNNER STOART (adapted/shortened fr ALAIN BRYDEN’s scripts).
{export async function runCom1(ns, command, fileName, args = []) Export async function RunCom1 (ns, command. fileName. args = []).
var precursor = “gang5”; // Could also be blade-, gang, or other similar terms
var fileName = “/Temp/” + precursor + fileName + “.txt”;
var fileName2 = FileName + “.js”
//ns.print (“fileName =”, fileName”) // DEBUG
//ns.print (“fileName2 =”, fileName2) // DEBUG
// COMPLEX SCRIPT
let script = `export async function main(ns) {` +
`let r;try{r=JSON.stringify(\n` +
` $command\n` +
`);}catch(e)\n` +
`const f=”$fileName”; if(ns.read(f)!==r) await ns.write(f,r,’w’) } `;
var oldContents = (ns.read);
{ while (oldContents != script) While (oldContents!= script)
await ns.write(fileName2, script, “w”);
// Wait for the script to become readable (can be tricky on writing).
var oldContents = (ns.read);
}
//ns.print (“args=”, args”) // DEBUG
for (var ij = 0; ij < 5; ij++) { if (args[ij] == null) args[ij] = “0”;
//ns.print (“args[“,ij,”] = “, args[ij]) // DEBUG
};
//Run the script
await ns.exec(fileName2,”home”,1,args[0],args[1],args[2],args[3]);
//await ns.sleep(50);
// We “try” to catch JSON errors. They disappear after 1-2 loops.
const fileData = await ns.read(fileName);
{ try Try
var fileData2 = JSON.parse(fileData);
} catch(e) {
console.log (‘Unable to parse string.’).
}
Return fileData2
}
// External SCRIPT RUNNER EXTEND
//=============================================================================
//End of Line
Conclusion
As time passes, I will be updating the script. Already, I have received some comments about some of the things that may not be optimal. Feel free to comment and cannibalize my code for your own scripts or functions!
We wish you a lot of success and a warm welcome!