Add feature decorator system #13
|
@ -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<T extends AchievementOptions>(
|
||||
optionsFunc?: OptionsFunc<T, BaseAchievement, GenericAchievement>,
|
||||
...decorators: Decorator<T, BaseAchievement, GenericAchievement>[]
|
||||
...decorators: GenericDecorator[]
|
||||
): Achievement<T> {
|
||||
const earned = persistent<boolean>(false, false);
|
||||
const decoratedData = decorators.reduce((current, next) => Object.assign(current, next.getPersistentData?.()), {});
|
||||
|
|
|
@ -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<T extends ActionOptions>(
|
||||
optionsFunc?: OptionsFunc<T, BaseAction, GenericAction>,
|
||||
...decorators: Decorator<T, BaseAction, GenericAction>[]
|
||||
...decorators: GenericDecorator[]
|
||||
): Action<T> {
|
||||
const progress = persistent<DecimalSource>(0);
|
||||
const decoratedData = decorators.reduce((current, next) => Object.assign(current, next.getPersistentData?.()), {});
|
||||
|
|
|
@ -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<T extends BarOptions>(
|
||||
optionsFunc: OptionsFunc<T, BaseBar, GenericBar>,
|
||||
...decorators: Decorator<T, BaseBar, GenericBar>[]
|
||||
...decorators: GenericDecorator[]
|
||||
): Bar<T> {
|
||||
const decoratedData = decorators.reduce((current, next) => Object.assign(current, next.getPersistentData?.()), {});
|
||||
return createLazyProxy(feature => {
|
||||
|
|
|
@ -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<T extends ChallengeOptions>(
|
||||
optionsFunc: OptionsFunc<T, BaseChallenge, GenericChallenge>,
|
||||
...decorators: Decorator<T, BaseChallenge, GenericChallenge>[]
|
||||
...decorators: GenericDecorator[]
|
||||
): Challenge<T> {
|
||||
const completions = persistent(0);
|
||||
const active = persistent(false, false);
|
||||
|
|
|
@ -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<T extends ClickableOptions>(
|
||||
optionsFunc?: OptionsFunc<T, BaseClickable, GenericClickable>,
|
||||
...decorators: Decorator<T, BaseClickable, GenericClickable>[]
|
||||
...decorators: GenericDecorator[]
|
||||
): Clickable<T> {
|
||||
const decoratedData = decorators.reduce((current, next) => Object.assign(current, next.getPersistentData?.()), {});
|
||||
return createLazyProxy(feature => {
|
||||
|
|
|
@ -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<T extends ConversionOptions>(
|
||||
optionsFunc: OptionsFunc<T, BaseConversion, GenericConversion>,
|
||||
...decorators: Decorator<T, BaseConversion, GenericConversion>[]
|
||||
...decorators: GenericDecorator[]
|
||||
): Conversion<T> {
|
||||
return createLazyProxy(feature => {
|
||||
const conversion = optionsFunc.call(feature, feature);
|
||||
|
|
|
@ -15,11 +15,13 @@ export interface BonusCompletionsFeatureOptions {
|
|||
Heh, guess that's what I get for just letting it mass-import everything Heh, guess that's what I get for just letting it mass-import everything
Trust me, I've made this same mistake so many times. I wish I had a better way to hint to the IDE what the default export is expected to be called Trust me, I've made this same mistake so many times. I wish I had a better way to hint to the IDE what the default export is expected to be called
Please change this back to util/bignum Please change this back to util/bignum
Heh, guess that's what I get for just letting it mass-import everything Heh, guess that's what I get for just letting it mass-import everything
Trust me, I've made this same mistake so many times. I wish I had a better way to hint to the IDE what the default export is expected to be called Trust me, I've made this same mistake so many times. I wish I had a better way to hint to the IDE what the default export is expected to be called
|
||||
|
||||
export interface BaseBonusAmountFeature {
|
||||
amount: Ref<DecimalSource>;
|
||||
totalAmount: Ref<DecimalSource>;
|
||||
Please change this back to util/bignum Please change this back to util/bignum
Heh, guess that's what I get for just letting it mass-import everything Heh, guess that's what I get for just letting it mass-import everything
Trust me, I've made this same mistake so many times. I wish I had a better way to hint to the IDE what the default export is expected to be called Trust me, I've made this same mistake so many times. I wish I had a better way to hint to the IDE what the default export is expected to be called
|
||||
bonusAmount: ProcessedComputable<DecimalSource>;
|
||||
Please change this back to util/bignum Please change this back to util/bignum
Heh, guess that's what I get for just letting it mass-import everything Heh, guess that's what I get for just letting it mass-import everything
Trust me, I've made this same mistake so many times. I wish I had a better way to hint to the IDE what the default export is expected to be called Trust me, I've made this same mistake so many times. I wish I had a better way to hint to the IDE what the default export is expected to be called
|
||||
totalAmount?: Ref<DecimalSource>;
|
||||
Please change this back to util/bignum Please change this back to util/bignum
Heh, guess that's what I get for just letting it mass-import everything Heh, guess that's what I get for just letting it mass-import everything
Trust me, I've made this same mistake so many times. I wish I had a better way to hint to the IDE what the default export is expected to be called Trust me, I've made this same mistake so many times. I wish I had a better way to hint to the IDE what the default export is expected to be called
|
||||
}
|
||||
export interface BaseBonusCompletionsFeature {
|
||||
completions: Ref<DecimalSource>;
|
||||
totalCompletions: Ref<DecimalSource>;
|
||||
Please change this back to util/bignum Please change this back to util/bignum
Heh, guess that's what I get for just letting it mass-import everything Heh, guess that's what I get for just letting it mass-import everything
Trust me, I've made this same mistake so many times. I wish I had a better way to hint to the IDE what the default export is expected to be called Trust me, I've made this same mistake so many times. I wish I had a better way to hint to the IDE what the default export is expected to be called
|
||||
bonusCompletions: ProcessedComputable<DecimalSource>;
|
||||
Please change this back to util/bignum Please change this back to util/bignum
Heh, guess that's what I get for just letting it mass-import everything Heh, guess that's what I get for just letting it mass-import everything
Trust me, I've made this same mistake so many times. I wish I had a better way to hint to the IDE what the default export is expected to be called Trust me, I've made this same mistake so many times. I wish I had a better way to hint to the IDE what the default export is expected to be called
|
||||
totalCompletions?: Ref<DecimalSource>;
|
||||
Please change this back to util/bignum Please change this back to util/bignum
Heh, guess that's what I get for just letting it mass-import everything Heh, guess that's what I get for just letting it mass-import everything
Trust me, I've made this same mistake so many times. I wish I had a better way to hint to the IDE what the default export is expected to be called Trust me, I've made this same mistake so many times. I wish I had a better way to hint to the IDE what the default export is expected to be called
|
||||
}
|
||||
|
||||
export type BonusAmountFeature<T extends BonusAmountFeatureOptions> = Replace<
|
||||
|
@ -47,6 +49,7 @@ export type GenericBonusCompletionsFeature = Replace<
|
|||
Please change this back to util/bignum Please change this back to util/bignum
Heh, guess that's what I get for just letting it mass-import everything Heh, guess that's what I get for just letting it mass-import everything
Trust me, I've made this same mistake so many times. I wish I had a better way to hint to the IDE what the default export is expected to be called Trust me, I've made this same mistake so many times. I wish I had a better way to hint to the IDE what the default export is expected to be called
Please change this back to util/bignum Please change this back to util/bignum
Heh, guess that's what I get for just letting it mass-import everything Heh, guess that's what I get for just letting it mass-import everything
Trust me, I've made this same mistake so many times. I wish I had a better way to hint to the IDE what the default export is expected to be called Trust me, I've made this same mistake so many times. I wish I had a better way to hint to the IDE what the default export is expected to be called
|
||||
/**
|
||||
* 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.
|
||||
Please change this back to util/bignum Please change this back to util/bignum
Heh, guess that's what I get for just letting it mass-import everything Heh, guess that's what I get for just letting it mass-import everything
Trust me, I've made this same mistake so many times. I wish I had a better way to hint to the IDE what the default export is expected to be called Trust me, I've made this same mistake so many times. I wish I had a better way to hint to the IDE what the default export is expected to be called
|
||||
* To allow access to the decorated values outside the `createFeature()` function, the output type must be extended by {@linkcode GenericBonusAmountFeature}.
|
||||
* @example ```ts
|
||||
* createRepeatable<RepeatableOptions & BonusAmountFeatureOptions>(() => ({
|
||||
|
|
|||
Please change this back to util/bignum Please change this back to util/bignum
Heh, guess that's what I get for just letting it mass-import everything Heh, guess that's what I get for just letting it mass-import everything
Trust me, I've made this same mistake so many times. I wish I had a better way to hint to the IDE what the default export is expected to be called Trust me, I've made this same mistake so many times. I wish I had a better way to hint to the IDE what the default export is expected to be called
Please change this back to util/bignum Please change this back to util/bignum
Heh, guess that's what I get for just letting it mass-import everything Heh, guess that's what I get for just letting it mass-import everything
Trust me, I've made this same mistake so many times. I wish I had a better way to hint to the IDE what the default export is expected to be called Trust me, I've made this same mistake so many times. I wish I had a better way to hint to the IDE what the default export is expected to be called
|
|
@ -2,13 +2,15 @@ import { Replace, OptionsObject } from "../feature";
|
|||
I'm not a huge fan of adding these separators and #region comments since nowhere else in the project has them I'm not a huge fan of adding these separators and #region comments since nowhere else in the project has them
I'm not a huge fan of adding these separators and #region comments since nowhere else in the project has them I'm not a huge fan of adding these separators and #region comments since nowhere else in the project has them
|
||||
import { Computable, GetComputableType, processComputable, ProcessedComputable } from "util/computed";
|
||||
import { Persistent, State } from "game/persistence";
|
||||
|
||||
export type Decorator<FeatureOptions, BaseFeature = {}, GenericFeature = BaseFeature, S extends State = State> = {
|
||||
I'm not a huge fan of adding these separators and #region comments since nowhere else in the project has them I'm not a huge fan of adding these separators and #region comments since nowhere else in the project has them
|
||||
export type Decorator<FeatureOptions, BaseFeature = Object, GenericFeature = BaseFeature, S extends State = State> = {
|
||||
I'm not a huge fan of adding these separators and #region comments since nowhere else in the project has them I'm not a huge fan of adding these separators and #region comments since nowhere else in the project has them
|
||||
getPersistentData?(): Record<string, Persistent<S>>;
|
||||
preConstruct?(feature: OptionsObject<FeatureOptions,BaseFeature,GenericFeature>): void;
|
||||
postConstruct?(feature: OptionsObject<FeatureOptions,BaseFeature,GenericFeature>): void;
|
||||
getGatheredProps?(feature: OptionsObject<FeatureOptions,BaseFeature,GenericFeature>): Partial<OptionsObject<FeatureOptions,BaseFeature,GenericFeature>>
|
||||
}
|
||||
|
||||
export type GenericDecorator = Decorator<unknown>;
|
||||
I'm not a huge fan of adding these separators and #region comments since nowhere else in the project has them I'm not a huge fan of adding these separators and #region comments since nowhere else in the project has them
|
||||
|
||||
I'm not a huge fan of adding these separators and #region comments since nowhere else in the project has them I'm not a huge fan of adding these separators and #region comments since nowhere else in the project has them
|
||||
export interface EffectFeatureOptions {
|
||||
effect: Computable<any>;
|
||||
}
|
||||
|
@ -33,7 +35,7 @@ export type GenericEffectFeature = Replace<
|
|||
I'm not a huge fan of adding these separators and #region comments since nowhere else in the project has them I'm not a huge fan of adding these separators and #region comments since nowhere else in the project has them
I'm not a huge fan of adding these separators and #region comments since nowhere else in the project has them I'm not a huge fan of adding these separators and #region comments since nowhere else in the project has them
|
||||
* }), effectDecorator) as GenericUpgrade & GenericEffectFeature;
|
||||
* ```
|
||||
*/
|
||||
export const effectDecorator: Decorator<EffectFeatureOptions, {}, GenericEffectFeature> = {
|
||||
I'm not a huge fan of adding these separators and #region comments since nowhere else in the project has them I'm not a huge fan of adding these separators and #region comments since nowhere else in the project has them
|
||||
export const effectDecorator: Decorator<EffectFeatureOptions, unknown, GenericEffectFeature> = {
|
||||
I'm not a huge fan of adding these separators and #region comments since nowhere else in the project has them I'm not a huge fan of adding these separators and #region comments since nowhere else in the project has them
|
||||
postConstruct(feature) {
|
||||
processComputable(feature, "effect");
|
||||
}
|
||||
|
|
|||
I'm not a huge fan of adding these separators and #region comments since nowhere else in the project has them I'm not a huge fan of adding these separators and #region comments since nowhere else in the project has them
I'm not a huge fan of adding these separators and #region comments since nowhere else in the project has them I'm not a huge fan of adding these separators and #region comments since nowhere else in the project has them
|
|
@ -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<T extends RepeatableOptions>(
|
||||
optionsFunc: OptionsFunc<T, BaseRepeatable, GenericRepeatable>,
|
||||
...decorators: Decorator<T, BaseRepeatable, GenericRepeatable>[]
|
||||
...decorators: GenericDecorator[]
|
||||
): Repeatable<T> {
|
||||
const amount = persistent<DecimalSource>(0);
|
||||
const decoratedData = decorators.reduce((current, next) => Object.assign(current, next.getPersistentData?.()), {});
|
||||
return createLazyProxy(feature => {
|
||||
return createLazyProxy<Repeatable<T>, Repeatable<T>>(feature => {
|
||||
const repeatable = optionsFunc.call(feature, feature);
|
||||
|
||||
repeatable.id = getUniqueID("repeatable-");
|
||||
|
|
|
@ -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<T extends TreeNodeOptions>(
|
||||
optionsFunc?: OptionsFunc<T, BaseTreeNode, GenericTreeNode>,
|
||||
...decorators: Decorator<T, BaseTreeNode, GenericTreeNode>[]
|
||||
...decorators: GenericDecorator[]
|
||||
): TreeNode<T> {
|
||||
const decoratedData = decorators.reduce((current, next) => Object.assign(current, next.getPersistentData?.()), {});
|
||||
return createLazyProxy(feature => {
|
||||
|
|
|
@ -119,7 +119,7 @@ export type GenericUpgrade = Replace<
|
|||
*/
|
||||
export function createUpgrade<T extends UpgradeOptions>(
|
||||
optionsFunc: OptionsFunc<T, BaseUpgrade, GenericUpgrade>,
|
||||
...decorators: Decorator<T, BaseUpgrade, GenericUpgrade>[]
|
||||
...decorators: GenericDecorator[]
|
||||
): Upgrade<T> {
|
||||
const bought = persistent<boolean>(false, false);
|
||||
const decoratedData = decorators.reduce((current, next) => Object.assign(current, next.getPersistentData?.()), {});
|
||||
|
|
Please change this back to util/bignum