FACTIONS: Add "Rumors" system for learning about faction join requirements (#888)

This commit is contained in:
Jesse Clark
2023-11-02 07:20:24 -07:00
committed by GitHub
parent 023f32bce3
commit fdcb8306d9
27 changed files with 1049 additions and 601 deletions
@@ -4,6 +4,7 @@ import {
CompanyName,
CompletedProgramName,
FactionName,
FactionDiscovery,
JobName,
LocationName,
ToastVariant,
@@ -33,8 +34,7 @@ import { Locations } from "../../Locations/Locations";
import { Sleeve } from "../Sleeve/Sleeve";
import { isSleeveCompanyWork } from "../Sleeve/Work/SleeveCompanyWork";
import { calculateSkillProgress as calculateSkillProgressF, ISkillProgress } from "../formulas/skill";
import { GetServer, AddToAllServers, createUniqueRandomIp } from "../../Server/AllServers";
import { Server } from "../../Server/Server";
import { AddToAllServers, createUniqueRandomIp } from "../../Server/AllServers";
import { safelyCreateUniqueServer } from "../../Server/ServerHelpers";
import { SpecialServers } from "../../Server/data/SpecialServers";
@@ -42,7 +42,6 @@ import { applySourceFile } from "../../SourceFile/applySourceFile";
import { applyExploit } from "../../Exploits/applyExploits";
import { SourceFiles } from "../../SourceFile/SourceFiles";
import { getHospitalizationCost } from "../../Hospital/Hospital";
import { HacknetServer } from "../../Hacknet/HacknetServer";
import { formatMoney } from "../../ui/formatNumber";
import { MoneySource, MoneySourceTracker } from "../../utils/MoneySourceTracker";
@@ -52,7 +51,6 @@ import { SnackbarEvents } from "../../ui/React/Snackbar";
import { achievements } from "../../Achievements/Achievements";
import { isCompanyWork } from "../../Work/CompanyWork";
import { serverMetadata } from "../../Server/data/servers";
import { getEnumHelper, isMember } from "../../utils/EnumHelper";
export function init(this: PlayerObject): void {
@@ -105,6 +103,7 @@ export function prestigeAugmentation(this: PlayerObject): void {
this.factions = [];
this.factionInvitations = [];
this.factionRumors = [];
// Clear any pending invitation modals
InvitationEvent.emit(null);
@@ -171,10 +170,37 @@ export function prestigeSourceFile(this: PlayerObject): void {
}
export function receiveInvite(this: PlayerObject, factionName: FactionName): void {
if (this.factionInvitations.includes(factionName) || this.factions.includes(factionName)) {
if (
this.factionInvitations.includes(factionName) ||
Factions[factionName].isMember ||
Factions[factionName].isBanned
) {
return;
}
this.factionInvitations.push(factionName);
if (this.factionRumors.includes(factionName)) {
this.factionRumors.splice(this.factionRumors.indexOf(factionName), 1);
}
Factions[factionName].discovery = FactionDiscovery.known;
}
export function receiveRumor(
this: PlayerObject,
factionName: FactionName,
discovery?: FactionDiscovery | undefined,
): void {
if (Factions[factionName].discovery == FactionDiscovery.unknown) {
Factions[factionName].discovery = discovery || FactionDiscovery.rumored;
}
if (
this.factionRumors.includes(factionName) ||
this.factionInvitations.includes(factionName) ||
Factions[factionName].isMember ||
Factions[factionName].isBanned
) {
return;
}
this.factionRumors.push(factionName);
}
//Calculates skill level progress based on experience. The same formula will be used for every skill
@@ -609,478 +635,11 @@ export function reapplyAllSourceFiles(this: PlayerObject): void {
//those requirements and will return an array of all factions that the Player should
//receive an invitation to
export function checkForFactionInvitations(this: PlayerObject): Faction[] {
const invitedFactions: Faction[] = []; //Array which will hold all Factions the player should be invited to
const numAugmentations = this.augmentations.length;
const allCompanies = Object.keys(this.jobs);
const allPositions = Object.values(this.jobs);
// Given a company name, safely returns the reputation (returns 0 if invalid company is specified)
function getCompanyRep(companyName: CompanyName): number {
const company = Companies[companyName];
return company.playerReputation;
const invitedFactions = [];
for (const faction of Object.values(Factions)) {
if (faction.checkForInvite(this)) invitedFactions.push(faction);
if (faction.checkForRumor(this)) this.receiveRumor(faction.name);
}
// Helper function that returns a boolean indicating whether the Player meets
// the requirements for the specified company. There are two requirements:
// 1. High enough reputation
// 2. Player is employed at the company
function checkMegacorpRequirements(companyName: CompanyName): boolean {
const serverMeta = serverMetadata.find((s) => s.specialName === companyName);
const server = GetServer(serverMeta ? serverMeta.hostname : "");
const bonus = (server as Server).backdoorInstalled ? -100e3 : 0;
return (
allCompanies.includes(companyName) && getCompanyRep(companyName) > CONSTANTS.CorpFactionRepRequirement + bonus
);
}
//Illuminati
const illuminatiFac = Factions[FactionName.Illuminati];
if (
!illuminatiFac.isBanned &&
!illuminatiFac.isMember &&
!illuminatiFac.alreadyInvited &&
numAugmentations >= 30 &&
this.money >= 150000000000 &&
this.skills.hacking >= 1500 &&
this.skills.strength >= 1200 &&
this.skills.defense >= 1200 &&
this.skills.dexterity >= 1200 &&
this.skills.agility >= 1200
) {
invitedFactions.push(illuminatiFac);
}
//Daedalus
const daedalusFac = Factions[FactionName.Daedalus];
if (
!daedalusFac.isBanned &&
!daedalusFac.isMember &&
!daedalusFac.alreadyInvited &&
numAugmentations >= currentNodeMults.DaedalusAugsRequirement &&
this.money >= 100000000000 &&
(this.skills.hacking >= 2500 ||
(this.skills.strength >= 1500 &&
this.skills.defense >= 1500 &&
this.skills.dexterity >= 1500 &&
this.skills.agility >= 1500))
) {
invitedFactions.push(daedalusFac);
}
//The Covenant
const covenantFac = Factions[FactionName.TheCovenant];
if (
!covenantFac.isBanned &&
!covenantFac.isMember &&
!covenantFac.alreadyInvited &&
numAugmentations >= 20 &&
this.money >= 75000000000 &&
this.skills.hacking >= 850 &&
this.skills.strength >= 850 &&
this.skills.defense >= 850 &&
this.skills.dexterity >= 850 &&
this.skills.agility >= 850
) {
invitedFactions.push(covenantFac);
}
//ECorp
const ecorpFac = Factions[FactionName.ECorp];
if (
!ecorpFac.isBanned &&
!ecorpFac.isMember &&
!ecorpFac.alreadyInvited &&
checkMegacorpRequirements(CompanyName.ECorp)
) {
invitedFactions.push(ecorpFac);
}
//MegaCorp
const megacorpFac = Factions[FactionName.MegaCorp];
if (
!megacorpFac.isBanned &&
!megacorpFac.isMember &&
!megacorpFac.alreadyInvited &&
checkMegacorpRequirements(CompanyName.MegaCorp)
) {
invitedFactions.push(megacorpFac);
}
//Bachman & Associates
const bachmanandassociatesFac = Factions[FactionName.BachmanAssociates];
if (
!bachmanandassociatesFac.isBanned &&
!bachmanandassociatesFac.isMember &&
!bachmanandassociatesFac.alreadyInvited &&
checkMegacorpRequirements(CompanyName.BachmanAndAssociates)
) {
invitedFactions.push(bachmanandassociatesFac);
}
//Blade Industries
const bladeindustriesFac = Factions[FactionName.BladeIndustries];
if (
!bladeindustriesFac.isBanned &&
!bladeindustriesFac.isMember &&
!bladeindustriesFac.alreadyInvited &&
checkMegacorpRequirements(CompanyName.BladeIndustries)
) {
invitedFactions.push(bladeindustriesFac);
}
//NWO
const nwoFac = Factions[FactionName.NWO];
if (!nwoFac.isBanned && !nwoFac.isMember && !nwoFac.alreadyInvited && checkMegacorpRequirements(CompanyName.NWO)) {
invitedFactions.push(nwoFac);
}
//Clarke Incorporated
const clarkeincorporatedFac = Factions[FactionName.ClarkeIncorporated];
if (
!clarkeincorporatedFac.isBanned &&
!clarkeincorporatedFac.isMember &&
!clarkeincorporatedFac.alreadyInvited &&
checkMegacorpRequirements(CompanyName.ClarkeIncorporated)
) {
invitedFactions.push(clarkeincorporatedFac);
}
//OmniTek Incorporated
const omnitekincorporatedFac = Factions[FactionName.OmniTekIncorporated];
if (
!omnitekincorporatedFac.isBanned &&
!omnitekincorporatedFac.isMember &&
!omnitekincorporatedFac.alreadyInvited &&
checkMegacorpRequirements(CompanyName.OmniTekIncorporated)
) {
invitedFactions.push(omnitekincorporatedFac);
}
//Four Sigma
const foursigmaFac = Factions[FactionName.FourSigma];
if (
!foursigmaFac.isBanned &&
!foursigmaFac.isMember &&
!foursigmaFac.alreadyInvited &&
checkMegacorpRequirements(CompanyName.FourSigma)
) {
invitedFactions.push(foursigmaFac);
}
//KuaiGong International
const kuaigonginternationalFac = Factions[FactionName.KuaiGongInternational];
if (
!kuaigonginternationalFac.isBanned &&
!kuaigonginternationalFac.isMember &&
!kuaigonginternationalFac.alreadyInvited &&
checkMegacorpRequirements(CompanyName.KuaiGongInternational)
) {
invitedFactions.push(kuaigonginternationalFac);
}
//Fulcrum Secret Technologies - If you've unlocked fulcrum secret technologies server and have a high rep with the company
const fulcrumsecrettechonologiesFac = Factions[FactionName.FulcrumSecretTechnologies];
const fulcrumSecretServer = GetServer(SpecialServers.FulcrumSecretTechnologies);
if (!(fulcrumSecretServer instanceof Server))
throw new Error(`${FactionName.FulcrumSecretTechnologies} should be normal server`);
if (fulcrumSecretServer == null) {
console.error(`Could not find ${FactionName.FulcrumSecretTechnologies} Server`);
} else if (
!fulcrumsecrettechonologiesFac.isBanned &&
!fulcrumsecrettechonologiesFac.isMember &&
!fulcrumsecrettechonologiesFac.alreadyInvited &&
fulcrumSecretServer.backdoorInstalled &&
checkMegacorpRequirements(CompanyName.FulcrumTechnologies)
) {
invitedFactions.push(fulcrumsecrettechonologiesFac);
}
//BitRunners
const bitrunnersFac = Factions[FactionName.BitRunners];
const bitrunnersServer = GetServer(SpecialServers.BitRunnersServer);
if (!(bitrunnersServer instanceof Server)) throw new Error(`${FactionName.BitRunners} should be normal server`);
if (bitrunnersServer == null) {
console.error(`Could not find ${FactionName.BitRunners} Server`);
} else if (
!bitrunnersFac.isBanned &&
!bitrunnersFac.isMember &&
bitrunnersServer.backdoorInstalled &&
!bitrunnersFac.alreadyInvited
) {
invitedFactions.push(bitrunnersFac);
}
//The Black Hand
const theblackhandFac = Factions[FactionName.TheBlackHand];
const blackhandServer = GetServer(SpecialServers.TheBlackHandServer);
if (!(blackhandServer instanceof Server)) throw new Error(`${FactionName.TheBlackHand} should be normal server`);
if (blackhandServer == null) {
console.error(`Could not find ${FactionName.TheBlackHand} Server`);
} else if (
!theblackhandFac.isBanned &&
!theblackhandFac.isMember &&
blackhandServer.backdoorInstalled &&
!theblackhandFac.alreadyInvited
) {
invitedFactions.push(theblackhandFac);
}
//NiteSec
const nitesecFac = Factions[FactionName.NiteSec];
const nitesecServer = GetServer(SpecialServers.NiteSecServer);
if (!(nitesecServer instanceof Server)) throw new Error(`${FactionName.NiteSec} should be normal server`);
if (nitesecServer == null) {
console.error(`Could not find ${FactionName.NiteSec} Server`);
} else if (
!nitesecFac.isBanned &&
!nitesecFac.isMember &&
nitesecServer.backdoorInstalled &&
!nitesecFac.alreadyInvited
) {
invitedFactions.push(nitesecFac);
}
//Chongqing
const chongqingFac = Factions[FactionName.Chongqing];
if (
!chongqingFac.isBanned &&
!chongqingFac.isMember &&
!chongqingFac.alreadyInvited &&
this.money >= 20000000 &&
this.city == CityName.Chongqing
) {
invitedFactions.push(chongqingFac);
}
//Sector-12
const sector12Fac = Factions[FactionName.Sector12];
if (
!sector12Fac.isBanned &&
!sector12Fac.isMember &&
!sector12Fac.alreadyInvited &&
this.money >= 15000000 &&
this.city == CityName.Sector12
) {
invitedFactions.push(sector12Fac);
}
//New Tokyo
const newtokyoFac = Factions[FactionName.NewTokyo];
if (
!newtokyoFac.isBanned &&
!newtokyoFac.isMember &&
!newtokyoFac.alreadyInvited &&
this.money >= 20000000 &&
this.city == CityName.NewTokyo
) {
invitedFactions.push(newtokyoFac);
}
//Aevum
const aevumFac = Factions[FactionName.Aevum];
if (
!aevumFac.isBanned &&
!aevumFac.isMember &&
!aevumFac.alreadyInvited &&
this.money >= 40000000 &&
this.city == CityName.Aevum
) {
invitedFactions.push(aevumFac);
}
//Ishima
const ishimaFac = Factions[FactionName.Ishima];
if (
!ishimaFac.isBanned &&
!ishimaFac.isMember &&
!ishimaFac.alreadyInvited &&
this.money >= 30000000 &&
this.city == CityName.Ishima
) {
invitedFactions.push(ishimaFac);
}
//Volhaven
const volhavenFac = Factions[FactionName.Volhaven];
if (
!volhavenFac.isBanned &&
!volhavenFac.isMember &&
!volhavenFac.alreadyInvited &&
this.money >= 50000000 &&
this.city == CityName.Volhaven
) {
invitedFactions.push(volhavenFac);
}
//Speakers for the Dead
const speakersforthedeadFac = Factions[FactionName.SpeakersForTheDead];
if (
!speakersforthedeadFac.isBanned &&
!speakersforthedeadFac.isMember &&
!speakersforthedeadFac.alreadyInvited &&
this.skills.hacking >= 100 &&
this.skills.strength >= 300 &&
this.skills.defense >= 300 &&
this.skills.dexterity >= 300 &&
this.skills.agility >= 300 &&
this.numPeopleKilled >= 30 &&
this.karma <= -45 &&
!allCompanies.includes(LocationName.Sector12CIA) &&
!allCompanies.includes(LocationName.Sector12NSA)
) {
invitedFactions.push(speakersforthedeadFac);
}
//The Dark Army
const thedarkarmyFac = Factions[FactionName.TheDarkArmy];
if (
!thedarkarmyFac.isBanned &&
!thedarkarmyFac.isMember &&
!thedarkarmyFac.alreadyInvited &&
this.skills.hacking >= 300 &&
this.skills.strength >= 300 &&
this.skills.defense >= 300 &&
this.skills.dexterity >= 300 &&
this.skills.agility >= 300 &&
this.city == CityName.Chongqing &&
this.numPeopleKilled >= 5 &&
this.karma <= -45 &&
!allCompanies.includes(LocationName.Sector12CIA) &&
!allCompanies.includes(LocationName.Sector12NSA)
) {
invitedFactions.push(thedarkarmyFac);
}
//The Syndicate
const thesyndicateFac = Factions[FactionName.TheSyndicate];
if (
!thesyndicateFac.isBanned &&
!thesyndicateFac.isMember &&
!thesyndicateFac.alreadyInvited &&
this.skills.hacking >= 200 &&
this.skills.strength >= 200 &&
this.skills.defense >= 200 &&
this.skills.dexterity >= 200 &&
this.skills.agility >= 200 &&
(this.city == CityName.Aevum || this.city == CityName.Sector12) &&
this.money >= 10000000 &&
this.karma <= -90 &&
!allCompanies.includes(LocationName.Sector12CIA) &&
!allCompanies.includes(LocationName.Sector12NSA)
) {
invitedFactions.push(thesyndicateFac);
}
//Silhouette
const silhouetteFac = Factions[FactionName.Silhouette];
if (
!silhouetteFac.isBanned &&
!silhouetteFac.isMember &&
!silhouetteFac.alreadyInvited &&
(allPositions.includes(JobName.software7) || // CTO
allPositions.includes(JobName.business4) || // CFO
allPositions.includes(JobName.business5)) && // CEO
this.money >= 15000000 &&
this.karma <= -22
) {
invitedFactions.push(silhouetteFac);
}
//Tetrads
const tetradsFac = Factions[FactionName.Tetrads];
if (
!tetradsFac.isBanned &&
!tetradsFac.isMember &&
!tetradsFac.alreadyInvited &&
(this.city == CityName.Chongqing || this.city == CityName.NewTokyo || this.city == CityName.Ishima) &&
this.skills.strength >= 75 &&
this.skills.defense >= 75 &&
this.skills.dexterity >= 75 &&
this.skills.agility >= 75 &&
this.karma <= -18
) {
invitedFactions.push(tetradsFac);
}
//SlumSnakes
const slumsnakesFac = Factions[FactionName.SlumSnakes];
if (
!slumsnakesFac.isBanned &&
!slumsnakesFac.isMember &&
!slumsnakesFac.alreadyInvited &&
this.skills.strength >= 30 &&
this.skills.defense >= 30 &&
this.skills.dexterity >= 30 &&
this.skills.agility >= 30 &&
this.karma <= -9 &&
this.money >= 1000000
) {
invitedFactions.push(slumsnakesFac);
}
//Netburners
const netburnersFac = Factions[FactionName.Netburners];
let totalHacknetRam = 0;
let totalHacknetCores = 0;
let totalHacknetLevels = 0;
for (let i = 0; i < this.hacknetNodes.length; ++i) {
const v = this.hacknetNodes[i];
if (typeof v === "string") {
const hserver = GetServer(v);
if (hserver === null || !(hserver instanceof HacknetServer))
throw new Error("player hacknet server was not HacknetServer");
totalHacknetLevels += hserver.level;
totalHacknetRam += hserver.maxRam;
totalHacknetCores += hserver.cores;
} else {
totalHacknetLevels += v.level;
totalHacknetRam += v.ram;
totalHacknetCores += v.cores;
}
}
if (
!netburnersFac.isBanned &&
!netburnersFac.isMember &&
!netburnersFac.alreadyInvited &&
this.skills.hacking >= 80 &&
totalHacknetRam >= 8 &&
totalHacknetCores >= 4 &&
totalHacknetLevels >= 100
) {
invitedFactions.push(netburnersFac);
}
//Tian Di Hui
const tiandihuiFac = Factions[FactionName.TianDiHui];
if (
!tiandihuiFac.isBanned &&
!tiandihuiFac.isMember &&
!tiandihuiFac.alreadyInvited &&
this.money >= 1000000 &&
this.skills.hacking >= 50 &&
(this.city == CityName.Chongqing || this.city == CityName.NewTokyo || this.city == CityName.Ishima)
) {
invitedFactions.push(tiandihuiFac);
}
//CyberSec
const cybersecFac = Factions[FactionName.CyberSec];
const cybersecServer = GetServer(SpecialServers.CyberSecServer);
if (!(cybersecServer instanceof Server)) throw new Error(`${FactionName.CyberSec} should be normal server`);
if (cybersecServer == null) {
console.error(`Could not find ${FactionName.CyberSec} Server`);
} else if (
!cybersecFac.isBanned &&
!cybersecFac.isMember &&
cybersecServer.backdoorInstalled &&
!cybersecFac.alreadyInvited
) {
invitedFactions.push(cybersecFac);
}
return invitedFactions;
}