From f7f4d0aa9fbde2653c2362fd839b24898c64a3f9 Mon Sep 17 00:00:00 2001 From: thepaperpilot Date: Sat, 22 Apr 2023 17:58:31 -0500 Subject: [PATCH] Fix non-integrable requirements crashing in cost requirements with spendResources true (Which should be valid in the event the dev doesn't want to maximize) --- src/game/requirements.tsx | 28 +++++++++++-- tests/game/requirements.test.ts | 72 ++++++++++++++++++++++++++++++--- 2 files changed, 90 insertions(+), 10 deletions(-) diff --git a/src/game/requirements.tsx b/src/game/requirements.tsx index ac0f551..0b00192 100644 --- a/src/game/requirements.tsx +++ b/src/game/requirements.tsx @@ -101,6 +101,7 @@ export type CostRequirement = Replace< visibility: ProcessedComputable; requiresPay: ProcessedComputable; spendResources: ProcessedComputable; + canMaximize: ProcessedComputable; } >; @@ -159,14 +160,33 @@ export function createCostRequirement( req.resource.value = Decimal.sub(req.resource.value, cost).max(0); }); - req.canMaximize = req.cost instanceof Formula && req.cost.isInvertible(); + req.canMaximize = computed( + () => + req.cost instanceof Formula && + req.cost.isInvertible() && + (unref(req.spendResources) === false || req.cost.isIntegrable()) + ); - if (req.canMaximize) { - req.requirementMet = calculateMaxAffordable( - req.cost as InvertibleFormula, + if (req.cost instanceof Formula && req.cost.isInvertible()) { + const maxAffordable = calculateMaxAffordable( + req.cost, req.resource, unref(req.spendResources) as boolean ); + req.requirementMet = computed(() => { + if (unref(req.canMaximize)) { + return maxAffordable.value; + } else { + if (req.cost instanceof Formula) { + return Decimal.gte(req.resource.value, req.cost.evaluate()); + } else { + return Decimal.gte( + req.resource.value, + unref(req.cost as ProcessedComputable) + ); + } + } + }); } else { req.requirementMet = computed(() => { if (req.cost instanceof Formula) { diff --git a/tests/game/requirements.test.ts b/tests/game/requirements.test.ts index 13a13e9..2222276 100644 --- a/tests/game/requirements.test.ts +++ b/tests/game/requirements.test.ts @@ -16,11 +16,14 @@ import { isRef, ref, unref } from "vue"; import "../utils"; describe("Creating cost requirement", () => { + let resource: Resource; + beforeAll(() => { + resource = createResource(ref(10)); + }); + describe("Minimal requirement", () => { - let resource: Resource; let requirement: CostRequirement; beforeAll(() => { - resource = createResource(ref(10)); requirement = createCostRequirement(() => ({ resource, cost: 10, @@ -46,10 +49,8 @@ describe("Creating cost requirement", () => { }); describe("Fully customized", () => { - let resource: Resource; let requirement: CostRequirement; beforeAll(() => { - resource = createResource(ref(10)); requirement = createCostRequirement(() => ({ resource, cost: Formula.variable(resource).times(10), @@ -73,7 +74,6 @@ describe("Creating cost requirement", () => { }); test("Requirement met when meeting the cost", () => { - const resource = createResource(ref(10)); const requirement = createCostRequirement(() => ({ resource, cost: 10, @@ -83,7 +83,6 @@ describe("Creating cost requirement", () => { }); test("Requirement not met when not meeting the cost", () => { - const resource = createResource(ref(10)); const requirement = createCostRequirement(() => ({ resource, cost: 100, @@ -91,6 +90,67 @@ describe("Creating cost requirement", () => { })); expect(unref(requirement.requirementMet)).toBe(false); }); + + describe("canMaximize works correctly", () => { + test("Cost function cannot maximize", () => + expect( + unref( + createCostRequirement(() => ({ + resource, + cost: () => 10 + })).canMaximize + ) + ).toBe(false)); + test("Non-invertible formula cannot maximize", () => + expect( + unref( + createCostRequirement(() => ({ + resource, + cost: Formula.variable(resource).abs() + })).canMaximize + ) + ).toBe(false)); + test("Invertible formula can maximize if spendResources is false", () => + expect( + unref( + createCostRequirement(() => ({ + resource, + cost: Formula.variable(resource).lambertw(), + spendResources: false + })).canMaximize + ) + ).toBe(true)); + test("Invertible formula cannot maximize if spendResources is true", () => + expect( + unref( + createCostRequirement(() => ({ + resource, + cost: Formula.variable(resource).lambertw(), + spendResources: true + })).canMaximize + ) + ).toBe(false)); + test("Integrable formula can maximize if spendResources is false", () => + expect( + unref( + createCostRequirement(() => ({ + resource, + cost: Formula.variable(resource).pow(2), + spendResources: false + })).canMaximize + ) + ).toBe(true)); + test("Integrable formula can maximize if spendResources is true", () => + expect( + unref( + createCostRequirement(() => ({ + resource, + cost: Formula.variable(resource).pow(2), + spendResources: true + })).canMaximize + ) + ).toBe(true)); + }); }); describe("Creating visibility requirement", () => {