diff --git a/src/features/achievements/achievement.tsx b/src/features/achievements/achievement.tsx index 3af6650..eb7ad60 100644 --- a/src/features/achievements/achievement.tsx +++ b/src/features/achievements/achievement.tsx @@ -2,7 +2,7 @@ import { computed } from "@vue/reactivity"; import { isArray } from "@vue/shared"; import Select from "components/fields/Select.vue"; import AchievementComponent from "features/achievements/Achievement.vue"; -import { Decorator } from "features/decorators/common"; +import { Decorator, GenericDecorator } from "features/decorators/common"; import { CoercableComponent, Component, @@ -139,7 +139,7 @@ export type GenericAchievement = Replace< */ export function createAchievement( optionsFunc?: OptionsFunc, - ...decorators: Decorator[] + ...decorators: GenericDecorator[] ): Achievement { const earned = persistent(false, false); const decoratedData = decorators.reduce((current, next) => Object.assign(current, next.getPersistentData?.()), {}); diff --git a/src/features/action.tsx b/src/features/action.tsx index 3b15756..1dc9498 100644 --- a/src/features/action.tsx +++ b/src/features/action.tsx @@ -31,7 +31,7 @@ import { coerceComponent, isCoercableComponent, render } from "util/vue"; import { computed, Ref, ref, unref } from "vue"; import { BarOptions, createBar, GenericBar } from "./bars/bar"; import { ClickableOptions } from "./clickables/clickable"; -import { Decorator } from "./decorators/common"; +import { Decorator, GenericDecorator } from "./decorators/common"; /** A symbol used to identify {@link Action} features. */ export const ActionType = Symbol("Action"); @@ -104,7 +104,7 @@ export type GenericAction = Replace< */ export function createAction( optionsFunc?: OptionsFunc, - ...decorators: Decorator[] + ...decorators: GenericDecorator[] ): Action { const progress = persistent(0); const decoratedData = decorators.reduce((current, next) => Object.assign(current, next.getPersistentData?.()), {}); diff --git a/src/features/bars/bar.ts b/src/features/bars/bar.ts index 32e45c6..e2be951 100644 --- a/src/features/bars/bar.ts +++ b/src/features/bars/bar.ts @@ -1,5 +1,5 @@ import BarComponent from "features/bars/Bar.vue"; -import { Decorator } from "features/decorators/common"; +import { Decorator, GenericDecorator } from "features/decorators/common"; import type { CoercableComponent, GenericComponent, @@ -103,7 +103,7 @@ export type GenericBar = Replace< */ export function createBar( optionsFunc: OptionsFunc, - ...decorators: Decorator[] + ...decorators: GenericDecorator[] ): Bar { const decoratedData = decorators.reduce((current, next) => Object.assign(current, next.getPersistentData?.()), {}); return createLazyProxy(feature => { diff --git a/src/features/challenges/challenge.tsx b/src/features/challenges/challenge.tsx index 095b15a..ad6ca6a 100644 --- a/src/features/challenges/challenge.tsx +++ b/src/features/challenges/challenge.tsx @@ -1,7 +1,7 @@ import { isArray } from "@vue/shared"; import Toggle from "components/fields/Toggle.vue"; import ChallengeComponent from "features/challenges/Challenge.vue"; -import { Decorator } from "features/decorators/common"; +import { Decorator, GenericDecorator } from "features/decorators/common"; import type { CoercableComponent, GenericComponent, @@ -150,7 +150,7 @@ export type GenericChallenge = Replace< */ export function createChallenge( optionsFunc: OptionsFunc, - ...decorators: Decorator[] + ...decorators: GenericDecorator[] ): Challenge { const completions = persistent(0); const active = persistent(false, false); diff --git a/src/features/clickables/clickable.ts b/src/features/clickables/clickable.ts index 0da6fda..4e3dfcf 100644 --- a/src/features/clickables/clickable.ts +++ b/src/features/clickables/clickable.ts @@ -1,5 +1,5 @@ import ClickableComponent from "features/clickables/Clickable.vue"; -import { Decorator } from "features/decorators/common"; +import { Decorator, GenericDecorator } from "features/decorators/common"; import type { CoercableComponent, GenericComponent, @@ -97,7 +97,7 @@ export type GenericClickable = Replace< */ export function createClickable( optionsFunc?: OptionsFunc, - ...decorators: Decorator[] + ...decorators: GenericDecorator[] ): Clickable { const decoratedData = decorators.reduce((current, next) => Object.assign(current, next.getPersistentData?.()), {}); return createLazyProxy(feature => { diff --git a/src/features/conversion.ts b/src/features/conversion.ts index 41b7f32..c9c22c2 100644 --- a/src/features/conversion.ts +++ b/src/features/conversion.ts @@ -15,7 +15,7 @@ import { convertComputable, processComputable } from "util/computed"; import { createLazyProxy } from "util/proxies"; import type { Ref } from "vue"; import { computed, unref } from "vue"; -import { Decorator } from "./decorators/common"; +import { GenericDecorator } from "./decorators/common"; /** An object that configures a {@link Conversion}. */ export interface ConversionOptions { @@ -125,7 +125,7 @@ export type GenericConversion = Replace< */ export function createConversion( optionsFunc: OptionsFunc, - ...decorators: Decorator[] + ...decorators: GenericDecorator[] ): Conversion { return createLazyProxy(feature => { const conversion = optionsFunc.call(feature, feature); diff --git a/src/features/decorators/bonusDecorator.ts b/src/features/decorators/bonusDecorator.ts index d019010..1c26b14 100644 --- a/src/features/decorators/bonusDecorator.ts +++ b/src/features/decorators/bonusDecorator.ts @@ -15,11 +15,13 @@ export interface BonusCompletionsFeatureOptions { export interface BaseBonusAmountFeature { amount: Ref; - totalAmount: Ref; + bonusAmount: ProcessedComputable; + totalAmount?: Ref; } export interface BaseBonusCompletionsFeature { completions: Ref; - totalCompletions: Ref; + bonusCompletions: ProcessedComputable; + totalCompletions?: Ref; } export type BonusAmountFeature = Replace< @@ -47,6 +49,7 @@ export type GenericBonusCompletionsFeature = Replace< /** * Allows the addition of "bonus levels" to the decorated feature, with an accompanying "total amount". * To function properly, the `createFeature()` function must have its generic type extended by {@linkcode BonusAmountFeatureOptions}. + * Additionally, the base feature must have an `amount` property. * To allow access to the decorated values outside the `createFeature()` function, the output type must be extended by {@linkcode GenericBonusAmountFeature}. * @example ```ts * createRepeatable(() => ({ diff --git a/src/features/decorators/common.ts b/src/features/decorators/common.ts index 362d787..a4656d3 100644 --- a/src/features/decorators/common.ts +++ b/src/features/decorators/common.ts @@ -2,13 +2,15 @@ import { Replace, OptionsObject } from "../feature"; import { Computable, GetComputableType, processComputable, ProcessedComputable } from "util/computed"; import { Persistent, State } from "game/persistence"; -export type Decorator = { +export type Decorator = { getPersistentData?(): Record>; preConstruct?(feature: OptionsObject): void; postConstruct?(feature: OptionsObject): void; getGatheredProps?(feature: OptionsObject): Partial> } +export type GenericDecorator = Decorator; + export interface EffectFeatureOptions { effect: Computable; } @@ -33,7 +35,7 @@ export type GenericEffectFeature = Replace< * }), effectDecorator) as GenericUpgrade & GenericEffectFeature; * ``` */ -export const effectDecorator: Decorator = { +export const effectDecorator: Decorator = { postConstruct(feature) { processComputable(feature, "effect"); } diff --git a/src/features/repeatable.tsx b/src/features/repeatable.tsx index 1a4774c..bc486e4 100644 --- a/src/features/repeatable.tsx +++ b/src/features/repeatable.tsx @@ -30,7 +30,7 @@ import { createLazyProxy } from "util/proxies"; import { coerceComponent, isCoercableComponent } from "util/vue"; import type { Ref } from "vue"; import { computed, unref } from "vue"; -import { Decorator } from "./decorators/common"; +import { Decorator, GenericDecorator } from "./decorators/common"; /** A symbol used to identify {@link Repeatable} features. */ export const RepeatableType = Symbol("Repeatable"); @@ -131,11 +131,11 @@ export type GenericRepeatable = Replace< */ export function createRepeatable( optionsFunc: OptionsFunc, - ...decorators: Decorator[] + ...decorators: GenericDecorator[] ): Repeatable { const amount = persistent(0); const decoratedData = decorators.reduce((current, next) => Object.assign(current, next.getPersistentData?.()), {}); - return createLazyProxy(feature => { + return createLazyProxy, Repeatable>(feature => { const repeatable = optionsFunc.call(feature, feature); repeatable.id = getUniqueID("repeatable-"); diff --git a/src/features/trees/tree.ts b/src/features/trees/tree.ts index 22aa627..b773ff9 100644 --- a/src/features/trees/tree.ts +++ b/src/features/trees/tree.ts @@ -1,4 +1,4 @@ -import { Decorator } from "features/decorators/common"; +import { Decorator, GenericDecorator } from "features/decorators/common"; import type { CoercableComponent, GenericComponent, @@ -103,7 +103,7 @@ export type GenericTreeNode = Replace< */ export function createTreeNode( optionsFunc?: OptionsFunc, - ...decorators: Decorator[] + ...decorators: GenericDecorator[] ): TreeNode { const decoratedData = decorators.reduce((current, next) => Object.assign(current, next.getPersistentData?.()), {}); return createLazyProxy(feature => { diff --git a/src/features/upgrades/upgrade.ts b/src/features/upgrades/upgrade.ts index 08fd2e6..d64131a 100644 --- a/src/features/upgrades/upgrade.ts +++ b/src/features/upgrades/upgrade.ts @@ -119,7 +119,7 @@ export type GenericUpgrade = Replace< */ export function createUpgrade( optionsFunc: OptionsFunc, - ...decorators: Decorator[] + ...decorators: GenericDecorator[] ): Upgrade { const bought = persistent(false, false); const decoratedData = decorators.reduce((current, next) => Object.assign(current, next.getPersistentData?.()), {});