diff --git a/src/Gang/AllGangs.ts b/src/Gang/AllGangs.ts index 1569ffb59..68b03c6aa 100644 --- a/src/Gang/AllGangs.ts +++ b/src/Gang/AllGangs.ts @@ -48,3 +48,9 @@ export function resetGangs(): void { export function loadAllGangs(saveString: string): void { AllGangs = JSON.parse(saveString, Reviver); } + +export function getClashWinChance(thisGang: string, otherGang: string): number { + const thisGangPower = AllGangs[thisGang].power; + const otherGangPower = AllGangs[otherGang].power; + return thisGangPower / (thisGangPower + otherGangPower); +} diff --git a/src/Gang/Gang.ts b/src/Gang/Gang.ts index 813a392ed..45589a1df 100644 --- a/src/Gang/Gang.ts +++ b/src/Gang/Gang.ts @@ -18,7 +18,7 @@ import { GangConstants } from "./data/Constants"; import { GangMemberTasks } from "./GangMemberTasks"; import { IAscensionResult } from "./IAscensionResult"; -import { AllGangs } from "./AllGangs"; +import { AllGangs, getClashWinChance } from "./AllGangs"; import { GangMember } from "./GangMember"; import { WorkerScript } from "../Netscript/WorkerScript"; @@ -236,11 +236,7 @@ export class Gang { 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 (Math.random() < getClashWinChance(thisGang, otherGang)) { if (AllGangs[otherGang].territory <= 0) return; const territoryGain = calculateTerritoryGain(thisGang, otherGang); AllGangs[thisGang].territory += territoryGain; diff --git a/src/Gang/ui/TerritorySubpage.tsx b/src/Gang/ui/TerritorySubpage.tsx index 16596b05a..ea04d1c28 100644 --- a/src/Gang/ui/TerritorySubpage.tsx +++ b/src/Gang/ui/TerritorySubpage.tsx @@ -5,10 +5,11 @@ import { Help } from "@mui/icons-material"; import { formatNumberNoSuffix, formatPercent } from "../../ui/formatNumber"; -import { AllGangs } from "../AllGangs"; +import { AllGangs, getClashWinChance } from "../AllGangs"; import { useGang } from "./Context"; import { TerritoryInfoModal } from "./TerritoryInfoModal"; +import { PromptEvent } from "../../ui/React/PromptManager"; /** React Component for the territory subpage. */ export function TerritorySubpage(): React.ReactElement { @@ -37,7 +38,34 @@ export function TerritorySubpage(): React.ReactElement { control={ (gang.territoryWarfareEngaged = event.target.checked)} + onChange={(event) => { + let canWinAtLeastOneGang = false; + for (const gangName of Object.keys(AllGangs)) { + if (gang.facName === gangName) { + continue; + } + if (getClashWinChance(gang.facName, gangName) >= 0.5) { + canWinAtLeastOneGang = true; + break; + } + } + /** + * Show a confirmation popup if the player tries to enable the territory clash when their gang is too + * weak and cannot win any other gangs. + */ + if (event.target.checked && !canWinAtLeastOneGang) { + PromptEvent.emit({ + txt: "Your gang is too weak. Its win chances against all other gangs are below 50%.\nOn average, you will always lose territory when being engaged in clashes.\n\nDo you really want to engage in territory clashes?", + resolve: (value: string | boolean) => { + if (value === true) { + gang.territoryWarfareEngaged = true; + } + }, + }); + } else { + gang.territoryWarfareEngaged = event.target.checked; + } + }} /> } label={ @@ -114,20 +142,17 @@ interface ITerritoryProps { function OtherGangTerritory(props: ITerritoryProps): React.ReactElement { const gang = useGang(); - const playerPower = AllGangs[gang.facName].power; - const power = AllGangs[props.name].power; - const clashVictoryChance = playerPower / (power + playerPower); const territory = AllGangs[props.name].territory; - const opacity = territory ? 1 : 0.75; + const opacity = territory > 0 ? 1 : 0.75; return ( {props.name} - Power: {formatNumberNoSuffix(power, 3)}
+ Power: {formatNumberNoSuffix(AllGangs[props.name].power, 3)}
Territory: {formatTerritory(territory)}%
- Clash Win Chance: {formatPercent(clashVictoryChance, 3)} + Clash Win Chance: {formatPercent(getClashWinChance(gang.facName, props.name), 3)}
);