Made modifier descriptions use CoercableComponents
This commit is contained in:
parent
c918f1b54b
commit
6efd01fc43
3 changed files with 127 additions and 76 deletions
12
src/components/common/modifiers.css
Normal file
12
src/components/common/modifiers.css
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
.modifier-container {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modifier-amount {
|
||||||
|
flex-basis: 100px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modifier-description {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
|
@ -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
115
src/game/modifiers.tsx
Normal 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)}
|
||||||
|
</>
|
||||||
|
))
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in a new issue