mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-26 01:23:49 +01:00
Format/cleanup of Gang UI
This commit is contained in:
parent
2c7fbc03cf
commit
97fdf7cb7f
@ -1,16 +1,15 @@
|
||||
import { IMults } from "./data/upgrades";
|
||||
import { IMults, UpgradeType } from "./data/upgrades";
|
||||
|
||||
export class GangMemberUpgrade {
|
||||
name: string;
|
||||
cost: number;
|
||||
type: string;
|
||||
type: UpgradeType;
|
||||
desc: string;
|
||||
mults: IMults;
|
||||
|
||||
constructor(name = "", cost = 0, type = "w", mults: IMults = {}) {
|
||||
constructor(name = "", cost = 0, type: UpgradeType = UpgradeType.Weapon, mults: IMults = {}) {
|
||||
this.name = name;
|
||||
this.cost = cost;
|
||||
//w = weapon, a = armor, v = vehicle, r = rootkit, g = Aug
|
||||
this.type = type;
|
||||
this.mults = mults;
|
||||
|
||||
@ -43,15 +42,15 @@ export class GangMemberUpgrade {
|
||||
// User friendly version of type.
|
||||
getType(): string {
|
||||
switch (this.type) {
|
||||
case "w":
|
||||
case UpgradeType.Weapon:
|
||||
return "Weapon";
|
||||
case "a":
|
||||
case UpgradeType.Armor:
|
||||
return "Armor";
|
||||
case "v":
|
||||
case UpgradeType.Vehicle:
|
||||
return "Vehicle";
|
||||
case "r":
|
||||
case UpgradeType.Rootkit:
|
||||
return "Rootkit";
|
||||
case "g":
|
||||
case UpgradeType.Augmentation:
|
||||
return "Augmentation";
|
||||
default:
|
||||
return "";
|
||||
|
@ -6,4 +6,4 @@ export interface IAscensionResult {
|
||||
dex: number;
|
||||
agi: number;
|
||||
cha: number;
|
||||
};
|
||||
}
|
@ -7,6 +7,14 @@ export interface IMults {
|
||||
cha?: number;
|
||||
}
|
||||
|
||||
export enum UpgradeType {
|
||||
Weapon = "w",
|
||||
Armor = "a",
|
||||
Vehicle = "v",
|
||||
Rootkit = "r",
|
||||
Augmentation = "g",
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the parameters that can be used to initialize and describe a GangMemberUpgrade
|
||||
* (defined in Gang.js)
|
||||
@ -15,7 +23,7 @@ export interface IGangMemberUpgradeMetadata {
|
||||
cost: number;
|
||||
mults: IMults;
|
||||
name: string;
|
||||
upgType: string;
|
||||
upgType: UpgradeType;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -27,192 +35,192 @@ export const gangMemberUpgradesMetadata: IGangMemberUpgradeMetadata[] = [
|
||||
cost: 1e6,
|
||||
mults: {str: 1.04, def: 1.04},
|
||||
name: "Baseball Bat",
|
||||
upgType: "w",
|
||||
upgType: UpgradeType.Weapon,
|
||||
},
|
||||
{
|
||||
cost: 12e6,
|
||||
mults: {str: 1.08, def: 1.08, dex: 1.08},
|
||||
name: "Katana",
|
||||
upgType: "w",
|
||||
upgType: UpgradeType.Weapon,
|
||||
},
|
||||
{
|
||||
cost: 25e6,
|
||||
mults: {str: 1.1, def: 1.1, dex: 1.1, agi: 1.1},
|
||||
name: "Glock 18C",
|
||||
upgType: "w",
|
||||
upgType: UpgradeType.Weapon,
|
||||
},
|
||||
{
|
||||
cost: 50e6,
|
||||
mults: {str: 1.12, def: 1.1, agi: 1.1},
|
||||
name: "P90C",
|
||||
upgType: "w",
|
||||
upgType: UpgradeType.Weapon,
|
||||
},
|
||||
{
|
||||
cost: 60e6,
|
||||
mults: {str: 1.2, def: 1.15},
|
||||
name: "Steyr AUG",
|
||||
upgType: "w",
|
||||
upgType: UpgradeType.Weapon,
|
||||
},
|
||||
{
|
||||
cost: 100e6,
|
||||
mults: {str: 1.25, def: 1.2},
|
||||
name: "AK-47",
|
||||
upgType: "w",
|
||||
upgType: UpgradeType.Weapon,
|
||||
},
|
||||
{
|
||||
cost: 150e6,
|
||||
mults: {str: 1.3, def: 1.25},
|
||||
name: "M15A10 Assault Rifle",
|
||||
upgType: "w",
|
||||
upgType: UpgradeType.Weapon,
|
||||
},
|
||||
{
|
||||
cost: 225e6,
|
||||
mults: {str: 1.3, dex: 1.25, agi: 1.3},
|
||||
name: "AWM Sniper Rifle",
|
||||
upgType: "w",
|
||||
upgType: UpgradeType.Weapon,
|
||||
},
|
||||
{
|
||||
cost: 2e6,
|
||||
mults: {def: 1.04},
|
||||
name: "Bulletproof Vest",
|
||||
upgType: "a",
|
||||
upgType: UpgradeType.Armor,
|
||||
},
|
||||
{
|
||||
cost: 5e6,
|
||||
mults: {def: 1.08},
|
||||
name: "Full Body Armor",
|
||||
upgType: "a",
|
||||
upgType: UpgradeType.Armor,
|
||||
},
|
||||
{
|
||||
cost: 25e6,
|
||||
mults: {def: 1.15, agi: 1.15},
|
||||
name: "Liquid Body Armor",
|
||||
upgType: "a",
|
||||
upgType: UpgradeType.Armor,
|
||||
},
|
||||
{
|
||||
cost: 40e6,
|
||||
mults: {def: 1.2},
|
||||
name: "Graphene Plating Armor",
|
||||
upgType: "a",
|
||||
upgType: UpgradeType.Armor,
|
||||
},
|
||||
{
|
||||
cost: 3e6,
|
||||
mults: {agi: 1.04, cha: 1.04},
|
||||
name: "Ford Flex V20",
|
||||
upgType: "v",
|
||||
upgType: UpgradeType.Vehicle,
|
||||
},
|
||||
{
|
||||
cost: 9e6,
|
||||
mults: {agi: 1.08, cha: 1.08},
|
||||
name: "ATX1070 Superbike",
|
||||
upgType: "v",
|
||||
upgType: UpgradeType.Vehicle,
|
||||
},
|
||||
{
|
||||
cost: 18e6,
|
||||
mults: {agi: 1.12, cha: 1.12},
|
||||
name: "Mercedes-Benz S9001",
|
||||
upgType: "v",
|
||||
upgType: UpgradeType.Vehicle,
|
||||
},
|
||||
{
|
||||
cost: 30e6,
|
||||
mults: {agi: 1.16, cha: 1.16},
|
||||
name: "White Ferrari",
|
||||
upgType: "v",
|
||||
upgType: UpgradeType.Vehicle,
|
||||
},
|
||||
{
|
||||
cost: 5e6,
|
||||
mults: {hack: 1.05},
|
||||
name: "NUKE Rootkit",
|
||||
upgType: "r",
|
||||
upgType: UpgradeType.Rootkit,
|
||||
},
|
||||
{
|
||||
cost: 25e6,
|
||||
mults: {hack: 1.1},
|
||||
name: "Soulstealer Rootkit",
|
||||
upgType: "r",
|
||||
upgType: UpgradeType.Rootkit,
|
||||
},
|
||||
{
|
||||
cost: 75e6,
|
||||
mults: {hack: 1.15},
|
||||
name: "Demon Rootkit",
|
||||
upgType: "r",
|
||||
upgType: UpgradeType.Rootkit,
|
||||
},
|
||||
{
|
||||
cost: 40e6,
|
||||
mults: {hack: 1.12},
|
||||
name: "Hmap Node",
|
||||
upgType: "r",
|
||||
upgType: UpgradeType.Rootkit,
|
||||
},
|
||||
{
|
||||
cost: 75e6,
|
||||
mults: {hack: 1.15},
|
||||
name: "Jack the Ripper",
|
||||
upgType: "r",
|
||||
upgType: UpgradeType.Rootkit,
|
||||
},
|
||||
{
|
||||
cost: 10e9,
|
||||
mults: {str: 1.3, dex: 1.3},
|
||||
name: "Bionic Arms",
|
||||
upgType: "g",
|
||||
upgType: UpgradeType.Augmentation,
|
||||
},
|
||||
{
|
||||
cost: 10e9,
|
||||
mults: {agi: 1.6},
|
||||
name: "Bionic Legs",
|
||||
upgType: "g",
|
||||
upgType: UpgradeType.Augmentation,
|
||||
},
|
||||
{
|
||||
cost: 15e9,
|
||||
mults: {str: 1.15, def: 1.15, dex: 1.15, agi: 1.15},
|
||||
name: "Bionic Spine",
|
||||
upgType: "g",
|
||||
upgType: UpgradeType.Augmentation,
|
||||
},
|
||||
{
|
||||
cost: 20e9,
|
||||
mults: {str: 1.4, def: 1.4},
|
||||
name: "BrachiBlades",
|
||||
upgType: "g",
|
||||
upgType: UpgradeType.Augmentation,
|
||||
},
|
||||
{
|
||||
cost: 12e9,
|
||||
mults: {str: 1.2, def: 1.2},
|
||||
name: "Nanofiber Weave",
|
||||
upgType: "g",
|
||||
upgType: UpgradeType.Augmentation,
|
||||
},
|
||||
{
|
||||
cost: 25e9,
|
||||
mults: {str: 1.5, agi: 1.5},
|
||||
name: "Synthetic Heart",
|
||||
upgType: "g",
|
||||
upgType: UpgradeType.Augmentation,
|
||||
},
|
||||
{
|
||||
cost: 15e9,
|
||||
mults: {str: 1.3, def: 1.3},
|
||||
name: "Synfibril Muscle",
|
||||
upgType: "g",
|
||||
upgType: UpgradeType.Augmentation,
|
||||
},
|
||||
{
|
||||
cost: 5e9,
|
||||
mults: {hack: 1.05},
|
||||
name: "BitWire",
|
||||
upgType: "g",
|
||||
upgType: UpgradeType.Augmentation,
|
||||
},
|
||||
{
|
||||
cost: 10e9,
|
||||
mults: {hack: 1.15},
|
||||
name: "Neuralstimulator",
|
||||
upgType: "g",
|
||||
upgType: UpgradeType.Augmentation,
|
||||
},
|
||||
{
|
||||
cost: 7.5e9,
|
||||
mults: {hack: 1.1},
|
||||
name: "DataJack",
|
||||
upgType: "g",
|
||||
upgType: UpgradeType.Augmentation,
|
||||
},
|
||||
{
|
||||
cost: 50e9,
|
||||
mults: {str: 1.7, def: 1.7},
|
||||
name: "Graphene Bone Lacings",
|
||||
upgType: "g",
|
||||
upgType: UpgradeType.Augmentation,
|
||||
},
|
||||
];
|
||||
|
43
src/Gang/ui/AscensionPopup.tsx
Normal file
43
src/Gang/ui/AscensionPopup.tsx
Normal file
@ -0,0 +1,43 @@
|
||||
import React from "react";
|
||||
import { Gang } from "../Gang";
|
||||
import { GangMember } from "../GangMember";
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { removePopup } from "../../ui/React/createPopup";
|
||||
|
||||
interface IProps {
|
||||
member: GangMember;
|
||||
gang: Gang;
|
||||
popupId: string;
|
||||
}
|
||||
|
||||
export function AscensionPopup(props: IProps): React.ReactElement {
|
||||
function confirm(): void {
|
||||
props.gang.ascendMember(props.member);
|
||||
removePopup(props.popupId);
|
||||
}
|
||||
|
||||
function cancel(): void {
|
||||
removePopup(props.popupId);
|
||||
}
|
||||
|
||||
const ascendBenefits = props.member.getAscensionResults();
|
||||
|
||||
return (<>
|
||||
<pre>
|
||||
Are you sure you want to ascend this member? They will lose all of<br />
|
||||
their non-Augmentation upgrades and their stats will reset back to 1.<br />
|
||||
<br />
|
||||
Furthermore, your gang will lose {numeralWrapper.formatRespect(props.member.earnedRespect)} respect<br />
|
||||
<br />
|
||||
In return, they will gain the following permanent boost to stat multipliers:<br />
|
||||
Hacking: +{numeralWrapper.formatPercentage(ascendBenefits.hack/100)}<br />
|
||||
Strength: +{numeralWrapper.formatPercentage(ascendBenefits.str/100)}<br />
|
||||
Defense: +{numeralWrapper.formatPercentage(ascendBenefits.def/100)}<br />
|
||||
Dexterity: +{numeralWrapper.formatPercentage(ascendBenefits.dex/100)}<br />
|
||||
Agility: +{numeralWrapper.formatPercentage(ascendBenefits.agi/100)}<br />
|
||||
Charisma: +{numeralWrapper.formatPercentage(ascendBenefits.cha/100)}<br />
|
||||
</pre>
|
||||
<button className="std-button" onClick={confirm}>Ascend</button>
|
||||
<button className="std-button" onClick={cancel}>Cancel</button>
|
||||
</>);
|
||||
}
|
26
src/Gang/ui/BonusTime.tsx
Normal file
26
src/Gang/ui/BonusTime.tsx
Normal file
@ -0,0 +1,26 @@
|
||||
import * as React from "react";
|
||||
import { Gang } from "../Gang";
|
||||
import { CONSTANTS } from "../../Constants";
|
||||
import { convertTimeMsToTimeElapsedString } from "../../../utils/StringHelperFunctions";
|
||||
|
||||
interface IProps {
|
||||
gang: Gang;
|
||||
}
|
||||
|
||||
export function BonusTime(props: IProps): React.ReactElement {
|
||||
const CyclerPerSecond = 1000 / CONSTANTS._idleSpeed;
|
||||
if (props.gang.storedCycles / CyclerPerSecond*1000 <= 5000) return (<></>);
|
||||
const bonusMillis = props.gang.storedCycles / CyclerPerSecond * 1000;
|
||||
return (<>
|
||||
<p className="tooltip" style={{display: "inline-block"}}>
|
||||
Bonus time: {convertTimeMsToTimeElapsedString(bonusMillis)}
|
||||
<span className="tooltiptext">
|
||||
You gain bonus time while offline or when the game is inactive
|
||||
(e.g. when the tab is throttled by the browser). Bonus time
|
||||
makes the Gang mechanic progress faster, up to 5x the normal
|
||||
speed.
|
||||
</span>
|
||||
</p>
|
||||
<br />
|
||||
</>);
|
||||
}
|
19
src/Gang/ui/GangMemberAccordion.tsx
Normal file
19
src/Gang/ui/GangMemberAccordion.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
import React from "react";
|
||||
import { Gang } from "../Gang";
|
||||
import { GangMember } from "../GangMember";
|
||||
import { Accordion } from "../../ui/React/Accordion";
|
||||
import { GangMemberAccordionContent } from "./GangMemberAccordionContent";
|
||||
|
||||
interface IProps {
|
||||
gang: Gang;
|
||||
member: GangMember;
|
||||
}
|
||||
|
||||
export function GangMemberAccordion(props: IProps): React.ReactElement {
|
||||
return <Accordion
|
||||
panelInitiallyOpened={true}
|
||||
headerContent={<>{props.member.name}</>}
|
||||
panelContent={<GangMemberAccordionContent
|
||||
gang={props.gang}
|
||||
member={props.member} />} />
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
import React, { useState } from "react";
|
||||
import { Panel1 } from "./Panel1";
|
||||
import { Panel2 } from "./Panel2";
|
||||
import { Panel3 } from "./Panel3";
|
||||
import { GangMemberStats } from "./GangMemberStats";
|
||||
import { TaskSelector } from "./TaskSelector";
|
||||
import { TaskDescription } from "./TaskDescription";
|
||||
import { Gang } from "../Gang";
|
||||
import { GangMember } from "../GangMember";
|
||||
|
||||
@ -14,13 +14,16 @@ export function GangMemberAccordionContent(props: IProps): React.ReactElement {
|
||||
const setRerender = useState(false)[1];
|
||||
return (<>
|
||||
<div className={"gang-member-info-div tooltip"}>
|
||||
<Panel1 gang={props.gang} member={props.member} />
|
||||
<GangMemberStats gang={props.gang} member={props.member} />
|
||||
</div>
|
||||
<div className={"gang-member-info-div"}>
|
||||
<Panel2 onTaskChange={()=>setRerender(old => !old)} gang={props.gang} member={props.member} />
|
||||
<TaskSelector
|
||||
onTaskChange={()=>setRerender(old => !old)}
|
||||
gang={props.gang}
|
||||
member={props.member} />
|
||||
</div>
|
||||
<div className={"gang-member-info-div"}>
|
||||
<Panel3 member={props.member} />
|
||||
<TaskDescription member={props.member} />
|
||||
</div>
|
||||
</>);
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Accordion } from "../../ui/React/Accordion";
|
||||
import { GangMemberAccordionContent } from "./GangMemberAccordionContent"
|
||||
import { GangMemberUpgradePopup } from "./GangMemberUpgradePopup"
|
||||
import React, { useState } from "react";
|
||||
import { GangMemberUpgradePopup } from "./GangMemberUpgradePopup";
|
||||
import { GangMemberAccordion } from "./GangMemberAccordion";
|
||||
import { createPopup } from "../../ui/React/createPopup";
|
||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
import { Gang } from "../Gang";
|
||||
import { GangMember } from "../GangMember";
|
||||
import { RecruitButton } from "./RecruitButton";
|
||||
|
||||
interface IProps {
|
||||
gang: Gang;
|
||||
@ -14,6 +14,7 @@ interface IProps {
|
||||
|
||||
export function GangMemberList(props: IProps): React.ReactElement {
|
||||
const [filter, setFilter] = useState("");
|
||||
const setRerender = useState(false)[1];
|
||||
|
||||
function openUpgradePopup(): void {
|
||||
const popupId = `gang-upgrade-popup`;
|
||||
@ -28,19 +29,27 @@ export function GangMemberList(props: IProps): React.ReactElement {
|
||||
setFilter(event.target.value);
|
||||
}
|
||||
|
||||
function members(): GangMember[] {
|
||||
return props.gang.members.filter((member: GangMember) => member.name.indexOf(filter) > -1 || member.task.indexOf(filter) > -1)
|
||||
}
|
||||
const members = props.gang.members.filter((member: GangMember) =>
|
||||
member.name.indexOf(filter) > -1 || member.task.indexOf(filter) > -1);
|
||||
|
||||
return (<>
|
||||
<input className="text-input" placeholder="Filter gang member" style={{margin: "5px", padding: "5px"}} value={filter} onChange={onChange} />
|
||||
<a className="a-link-button" style={{display: 'inline-block'}} onClick={openUpgradePopup}>Manage Equipment</a>
|
||||
<RecruitButton
|
||||
onRecruit={() => setRerender(old => !old)}
|
||||
gang={props.gang} />
|
||||
<br />
|
||||
<input
|
||||
className="text-input"
|
||||
placeholder="Filter gang member"
|
||||
style={{margin: "5px", padding: "5px"}}
|
||||
value={filter}
|
||||
onChange={onChange} />
|
||||
<a
|
||||
className="a-link-button"
|
||||
style={{display: 'inline-block'}}
|
||||
onClick={openUpgradePopup}>Manage Equipment</a>
|
||||
<ul>
|
||||
{members().map((member: GangMember) => <li key={member.name}>
|
||||
<Accordion
|
||||
panelInitiallyOpened={true}
|
||||
headerContent={<>{member.name}</>}
|
||||
panelContent={<GangMemberAccordionContent gang={props.gang} member={member} />} />
|
||||
{members.map((member: GangMember) => <li key={member.name}>
|
||||
<GangMemberAccordion gang={props.gang} member={member} />
|
||||
</li>)}
|
||||
</ul>
|
||||
</>);
|
||||
|
@ -1,59 +1,21 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React from "react";
|
||||
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
||||
import { formatNumber } from "../../../utils/StringHelperFunctions";
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { createPopup, removePopup } from "../../ui/React/createPopup";
|
||||
import { Gang } from "../Gang";
|
||||
import { GangMember } from "../GangMember";
|
||||
|
||||
interface IAscendProps {
|
||||
member: GangMember;
|
||||
gang: Gang;
|
||||
popupId: string;
|
||||
}
|
||||
|
||||
function ascendPopup(props: IAscendProps): React.ReactElement {
|
||||
function confirm(): void {
|
||||
props.gang.ascendMember(props.member);
|
||||
removePopup(props.popupId);
|
||||
}
|
||||
|
||||
function cancel(): void {
|
||||
removePopup(props.popupId);
|
||||
}
|
||||
|
||||
const ascendBenefits = props.member.getAscensionResults();
|
||||
|
||||
return (<>
|
||||
<pre>
|
||||
Are you sure you want to ascend this member? They will lose all of<br />
|
||||
their non-Augmentation upgrades and their stats will reset back to 1.<br />
|
||||
<br />
|
||||
Furthermore, your gang will lose {numeralWrapper.formatRespect(props.member.earnedRespect)} respect<br />
|
||||
<br />
|
||||
In return, they will gain the following permanent boost to stat multipliers:<br />
|
||||
Hacking: +{numeralWrapper.formatPercentage(ascendBenefits.hack/100)}<br />
|
||||
Strength: +{numeralWrapper.formatPercentage(ascendBenefits.str/100)}<br />
|
||||
Defense: +{numeralWrapper.formatPercentage(ascendBenefits.def/100)}<br />
|
||||
Dexterity: +{numeralWrapper.formatPercentage(ascendBenefits.dex/100)}<br />
|
||||
Agility: +{numeralWrapper.formatPercentage(ascendBenefits.agi/100)}<br />
|
||||
Charisma: +{numeralWrapper.formatPercentage(ascendBenefits.cha/100)}<br />
|
||||
</pre>
|
||||
<button className="std-button" onClick={confirm}>Ascend</button>
|
||||
<button className="std-button" onClick={cancel}>Cancel</button>
|
||||
</>);
|
||||
}
|
||||
import { AscensionPopup } from "./AscensionPopup";
|
||||
|
||||
interface IProps {
|
||||
member: GangMember;
|
||||
gang: Gang;
|
||||
}
|
||||
|
||||
export function Panel1(props: IProps): React.ReactElement {
|
||||
|
||||
export function GangMemberStats(props: IProps): React.ReactElement {
|
||||
function ascend(): void {
|
||||
const popupId = `gang-management-ascend-member ${props.member.name}`;
|
||||
createPopup(popupId, ascendPopup, {
|
||||
createPopup(popupId, AscensionPopup, {
|
||||
member: props.member,
|
||||
gang: props.gang,
|
||||
popupId: popupId,
|
||||
@ -85,12 +47,12 @@ Ag: x{numeralWrapper.formatMultiplier(props.member.agi_mult * props.member.agi_a
|
||||
Ch: x{numeralWrapper.formatMultiplier(props.member.cha_mult * props.member.cha_asc_mult)}(x{numeralWrapper.formatMultiplier(props.member.cha_mult)} Eq, x{numeralWrapper.formatMultiplier(props.member.cha_asc_mult)} Asc)
|
||||
</span>
|
||||
<pre id={`${props.member.name}gang-member-stats-text`}>
|
||||
Hacking: {formatNumber(props.member.hack, 0)} ({numeralWrapper.formatExp(props.member.hack_exp)} exp)<br />
|
||||
Strength: {formatNumber(props.member.str, 0)} ({numeralWrapper.formatExp(props.member.str_exp)} exp)<br />
|
||||
Defense: {formatNumber(props.member.def, 0)} ({numeralWrapper.formatExp(props.member.def_exp)} exp)<br />
|
||||
Dexterity: {formatNumber(props.member.dex, 0)} ({numeralWrapper.formatExp(props.member.dex_exp)} exp)<br />
|
||||
Agility: {formatNumber(props.member.agi, 0)} ({numeralWrapper.formatExp(props.member.agi_exp)} exp)<br />
|
||||
Charisma: {formatNumber(props.member.cha, 0)} ({numeralWrapper.formatExp(props.member.cha_exp)} exp)<br />
|
||||
Hacking: {formatNumber(props.member.hack, 0)} ({numeralWrapper.formatExp(props.member.hack_exp)} exp)<br />
|
||||
Strength: {formatNumber(props.member.str, 0)} ({numeralWrapper.formatExp(props.member.str_exp)} exp)<br />
|
||||
Defense: {formatNumber(props.member.def, 0)} ({numeralWrapper.formatExp(props.member.def_exp)} exp)<br />
|
||||
Dexterity: {formatNumber(props.member.dex, 0)} ({numeralWrapper.formatExp(props.member.dex_exp)} exp)<br />
|
||||
Agility: {formatNumber(props.member.agi, 0)} ({numeralWrapper.formatExp(props.member.agi_exp)} exp)<br />
|
||||
Charisma: {formatNumber(props.member.cha, 0)} ({numeralWrapper.formatExp(props.member.cha_exp)} exp)<br />
|
||||
</pre>
|
||||
<br />
|
||||
<button className="accordion-button" onClick={ascend}>Ascend</button>
|
@ -8,6 +8,7 @@ import { Money } from "../../ui/React/Money";
|
||||
import { removePopup } from "../../ui/React/createPopup";
|
||||
import { GangMember } from "../GangMember";
|
||||
import { Gang } from "../Gang";
|
||||
import { UpgradeType } from "../data/upgrades";
|
||||
|
||||
interface IPanelProps {
|
||||
member: GangMember;
|
||||
@ -17,49 +18,31 @@ interface IPanelProps {
|
||||
|
||||
function GangMemberUpgradePanel(props: IPanelProps): React.ReactElement {
|
||||
const setRerender = useState(false)[1];
|
||||
// Upgrade buttons. Only show upgrades that can be afforded
|
||||
const weaponUpgrades: GangMemberUpgrade[] = [];
|
||||
const armorUpgrades: GangMemberUpgrade[] = [];
|
||||
const vehicleUpgrades: GangMemberUpgrade[] = [];
|
||||
const rootkitUpgrades: GangMemberUpgrade[] = [];
|
||||
const augUpgrades: GangMemberUpgrade[] = [];
|
||||
|
||||
for (const upgName in GangMemberUpgrades) {
|
||||
if (GangMemberUpgrades.hasOwnProperty(upgName)) {
|
||||
function filterUpgrades(list: string[], type: UpgradeType): GangMemberUpgrade[] {
|
||||
return Object.keys(GangMemberUpgrades).filter((upgName: string) => {
|
||||
const upg = GangMemberUpgrades[upgName];
|
||||
if (props.player.money.lt(props.gang.getUpgradeCost(upg))) continue;
|
||||
if (props.member.upgrades.includes(upgName) || props.member.augmentations.includes(upgName)) continue;
|
||||
switch (upg.type) {
|
||||
case "w":
|
||||
weaponUpgrades.push(upg);
|
||||
break;
|
||||
case "a":
|
||||
armorUpgrades.push(upg);
|
||||
break;
|
||||
case "v":
|
||||
vehicleUpgrades.push(upg);
|
||||
break;
|
||||
case "r":
|
||||
rootkitUpgrades.push(upg);
|
||||
break;
|
||||
case "g":
|
||||
augUpgrades.push(upg);
|
||||
break;
|
||||
default:
|
||||
console.error(`ERROR: Invalid Gang Member Upgrade Type: ${upg.type}`);
|
||||
}
|
||||
}
|
||||
if (props.player.money.lt(props.gang.getUpgradeCost(upg)))
|
||||
return false;
|
||||
if(upg.type !== type) return false;
|
||||
if(list.includes(upgName)) return false;
|
||||
return true;
|
||||
}).map((upgName: string) => GangMemberUpgrades[upgName]);
|
||||
}
|
||||
const weaponUpgrades = filterUpgrades(props.member.upgrades, UpgradeType.Weapon);
|
||||
const armorUpgrades = filterUpgrades(props.member.upgrades, UpgradeType.Armor);
|
||||
const vehicleUpgrades = filterUpgrades(props.member.upgrades, UpgradeType.Vehicle);
|
||||
const rootkitUpgrades = filterUpgrades(props.member.upgrades, UpgradeType.Rootkit);
|
||||
const augUpgrades = filterUpgrades(props.member.augmentations, UpgradeType.Augmentation);
|
||||
|
||||
function purchased(name: string): React.ReactElement {
|
||||
const upg = GangMemberUpgrades[name]
|
||||
return (<div key={name} className="gang-owned-upgrade tooltip">
|
||||
function purchased(upgName: string): React.ReactElement {
|
||||
const upg = GangMemberUpgrades[upgName]
|
||||
return (<div key={upgName} className="gang-owned-upgrade tooltip">
|
||||
{upg.name}
|
||||
<span className="tooltiptext" dangerouslySetInnerHTML={{__html: upg.desc}} />
|
||||
</div>);
|
||||
}
|
||||
|
||||
function upgradeButton(upg: GangMemberUpgrade, left = false): React.ReactElement {
|
||||
function upgradeButton(upg: GangMemberUpgrade, left: boolean = false): React.ReactElement {
|
||||
function onClick(): void {
|
||||
props.member.buyUpgrade(upg, props.player, props.gang);
|
||||
setRerender(old => !old);
|
||||
@ -132,11 +115,25 @@ export function GangMemberUpgradePopup(props: IProps): React.ReactElement {
|
||||
}, []);
|
||||
|
||||
return (<>
|
||||
<input className="text-input" value={filter} placeholder="Filter gang member" onChange={event => setFilter(event.target.value)} />
|
||||
<input
|
||||
className="text-input"
|
||||
value={filter}
|
||||
placeholder="Filter gang member"
|
||||
onChange={event => setFilter(event.target.value)} />
|
||||
<p className="tooltip" style={{marginLeft: '6px', display: 'inline-block'}}>
|
||||
Discount: -{numeralWrapper.formatPercentage(1 - 1 / props.gang.getDiscount())}
|
||||
<span className="tooltiptext">You get a discount on equipment and upgrades based on your gang's respect and power. More respect and power leads to more discounts.</span>
|
||||
<span className="tooltiptext">
|
||||
You get a discount on equipment and upgrades based on your
|
||||
gang's respect and power. More respect and power leads to more
|
||||
discounts.
|
||||
</span>
|
||||
</p>
|
||||
{props.gang.members.map((member: GangMember) => <GangMemberUpgradePanel key={member.name} player={props.player} gang={props.gang} member={member} />)}
|
||||
{props.gang.members.map((member: GangMember) =>
|
||||
<GangMemberUpgradePanel
|
||||
key={member.name}
|
||||
player={props.player}
|
||||
gang={props.gang}
|
||||
member={member} />)
|
||||
}
|
||||
</>);
|
||||
}
|
||||
|
@ -1,125 +1,18 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React from "react";
|
||||
import { Factions } from "../../Faction/Factions";
|
||||
import { Gang } from "../Gang";
|
||||
|
||||
import {
|
||||
formatNumber,
|
||||
convertTimeMsToTimeElapsedString,
|
||||
} from "../../../utils/StringHelperFunctions";
|
||||
import { formatNumber } from "../../../utils/StringHelperFunctions";
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { MoneyRate } from "../../ui/React/MoneyRate";
|
||||
import { Reputation } from "../../ui/React/Reputation";
|
||||
import { AllGangs } from "../AllGangs";
|
||||
import { GangConstants } from "../data/Constants";
|
||||
import { createPopup, removePopup } from "../../ui/React/createPopup";
|
||||
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
||||
|
||||
interface IRecruitPopupProps {
|
||||
gang: Gang;
|
||||
popupId: string;
|
||||
}
|
||||
|
||||
function recruitPopup(props: IRecruitPopupProps): React.ReactElement {
|
||||
const [name, setName] = useState("");
|
||||
|
||||
function recruit(): void {
|
||||
if (name === "") {
|
||||
dialogBoxCreate("You must enter a name for your Gang member!");
|
||||
return;
|
||||
}
|
||||
if (!props.gang.canRecruitMember()) {
|
||||
dialogBoxCreate("You cannot recruit another Gang member!");
|
||||
return;
|
||||
}
|
||||
|
||||
// At this point, the only way this can fail is if you already
|
||||
// have a gang member with the same name
|
||||
if (!props.gang.recruitMember(name)) {
|
||||
dialogBoxCreate("You already have a gang member with this name!");
|
||||
return;
|
||||
}
|
||||
|
||||
removePopup(props.popupId);
|
||||
}
|
||||
|
||||
function cancel(): void {
|
||||
removePopup(props.popupId);
|
||||
}
|
||||
|
||||
function onKeyUp(event: React.KeyboardEvent<HTMLInputElement>): void {
|
||||
if(event.keyCode === 13) recruit();
|
||||
if(event.keyCode === 27) cancel();
|
||||
}
|
||||
|
||||
function onChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||
setName(event.target.value);
|
||||
}
|
||||
|
||||
return (<>
|
||||
<p>Enter a name for your new Gang member:</p><br />
|
||||
<input autoFocus
|
||||
onKeyUp={onKeyUp}
|
||||
onChange={onChange}
|
||||
className="text-input"
|
||||
type="text"
|
||||
placeholder="unique name" />
|
||||
<a className="std-button" onClick={recruit}>Recruit Gang Member</a>
|
||||
<a className="std-button" onClick={cancel}>Cancel</a>
|
||||
</>);
|
||||
}
|
||||
import { BonusTime } from "./BonusTime";
|
||||
|
||||
interface IProps {
|
||||
gang: Gang;
|
||||
}
|
||||
|
||||
function Recruitment(props: IProps): React.ReactElement {
|
||||
// Toggle the 'Recruit member button' if valid
|
||||
const numMembers = props.gang.members.length;
|
||||
const respectCost = props.gang.getRespectNeededToRecruitMember();
|
||||
|
||||
if (numMembers >= GangConstants.MaximumGangMembers) {
|
||||
return (<></>);
|
||||
} else if (props.gang.canRecruitMember()) {
|
||||
function onClick(): void {
|
||||
const popupId = "recruit-gang-member-popup";
|
||||
createPopup(popupId, recruitPopup, {
|
||||
gang: props.gang,
|
||||
popupId: popupId,
|
||||
});
|
||||
}
|
||||
return (<>
|
||||
<a className="a-link-button"
|
||||
onClick={onClick}
|
||||
style={{display: 'inline-block', margin: '10px'}}>
|
||||
Recruit Gang Member
|
||||
</a>
|
||||
</>);
|
||||
}
|
||||
return (<>
|
||||
<a className="a-link-button-inactive"
|
||||
style={{display: 'inline-block', margin: '10px'}}>
|
||||
Recruit Gang Member
|
||||
</a>
|
||||
<p style={{margin: '10px', color: 'red', display: 'inline-block'}}>
|
||||
{formatNumber(respectCost, 2)} respect needed to recruit next member
|
||||
</p>
|
||||
</>);
|
||||
}
|
||||
|
||||
function BonusTime(props: IProps): React.ReactElement {
|
||||
const CyclesPerSecond = 1000 / 200;
|
||||
if (props.gang.storedCycles / CyclesPerSecond*1000 <= 5000) return <></>;
|
||||
return (<>
|
||||
<p className="tooltip" style={{display: "inline-block"}}>
|
||||
Bonus time: {convertTimeMsToTimeElapsedString(props.gang.storedCycles / CyclesPerSecond*1000)}
|
||||
<span className="tooltiptext">
|
||||
You gain bonus time while offline or when the game is inactive (e.g. when the tab is throttled by the browser). Bonus time makes the Gang mechanic progress faster, up to 5x the normal speed
|
||||
</span>
|
||||
</p>
|
||||
<br />
|
||||
</>);
|
||||
}
|
||||
|
||||
export function GangStats(props: IProps): React.ReactElement {
|
||||
const territoryMult = AllGangs[props.gang.facName].territory * 100;
|
||||
let territoryStr;
|
||||
@ -171,7 +64,5 @@ export function GangStats(props: IProps): React.ReactElement {
|
||||
</p>
|
||||
<br />
|
||||
<BonusTime gang={props.gang} />
|
||||
<br />
|
||||
<Recruitment gang={props.gang} />
|
||||
</>);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React from "react";
|
||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
import { GangStats } from "./GangStats";
|
||||
import { Gang } from "../Gang";
|
||||
@ -12,24 +12,28 @@ interface IProps {
|
||||
export function ManagementSubpage(props: IProps): React.ReactElement {
|
||||
return (<div style={{display: 'block'}}>
|
||||
<p style={{width: "70%"}}>
|
||||
This page is used to manage your gang members and get an overview of your gang's stats.
|
||||
This page is used to manage your gang members and get an overview of
|
||||
your gang's stats.
|
||||
<br />
|
||||
<br />
|
||||
If a gang member is not earning much money or respect, the task that you
|
||||
have assigned to that member might be too difficult. Consider training that
|
||||
member's stats or choosing an easier task. The tasks closer to the
|
||||
top of the dropdown list are generally easier. Alternatively, the gang member's
|
||||
low production might be due to the fact that your wanted level is too high.
|
||||
Consider assigning a few members to the '{props.gang.isHackingGang?"Ethical Hacking":"Vigilante Justice"}'
|
||||
If a gang member is not earning much money or respect, the task that
|
||||
you have assigned to that member might be too difficult. Consider
|
||||
training that member's stats or choosing an easier task. The tasks
|
||||
closer to the top of the dropdown list are generally easier.
|
||||
Alternatively, the gang member's low production might be due to the
|
||||
fact that your wanted level is too high. Consider assigning a few
|
||||
members to the '{props.gang.isHackingGang?"Ethical Hacking":"Vigilante Justice"}'
|
||||
task to lower your wanted level.
|
||||
<br />
|
||||
<br />
|
||||
Installing Augmentations does NOT reset your progress with your Gang.
|
||||
Furthermore, after installing Augmentations, you will
|
||||
automatically be a member of whatever Faction you created your gang with.
|
||||
Installing Augmentations does NOT reset your progress with your
|
||||
Gang. Furthermore, after installing Augmentations, you will
|
||||
automatically be a member of whatever Faction you created your gang
|
||||
with.
|
||||
<br />
|
||||
<br />
|
||||
You can also manage your gang programmatically through Netscript using the Gang API
|
||||
You can also manage your gang programmatically through Netscript
|
||||
using the Gang API
|
||||
</p>
|
||||
<br />
|
||||
<GangStats gang={props.gang} />
|
||||
|
47
src/Gang/ui/RecruitButton.tsx
Normal file
47
src/Gang/ui/RecruitButton.tsx
Normal file
@ -0,0 +1,47 @@
|
||||
import React from "react";
|
||||
import { Gang } from "../Gang";
|
||||
import { RecruitPopup } from "./RecruitPopup";
|
||||
import { GangConstants } from "../data/Constants";
|
||||
import { formatNumber } from "../../../utils/StringHelperFunctions";
|
||||
import { createPopup } from "../../ui/React/createPopup";
|
||||
|
||||
interface IProps {
|
||||
gang: Gang;
|
||||
onRecruit: () => void;
|
||||
}
|
||||
|
||||
export function RecruitButton(props: IProps): React.ReactElement {
|
||||
if (props.gang.members.length >= GangConstants.MaximumGangMembers) {
|
||||
return (<></>);
|
||||
}
|
||||
|
||||
if (!props.gang.canRecruitMember()) {
|
||||
const respect = props.gang.getRespectNeededToRecruitMember();
|
||||
return (<>
|
||||
<a className="a-link-button-inactive"
|
||||
style={{display: 'inline-block', margin: '10px'}}>
|
||||
Recruit Gang Member
|
||||
</a>
|
||||
<p style={{margin: '10px', color: 'red', display: 'inline-block'}}>
|
||||
{formatNumber(respect, 2)} respect needed to recruit next member
|
||||
</p>
|
||||
</>);
|
||||
}
|
||||
|
||||
function onClick(): void {
|
||||
const popupId = "recruit-gang-member-popup";
|
||||
createPopup(popupId, RecruitPopup, {
|
||||
gang: props.gang,
|
||||
popupId: popupId,
|
||||
onRecruit: props.onRecruit,
|
||||
});
|
||||
}
|
||||
|
||||
return (<>
|
||||
<a className="a-link-button"
|
||||
onClick={onClick}
|
||||
style={{display: 'inline-block', margin: '10px'}}>
|
||||
Recruit Gang Member
|
||||
</a>
|
||||
</>);
|
||||
}
|
60
src/Gang/ui/RecruitPopup.tsx
Normal file
60
src/Gang/ui/RecruitPopup.tsx
Normal file
@ -0,0 +1,60 @@
|
||||
import React, { useState } from "react";
|
||||
import { Gang } from "../Gang";
|
||||
import { removePopup } from "../../ui/React/createPopup";
|
||||
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
||||
|
||||
interface IRecruitPopupProps {
|
||||
gang: Gang;
|
||||
popupId: string;
|
||||
onRecruit: () => void;
|
||||
}
|
||||
|
||||
export function RecruitPopup(props: IRecruitPopupProps): React.ReactElement {
|
||||
const [name, setName] = useState("");
|
||||
|
||||
function recruit(): void {
|
||||
if (name === "") {
|
||||
dialogBoxCreate("You must enter a name for your Gang member!");
|
||||
return;
|
||||
}
|
||||
if (!props.gang.canRecruitMember()) {
|
||||
dialogBoxCreate("You cannot recruit another Gang member!");
|
||||
return;
|
||||
}
|
||||
|
||||
// At this point, the only way this can fail is if you already
|
||||
// have a gang member with the same name
|
||||
if (!props.gang.recruitMember(name)) {
|
||||
dialogBoxCreate("You already have a gang member with this name!");
|
||||
return;
|
||||
}
|
||||
|
||||
props.onRecruit();
|
||||
removePopup(props.popupId);
|
||||
}
|
||||
|
||||
function cancel(): void {
|
||||
removePopup(props.popupId);
|
||||
}
|
||||
|
||||
function onKeyUp(event: React.KeyboardEvent<HTMLInputElement>): void {
|
||||
if(event.keyCode === 13) recruit();
|
||||
if(event.keyCode === 27) cancel();
|
||||
}
|
||||
|
||||
function onChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||
setName(event.target.value);
|
||||
}
|
||||
|
||||
return (<>
|
||||
<p>Enter a name for your new Gang member:</p><br />
|
||||
<input autoFocus
|
||||
onKeyUp={onKeyUp}
|
||||
onChange={onChange}
|
||||
className="text-input"
|
||||
type="text"
|
||||
placeholder="unique name" />
|
||||
<a className="std-button" onClick={recruit}>Recruit Gang Member</a>
|
||||
<a className="std-button" onClick={cancel}>Cancel</a>
|
||||
</>);
|
||||
}
|
@ -27,9 +27,18 @@ export function Root(props: IProps): React.ReactElement {
|
||||
}
|
||||
|
||||
return (<>
|
||||
<a className="a-link-button" style={{display: "inline-block"}} onClick={back}>Back</a>
|
||||
<a className={management?"a-link-button-inactive":"a-link-button"} style={{display: "inline-block"}} onClick={() => setManagement(true)}>Gang Management</a>
|
||||
<a className={!management?"a-link-button-inactive":"a-link-button"} style={{display: "inline-block"}} onClick={() => setManagement(false)}>Gang Territory</a>
|
||||
<a className="a-link-button" style={{display: "inline-block"}}
|
||||
onClick={back}>Back</a>
|
||||
<a className={management?"a-link-button-inactive":"a-link-button"}
|
||||
style={{display: "inline-block"}}
|
||||
onClick={() => setManagement(true)}>
|
||||
Gang Management
|
||||
</a>
|
||||
<a className={!management?"a-link-button-inactive":"a-link-button"}
|
||||
style={{display: "inline-block"}}
|
||||
onClick={() => setManagement(false)}>
|
||||
Gang Territory
|
||||
</a>
|
||||
{management ?
|
||||
<ManagementSubpage gang={props.gang} player={props.player} /> :
|
||||
<TerritorySubpage gang={props.gang} />}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React from "react";
|
||||
import { GangMemberTasks } from "../GangMemberTasks";
|
||||
import { GangMember } from "../GangMember";
|
||||
|
||||
@ -6,7 +6,7 @@ interface IProps {
|
||||
member: GangMember;
|
||||
}
|
||||
|
||||
export function Panel3(props: IProps): React.ReactElement {
|
||||
export function TaskDescription(props: IProps): React.ReactElement {
|
||||
const task = GangMemberTasks[props.member.task];
|
||||
const desc = task ? task.desc: GangMemberTasks["Unassigned"].desc;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React, { useState } from "react";
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { StatsTable } from "../../ui/React/StatsTable";
|
||||
import { MoneyRate } from "../../ui/React/MoneyRate";
|
||||
@ -11,7 +11,7 @@ interface IProps {
|
||||
onTaskChange: () => void;
|
||||
}
|
||||
|
||||
export function Panel2(props: IProps): React.ReactElement {
|
||||
export function TaskSelector(props: IProps): React.ReactElement {
|
||||
const [currentTask, setCurrentTask] = useState(props.member.task);
|
||||
|
||||
function onChange(event: React.ChangeEvent<HTMLSelectElement>): void {
|
@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React from "react";
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
||||
import { formatNumber } from "../../../utils/StringHelperFunctions";
|
||||
@ -11,13 +11,13 @@ interface IProps {
|
||||
|
||||
export function TerritorySubpage(props: IProps): React.ReactElement {
|
||||
function openWarfareHelp(): void {
|
||||
dialogBoxCreate("This percentage represents the chance you have of 'clashing' with " +
|
||||
"with another gang. If you do not wish to gain/lose territory, " +
|
||||
"then keep this percentage at 0% by not engaging in territory " +
|
||||
"warfare.")
|
||||
dialogBoxCreate("This percentage represents the chance you have of " +
|
||||
"'clashing' with with another gang. If you do not " +
|
||||
"wish to gain/lose territory, then keep this " +
|
||||
"percentage at 0% by not engaging in territory warfare.");
|
||||
}
|
||||
|
||||
function formatTerritoryP(n: number): string {
|
||||
function formatTerritory(n: number): string {
|
||||
const v = n * 100;
|
||||
if (v <= 0) {
|
||||
return formatNumber(0, 2);
|
||||
@ -35,7 +35,7 @@ export function TerritorySubpage(props: IProps): React.ReactElement {
|
||||
return (<span key={name}>
|
||||
<u>{name}</u><br />
|
||||
Power: {formatNumber(power, 6)}<br />
|
||||
Territory: {formatTerritoryP(AllGangs[name].territory)}%<br />
|
||||
Territory: {formatTerritory(AllGangs[name].territory)}%<br />
|
||||
Chance to win clash with this gang: {numeralWrapper.formatPercentage(clashVictoryChance, 3)}<br />
|
||||
<br />
|
||||
</span>);
|
||||
@ -72,8 +72,17 @@ export function TerritorySubpage(props: IProps): React.ReactElement {
|
||||
<br />
|
||||
<br />
|
||||
</p>
|
||||
<input checked={props.gang.territoryWarfareEngaged} id="warfare" type="checkbox" style={{display: "inline-block", margin: "2px"}} onChange={(event)=> props.gang.territoryWarfareEngaged = event.target.checked}/>
|
||||
<label htmlFor="warfare" className="tooltip" style={{color: "white", display: 'inline-block'}}>
|
||||
<input
|
||||
checked={props.gang.territoryWarfareEngaged}
|
||||
id="warfare"
|
||||
type="checkbox"
|
||||
style={{display: "inline-block", margin: "2px"}}
|
||||
onChange={(event)=>
|
||||
props.gang.territoryWarfareEngaged = event.target.checked}/>
|
||||
<label
|
||||
htmlFor="warfare"
|
||||
className="tooltip"
|
||||
style={{color: "white", display: 'inline-block'}}>
|
||||
Engage in Territory Warfare
|
||||
<span className="tooltiptext" style={{display: "inline-block"}}>
|
||||
Engaging in Territory Warfare sets your clash chance to 100%.
|
||||
@ -85,10 +94,19 @@ export function TerritorySubpage(props: IProps): React.ReactElement {
|
||||
<p style={{display: 'inline-block'}}>
|
||||
Territory Clash Chance: {numeralWrapper.formatPercentage(props.gang.territoryClashChance, 3)}
|
||||
</p>
|
||||
<div className="help-tip" style={{display: "inline-block"}} onClick={openWarfareHelp}>?</div>
|
||||
<div
|
||||
className="help-tip"
|
||||
style={{display: "inline-block"}}
|
||||
onClick={openWarfareHelp}>?</div>
|
||||
<br />
|
||||
|
||||
<input checked={props.gang.notifyMemberDeath} id="notify" type="checkbox" style={{display: "inline-block", margin: "2px"}} onChange={(event)=> props.gang.notifyMemberDeath = event.target.checked}/>
|
||||
<input
|
||||
checked={props.gang.notifyMemberDeath}
|
||||
id="notify"
|
||||
type="checkbox"
|
||||
style={{display: "inline-block", margin: "2px"}}
|
||||
onChange={(event)=>
|
||||
props.gang.notifyMemberDeath = event.target.checked}/>
|
||||
<label htmlFor="warfare" className="tooltip" style={{color: "white", display: 'inline-block'}}>
|
||||
Notify about Gang Member Deaths
|
||||
<span className="tooltiptext" style={{display: "inline-block"}}>
|
||||
@ -101,7 +119,7 @@ export function TerritorySubpage(props: IProps): React.ReactElement {
|
||||
<p>
|
||||
<b><u>{props.gang.facName}</u></b><br />
|
||||
Power: {formatNumber(AllGangs[props.gang.facName].power, 6)}<br />
|
||||
Territory: {formatTerritoryP(AllGangs[props.gang.facName].territory)}%<br />
|
||||
Territory: {formatTerritory(AllGangs[props.gang.facName].territory)}%<br />
|
||||
<br />
|
||||
{gangNames.map(name => otherGangTerritory(name))}
|
||||
</p>
|
||||
|
Loading…
Reference in New Issue
Block a user