As of Profectus 0.7, decorators got replaced with mixins and wrappers. Since mixins require creating or extending a feature, and the bonus decorators became a mixin, I wanted to share exactly how to extend the repeatable and challenge to use bonus amounts/completions. These will work out of the box and are well type annotated.

bonusRepeatable.ts:

import { createRepeatable, Repeatable, RepeatableOptions } from "features/clickables/repeatable";import { bonusAmountMixin } from "mixins/bonusAmount";import { DecimalSource } from "util/bignum";import { createLazyProxy } from "util/proxies";import { MaybeRef, MaybeRefOrGetter, Ref } from "vue";export interface BonusRepeatableOptions extends RepeatableOptions { bonusAmount: MaybeRefOrGetter;}export interface BonusRepeatable extends Repeatable { bonusAmount: MaybeRef; totalAmount: Ref;}export function createBonusRepeatable(optionsFunc: () => BonusRepeatableOptions) { return createLazyProxy(() => { const repeatable = createRepeatable(optionsFunc); const bonusRepeatable = { ...repeatable, ...bonusAmountMixin(repeatable.amount, repeatable.bonusAmount) } satisfies BonusRepeatable; return bonusRepeatable; });}

bonusChallenge.ts:

import { Challenge, ChallengeOptions, createChallenge } from "features/challenges/challenge";import { bonusAmountMixin } from "mixins/bonusAmount";import { DecimalSource } from "util/bignum";import { createLazyProxy } from "util/proxies";import { MaybeRef, MaybeRefOrGetter, Ref } from "vue";export interface BonusChallengeOptions extends ChallengeOptions { bonusCompletions: MaybeRefOrGetter;}export interface BonusChallenge extends Challenge { bonusCompletions: MaybeRef; totalCompletions: Ref;}export function createBonusChallenge(optionsFunc: () => BonusChallengeOptions) { return createLazyProxy(() => { const challenge = createChallenge(optionsFunc); const { bonusAmount, totalAmount } = bonusAmountMixin( challenge.completions, challenge.bonusCompletions ); const bonusChallenge = { ...challenge, bonusCompletions: bonusAmount, totalCompletions: totalAmount } satisfies BonusChallenge; return bonusChallenge; });}


Discuss this on our forum.