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<DecimalSource>;
}
export interface BonusRepeatable extends Repeatable {
bonusAmount: MaybeRef<DecimalSource>;
totalAmount: Ref<DecimalSource>;
}
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<DecimalSource>;
}
export interface BonusChallenge extends Challenge {
bonusCompletions: MaybeRef<DecimalSource>;
totalCompletions: Ref<DecimalSource>;
}
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;
});
}