Made modifier descriptions use CoercableComponents

This commit is contained in:
thepaperpilot 2022-04-16 00:56:37 -05:00
parent c918f1b54b
commit 6efd01fc43
3 changed files with 127 additions and 76 deletions

View file

@ -0,0 +1,12 @@
.modifier-container {
display: flex;
}
.modifier-amount {
flex-basis: 100px;
flex-shrink: 0;
}
.modifier-description {
flex-grow: 1;
}

View file

@ -1,76 +0,0 @@
import Decimal, { DecimalSource, format } from "util/bignum";
import { Computable, convertComputable, ProcessedComputable } from "util/computed";
import { computed, unref } from "vue";
export interface Modifier {
apply: (gain: DecimalSource) => DecimalSource;
revert: (gain: DecimalSource) => DecimalSource;
enabled: ProcessedComputable<boolean>;
description?: ProcessedComputable<string>;
}
export function createAdditiveModifier(
addend: Computable<DecimalSource>,
description?: string,
enabled?: Computable<boolean>
): Modifier {
const processedAddend = convertComputable(addend);
const processedEnabled = convertComputable(enabled == null ? true : enabled);
return {
apply: gain => Decimal.add(gain, unref(processedAddend)),
revert: gain => Decimal.sub(gain, unref(processedAddend)),
enabled: processedEnabled,
description: computed(() => `+${format(unref(processedAddend))} ${description}`)
};
}
export function createMultiplicativeModifier(
multiplier: Computable<DecimalSource>,
description?: string,
enabled?: Computable<boolean>
): Modifier {
const processedMultiplier = convertComputable(multiplier);
const processedEnabled = convertComputable(enabled == null ? true : enabled);
return {
apply: gain => Decimal.times(gain, unref(processedMultiplier)),
revert: gain => Decimal.div(gain, unref(processedMultiplier)),
enabled: processedEnabled,
description: computed(() => `x${format(unref(processedMultiplier))} ${description}`)
};
}
export function createExponentialModifier(
exponent: Computable<DecimalSource>,
description?: string,
enabled?: Computable<boolean>
): Modifier {
const processedExponent = convertComputable(exponent);
const processedEnabled = convertComputable(enabled == null ? true : enabled);
return {
apply: gain => Decimal.pow(gain, unref(processedExponent)),
revert: gain => Decimal.root(gain, unref(processedExponent)),
enabled: processedEnabled,
description: computed(() => `^${format(unref(processedExponent))} ${description}`)
};
}
export function createSequentialModifier(...modifiers: Modifier[]): Modifier {
return {
apply: gain =>
modifiers
.filter(m => unref(m.enabled))
.reduce((gain, modifier) => modifier.apply(gain), gain),
revert: gain =>
modifiers
.filter(m => unref(m.enabled))
.reduceRight((gain, modifier) => modifier.revert(gain), gain),
enabled: computed(() => modifiers.filter(m => unref(m.enabled)).length > 0),
description: computed(() => {
return modifiers
.filter(m => unref(m.enabled))
.map(m => unref(m.description))
.filter(d => d)
.join("\n");
})
};
}

115
src/game/modifiers.tsx Normal file
View file

@ -0,0 +1,115 @@
import { CoercableComponent, jsx } from "features/feature";
import Decimal, { DecimalSource, format } from "util/bignum";
import { Computable, convertComputable, ProcessedComputable } from "util/computed";
import { renderJSX } from "util/vue";
import { computed, unref } from "vue";
import "components/common/modifiers.css";
export interface Modifier {
apply: (gain: DecimalSource) => DecimalSource;
revert: (gain: DecimalSource) => DecimalSource;
enabled: ProcessedComputable<boolean>;
description?: ProcessedComputable<CoercableComponent>;
}
export function createAdditiveModifier(
addend: Computable<DecimalSource>,
description?: Computable<CoercableComponent>,
enabled?: Computable<boolean>
): Modifier {
const processedAddend = convertComputable(addend);
const processedDescription = convertComputable(description);
const processedEnabled = convertComputable(enabled == null ? true : enabled);
return {
apply: gain => Decimal.add(gain, unref(processedAddend)),
revert: gain => Decimal.sub(gain, unref(processedAddend)),
enabled: processedEnabled,
description: jsx(() => (
<div class="modifier-container">
<span class="modifier-amount">+{format(unref(processedAddend))}</span>
{unref(processedDescription) ? (
<span class="modifier-description">
{/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */}
{renderJSX(unref(processedDescription)!)}
</span>
) : null}
</div>
))
};
}
export function createMultiplicativeModifier(
multiplier: Computable<DecimalSource>,
description?: Computable<CoercableComponent>,
enabled?: Computable<boolean>
): Modifier {
const processedMultiplier = convertComputable(multiplier);
const processedDescription = convertComputable(description);
const processedEnabled = convertComputable(enabled == null ? true : enabled);
return {
apply: gain => Decimal.times(gain, unref(processedMultiplier)),
revert: gain => Decimal.div(gain, unref(processedMultiplier)),
enabled: processedEnabled,
description: jsx(() => (
<div class="modifier-container">
<span class="modifier-amount">x{format(unref(processedMultiplier))}</span>
{unref(processedDescription) ? (
<span class="modifier-description">
{/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */}
{renderJSX(unref(processedDescription)!)}
</span>
) : null}
</div>
))
};
}
export function createExponentialModifier(
exponent: Computable<DecimalSource>,
description?: Computable<CoercableComponent>,
enabled?: Computable<boolean>
): Modifier {
const processedExponent = convertComputable(exponent);
const processedDescription = convertComputable(description);
const processedEnabled = convertComputable(enabled == null ? true : enabled);
return {
apply: gain => Decimal.pow(gain, unref(processedExponent)),
revert: gain => Decimal.root(gain, unref(processedExponent)),
enabled: processedEnabled,
description: jsx(() => (
<div class="modifier-container">
<span class="modifier-amount">^{format(unref(processedExponent))}</span>
{unref(processedDescription) ? (
<span class="modifier-description">
{/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */}
{renderJSX(unref(processedDescription)!)}
</span>
) : null}
</div>
))
};
}
export function createSequentialModifier(...modifiers: Modifier[]): Required<Modifier> {
return {
apply: gain =>
modifiers
.filter(m => unref(m.enabled))
.reduce((gain, modifier) => modifier.apply(gain), gain),
revert: gain =>
modifiers
.filter(m => unref(m.enabled))
.reduceRight((gain, modifier) => modifier.revert(gain), gain),
enabled: computed(() => modifiers.filter(m => unref(m.enabled)).length > 0),
description: jsx(() => (
<>
{(
modifiers
.filter(m => unref(m.enabled))
.map(m => unref(m.description))
.filter(d => d) as CoercableComponent[]
).map(renderJSX)}
</>
))
};
}