Android build v1.1.2

This commit is contained in:
Warren H
2026-06-29 22:35:49 -04:00
parent cbe42b6164
commit c6251167a5
52 changed files with 5554 additions and 3117 deletions
+131
View File
@@ -0,0 +1,131 @@
import { memo } from 'react'
import type { ControllerIconStyle } from '../input'
import type { Spell } from '../game'
import { ControllerBindingLabel } from './ControllerIcons'
export type SpellSlot = (Spell & {
cost: number
remaining: number
slotIndex: number
}) | null
export const ResourceBar = memo(function ResourceBar({
resource,
maxResource,
resourceName,
speedMultiplier,
unavailableText,
}: {
resource: number
maxResource: number
resourceName: string
speedMultiplier?: 1 | 2
unavailableText?: string
}) {
return (
<div className="mana-wrap party-mana-wrap">
<span>
{unavailableText ?? `${resourceName} ${Math.floor(resource)} / ${maxResource}`}
</span>
{speedMultiplier === 2 && <strong className="speed-badge">2x speed</strong>}
<div className="bar mana-bar"><span style={{ width: `${(resource / maxResource) * 100}%` }} /></div>
</div>
)
})
export const SpellButton = memo(function SpellButton({
spell,
binding,
iconStyle,
resourceName,
disabled,
onCast,
emptyKeyPrefix = 'empty',
}: {
spell: SpellSlot
binding?: string
iconStyle: ControllerIconStyle
resourceName: string
disabled?: boolean
onCast: (spell: Spell) => void
emptyKeyPrefix?: string
}) {
if (!spell) {
return (
<div className="spell empty-spell" key={emptyKeyPrefix}>
<kbd>{emptyKeyPrefix}</kbd><strong>Empty</strong>
</div>
)
}
return (
<button
className="spell"
disabled={disabled}
key={spell.id}
onClick={() => onCast(spell)}
title={spell.description}
type="button"
>
<kbd>
{binding
? (
<ControllerBindingLabel
binding={binding}
compact
iconStyle={iconStyle}
/>
)
: spell.slotIndex + 1}
</kbd>
<span className={`spell-icon spell-${spell.kind}`}>{spell.glyph}</span>
<strong>{spell.name}</strong>
<small>{spell.cost} {resourceName}</small>
{spell.remaining > 0 && <i>{spell.remaining.toFixed(1)}</i>}
</button>
)
})
export const SpellBar = memo(function SpellBar({
spells,
bindings,
iconStyle,
resource,
resourceName,
canCast,
onCast,
className = 'spell-bar six-slots vertical-spell-bar',
}: {
spells: SpellSlot[]
bindings: Record<string, string>
iconStyle: ControllerIconStyle
resource: number
resourceName: string
canCast: boolean
onCast: (spell: Spell) => void
className?: string
}) {
return (
<div className={className}>
{spells.map((spell, slotIndex) => {
if (!spell) {
return (
<div className="spell empty-spell" key={`empty-${slotIndex}`}>
<kbd>{slotIndex + 1}</kbd><strong>Empty</strong>
</div>
)
}
return (
<SpellButton
binding={bindings[`ability${slotIndex + 1}`]}
disabled={!canCast || resource < spell.cost || spell.remaining > 0}
iconStyle={iconStyle}
key={spell.id}
onCast={onCast}
resourceName={resourceName}
spell={spell}
/>
)
})}
</div>
)
})