Bug fixes in dev menu. Gang member stat mult tooltip now properly updates. Beginning re-work of territory warfare/clash

This commit is contained in:
danielyxie 2018-10-18 14:52:02 -05:00
parent c4dbfa43c9
commit a0ebcff0aa
2 changed files with 183 additions and 102 deletions

@ -3,6 +3,7 @@ import {Programs} from "./CreateProgram"
import {Factions} from "./Faction"; import {Factions} from "./Faction";
import {Player} from "./Player"; import {Player} from "./Player";
import {AllServers} from "./Server"; import {AllServers} from "./Server";
import {hackWorldDaemon} from "./RedPill";
import {Terminal} from "./Terminal"; import {Terminal} from "./Terminal";
import {exceptionAlert} from "../utils/helpers/exceptionAlert"; import {exceptionAlert} from "../utils/helpers/exceptionAlert";
import {createElement} from "../utils/uiHelpers/createElement"; import {createElement} from "../utils/uiHelpers/createElement";
@ -69,7 +70,7 @@ export function createDevMenu() {
const statsHackingExpInput = createElement("input", { const statsHackingExpInput = createElement("input", {
class: "text-input", class: "text-input",
display: "block", margin: "5px",
placeholder: "+/- hacking exp", placeholder: "+/- hacking exp",
type: "number", type: "number",
}); });
@ -80,14 +81,13 @@ export function createDevMenu() {
Player.gainHackingExp(exp); Player.gainHackingExp(exp);
Player.updateSkillLevels(); Player.updateSkillLevels();
}, },
display: "block",
innerText: "Add Hacking Exp", innerText: "Add Hacking Exp",
}); });
const statsStrengthExpInput = createElement("input", { const statsStrengthExpInput = createElement("input", {
class: "text-input", class: "text-input",
display: "block", margin: "5px",
placeholder: "+/- hacking exp", placeholder: "+/- strength exp",
type: "number", type: "number",
}); });
const statsStrengthExpButton = createElement("button", { const statsStrengthExpButton = createElement("button", {
@ -97,14 +97,13 @@ export function createDevMenu() {
Player.gainStrengthExp(exp); Player.gainStrengthExp(exp);
Player.updateSkillLevels(); Player.updateSkillLevels();
}, },
display: "block", innerText: "Add Strength Exp",
innerText: "Add Hacking Exp",
}); });
const statsDefenseExpInput = createElement("input", { const statsDefenseExpInput = createElement("input", {
class: "text-input", class: "text-input",
display: "block", margin: "5px",
placeholder: "+/- hacking exp", placeholder: "+/- defense exp",
type: "number", type: "number",
}); });
const statsDefenseExpButton = createElement("button", { const statsDefenseExpButton = createElement("button", {
@ -114,14 +113,13 @@ export function createDevMenu() {
Player.gainDefenseExp(exp); Player.gainDefenseExp(exp);
Player.updateSkillLevels(); Player.updateSkillLevels();
}, },
display: "block", innerText: "Add Defense Exp",
innerText: "Add Hacking Exp",
}); });
const statsDexterityExpInput = createElement("input", { const statsDexterityExpInput = createElement("input", {
class: "text-input", class: "text-input",
display: "block", margin: "5px",
placeholder: "+/- hacking exp", placeholder: "+/- dexterity exp",
type: "number", type: "number",
}); });
const statsDexterityExpButton = createElement("button", { const statsDexterityExpButton = createElement("button", {
@ -131,31 +129,29 @@ export function createDevMenu() {
Player.gainDexterityExp(exp); Player.gainDexterityExp(exp);
Player.updateSkillLevels(); Player.updateSkillLevels();
}, },
display: "block", innerText: "Add Dexterity Exp",
innerText: "Add Hacking Exp",
}); });
const statsAgilityExpInput = createElement("input", { const statsAgilityExpInput = createElement("input", {
class: "text-input", class: "text-input",
display: "block", margin: "5px",
placeholder: "+/- hacking exp", placeholder: "+/- agility exp",
type: "number", type: "number",
}); });
const statsAgilityExpButton = createElement("button", { const statsAgilityExpButton = createElement("button", {
class: "std-button", class: "std-button",
clickListener: () => { clickListener: () => {
const exp = parseInt(statsAgilityExpButton.value); const exp = parseInt(statsAgilityExpInput.value);
Player.gainAgilityExp(exp); Player.gainAgilityExp(exp);
Player.updateSkillLevels(); Player.updateSkillLevels();
}, },
display: "block", innerText: "Add Agility Exp",
innerText: "Add Hacking Exp",
}); });
const statsCharismaExpInput = createElement("input", { const statsCharismaExpInput = createElement("input", {
class: "text-input", class: "text-input",
display: "block", margin: "5px",
placeholder: "+/- hacking exp", placeholder: "+/- charisma exp",
type: "number", type: "number",
}); });
const statsCharismaExpButton = createElement("button", { const statsCharismaExpButton = createElement("button", {
@ -165,14 +161,13 @@ export function createDevMenu() {
Player.gainCharismaExp(exp); Player.gainCharismaExp(exp);
Player.updateSkillLevels(); Player.updateSkillLevels();
}, },
display: "block", innerText: "Add Charisma Exp",
innerText: "Add Hacking Exp",
}); });
const statsIntelligenceExpInput = createElement("input", { const statsIntelligenceExpInput = createElement("input", {
class: "text-input", class: "text-input",
display: "block", margin: "5px",
placeholder: "+/- hacking exp", placeholder: "+/- intelligence exp",
type: "number", type: "number",
}); });
const statsIntelligenceExpButton = createElement("button", { const statsIntelligenceExpButton = createElement("button", {
@ -182,8 +177,7 @@ export function createDevMenu() {
Player.gainIntelligenceExp(exp); Player.gainIntelligenceExp(exp);
Player.updateSkillLevels(); Player.updateSkillLevels();
}, },
display: "block", innerText: "Add Intelligence Exp",
innerText: "Add Hacking Exp",
}); });
const statsEnableIntelligenceButton = createElement("button", { const statsEnableIntelligenceButton = createElement("button", {
@ -205,7 +199,10 @@ export function createDevMenu() {
// Factions // Factions
const factionsHeader = createElement("h2", {innerText: "Factions"}); const factionsHeader = createElement("h2", {innerText: "Factions"});
const factionsDropdown = createElement("select", {class: "dropdown"}); const factionsDropdown = createElement("select", {
class: "dropdown",
margin: "5px",
});
for (const i in Factions) { for (const i in Factions) {
factionsDropdown.options[factionsDropdown.options.length] = new Option(Factions[i].name, Factions[i].name); factionsDropdown.options[factionsDropdown.options.length] = new Option(Factions[i].name, Factions[i].name);
} }
@ -222,7 +219,10 @@ export function createDevMenu() {
// Augmentations / Source Files // Augmentations / Source Files
const augmentationsHeader = createElement("h2", {innerText: "Augmentations"}); const augmentationsHeader = createElement("h2", {innerText: "Augmentations"});
const augmentationsDropdown = createElement("select", {class: "dropdown"}); const augmentationsDropdown = createElement("select", {
class: "dropdown",
margin: "5px",
});
for (const i in AugmentationNames) { for (const i in AugmentationNames) {
const augName = AugmentationNames[i]; const augName = AugmentationNames[i];
augmentationsDropdown.options[augmentationsDropdown.options.length] = new Option(augName, augName); augmentationsDropdown.options[augmentationsDropdown.options.length] = new Option(augName, augName);
@ -239,7 +239,10 @@ export function createDevMenu() {
// Programs // Programs
const programsHeader = createElement("h2", {innerText: "Programs"}); const programsHeader = createElement("h2", {innerText: "Programs"});
const programsAddDropdown = createElement("select", {class: "dropdown"}); const programsAddDropdown = createElement("select", {
class: "dropdown",
margin: "5px",
});
for (const i in Programs) { for (const i in Programs) {
const progName = Programs[i].name; const progName = Programs[i].name;
programsAddDropdown.options[programsAddDropdown.options.length] = new Option(progName, progName); programsAddDropdown.options[programsAddDropdown.options.length] = new Option(progName, progName);
@ -351,24 +354,32 @@ export function createDevMenu() {
devMenuContainer.appendChild(statsHeader); devMenuContainer.appendChild(statsHeader);
devMenuContainer.appendChild(statsHackingExpInput); devMenuContainer.appendChild(statsHackingExpInput);
devMenuContainer.appendChild(statsHackingExpButton); devMenuContainer.appendChild(statsHackingExpButton);
devMenuContainer.appendChild(createElement("br"));
devMenuContainer.appendChild(statsStrengthExpInput); devMenuContainer.appendChild(statsStrengthExpInput);
devMenuContainer.appendChild(statsStrengthExpButton); devMenuContainer.appendChild(statsStrengthExpButton);
devMenuContainer.appendChild(createElement("br"));
devMenuContainer.appendChild(statsDefenseExpInput); devMenuContainer.appendChild(statsDefenseExpInput);
devMenuContainer.appendChild(statsDefenseExpButton); devMenuContainer.appendChild(statsDefenseExpButton);
devMenuContainer.appendChild(createElement("br"));
devMenuContainer.appendChild(statsDexterityExpInput); devMenuContainer.appendChild(statsDexterityExpInput);
devMenuContainer.appendChild(statsDexterityExpButton); devMenuContainer.appendChild(statsDexterityExpButton);
devMenuContainer.appendChild(createElement("br"));
devMenuContainer.appendChild(statsAgilityExpInput); devMenuContainer.appendChild(statsAgilityExpInput);
devMenuContainer.appendChild(statsAgilityExpButton); devMenuContainer.appendChild(statsAgilityExpButton);
devMenuContainer.appendChild(createElement("br"));
devMenuContainer.appendChild(statsCharismaExpInput); devMenuContainer.appendChild(statsCharismaExpInput);
devMenuContainer.appendChild(statsCharismaExpButton); devMenuContainer.appendChild(statsCharismaExpButton);
devMenuContainer.appendChild(createElement("br"));
devMenuContainer.appendChild(statsIntelligenceExpInput); devMenuContainer.appendChild(statsIntelligenceExpInput);
devMenuContainer.appendChild(statsIntelligenceExpButton); devMenuContainer.appendChild(statsIntelligenceExpButton);
devMenuContainer.appendChild(createElement("br"));
devMenuContainer.appendChild(statsEnableIntelligenceButton); devMenuContainer.appendChild(statsEnableIntelligenceButton);
devMenuContainer.appendChild(statsDisableIntelligenceButton); devMenuContainer.appendChild(statsDisableIntelligenceButton);
devMenuContainer.appendChild(factionsHeader); devMenuContainer.appendChild(factionsHeader);
devMenuContainer.appendChild(factionsDropdown); devMenuContainer.appendChild(factionsDropdown);
devMenuContainer.appendChild(factionsAddButton); devMenuContainer.appendChild(factionsAddButton);
devMenuContainer.appendChild(augmentationsHeader); devMenuContainer.appendChild(augmentationsHeader);
devMenuContainer.appendChild(augmentationsDropdown);
devMenuContainer.appendChild(augmentationsQueueButton); devMenuContainer.appendChild(augmentationsQueueButton);
devMenuContainer.appendChild(programsHeader); devMenuContainer.appendChild(programsHeader);
devMenuContainer.appendChild(programsAddDropdown); devMenuContainer.appendChild(programsAddDropdown);

@ -42,7 +42,7 @@ import {yesNoBoxCreate, yesNoTxtInpBoxCreate,
const GangRespectToReputationRatio = 2; // Respect is divided by this to get rep gain const GangRespectToReputationRatio = 2; // Respect is divided by this to get rep gain
const MaximumGangMembers = 50; const MaximumGangMembers = 50;
const GangRecruitCostMultiplier = 2; const GangRecruitCostMultiplier = 2;
const GangTerritoryUpdateTimer = 150; const CyclesPerTerritoryAndPowerUpdate = 100;
const AscensionMultiplierRatio = 10 / 100; // Portion of upgrade multiplier that is kept after ascending const AscensionMultiplierRatio = 10 / 100; // Portion of upgrade multiplier that is kept after ascending
// Switch between territory and management screen with 1 and 2 // Switch between territory and management screen with 1 and 2
@ -147,62 +147,9 @@ export function loadAllGangs(saveString) {
AllGangs = JSON.parse(saveString, Reviver); AllGangs = JSON.parse(saveString, Reviver);
} }
//Power is an estimate of a gang's ability to gain/defend territory /**
let gangStoredPowerCycles = 0; * @param facName - Name of corresponding faction
function processAllGangPowerGains(numCycles=1) { * @param hacking - Boolean indicating whether or not its a hacking gang
if (!Player.inGang()) {return;}
gangStoredPowerCycles += numCycles;
if (gangStoredPowerCycles < 150) {return;}
var playerGangName = Player.gang.facName;
for (var name in AllGangs) {
if (AllGangs.hasOwnProperty(name)) {
if (name == playerGangName) {
AllGangs[name].power += Player.gang.calculatePower();
} else {
var gain = Math.random() * 0.02; //TODO Adjust as necessary
AllGangs[name].power += (gain);
}
}
}
gangStoredPowerCycles -= 150;
}
let gangStoredTerritoryCycles = 0;
function processAllGangTerritory(numCycles=1) {
if (!Player.inGang()) {return;}
gangStoredTerritoryCycles += numCycles;
if (gangStoredTerritoryCycles < GangTerritoryUpdateTimer) {return;}
for (var i = 0; i < GangNames.length; ++i) {
var other = getRandomInt(0, GangNames.length-1);
while(other == i) {
other = getRandomInt(0, GangNames.length-1);
}
var thisPwr = AllGangs[GangNames[i]].power;
var otherPwr = AllGangs[GangNames[other]].power;
var thisChance = thisPwr / (thisPwr + otherPwr);
if (Math.random() < thisChance) {
if (AllGangs[GangNames[other]].territory <= 0) {
return;
}
AllGangs[GangNames[i]].territory += 0.0001;
AllGangs[GangNames[other]].territory -= 0.0001;
} else {
if (AllGangs[GangNames[i]].territory <= 0) {
return;
}
AllGangs[GangNames[i]].territory -= 0.0001;
AllGangs[GangNames[other]].territory += 0.0001;
}
}
gangStoredTerritoryCycles -= GangTerritoryUpdateTimer;
}
/* faction - Name of corresponding faction
hacking - Boolean indicating whether its a hacking gang or not
*/ */
export function Gang(facName, hacking=false) { export function Gang(facName, hacking=false) {
this.facName = facName; this.facName = facName;
@ -220,6 +167,13 @@ export function Gang(facName, hacking=false) {
// When processing gains, this stores the number of cycles until some // When processing gains, this stores the number of cycles until some
// limit is reached, and then calculates and applies the gains only at that limit // limit is reached, and then calculates and applies the gains only at that limit
this.storedCycles = 0; this.storedCycles = 0;
// Separate variable to keep track of cycles for Territry + Power gang, which
// happens on a slower "clock" than normal processing
this.storedTerritoryAndPowerCycles = 0;
this.territoryClashChance = 0;
this.territoryWarfareEngaged = false;
} }
Gang.prototype.process = function(numCycles=1) { Gang.prototype.process = function(numCycles=1) {
@ -237,13 +191,11 @@ Gang.prototype.process = function(numCycles=1) {
try { try {
this.processGains(cycles); this.processGains(cycles);
this.processExperienceGains(cycles); this.processExperienceGains(cycles);
processAllGangPowerGains(cycles); this.processTerritoryAndPowerGains(cycles);
processAllGangTerritory(cycles);
this.storedCycles -= cycles; this.storedCycles -= cycles;
} catch(e) { } catch(e) {
exceptionAlert(`Exception caught when processing Gang: ${e}`); exceptionAlert(`Exception caught when processing Gang: ${e}`);
} }
} }
Gang.prototype.processGains = function(numCycles=1) { Gang.prototype.processGains = function(numCycles=1) {
@ -302,6 +254,64 @@ Gang.prototype.processGains = function(numCycles=1) {
} }
} }
Gang.prototype.processTerritoryAndPowerGains = function(numCycles=1) {
this.storedTerritoryAndPowerCycles += numCycles;
if (this.storedTerritoryAndPowerCycles < CyclesPerTerritoryAndPowerUpdate) { return; }
// Process power first
var gangName = this.facName;
for (const name in AllGangs) {
if (AllGangs.hasOwnProperty(name)) {
if (name == gangName) {
AllGangs[name].power += this.calculatePower();
} else {
var gain = Math.random() * 0.02; //TODO Adjust as necessary
AllGangs[name].power += (gain);
}
}
}
// Determine if territory should be processed
if (!this.territoryWarfareEngaged) { return; }
// Then process territory
for (var i = 0; i < GangNames.length; ++i) {
const others = GangNames.filter((e) => {
return e !== i;
});
const other = getRandomInt(0, others.length - 1);
const thisGang = GangNames[i];
const otherGang = others[other];
// If either of the gangs involved in this clash is the player, determine
// whether to skip or process it using the clash chance
if (thisGang === gangName || otherGang === gangName) {
if (!(Math.random() <= this.territoryClashChance)) { continue; }
}
const thisPwr = AllGangs[thisGang].power;
const otherPwr = AllGangs[otherGang].power;
const thisChance = thisPwr / (thisPwr + otherPwr);
if (Math.random() < thisChance) {
if (AllGangs[otherGang].territory <= 0) {
return;
}
AllGangs[thisGang].territory += 0.0001;
AllGangs[otherGang].territory -= 0.0001;
} else {
if (AllGangs[thisGang].territory <= 0) {
return;
}
AllGangs[thisGang].territory -= 0.0001;
AllGangs[otherGang].territory += 0.0001;
}
}
this.storedTerritoryAndPowerCycles -= CyclesPerTerritoryAndPowerUpdate;
}
Gang.prototype.canRecruitMember = function() { Gang.prototype.canRecruitMember = function() {
if (this.members.length >= MaximumGangMembers) { return false; } if (this.members.length >= MaximumGangMembers) { return false; }
return (this.respect >= this.getRespectNeededToRecruitMember()); return (this.respect >= this.getRespectNeededToRecruitMember());
@ -947,7 +957,7 @@ const UIElems = {
gangMemberFilter: null, gangMemberFilter: null,
gangManageEquipmentButton: null, gangManageEquipmentButton: null,
gangMemberList: null, gangMemberList: null,
gangMemberPanels: null, gangMemberPanels: {},
// Gang Equipment Upgrade Elements // Gang Equipment Upgrade Elements
gangMemberUpgradeBoxOpened: false, gangMemberUpgradeBoxOpened: false,
@ -958,6 +968,9 @@ const UIElems = {
// Gang Territory Elements // Gang Territory Elements
gangTerritoryDescText: null, gangTerritoryDescText: null,
gangTerritoryWarfareCheckbox: null,
gangTerritoryWarfareCheckboxLabel: null,
gangTerritoryWarfareClashChance: null,
gangTerritoryInfoText: null, gangTerritoryInfoText: null,
} }
@ -1178,7 +1191,7 @@ Gang.prototype.displayGangContent = function() {
width:"70%", width:"70%",
innerHTML:"This page shows how much territory your Gang controls. This statistic is listed as a percentage, " + innerHTML:"This page shows how much territory your Gang controls. This statistic is listed as a percentage, " +
"which represents how much of the total territory you control.<br><br>" + "which represents how much of the total territory you control.<br><br>" +
"Territory gain and loss is processed automatically and is updated every ~30 seconds. Your chances " + "Territory gain and loss is processed automatically and is updated every ~20 seconds. Your chances " +
"to gain and lose territory depend on your Gang's power, which is listed in the display below. " + "to gain and lose territory depend on your Gang's power, which is listed in the display below. " +
"Your gang's power is determined by the stats of all Gang members you have assigned to the " + "Your gang's power is determined by the stats of all Gang members you have assigned to the " +
"'Territory Warfare' task. Gang members that are not assigned to this task do not contribute to " + "'Territory Warfare' task. Gang members that are not assigned to this task do not contribute to " +
@ -1188,9 +1201,36 @@ Gang.prototype.displayGangContent = function() {
}); });
UIElems.gangTerritorySubpage.appendChild(UIElems.gangTerritoryDescText); UIElems.gangTerritorySubpage.appendChild(UIElems.gangTerritoryDescText);
var territoryBorder = createElement("fieldset", {width:"50%", display:"inline-block"}); // Checkbox for Engaging in Territory Warfare
UIElems.gangTerritoryWarfareCheckbox = createElement("input", {
display: "inline-block",
id: "gang-management-territory-warfare-checkbox",
changeListener: () => {
this.territoryWarfareEngaged = UIElems.gangTerritoryWarfareCheckbox.checked;
},
margin: "2px",
type: "checkbox",
});
UIElems.gangTerritoryWarfareCheckbox.checked = this.territoryWarfareEngaged;
UIElems.gangTerritoryInfoText = createElement("p", {id:"gang-territory-info"}); UIElems.gangTerritoryWarfareCheckboxLabel = createElement("label", {
color: "white",
for: "gang-management-territory-warfare-checkbox",
innerText: "Engage in Territory Warfare",
tooltip: "Test",
});
UIElems.gangTerritorySubpage.appendChild(UIElems.gangTerritoryWarfareCheckbox);
UIElems.gangTerritorySubpage.appendChild(UIElems.gangTerritoryWarfareCheckboxLabel);
// Territory Clash chance
UIElems.gangTerritoryWarfareClashChance = createElement("p");
UIElems.gangTerritorySubpage.appendChild(UIElems.gangTerritoryWarfareClashChance);
// Territory info (percentages of territory owned for each gang)
UIElems.gangTerritorySubpage.appendChild(createElement("br"));
var territoryBorder = createElement("fieldset", {width:"50%", display:"block"});
UIElems.gangTerritoryInfoText = createElement("p");
territoryBorder.appendChild(UIElems.gangTerritoryInfoText); territoryBorder.appendChild(UIElems.gangTerritoryInfoText);
UIElems.gangTerritorySubpage.appendChild(territoryBorder); UIElems.gangTerritorySubpage.appendChild(territoryBorder);
@ -1205,6 +1245,7 @@ Gang.prototype.displayGangContent = function() {
Gang.prototype.displayGangMemberList = function() { Gang.prototype.displayGangMemberList = function() {
removeChildrenFromElement(UIElems.gangMemberList); removeChildrenFromElement(UIElems.gangMemberList);
UIElems.gangMemberPanels = {};
const members = this.members; const members = this.members;
const filter = UIElems.gangMemberFilter.value.toString(); const filter = UIElems.gangMemberFilter.value.toString();
for (var i = 0; i < members.length; ++i) { for (var i = 0; i < members.length; ++i) {
@ -1218,6 +1259,10 @@ Gang.prototype.updateGangContent = function() {
if (!UIElems.gangContentCreated) { return; } if (!UIElems.gangContentCreated) { return; }
if (UIElems.gangTerritorySubpage.style.display === "block") { if (UIElems.gangTerritorySubpage.style.display === "block") {
// Territory Warfare Clash Chance
UIElems.gangTerritoryWarfareClashChance.innerText =
`Territory Clash Chance: ${numeralWrapper.format(this.gangTerritoryWarfareClashChance, '0.000%')}`;
// Update territory information // Update territory information
UIElems.gangTerritoryInfoText.innerHTML = ""; UIElems.gangTerritoryInfoText.innerHTML = "";
for (var gangname in AllGangs) { for (var gangname in AllGangs) {
@ -1356,6 +1401,10 @@ Gang.prototype.createGangMemberDisplayElement = function(memberObj) {
if (!UIElems.gangContentCreated) { return; } if (!UIElems.gangContentCreated) { return; }
const name = memberObj.name; const name = memberObj.name;
// Clear/Update the UIElems map to keep track of this gang member's panel
UIElems.gangMemberPanels[name] = {};
// Create the accordion
var accordion = createAccordionElement({ var accordion = createAccordionElement({
id: name + "gang-member", id: name + "gang-member",
hdrText: name, hdrText: name,
@ -1364,6 +1413,8 @@ Gang.prototype.createGangMemberDisplayElement = function(memberObj) {
const hdr = accordion[1]; const hdr = accordion[1];
const gangMemberDiv = accordion[2]; const gangMemberDiv = accordion[2];
UIElems.gangMemberPanels[name]["panel"] = gangMemberDiv;
// Gang member content divided into 3 panels: // Gang member content divided into 3 panels:
// Panel 1 - Shows member's stats & Ascension stuff // Panel 1 - Shows member's stats & Ascension stuff
const statsDiv = createElement("div", { const statsDiv = createElement("div", {
@ -1376,6 +1427,7 @@ Gang.prototype.createGangMemberDisplayElement = function(memberObj) {
`Ag: x${numeralWrapper.format(memberObj.agi_mult * memberObj.agi_asc_mult, "0,0.00")}(x${numeralWrapper.format(memberObj.agi_mult, "0,0.00")} Up, x${numeralWrapper.format(memberObj.agi_asc_mult, "0,0.00")} Asc)`, `Ag: x${numeralWrapper.format(memberObj.agi_mult * memberObj.agi_asc_mult, "0,0.00")}(x${numeralWrapper.format(memberObj.agi_mult, "0,0.00")} Up, x${numeralWrapper.format(memberObj.agi_asc_mult, "0,0.00")} Asc)`,
`Ch: x${numeralWrapper.format(memberObj.cha_mult * memberObj.cha_asc_mult, "0,0.00")}(x${numeralWrapper.format(memberObj.cha_mult, "0,0.00")} Up, x${numeralWrapper.format(memberObj.cha_asc_mult, "0,0.00")} Asc)`].join("<br>"), `Ch: x${numeralWrapper.format(memberObj.cha_mult * memberObj.cha_asc_mult, "0,0.00")}(x${numeralWrapper.format(memberObj.cha_mult, "0,0.00")} Up, x${numeralWrapper.format(memberObj.cha_asc_mult, "0,0.00")} Asc)`].join("<br>"),
}); });
UIElems.gangMemberPanels[name]["statsDiv"] = statsDiv;
const statsP = createElement("pre", { const statsP = createElement("pre", {
display: "inline", display: "inline",
id: name + "gang-member-stats-text", id: name + "gang-member-stats-text",
@ -1518,7 +1570,7 @@ Gang.prototype.updateGangMemberDisplayElement = function(memberObj) {
if (!UIElems.gangContentCreated || !Player.inGang()) {return;} if (!UIElems.gangContentCreated || !Player.inGang()) {return;}
var name = memberObj.name; var name = memberObj.name;
//TODO Add upgrade information // Update stats + exp
var stats = document.getElementById(name + "gang-member-stats-text"); var stats = document.getElementById(name + "gang-member-stats-text");
if (stats) { if (stats) {
stats.innerText = stats.innerText =
@ -1530,6 +1582,22 @@ Gang.prototype.updateGangMemberDisplayElement = function(memberObj) {
`Charisma: ${formatNumber(memberObj.cha, 0)} (${numeralWrapper.format(memberObj.cha_exp, '(0.00a)')} exp)`].join("\n"); `Charisma: ${formatNumber(memberObj.cha, 0)} (${numeralWrapper.format(memberObj.cha_exp, '(0.00a)')} exp)`].join("\n");
} }
// Update tooltip for stat multipliers
const panel = UIElems.gangMemberPanels[name];
if (panel) {
const statsDiv = panel["statsDiv"];
if (statsDiv) {
statsDiv.firstChild.innerHTML =
[`Hk: x${numeralWrapper.format(memberObj.hack_mult * memberObj.hack_asc_mult, "0,0.00")}(x${numeralWrapper.format(memberObj.hack_mult, "0,0.00")} Up, x${numeralWrapper.format(memberObj.hack_asc_mult, "0,0.00")} Asc)`,
`St: x${numeralWrapper.format(memberObj.str_mult * memberObj.str_asc_mult, "0,0.00")}(x${numeralWrapper.format(memberObj.str_mult, "0,0.00")} Up, x${numeralWrapper.format(memberObj.str_asc_mult, "0,0.00")} Asc)`,
`Df: x${numeralWrapper.format(memberObj.def_mult * memberObj.def_asc_mult, "0,0.00")}(x${numeralWrapper.format(memberObj.def_mult, "0,0.00")} Up, x${numeralWrapper.format(memberObj.def_asc_mult, "0,0.00")} Asc)`,
`Dx: x${numeralWrapper.format(memberObj.dex_mult * memberObj.dex_asc_mult, "0,0.00")}(x${numeralWrapper.format(memberObj.dex_mult, "0,0.00")} Up, x${numeralWrapper.format(memberObj.dex_asc_mult, "0,0.00")} Asc)`,
`Ag: x${numeralWrapper.format(memberObj.agi_mult * memberObj.agi_asc_mult, "0,0.00")}(x${numeralWrapper.format(memberObj.agi_mult, "0,0.00")} Up, x${numeralWrapper.format(memberObj.agi_asc_mult, "0,0.00")} Asc)`,
`Ch: x${numeralWrapper.format(memberObj.cha_mult * memberObj.cha_asc_mult, "0,0.00")}(x${numeralWrapper.format(memberObj.cha_mult, "0,0.00")} Up, x${numeralWrapper.format(memberObj.cha_asc_mult, "0,0.00")} Asc)`].join("<br>");
}
}
// Update info about gang member's earnings/gains
var gainInfo = document.getElementById(name + "gang-member-gain-info"); var gainInfo = document.getElementById(name + "gang-member-gain-info");
if (gainInfo) { if (gainInfo) {
gainInfo.innerHTML = gainInfo.innerHTML =
@ -1556,7 +1624,9 @@ Gang.prototype.clearUI = function() {
for (const prop in UIElems) { for (const prop in UIElems) {
UIElems[prop] = null; UIElems[prop] = null;
}
UIElems.gangContentCreated = false; UIElems.gangContentCreated = false;
UIElems.gangMemberUpgradeBoxOpened = false; UIElems.gangMemberUpgradeBoxOpened = false;
} UIElems.gangMemberPanels = {};
} }