Android build v1.1.2
This commit is contained in:
@@ -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>
|
||||
)
|
||||
})
|
||||
Reference in New Issue
Block a user