feat: More bonus (exponential) and method to list icons needed
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
// Endless upgrades: families of upgrades that continue forever, level after level.
|
||||
|
||||
import { endlessQuote, lineAvailable, lineLevel } from '../engine/endless.js';
|
||||
import { t } from '../services/i18n.js';
|
||||
import { h, icon } from './dom.js';
|
||||
import { effectText, moneyFormatter, setText } from './text.js';
|
||||
|
||||
const AMOUNTS = [1, 10, 100, 'max'];
|
||||
|
||||
export function createEndlessView(root, actions) {
|
||||
let ctx;
|
||||
let fmt;
|
||||
let money;
|
||||
let amount = 1;
|
||||
const rows = new Map();
|
||||
|
||||
const lineName = (line) =>
|
||||
line.effect.target
|
||||
? t('endless.name.generator', { target: t(`theme.gen.${line.effect.target}.name`) })
|
||||
: t(`endless.name.${line.id}`);
|
||||
|
||||
function rowFor(line) {
|
||||
const level = h('span', { class: 'badge' });
|
||||
const total = h('p', { class: 'card__meta' });
|
||||
const label = h('span', { class: 'btn__label' });
|
||||
const cost = h('small');
|
||||
const buy = h(
|
||||
'button',
|
||||
{ class: 'btn btn--buy', type: 'button', onclick: () => actions.buy(line.id, amount) },
|
||||
label,
|
||||
cost,
|
||||
);
|
||||
const li = h(
|
||||
'li',
|
||||
{ class: 'card', hidden: true },
|
||||
icon(`endless.${line.id}`),
|
||||
h(
|
||||
'div',
|
||||
{ class: 'card__body' },
|
||||
h('h3', { class: 'card__title' }, h('span', { text: lineName(line) }), level),
|
||||
h('p', { class: 'card__desc', text: t('endless.perLevel', { effect: effectText(line.effect, fmt) }) }),
|
||||
total,
|
||||
),
|
||||
buy,
|
||||
);
|
||||
return { li, level, total, label, cost, buy, line };
|
||||
}
|
||||
|
||||
function rebuild(newCtx, formatter) {
|
||||
ctx = newCtx;
|
||||
fmt = formatter;
|
||||
money = moneyFormatter(fmt);
|
||||
rows.clear();
|
||||
|
||||
const list = h('ul', { class: 'cards cards--grid' });
|
||||
for (const line of ctx.endless) {
|
||||
const row = rowFor(line);
|
||||
rows.set(line.id, row);
|
||||
list.append(row.li);
|
||||
}
|
||||
const amountGroup = h(
|
||||
'fieldset',
|
||||
{ class: 'segmented' },
|
||||
h('legend', { class: 'sr-only', text: t('endless.amount') }),
|
||||
...AMOUNTS.map((a) =>
|
||||
h(
|
||||
'label',
|
||||
{},
|
||||
h('input', {
|
||||
type: 'radio',
|
||||
name: 'endless-amount',
|
||||
value: String(a),
|
||||
checked: a === amount,
|
||||
onchange: () => {
|
||||
amount = a;
|
||||
},
|
||||
}),
|
||||
h('span', { text: a === 'max' ? t('ui.max') : `×${a}` }),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
root.replaceChildren(
|
||||
h(
|
||||
'div',
|
||||
{ class: 'panel__head' },
|
||||
h('h2', { class: 'panel__title', text: t('endless.title') }),
|
||||
amountGroup,
|
||||
),
|
||||
h('p', { class: 'hint', text: t('endless.intro') }),
|
||||
list,
|
||||
);
|
||||
}
|
||||
|
||||
function update(state) {
|
||||
let any = false;
|
||||
for (const { li, level, total, label, cost, buy, line } of rows.values()) {
|
||||
const open = lineAvailable(state, line);
|
||||
li.hidden = !open;
|
||||
if (!open) continue;
|
||||
any = true;
|
||||
|
||||
const lv = lineLevel(state, line.id);
|
||||
const maxed = lv >= line.maxLevel;
|
||||
let quote = endlessQuote(state, ctx, line.id, amount);
|
||||
if (quote.count <= 0) quote = endlessQuote(state, ctx, line.id, 1);
|
||||
|
||||
setText(level, t('endless.level', { level: fmt.number(lv) }));
|
||||
setText(
|
||||
total,
|
||||
lv > 0
|
||||
? t('endless.total', { effect: effectText({ ...line.effect, value: line.effect.value ** lv }, fmt) })
|
||||
: t('endless.none'),
|
||||
);
|
||||
setText(label, maxed ? t('endless.maxed') : t('endless.buy', { count: fmt.number(quote.count) }));
|
||||
setText(cost, maxed ? '' : money(quote.cost));
|
||||
buy.disabled = maxed || quote.count <= 0 || !(state.funds >= quote.cost);
|
||||
}
|
||||
root.hidden = !any;
|
||||
}
|
||||
|
||||
return { rebuild, update };
|
||||
}
|
||||
Reference in New Issue
Block a user