[CHECK THIS]: seems to be working again after AI armageddon

This commit is contained in:
2025-10-28 22:22:17 +13:00
parent b951bed230
commit f2cb47f904
+184 -90
View File
@@ -937,49 +937,11 @@ function TIC()
dmg = math.max(0, dmg - weaken_reduction)
if not damage_applied then
-- Sequence: flash screen, flash health, adjust hearts
-- Sequence: flash background then run the unified sequenced damage effect
queue_effect(flash_background, 40)
queue_effect(function()
sfx(0, "E-4", 12, 0) -- play damage sound
for flash = 8, 1, -1 do
-- Tint screen red on alternating frames
if flash % 4 < 2 then -- Flash on/off every 2 frames
poke(0x3FC0, 255) -- Red tint
else
poke(0x3FC0, original_palette[0])
end
flash = flash - 1
coroutine.yield()
-- When effect ends, ensure palette is restored
if flash == 0 then
poke(0x3FC0, original_palette[0])
end
end
end, 40)
queue_effect(function()
local flash_damage = current_damage.enemy + dmg
sfx(0, "E-4", 12, 0) -- play damage sound
for flash = 8, 1, -1 do
-- Flash health bar red on alternating frames
if flash % 2 == 0 then
current_damage.enemy = flash_damage
else
current_damage.enemy = 0
end
coroutine.yield()
end
current_damage.enemy = flash_damage
end, 60)
queue_effect(function()
local old_hp = enemy.hp
for step = 1, dmg do
enemy.hp = old_hp - step
sfx(0, "E-4", 12, 0) -- play damage sound
for wait = 1, 30 do
coroutine.yield()
end
end
end, 30)
sequenced_damage("enemy", dmg, { flash_cycles = 8, damage_display_frames = 20, step_wait = 10 })
end, 0)
end
msgtxt = "You win!"
elseif enemy.total > player.total then
@@ -993,17 +955,29 @@ function TIC()
dmg = math.max(0, dmg - weaken_reduction)
if not damage_applied then
-- Apply shield reduction
-- Apply shield reduction (calculate now, but do visual/HP changes via sequenced_damage)
local shield_reduction = player.shield or 0
dmg = math.max(0, dmg - shield_reduction)
player.hp = player.hp - dmg
current_damage.player = current_damage.player + dmg
-- Remove shield after taking damage
if shield_reduction > 0 and dmg < (2 * enemy.mult) then
player.shield = math.max(0, (player.shield or 0) - 1)
local final_dmg = math.max(0, dmg - shield_reduction)
-- Queue flash + sequenced stepped HP change for player
queue_effect(flash_background, 40)
queue_effect(function()
sequenced_damage("player", final_dmg, { flash_cycles = 8, damage_display_frames = 20, step_wait = 10 })
end, 0)
-- After damage is applied, remove one shield if it was used and set shake
if shield_reduction > 0 then
queue_effect(function()
player.shield = math.max(0, (player.shield or 0) - 1)
shake = 10
coroutine.yield()
end, 0)
else
queue_effect(function()
shake = 10
coroutine.yield()
end, 0)
end
shake = 10
end
msgtxt = enemy.name .. " wins!"
else
@@ -1114,57 +1088,125 @@ function TIC()
end
run_effects()
end
-- === EFFECT QUEUE SYSTEM ===
-- Holds coroutines for queued effects
-- === EFFECTS HELPERS ===
-- flash_background(frames)
-- frames: optional number of frames to flash (defaults to 40)
function flash_background(frames)
local f = frames or 40
-- play impact sound safely
pcall(function() sfx(0, "E-4", 12, 0) end)
for i = 1, f do
if (i % 4) < 2 then
poke(0x3FC0, 255) -- red tint
else
poke(0x3FC0, original_palette[0])
end
coroutine.yield()
end
-- ensure palette restored
poke(0x3FC0, original_palette[0])
end
-- sequenced_damage(target_key, amount, opts)
-- target_key: "enemy" or "player" (used to pick table and current_damage key)
-- amount: integer damage to apply
-- opts: table optional fields:
-- flash_cycles (default 8) - number of flash toggles for damage readout
-- damage_display_frames (default 20) - frames to hold the damage readout steady
-- step_wait (default 10) - frames to wait between each HP decrement step
function sequenced_damage(target_key, amount, opts)
opts = opts or {}
local flash_cycles = opts.flash_cycles or 8
local damage_display_frames = opts.damage_display_frames or 20
local step_wait = opts.step_wait or 10
local target = (target_key == "enemy") and enemy or player
local dmg_key = (target_key == "enemy") and "enemy" or "player"
-- play impact sound once
pcall(function() sfx(0, "E-4", 12, 0) end)
-- Flash the damage readout on/off for visibility
for i = 1, flash_cycles do
if (i % 2) == 0 then
current_damage[dmg_key] = amount
else
current_damage[dmg_key] = 0
end
coroutine.yield()
end
-- Hold the damage readout steady for a short period
current_damage[dmg_key] = amount
for i = 1, damage_display_frames do
coroutine.yield()
end
-- Apply HP reduction stepwise so the hearts animate
for step = 1, amount do
target.hp = math.max(0, target.hp - 1)
pcall(function() sfx(0, "E-4", 12, 0) end)
for w = 1, step_wait do
coroutine.yield()
end
end
-- Clear damage display
current_damage[dmg_key] = 0
coroutine.yield()
end
-- === EFFECT QUEUE (restore missing functions) ===
-- simple sequential effect queue used by queued visual/audio effects
effect_queue = {}
effect_queue_timers = {}
-- Add a coroutine to the queue, with optional duration argument (frames to wait after effect yields)
function queue_effect(fn, duration)
local co = coroutine.create(fn)
table.insert(effect_queue, co)
table.insert(effect_queue_timers, duration or 1)
-- queue_effect(fn, delay)
-- fn: function() coroutine.yield() ... end -- a coroutine body (no explicit coroutine.create needed here)
-- delay: optional number of frames to wait before starting this effect
function queue_effect(fn, delay)
local co = coroutine.create(fn)
table.insert(effect_queue, co)
table.insert(effect_queue_timers, delay or 0)
end
-- Run all effects in the queue (call this each frame)
-- run_effects() -- call once per frame (already called at end of TIC)
-- Processes only the first queued effect (sequential). If the effect has an initial delay,
-- we decrement the timer each frame and only resume the coroutine once the delay reaches 0.
function run_effects()
if #effect_queue == 0 then
return
end
-- Only run the first effect in the queue (sequential)
local co = effect_queue[1]
local timer = effect_queue_timers[1]
if timer > 0 then
effect_queue_timers[1] = timer - 1
return
end
local ok, _ = coroutine.resume(co)
if not ok or coroutine.status(co) == "dead" then
table.remove(effect_queue, 1)
table.remove(effect_queue_timers, 1)
else
-- Reset timer for this effect before next resume
effect_queue_timers[1] = effect_queue_timers[1] or 1
end
if #effect_queue == 0 then return end
-- only run the front effect to keep effects sequential
local timer = effect_queue_timers[1]
if timer > 0 then
effect_queue_timers[1] = timer - 1
return
end
local co = effect_queue[1]
local ok, err = coroutine.resume(co)
if not ok then
-- error: remove and discard the effect to avoid blocking the queue
-- (keep message-free to avoid spamming; developer can add logging if needed)
table.remove(effect_queue, 1)
table.remove(effect_queue_timers, 1)
return
end
-- if coroutine finished, remove it; otherwise leave it for the next resume
if coroutine.status(co) == "dead" then
table.remove(effect_queue, 1)
table.remove(effect_queue_timers, 1)
end
end
-- Returns true if any effects are running
function effects_running()
return #effect_queue > 0
return #effect_queue > 0
end
-- Example: wrap a card effect for the queue
function make_card_effect(effect, timing, player_won)
return function()
if timing == "post_result" then
effect.use(player, enemy, player_won)
else
effect.use(player, enemy)
end
coroutine.yield() -- allow for animation/timing if needed
end
end
-- <TILES>
-- 000:3200000032000000322200003332000033322200333332003333322200000000
-- 001:0ff00ff0f22ff33ff22f223ff222223f0f2222f000f22f00000ff00000000000
@@ -1250,4 +1292,56 @@ end
-- <PALETTE>
-- 000:1a1c2c5d275db13e53ef7d57ffcd75a7f07038b76425717929366f3b5dc941a6f673eff7f4f4f494b0c2566c86333c57
-- </PALETTE>
-- 020:022222ff0222222f022222220222222202222222002222220002222200000000
-- 021:ff222220f222f220222fff20222fff202222f220222222002222200000000000
-- 022:02222222022f222202fff22202fff222022f2222002222220002222200000000
-- 023:222222202222f220222fff20222fff202222f220222222002222200000000000
-- 024:022222ff022f222f02fff22202fff222022f2222002222220002222200000000
-- 025:ff222220f222f220222fff20222fff202222f220222222002222200000000000
-- 026:02222222022f222202fff2ff02fff2ff022f222f002222220002222200000000
-- 027:22222220f222f220ff2fff20ff2fff202222f220222222002222200000000000
-- 032:0000000000066666006666660666666606666666066666660666666f066666ff
-- 033:000000006666600066666600666666606666666066666660f6666660ff666660
-- 034:000000000006666600666666066f666606fff66606fff666066f666606666666
-- 035:0000000066666000666666006666666066666660666666606666666066666660
-- 036:000000000006666600666666066f666606fff66606fff666066f666f066666ff
-- 037:000000006666600066666600666666606666666066666660f6666660ff666660
-- 038:000000000006666600666666066f666606fff66606fff666066f666606666666
-- 039:0000000066666000666666006666f660666fff60666fff606666f66066666660
-- 040:000000000006666600666666066f666606fff66606fff666066f666f066666ff
-- 041:0000000066666000666666006666f660666fff60666fff60f666f660ff666660
-- 042:000000000006666600666666066f666f06fff6ff06fff6ff066f666606666666
-- 043:0000000066666000666666006666f660ff6fff60ff6fff60f666f66066666660
-- 048:066666ff0666666f066666660666666606666666006666660006666600000000
-- 049:ff666660f6666660666666606666666066666660666666006666600000000000
-- 050:0666666606666666066666660666666606666666006666660006666600000000
-- 051:6666666066666660666f666066fff66066fff660666f66006666600000000000
-- 052:066666ff0666666f066666660666666606666666006666660006666600000000
-- 053:ff666660f666f660666fff60666fff606666f660666666006666600000000000
-- 054:06666666066f666606fff66606fff666066f6666006666660006666600000000
-- 055:666666606666f660666fff60666fff606666f660666666006666600000000000
-- 056:066666ff066f666f06fff66606fff666066f6666006666660006666600000000
-- 057:ff666660f666f660666fff60666fff606666f660666666006666600000000000
-- 058:06666666066f666606fff6ff06fff6ff066f666f006666660006666600000000
-- 059:66666660f666f660ff6fff60ff6fff606666f660666666006666600000000000
-- </SPRITES>
-- <WAVES>
-- 000:00000000ffffffff00000000ffffffff
-- 001:0123456789abcdeffedcba9876543210
-- 002:0123456789abcdef0123456789abcdef
-- 003:00022345555555554433222225888888
-- </WAVES>
-- <SFX>
-- 000:03070306130523043303e302f301f301f300f30ff30ef30ef30df30cf30bf30bf300f300f300f301f303f302f302f302e302e302e301e301e301e300300000000000
-- </SFX>
-- <TRACKS>
-- 000:100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
-- </TRACKS>
-- <PALETTE>
-- 000:1a1c2c5d275db13e53ef7d57ffcd75a7f07038b76425717929366f3b5dc941a6f673eff7f4f4f494b0c2566c86333c57
-- </PALETTE>