CORPORATION: Remove DreamSense upgrade (#2232)

This commit is contained in:
catloversg
2025-07-10 15:40:36 +07:00
committed by GitHub
parent 8deb34e64d
commit 6c7783aa85
17 changed files with 55 additions and 91 deletions

View File

@@ -11,7 +11,6 @@
type CorpUpgradeName = type CorpUpgradeName =
| "Smart Factories" | "Smart Factories"
| "Smart Storage" | "Smart Storage"
| "DreamSense"
| "Wilson Analytics" | "Wilson Analytics"
| "Nuoptimal Nootropic Injector Implants" | "Nuoptimal Nootropic Injector Implants"
| "Speech Processor Implants" | "Speech Processor Implants"

View File

@@ -57,11 +57,7 @@ export class Corporation {
storedCycles = 0; storedCycles = 0;
unlocks = new JSONSet<CorpUnlockName>(); unlocks = new JSONSet<CorpUnlockName>();
upgrades = createEnumKeyedRecord(CorpUpgradeName, (name) => ({ upgrades = createEnumKeyedRecord(CorpUpgradeName, () => ({ level: 0, value: 1 }));
level: 0,
// For dreamsense, value is not a multiplier so it starts at 0
value: name === CorpUpgradeName.DreamSense ? 0 : 1,
}));
previousTotalAssets = 150e9; previousTotalAssets = 150e9;
totalAssets = 150e9; totalAssets = 150e9;
@@ -415,7 +411,12 @@ export class Corporation {
}; };
} }
const upgrade = CorpUpgrades[upgradeName]; const upgrade = CorpUpgrades[upgradeName];
const totalCost = calculateUpgradeCost(this, upgrade, amount); const totalCost = calculateUpgradeCost(
upgrade.basePrice,
upgrade.priceMult,
this.upgrades[upgradeName].level,
amount,
);
if (this.funds < totalCost) { if (this.funds < totalCost) {
return { return {
success: false, success: false,
@@ -447,10 +448,6 @@ export class Corporation {
return this.upgrades[CorpUpgradeName.SmartStorage].value; return this.upgrades[CorpUpgradeName.SmartStorage].value;
} }
getDreamSenseGain(): number {
return this.upgrades[CorpUpgradeName.DreamSense].value;
}
getAdvertisingMultiplier(): number { getAdvertisingMultiplier(): number {
return this.upgrades[CorpUpgradeName.WilsonAnalytics].value; return this.upgrades[CorpUpgradeName.WilsonAnalytics].value;
} }

View File

@@ -195,17 +195,6 @@ export class Division {
this.popularity -= marketCycles * 0.0001; this.popularity -= marketCycles * 0.0001;
this.popularity = Math.max(0, this.popularity); this.popularity = Math.max(0, this.popularity);
// Process Dreamsense gains
const popularityGain = corporation.getDreamSenseGain(),
awarenessGain = popularityGain * 4;
if (popularityGain > 0) {
const awareness = this.awareness + awarenessGain * marketCycles;
this.awareness = Math.min(awareness, Number.MAX_VALUE);
const popularity = this.popularity + popularityGain * marketCycles;
this.popularity = Math.min(popularity, Number.MAX_VALUE);
}
return; return;
} }

View File

@@ -43,7 +43,6 @@ export enum CorpUnlockName {
export enum CorpUpgradeName { export enum CorpUpgradeName {
SmartFactories = "Smart Factories", SmartFactories = "Smart Factories",
SmartStorage = "Smart Storage", SmartStorage = "Smart Storage",
DreamSense = "DreamSense",
WilsonAnalytics = "Wilson Analytics", WilsonAnalytics = "Wilson Analytics",
NuoptimalNootropicInjectorImplants = "Nuoptimal Nootropic Injector Implants", NuoptimalNootropicInjectorImplants = "Nuoptimal Nootropic Injector Implants",
SpeechProcessorImplants = "Speech Processor Implants", SpeechProcessorImplants = "Speech Processor Implants",

View File

@@ -32,20 +32,6 @@ export const CorpUpgrades: Record<CorpUpgradeName, CorpUpgrade> = {
"Each level of this upgrade increases your global warehouse storage size by 10% (additive).", "Each level of this upgrade increases your global warehouse storage size by 10% (additive).",
}, },
//Advertise through dreams, passive popularity/ awareness gain
[CorpUpgradeName.DreamSense]: {
name: CorpUpgradeName.DreamSense,
basePrice: 4e9,
priceMult: 1.1,
benefit: 0.001,
desc:
"Use DreamSense LCC Technologies to advertise your corporation " +
"to consumers through their dreams. Each level of this upgrade provides a passive " +
"increase in awareness of all of your companies (divisions) by 0.004 / market cycle," +
"and in popularity by 0.001 / market cycle. A market cycle is approximately " +
"10 seconds.",
},
//Makes advertising more effective //Makes advertising more effective
[CorpUpgradeName.WilsonAnalytics]: { [CorpUpgradeName.WilsonAnalytics]: {
name: CorpUpgradeName.WilsonAnalytics, name: CorpUpgradeName.WilsonAnalytics,

View File

@@ -50,10 +50,13 @@ export function costOfCreatingCorporation(restart: boolean): number {
return 150e9; return 150e9;
} }
export function calculateUpgradeCost(corporation: Corporation, upgrade: CorpUpgrade, amount: PositiveInteger): number { export function calculateUpgradeCost(
const priceMult = upgrade.priceMult; basePrice: number,
const level = corporation.upgrades[upgrade.name].level; priceMult: number,
const baseCost = upgrade.basePrice * Math.pow(priceMult, level); fromLevel: number,
amount: PositiveInteger,
): number {
const baseCost = basePrice * Math.pow(priceMult, fromLevel);
const cost = (baseCost * (1 - Math.pow(priceMult, amount))) / (1 - priceMult); const cost = (baseCost * (1 - Math.pow(priceMult, amount))) / (1 - priceMult);
return cost; return cost;
} }

View File

@@ -27,7 +27,7 @@ export function LevelableUpgrade({ upgradeName, mult, rerender }: IProps): React
const amount = mult === "MAX" ? calculateMaxAffordableUpgrade(corp, data) : mult; const amount = mult === "MAX" ? calculateMaxAffordableUpgrade(corp, data) : mult;
const cost = amount === 0 ? 0 : calculateUpgradeCost(corp, data, amount); const cost = amount === 0 ? 0 : calculateUpgradeCost(data.basePrice, data.priceMult, level, amount);
const tooltip = data.desc; const tooltip = data.desc;
function onClick(): void { function onClick(): void {
if (corp.funds < cost) return; if (corp.funds < cost) return;

View File

@@ -163,10 +163,6 @@ Check this [section](./quality.md).
Check this [section](./wilson-analytics-advert.md). Check this [section](./wilson-analytics-advert.md).
#### Should I buy Dream Sense?
No. Check this [section](./wilson-analytics-advert.md) for the reason.
#### Is Wilson retroactive? #### Is Wilson retroactive?
No. No.

View File

@@ -60,9 +60,7 @@ $$UpgradeCost_{From\ a\ to\ b} = BasePrice\ast\left( \frac{{PriceMult}^{b} - {Pr
$$MaxUpgradeLevel = \log_{PriceMult}\left( MaxCost\ast\frac{PriceMult - 1}{BasePrice} + (PriceMult)^{CurrentLevel} \right)$$ $$MaxUpgradeLevel = \log_{PriceMult}\left( MaxCost\ast\frac{PriceMult - 1}{BasePrice} + (PriceMult)^{CurrentLevel} \right)$$
- Benefit: - Benefit: All benefits are multipliers. `BaseBenefit` is 1.
- All benefits are multipliers. `BaseBenefit` is 1.
- The only exception is DreamSense. Its benefit is raw value, its `BaseBenefit` is 0.
$$Benefit = BaseBenefit + Benefit\ast CurrentLevel$$ $$Benefit = BaseBenefit + Benefit\ast CurrentLevel$$
@@ -73,7 +71,6 @@ Normal upgrades:
| ---------------------------------- | -------------- | -------------------- | ----------- | ----------------------- | | ---------------------------------- | -------------- | -------------------- | ----------- | ----------------------- |
| SmartFactories | 2e9 | 1.06 | 0.03 | Production | | SmartFactories | 2e9 | 1.06 | 0.03 | Production |
| SmartStorage | 2e9 | 1.06 | 0.1 | Storage | | SmartStorage | 2e9 | 1.06 | 0.1 | Storage |
| DreamSense | 4e9 | 1.1 | 0.001 | Awareness/Popularity |
| WilsonAnalytics | 4e9 | 2 | 0.005 | Advert's benefits | | WilsonAnalytics | 4e9 | 2 | 0.005 | Advert's benefits |
| NuoptimalNootropicInjectorImplants | 1e9 | 1.06 | 0.1 | Employee's creativity | | NuoptimalNootropicInjectorImplants | 1e9 | 1.06 | 0.1 | Employee's creativity |
| SpeechProcessorImplants | 1e9 | 1.06 | 0.1 | Employee's charisma | | SpeechProcessorImplants | 1e9 | 1.06 | 0.1 | Employee's charisma |
@@ -94,7 +91,6 @@ Special upgrades:
&nbsp; &nbsp;
Advice: Advice:
- DreamSense is useless. Never buy it.
- Round 1: - Round 1:
- SmartStorage and Warehouse are the most important upgrades in this round. - SmartStorage and Warehouse are the most important upgrades in this round.
- Only buy 1 or 2 Advert level(s). - Only buy 1 or 2 Advert level(s).

View File

@@ -8,8 +8,6 @@ Awareness and popularity are capped at `Number.MAX_VALUE` (~1.7976931348623157E+
Raw values of those stats are crucial, but their ratio is also important. We want to have high ratio of popularity/awareness, check this [section](./optimal-selling-price-market-ta2.md) for formulas. Raw values of those stats are crucial, but their ratio is also important. We want to have high ratio of popularity/awareness, check this [section](./optimal-selling-price-market-ta2.md) for formulas.
DreamSense only increases popularity by 0.001/cycle/level and awareness by 0.004/cycle/level. Those benefits are minuscule. However, that's not its biggest problem, the biggest one is the ratio of popularity/awareness. We want that ratio to be as high as possible, but DreamSense constantly lowers it.
Popularity decreases by 0.0001 per cycle. Popularity decreases by 0.0001 per cycle.
## Wilson Analytics ## Wilson Analytics

View File

@@ -90,7 +90,13 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
function getUpgradeLevelCost(upgradeName: CorpUpgradeName): number { function getUpgradeLevelCost(upgradeName: CorpUpgradeName): number {
const corporation = getCorporation(); const corporation = getCorporation();
const cost = calculateUpgradeCost(corporation, CorpUpgrades[upgradeName], 1 as PositiveInteger); const upgrade = CorpUpgrades[upgradeName];
const cost = calculateUpgradeCost(
upgrade.basePrice,
upgrade.priceMult,
corporation.upgrades[upgradeName].level,
1 as PositiveInteger,
);
return cost; return cost;
} }

View File

@@ -9837,7 +9837,6 @@ type CorpUnlockName =
type CorpUpgradeName = type CorpUpgradeName =
| "Smart Factories" | "Smart Factories"
| "Smart Storage" | "Smart Storage"
| "DreamSense"
| "Wilson Analytics" | "Wilson Analytics"
| "Nuoptimal Nootropic Injector Implants" | "Nuoptimal Nootropic Injector Implants"
| "Speech Processor Implants" | "Speech Processor Implants"

View File

@@ -210,5 +210,10 @@ export const breakingChanges300: VersionBreakingChange = {
'"ns.enums.FactionName.BachmanAssociates" has been automatically replaced with "ns.enums.FactionName.BachmanAndAssociates".', '"ns.enums.FactionName.BachmanAssociates" has been automatically replaced with "ns.enums.FactionName.BachmanAndAssociates".',
showPopUp: false, showPopUp: false,
}, },
{
brokenAPIs: [{ name: "DreamSense" }],
info: 'The "DreamSense" upgrade was removed. The cost of that upgrade was refunded.',
showPopUp: false,
},
], ],
}; };

View File

@@ -31,6 +31,8 @@ import { getGoSave, loadGo } from "../Go/SaveLoad";
import { showAPIBreaks } from "./APIBreaks/APIBreak"; import { showAPIBreaks } from "./APIBreaks/APIBreak";
import { breakInfos261 } from "./APIBreaks/2.6.1"; import { breakInfos261 } from "./APIBreaks/2.6.1";
import { breakingChanges300 } from "./APIBreaks/3.0.0"; import { breakingChanges300 } from "./APIBreaks/3.0.0";
import { calculateUpgradeCost } from "../Corporation/helpers";
import type { PositiveInteger } from "../types";
/** Function for performing a series of defined replacements. See 0.58.0 for usage */ /** Function for performing a series of defined replacements. See 0.58.0 for usage */
function convert(code: string, changes: [RegExp, string][]): string { function convert(code: string, changes: [RegExp, string][]): string {
@@ -547,6 +549,18 @@ Error: ${e}`,
if (found) Terminal.error("Filenames with whitespace found and corrected, see console for details."); if (found) Terminal.error("Filenames with whitespace found and corrected, see console for details.");
} }
if (ver < 44) { if (ver < 44) {
if (Player.corporation) {
// Remove and refund DreamSense
for (const [name, upgrade] of Object.entries(Player.corporation.upgrades)) {
if (name !== "DreamSense") {
continue;
}
const cost = calculateUpgradeCost(4e9, 1.1, 0, upgrade.level as PositiveInteger);
Player.corporation.gainFunds(cost, "force majeure");
}
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete (Player.corporation.upgrades as Record<string, unknown>)["DreamSense"];
}
showAPIBreaks("3.0.0", breakingChanges300); showAPIBreaks("3.0.0", breakingChanges300);
} }
} }

View File

@@ -34,7 +34,13 @@ describe("Corporation", () => {
corporation.upgrades[upgrade.name].level = currentUpgradeLevel; corporation.upgrades[upgrade.name].level = currentUpgradeLevel;
for (let targetUpgradeLevel = currentUpgradeLevel + 1; targetUpgradeLevel < 6; targetUpgradeLevel++) { for (let targetUpgradeLevel = currentUpgradeLevel + 1; targetUpgradeLevel < 6; targetUpgradeLevel++) {
expect(calculateUpgradeCost(corporation, upgrade, targetUpgradeLevel as PositiveInteger)).toMatchSnapshot( const calculatedCost = calculateUpgradeCost(
upgrade.basePrice,
upgrade.priceMult,
currentUpgradeLevel,
targetUpgradeLevel as PositiveInteger,
);
expect(calculatedCost).toMatchSnapshot(
`${upgrade.name}: from ${currentUpgradeLevel} to ${targetUpgradeLevel}`, `${upgrade.name}: from ${currentUpgradeLevel} to ${targetUpgradeLevel}`,
); );
} }
@@ -66,7 +72,12 @@ describe("Corporation", () => {
corporation.upgrades[upgrade.name].level = currentUpgradeLevel; corporation.upgrades[upgrade.name].level = currentUpgradeLevel;
for (let targetUpgradeLevel = currentUpgradeLevel + 1; targetUpgradeLevel < 100; targetUpgradeLevel++) { for (let targetUpgradeLevel = currentUpgradeLevel + 1; targetUpgradeLevel < 100; targetUpgradeLevel++) {
const calculatedCost = calculateUpgradeCost(corporation, upgrade, targetUpgradeLevel as PositiveInteger); const calculatedCost = calculateUpgradeCost(
upgrade.basePrice,
upgrade.priceMult,
currentUpgradeLevel,
targetUpgradeLevel as PositiveInteger,
);
corporation.funds = calculatedCost + 1; // +1 for floating point accuracy issues corporation.funds = calculatedCost + 1; // +1 for floating point accuracy issues
expect(calculateMaxAffordableUpgrade(corporation, upgrade)).toEqual(targetUpgradeLevel); expect(calculateMaxAffordableUpgrade(corporation, upgrade)).toEqual(targetUpgradeLevel);
} }

View File

@@ -30,36 +30,6 @@ exports[`Corporation helpers.calculateUpgradeCost should have fixed formula: ABC
exports[`Corporation helpers.calculateUpgradeCost should have fixed formula: ABC SalesBots: from 4 to 5 1`] = `7538045748.859352`; exports[`Corporation helpers.calculateUpgradeCost should have fixed formula: ABC SalesBots: from 4 to 5 1`] = `7538045748.859352`;
exports[`Corporation helpers.calculateUpgradeCost should have fixed formula: DreamSense: from 0 to 1 1`] = `4000000000`;
exports[`Corporation helpers.calculateUpgradeCost should have fixed formula: DreamSense: from 0 to 2 1`] = `8400000000`;
exports[`Corporation helpers.calculateUpgradeCost should have fixed formula: DreamSense: from 0 to 3 1`] = `13240000000.000006`;
exports[`Corporation helpers.calculateUpgradeCost should have fixed formula: DreamSense: from 0 to 4 1`] = `18564000000.000008`;
exports[`Corporation helpers.calculateUpgradeCost should have fixed formula: DreamSense: from 0 to 5 1`] = `24420400000.000004`;
exports[`Corporation helpers.calculateUpgradeCost should have fixed formula: DreamSense: from 1 to 2 1`] = `9240000000`;
exports[`Corporation helpers.calculateUpgradeCost should have fixed formula: DreamSense: from 1 to 3 1`] = `14564000000.000004`;
exports[`Corporation helpers.calculateUpgradeCost should have fixed formula: DreamSense: from 1 to 4 1`] = `20420400000.00001`;
exports[`Corporation helpers.calculateUpgradeCost should have fixed formula: DreamSense: from 1 to 5 1`] = `26862440000`;
exports[`Corporation helpers.calculateUpgradeCost should have fixed formula: DreamSense: from 2 to 3 1`] = `16020400000.00001`;
exports[`Corporation helpers.calculateUpgradeCost should have fixed formula: DreamSense: from 2 to 4 1`] = `22462440000.000015`;
exports[`Corporation helpers.calculateUpgradeCost should have fixed formula: DreamSense: from 2 to 5 1`] = `29548684000.000008`;
exports[`Corporation helpers.calculateUpgradeCost should have fixed formula: DreamSense: from 3 to 4 1`] = `24708684000.00002`;
exports[`Corporation helpers.calculateUpgradeCost should have fixed formula: DreamSense: from 3 to 5 1`] = `32503552400.000015`;
exports[`Corporation helpers.calculateUpgradeCost should have fixed formula: DreamSense: from 4 to 5 1`] = `35753907640.000015`;
exports[`Corporation helpers.calculateUpgradeCost should have fixed formula: FocusWires: from 0 to 1 1`] = `1000000000`; exports[`Corporation helpers.calculateUpgradeCost should have fixed formula: FocusWires: from 0 to 1 1`] = `1000000000`;
exports[`Corporation helpers.calculateUpgradeCost should have fixed formula: FocusWires: from 0 to 2 1`] = `2060000000.0000007`; exports[`Corporation helpers.calculateUpgradeCost should have fixed formula: FocusWires: from 0 to 2 1`] = `2060000000.0000007`;

View File

@@ -330,10 +330,6 @@ exports[`Check Save File Continuity PlayerSave continuity 1`] = `
"level": 0, "level": 0,
"value": 1, "value": 1,
}, },
"DreamSense": {
"level": 0,
"value": 0,
},
"FocusWires": { "FocusWires": {
"level": 0, "level": 0,
"value": 1, "value": 1,