Android build v1.0.25

This commit is contained in:
Warren H
2026-06-18 23:28:43 -04:00
parent 7fe62d8c82
commit 814eb1998d
4 changed files with 42 additions and 25 deletions
Binary file not shown.
+2 -2
View File
@@ -7,8 +7,8 @@ android {
applicationId "com.warren.iwanttoheal"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 41
versionName "1.0.24"
versionCode 42
versionName "1.0.25"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
+10
View File
@@ -131,6 +131,13 @@ function App() {
})
}, [screen])
useEffect(() => {
if (!authChecked || !account || !profile || screen === 'combat') return
window.requestAnimationFrame(() => {
focusFirstControl()
})
}, [account, authChecked, profile, screen])
useEffect(() => {
window.localStorage.setItem(LAST_DIFFICULTY_KEY, String(selectedDifficultyId))
}, [selectedDifficultyId])
@@ -148,6 +155,9 @@ function App() {
setScreen('menu')
setError('')
setServerMessage('')
window.requestAnimationFrame(() => {
focusFirstControl()
})
}
async function signOut() {
+30 -23
View File
@@ -374,6 +374,7 @@ export function CombatScreen({
const partyRef = useRef(partyTemplate)
const enemyHealthRef = useRef(encounters[initialEncounterIndex].maxHealth)
const elapsedTicksRef = useRef(0)
const selectedIdRef = useRef(partyTemplate[0].id)
const encounter = encounters[encounterIndex]
const currentPart = getCurrentPart(encounterIndex)
const firstEncounterIndex = (startPart - 1) * 3
@@ -415,6 +416,11 @@ export function CombatScreen({
})
}, [paused])
const setSelectedTargetId = useCallback((id: string) => {
selectedIdRef.current = id
setSelectedId(id)
}, [])
const addLog = useCallback((text: string, tone: CombatLogEntry['tone']) => {
const entry = { id: nextLogId.current++, text, tone }
setLog((current) => [entry, ...current].slice(0, 60))
@@ -467,7 +473,7 @@ export function CombatScreen({
if (roguelikeMode) setRoguelikeEncounters(nextRoguelikeEncounters)
setRoguelikeStage(1)
setParty(freshParty)
setSelectedId(partyTemplate[0].id)
setSelectedTargetId(partyTemplate[0].id)
setResource(maxResource)
setEncounterIndex(initialEncounterIndex)
setEnemyHealth(nextEncounters[initialEncounterIndex].maxHealth)
@@ -494,7 +500,7 @@ export function CombatScreen({
runStartedAtRef.current = Date.now()
partStartTimesRef.current = { [startPart]: runStartedAtRef.current }
setLog([{ id: nextLogId.current++, text: 'A new run begins.', tone: 'system' }])
}, [difficulty, initialEncounterIndex, maxResource, partyTemplate, roguelikeMode, roguelikePool, startPart, staticEncounters])
}, [difficulty, initialEncounterIndex, maxResource, partyTemplate, roguelikeMode, roguelikePool, setSelectedTargetId, startPart, staticEncounters])
const castSpell = useCallback(
(spell: Spell) => {
@@ -502,26 +508,27 @@ export function CombatScreen({
if (status !== 'playing' || cooldowns[spell.id] > 0 || resource < effectiveCost) return
const healer = partyRef.current.find((member) => member.id === 'mira')
if (!healer || healer.health <= 0) return
const selected = partyRef.current.find((member) => member.id === selectedId)
const targetId = selectedIdRef.current
const selected = partyRef.current.find((member) => member.id === targetId)
if (!selected || selected.health <= 0) return
const extraTarget = (blockedIds: string[]) => partyRef.current
.filter((member) => member.health > 0 && !blockedIds.includes(member.id))
.sort((left, right) => (left.health / left.maxHealth) - (right.health / right.maxHealth))[0]
const directTargets = new Set([selectedId])
const directTargets = new Set([targetId])
const hotTargets = new Set<string>()
const shieldTargets = new Set<string>()
if (spell.kind === 'hot') hotTargets.add(selectedId)
if (spell.kind === 'shield') shieldTargets.add(selectedId)
if (spell.kind === 'hot') hotTargets.add(targetId)
if (spell.kind === 'shield') shieldTargets.add(targetId)
if (spell.name === 'Mend' && activeSetEffects.has('mend_extra_target')) {
const extra = extraTarget([selectedId])
const extra = extraTarget([targetId])
if (extra) directTargets.add(extra.id)
}
if (spell.name === 'Renew' && activeSetEffects.has('renew_extra_target')) {
const extra = extraTarget([selectedId])
const extra = extraTarget([targetId])
if (extra) hotTargets.add(extra.id)
}
if (spell.name === 'Mend' && activeSetEffects.has('mend_applies_renew')) {
hotTargets.add(selectedId)
hotTargets.add(targetId)
}
const extraTargets = upgradeStackCount(roguelikeUpgrades, `slot${spell.key as SlotKey}-extra-target` as RoguelikeUpgradeId)
for (let index = 0; index < extraTargets; index += 1) {
@@ -599,7 +606,7 @@ export function CombatScreen({
setParty(nextParty)
addLog(`${spell.name} cast on ${spell.kind === 'group' ? 'the party' : selected.name}${effectiveCost === 0 ? ' for free' : ''}.`, 'heal')
},
[activeSetEffects, addFloatingHeal, addLog, cooldowns, freeCastReady, resource, roguelikeUpgrades, selectedId, status],
[activeSetEffects, addFloatingHeal, addLog, cooldowns, freeCastReady, resource, roguelikeUpgrades, status],
)
const finishRun = useCallback(
@@ -664,18 +671,18 @@ export function CombatScreen({
const selectRelativeTarget = useCallback((direction: -1 | 1) => {
const living = partyRef.current.filter((member) => member.health > 0)
if (living.length === 0) return
const currentIndex = living.findIndex((member) => member.id === selectedId)
const currentIndex = living.findIndex((member) => member.id === selectedIdRef.current)
const nextIndex = currentIndex < 0
? 0
: (currentIndex + direction + living.length) % living.length
setSelectedId(living[nextIndex].id)
}, [selectedId])
setSelectedTargetId(living[nextIndex].id)
}, [setSelectedTargetId])
const selectDirectionalTarget = useCallback((action: InputAction) => {
const columns = dungeon.partySize >= 10 ? 6 : 3
const currentIndex = partyRef.current.findIndex((member) => member.id === selectedId)
const currentIndex = partyRef.current.findIndex((member) => member.id === selectedIdRef.current)
if (currentIndex < 0) {
setSelectedId(partyRef.current[0].id)
setSelectedTargetId(partyRef.current[0].id)
return
}
const currentRow = Math.floor(currentIndex / columns)
@@ -709,14 +716,14 @@ export function CombatScreen({
: Math.abs(b.column - currentColumn)
return aPrimary - bPrimary || aSecondary - bSecondary
})
if (candidates[0]) setSelectedId(candidates[0].member.id)
}, [dungeon.partySize, selectedId])
if (candidates[0]) setSelectedTargetId(candidates[0].member.id)
}, [dungeon.partySize, setSelectedTargetId])
const selectDirectTarget = useCallback((slot: number) => {
const index = slot + (dungeon.partySize > 6 ? targetGroup * 6 : 0)
const member = partyRef.current[index]
if (member) setSelectedId(member.id)
}, [dungeon.partySize, targetGroup])
if (member) setSelectedTargetId(member.id)
}, [dungeon.partySize, setSelectedTargetId, targetGroup])
const chooseRoguelikeUpgrade = useCallback((upgrade: RoguelikeUpgrade) => {
if (!roguelikeMode) return
@@ -778,9 +785,9 @@ export function CombatScreen({
setTargetGroup((current) => {
const groupCount = Math.max(1, Math.ceil(partyRef.current.length / 6))
const next = ((current + 1) % groupCount) as 0 | 1 | 2
const selectedIndex = partyRef.current.findIndex((member) => member.id === selectedId)
const selectedIndex = partyRef.current.findIndex((member) => member.id === selectedIdRef.current)
const nextMember = partyRef.current[(selectedIndex < 0 ? 0 : selectedIndex % 6) + next * 6]
if (nextMember) setSelectedId(nextMember.id)
if (nextMember) setSelectedTargetId(nextMember.id)
return next
})
return
@@ -1134,7 +1141,7 @@ export function CombatScreen({
<button
className={`party-member ${selectedId === member.id ? 'selected' : ''} ${member.health <= 0 ? 'dead' : ''}`}
key={member.id}
onClick={() => setSelectedId(member.id)}
onClick={() => setSelectedTargetId(member.id)}
aria-pressed={selectedId === member.id}
type="button"
>
@@ -1219,7 +1226,7 @@ export function CombatScreen({
{dualScreenEnabled && (
<DualScreenTopCombat
state={dualScreenState}
onSelectTarget={setSelectedId}
onSelectTarget={setSelectedTargetId}
/>
)}