From 3966f162d45372bc3df78cc7d7043f3c2b59747b Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Tue, 7 Oct 2025 22:15:21 +1300 Subject: [PATCH 01/15] feat: hit effect, energy system --- lucksmith.lua | 158 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 131 insertions(+), 27 deletions(-) diff --git a/lucksmith.lua b/lucksmith.lua index f32cd0f..444722e 100644 --- a/lucksmith.lua +++ b/lucksmith.lua @@ -7,15 +7,15 @@ player = { hp = 10, roll_mod = 0, mult = 1, - counter = false + counter = false, + energy = 0 } enemies = {{ hp = 8, roll_mod = 0, mult = 1, counter = false -}, -{ +}, { hp = 10, roll_mod = 0, mult = 1, @@ -29,13 +29,13 @@ enemies = {{ level = 1 function get_enemy(level) return { - hp = enemies[level].hp, - roll_mod = enemies[level].roll_mod, - mult = enemies[level].mult, - counter = enemies[level].counter -} + hp = enemies[level].hp, + roll_mod = enemies[level].roll_mod, + mult = enemies[level].mult, + counter = enemies[level].counter + } end -enemy = get_enemy(level) +enemy = get_enemy(level) msg = "" -- State @@ -52,11 +52,18 @@ player.display_roll = 0 enemy.display_roll = 0 shake = 0 d = 2 -- shake intensity +flash = 0 + +original_palette = {} +for i = 0, 15 do + original_palette[i] = peek(0x3FC0 + i) +end -- basic card pool cards = {{ name = "Str", desc = "+2 to roll", timing = "pre_roll", + energy = -1, -- costs 1 energy use = function(p, e) p.roll_mod = p.roll_mod + 2 end @@ -64,6 +71,7 @@ cards = {{ name = "Hex", desc = "-2 enemy roll", timing = "pre_roll", + energy = -2, -- costs 2 energy use = function(p, e) e.roll_mod = e.roll_mod - 2 end @@ -71,6 +79,7 @@ cards = {{ name = "2x", desc = "win/lose double dmg", timing = "pre_roll", + energy = -2, -- costs 2 energy use = function(p, e) p.mult = 2 end @@ -78,6 +87,7 @@ cards = {{ name = "0.5x", desc = "win/lose half dmg", timing = "pre_roll", + energy = 1, -- gives 1 energy use = function(p, e) p.mult = 0.5 end @@ -85,6 +95,7 @@ cards = {{ name = "Heal", desc = "+2 hp", timing = "immediate", + energy = -1, -- costs 1 energy use = function(p, e) p.hp = math.min(10, p.hp + 2) end @@ -92,40 +103,45 @@ cards = {{ name = "Counter", desc = "hit enemy for 1 if you lose", timing = "post_result", + energy = -1, -- costs 1 energy use = function(p, e, player_won) - -- player_won is from player's perspective when called on player cards - if player_won == false then -- player lost - e.hp = e.hp - 1 + -- player_won is from player's perspective, so enemy perspective is flipped + if player_won == true then -- enemy lost (player won) + p.hp = p.hp - 1 end end }, { name = "Weaken", desc = "-1 enemy dmg", timing = "pre_roll", + energy = -1, -- costs 1 energy use = function(p, e) - e.mult = math.max(0.5, e.mult - 0.5) + p.mult = math.max(0.5, p.mult - 0.5) end }, { name = "Rage", desc = "+1 your dmg", timing = "pre_roll", + energy = -1, -- costs 1 energy use = function(p, e) - p.mult = p.mult + 0.5 + e.mult = e.mult + 0.5 end }, { name = "Tier", desc = "if tie, you win", timing = "post_result", + energy = -2, -- costs 2 energy use = function(p, e, player_won) if player_won == nil then -- tie occurred - -- Player wins the tie, so enemy takes damage - e.hp = e.hp - (2 * p.mult) + -- Enemy wins the tie, so player takes damage + p.hp = p.hp - (2 * e.mult) end end }, { name = "Shield", desc = "take 1 less dmg this turn", timing = "pre_roll", + energy = -1, -- costs 1 energy use = function(p, e) p.shield = (p.shield or 0) + 1 end @@ -133,13 +149,15 @@ cards = {{ name = "Poison", desc = "enemy loses 1 hp at turn end", timing = "post_result", + energy = -1, -- costs 1 energy use = function(p, e, player_won) e.hp = e.hp - 1 end }, { name = "Spike", desc = "deal 1 dmg to whoever wins", - timing = "post_result", + timing = "post_result", + energy = 0, -- neutral use = function(p, e, player_won) if player_won == true then p.hp = p.hp - 1 -- hurt yourself if you win @@ -152,6 +170,7 @@ cards = {{ name = "Lucky", desc = "reroll if you roll 1-3", timing = "post_roll", -- New timing needed + energy = -2, -- costs 2 energy use = function(p, e) if p.roll <= 3 then p.roll = math.random(1, 6) @@ -162,6 +181,7 @@ cards = {{ name = "Curse", desc = "enemy rerolls if they roll 4-6", timing = "post_roll", + energy = -2, -- costs 2 energy use = function(p, e) if e.roll >= 4 then e.roll = math.random(1, 6) @@ -172,6 +192,7 @@ cards = {{ name = "Swap", desc = "switch your roll with enemy's", timing = "post_roll", + energy = -3, -- costs 3 energy use = function(p, e) local temp = p.roll p.roll = e.roll @@ -183,6 +204,7 @@ cards = {{ name = "Mirror", desc = "copy enemy's roll modifier", timing = "pre_roll", + energy = -1, -- costs 1 energy use = function(p, e) p.roll_mod = p.roll_mod + e.roll_mod end @@ -190,6 +212,7 @@ cards = {{ name = "Drain", desc = "heal 1 if you win", timing = "post_result", + energy = -1, -- costs 1 energy use = function(p, e, player_won) if player_won == true then p.hp = math.min(10, p.hp + 1) @@ -199,6 +222,7 @@ cards = {{ name = "Gamble", desc = "50% chance: +3 roll or -1 roll", timing = "pre_roll", + energy = 0, -- neutral use = function(p, e) if math.random() < 0.5 then p.roll_mod = p.roll_mod + 3 @@ -210,6 +234,7 @@ cards = {{ name = "Fury", desc = "+1 dmg per hp you're missing", timing = "pre_roll", + energy = -1, -- costs 1 energy use = function(p, e) local missing_hp = 10 - p.hp p.mult = p.mult + (missing_hp * 0.1) @@ -218,6 +243,7 @@ cards = {{ name = "Turtle", desc = "set your roll to 3", timing = "post_roll", + energy = 1, -- gives 1 energy use = function(p, e) p.roll = 3 p.total = p.roll + p.roll_mod @@ -226,16 +252,34 @@ cards = {{ name = "Berserk", desc = "2x dmg but take 1 dmg", timing = "immediate", + energy = -2, -- costs 2 energy use = function(p, e) p.mult = p.mult * 2 p.hp = p.hp - 1 end +}, { + name = "Focus", + desc = "+2 energy", + timing = "immediate", + energy = 2, -- gives 2 energy + use = function(p, e) + -- Energy gain handled automatically + end +}, { + name = "Rest", + desc = "+1 energy, +1 hp", + timing = "immediate", + energy = 1, -- gives 1 energy + use = function(p, e) + p.hp = math.min(10, p.hp + 1) + end }} enemy_cards = {{ name = "Str", desc = "+2 to roll", timing = "pre_roll", + energy = -1, use = function(p, e) e.roll_mod = e.roll_mod + 2 end @@ -243,6 +287,7 @@ enemy_cards = {{ name = "Hex", desc = "-2 enemy roll", timing = "pre_roll", + energy = -2, use = function(p, e) p.roll_mod = p.roll_mod - 2 end @@ -250,6 +295,7 @@ enemy_cards = {{ name = "2x", desc = "win/lose double dmg", timing = "pre_roll", + energy = -2, use = function(p, e) e.mult = 2 end @@ -257,6 +303,7 @@ enemy_cards = {{ name = "0.5x", desc = "win/lose half dmg", timing = "pre_roll", + energy = 1, use = function(p, e) e.mult = 0.5 end @@ -264,6 +311,7 @@ enemy_cards = {{ name = "Heal", desc = "+2 hp", timing = "immediate", + energy = -1, use = function(p, e) e.hp = math.min(10, e.hp + 2) end @@ -271,6 +319,7 @@ enemy_cards = {{ name = "Counter", desc = "hit enemy for 1 if you lose", timing = "post_result", + energy = -1, use = function(p, e, player_won) -- player_won is from player's perspective, so enemy perspective is flipped if player_won == true then -- enemy lost (player won) @@ -281,6 +330,7 @@ enemy_cards = {{ name = "Weaken", desc = "-1 enemy dmg", timing = "pre_roll", + energy = -1, use = function(p, e) p.mult = math.max(0.5, p.mult - 0.5) end @@ -288,6 +338,7 @@ enemy_cards = {{ name = "Rage", desc = "+1 your dmg", timing = "pre_roll", + energy = -1, use = function(p, e) e.mult = e.mult + 0.5 end @@ -295,6 +346,7 @@ enemy_cards = {{ name = "Tier", desc = "if tie, you win", timing = "post_result", + energy = -2, use = function(p, e, player_won) if player_won == nil then -- tie occurred -- Enemy wins the tie, so player takes damage @@ -307,7 +359,22 @@ enemy_cards = {{ hand = {} function draw_hand() hand = {} - for i = 1, 3 do + + -- First, get all cards that are playable with 0 energy (cost 0 or give energy) + local free_cards = {} + for _, card in ipairs(cards) do + if card.energy >= 0 then + table.insert(free_cards, card) + end + end + + -- Ensure at least one free/energy-giving card is in hand + if #free_cards > 0 then + table.insert(hand, free_cards[math.random(#free_cards)]) + end + + -- Fill the rest with random cards + while #hand < 3 do table.insert(hand, cards[math.random(#cards)]) end end @@ -338,6 +405,9 @@ function start_turn(card) current_card = card enemy_card = enemy_cards[math.random(#enemy_cards)] + -- Apply energy cost/gain for player card + player.energy = math.max(0, math.min(5, player.energy + card.energy)) + -- Store effects for proper timing pending_effects.player = {card} pending_effects.enemy = {enemy_card} @@ -365,7 +435,7 @@ end picked = 1 -- === INPUT === function TIC() - cls(1) + cls(0) if shake > 0 then poke(0x3FF9, math.random(-d, d)) @@ -376,11 +446,28 @@ function TIC() end end + -- Handle flash effect + if flash > 0 then + -- 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 + + -- When effect ends, ensure palette is restored + if flash == 0 then + poke(0x3FC0, original_palette[0]) + end + end + -- camera(dx, dy) -- Draw HUD - print("Level: " .. level, 100, 4, 12) - print("PLAYER HP: " .. player.hp, 4, 4, 12) - print("ENEMY HP: " .. enemy.hp, 4, 14, 8) + print("Level: " .. level, 100, 2, 12) + print("Energy: " .. player.energy .. "/5", 100, 12, 11) + print("PLAYER HP: " .. player.hp, 4, 2, 12) + print("ENEMY HP: " .. enemy.hp, 4, 12, 8) if phase == "choose" then -- Card Picker @@ -392,16 +479,31 @@ function TIC() picked = picked + 1 end picked = math.min(3, math.max(1, picked)) + -- Show cards for i, card in ipairs(hand) do local x = 10 + (i - 1) * 64 - rectb(x, 80, 62, 24, i == picked and 1 or 12) - print(card.name, x + 3, 90, i == picked and 11 or 10, false,1,true) + local can_afford = (card.energy >= 0) or (player.energy >= -card.energy) + local is_selected = i == picked + local border_color = can_afford and (is_selected and 1 or 12) or 6 + rectb(x, 80, 62, 24, border_color) + local text_color = can_afford and (is_selected and 11 or 10) or 6 + print(card.name, x + 3, 90, text_color, false, 1, true) + + -- Show energy cost/gain + local energy_text = card.energy >= 0 and ("+" .. card.energy) or tostring(card.energy) + print(energy_text, x + 50, 82, card.energy >= 0 and 11 or 8, false, 1, true) + end + + local selected_card = hand[picked] + local can_afford = (selected_card.energy >= 0) or (player.energy >= -selected_card.energy) + print(selected_card.desc, 4, 120, can_afford and 15 or 6) + if not can_afford then + print("Not enough energy!", 4, 130, 6) end - print(hand[picked].desc, 4, 120, 15) print(msg, 4, 40, 15) - if btnp(4) then + if btnp(4) and can_afford then start_turn(hand[picked]) end @@ -465,6 +567,7 @@ function TIC() local dmg = 2 * player.mult if not damage_applied then enemy.hp = enemy.hp - dmg + flash = 8 end msgtxt = "You win! Enemy -" .. dmg elseif enemy.total > player.total then @@ -517,7 +620,8 @@ function TIC() hp = 10, roll_mod = 0, mult = 1, - counter = false + counter = false, + energy = 0 } enemy = get_enemy(level) -- 2.20.1 From 529bf936d990703076951854fba1b90f89f5f465 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Tue, 7 Oct 2025 23:15:51 +1300 Subject: [PATCH 02/15] feat: deck, discard, level up select a card --- lucksmith.lua | 406 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 329 insertions(+), 77 deletions(-) diff --git a/lucksmith.lua b/lucksmith.lua index 444722e..238f836 100644 --- a/lucksmith.lua +++ b/lucksmith.lua @@ -58,9 +58,15 @@ original_palette = {} for i = 0, 15 do original_palette[i] = peek(0x3FC0 + i) end + +-- Deck system +draw_pile = {} +discard_pile = {} +unlocked_cards = {} -- tracks which cards are in your deck + -- basic card pool cards = {{ - name = "Str", + name = "Strength", desc = "+2 to roll", timing = "pre_roll", energy = -1, -- costs 1 energy @@ -71,25 +77,27 @@ cards = {{ name = "Hex", desc = "-2 enemy roll", timing = "pre_roll", - energy = -2, -- costs 2 energy + energy = -1, -- costs 1 energy use = function(p, e) e.roll_mod = e.roll_mod - 2 end }, { - name = "2x", + name = "Reckless", desc = "win/lose double dmg", timing = "pre_roll", - energy = -2, -- costs 2 energy + energy = -1, -- reduced from -2 use = function(p, e) - p.mult = 2 + p.mult = p.mult * 2 + e.mult = e.mult * 2 end }, { - name = "0.5x", + name = "Cautious", desc = "win/lose half dmg", timing = "pre_roll", - energy = 1, -- gives 1 energy + energy = 0, -- reduced from +1 since we get +1 per turn use = function(p, e) - p.mult = 0.5 + p.mult = p.mult * 0.5 + e.mult = e.mult * 0.5 end }, { name = "Heal", @@ -103,45 +111,43 @@ cards = {{ name = "Counter", desc = "hit enemy for 1 if you lose", timing = "post_result", - energy = -1, -- costs 1 energy + energy = 0, -- reduced from -1 use = function(p, e, player_won) - -- player_won is from player's perspective, so enemy perspective is flipped - if player_won == true then -- enemy lost (player won) - p.hp = p.hp - 1 + if player_won == false then -- fixed: should trigger when player loses + e.hp = e.hp - 1 end end }, { name = "Weaken", desc = "-1 enemy dmg", timing = "pre_roll", - energy = -1, -- costs 1 energy + energy = 0, -- reduced from -1 use = function(p, e) - p.mult = math.max(0.5, p.mult - 0.5) + e.mult = math.max(0.5, e.mult - 0.5) -- fixed: should affect enemy mult end }, { name = "Rage", desc = "+1 your dmg", - timing = "pre_roll", - energy = -1, -- costs 1 energy + timing = "pre_roll", -- changed from post_result for clarity + energy = -1, -- reduced from -1 use = function(p, e) - e.mult = e.mult + 0.5 + p.mult = p.mult + 0.5 end }, { name = "Tier", desc = "if tie, you win", timing = "post_result", - energy = -2, -- costs 2 energy + energy = -1, -- reduced from -2 use = function(p, e, player_won) if player_won == nil then -- tie occurred - -- Enemy wins the tie, so player takes damage - p.hp = p.hp - (2 * e.mult) + e.hp = e.hp - (2 * p.mult) end end }, { name = "Shield", - desc = "take 1 less dmg this turn", - timing = "pre_roll", - energy = -1, -- costs 1 energy + desc = "take 1 less dmg until damaged", + timing = "immediate", + energy = -1, -- increased from 0 use = function(p, e) p.shield = (p.shield or 0) + 1 end @@ -149,7 +155,7 @@ cards = {{ name = "Poison", desc = "enemy loses 1 hp at turn end", timing = "post_result", - energy = -1, -- costs 1 energy + energy = 0, -- reduced from -1 use = function(p, e, player_won) e.hp = e.hp - 1 end @@ -157,7 +163,7 @@ cards = {{ name = "Spike", desc = "deal 1 dmg to whoever wins", timing = "post_result", - energy = 0, -- neutral + energy = 1, -- now gives energy since it's risky use = function(p, e, player_won) if player_won == true then p.hp = p.hp - 1 -- hurt yourself if you win @@ -169,8 +175,8 @@ cards = {{ }, { name = "Lucky", desc = "reroll if you roll 1-3", - timing = "post_roll", -- New timing needed - energy = -2, -- costs 2 energy + timing = "post_roll", + energy = -1, -- reduced from -2 use = function(p, e) if p.roll <= 3 then p.roll = math.random(1, 6) @@ -181,7 +187,7 @@ cards = {{ name = "Curse", desc = "enemy rerolls if they roll 4-6", timing = "post_roll", - energy = -2, -- costs 2 energy + energy = -1, -- reduced from -2 use = function(p, e) if e.roll >= 4 then e.roll = math.random(1, 6) @@ -189,11 +195,14 @@ cards = {{ end end }, { - name = "Swap", - desc = "switch your roll with enemy's", + name = "Intuition", + desc = "Pick the higher roll", timing = "post_roll", - energy = -3, -- costs 3 energy + energy = -3, -- reduced from -3 use = function(p, e) + if p.roll >= e.roll then + return -- no change needed + end local temp = p.roll p.roll = e.roll e.roll = temp @@ -204,15 +213,23 @@ cards = {{ name = "Mirror", desc = "copy enemy's roll modifier", timing = "pre_roll", - energy = -1, -- costs 1 energy + energy = -1, -- reduced from -1 use = function(p, e) p.roll_mod = p.roll_mod + e.roll_mod end +}, { + name = "Double Vision", + desc = "copy enemy's multiplier", + timing = "post_roll", + energy = -1, -- reduced from -2 + use = function(p, e) + p.mult = e.mult + end }, { name = "Drain", desc = "heal 1 if you win", timing = "post_result", - energy = -1, -- costs 1 energy + energy = 0, -- reduced from -1 use = function(p, e, player_won) if player_won == true then p.hp = math.min(10, p.hp + 1) @@ -222,7 +239,7 @@ cards = {{ name = "Gamble", desc = "50% chance: +3 roll or -1 roll", timing = "pre_roll", - energy = 0, -- neutral + energy = 1, -- now gives energy since it's risky use = function(p, e) if math.random() < 0.5 then p.roll_mod = p.roll_mod + 3 @@ -232,18 +249,18 @@ cards = {{ end }, { name = "Fury", - desc = "+1 dmg per hp you're missing", + desc = "+0.5 dmg per hp missing", timing = "pre_roll", - energy = -1, -- costs 1 energy + energy = -1, -- reduced from -1 use = function(p, e) local missing_hp = 10 - p.hp - p.mult = p.mult + (missing_hp * 0.1) + p.mult = p.mult + (missing_hp * 0.5) -- increased effect end }, { name = "Turtle", desc = "set your roll to 3", timing = "post_roll", - energy = 1, -- gives 1 energy + energy = 2, -- increased from 1 use = function(p, e) p.roll = 3 p.total = p.roll + p.roll_mod @@ -252,7 +269,7 @@ cards = {{ name = "Berserk", desc = "2x dmg but take 1 dmg", timing = "immediate", - energy = -2, -- costs 2 energy + energy = -1, -- reduced from -2 use = function(p, e) p.mult = p.mult * 2 p.hp = p.hp - 1 @@ -261,7 +278,7 @@ cards = {{ name = "Focus", desc = "+2 energy", timing = "immediate", - energy = 2, -- gives 2 energy + energy = 2, -- gives 2 energy (net +3 with the +1 per turn) use = function(p, e) -- Energy gain handled automatically end @@ -269,7 +286,7 @@ cards = {{ name = "Rest", desc = "+1 energy, +1 hp", timing = "immediate", - energy = 1, -- gives 1 energy + energy = 1, -- gives 1 energy (net +2 with the +1 per turn) use = function(p, e) p.hp = math.min(10, p.hp + 1) end @@ -297,7 +314,8 @@ enemy_cards = {{ timing = "pre_roll", energy = -2, use = function(p, e) - e.mult = 2 + e.mult = e.mult * 2 + p.mult = p.mult * 2 end }, { name = "0.5x", @@ -305,7 +323,8 @@ enemy_cards = {{ timing = "pre_roll", energy = 1, use = function(p, e) - e.mult = 0.5 + e.mult = e.mult * 0.5 + p.mult = p.mult * 0.5 end }, { name = "Heal", @@ -337,10 +356,12 @@ enemy_cards = {{ }, { name = "Rage", desc = "+1 your dmg", - timing = "pre_roll", + timing = "post_result", energy = -1, - use = function(p, e) - e.mult = e.mult + 0.5 + use = function(p, e, player_won) + if player_won ~= true then + p.hp = p.hp - 1 + end end }, { name = "Tier", @@ -357,27 +378,173 @@ enemy_cards = {{ -- player's starting hand (random subset) hand = {} +card_choice_options = {} -- for level up card selection + +function shuffle_deck(deck) + for i = #deck, 2, -1 do + local j = math.random(i) + deck[i], deck[j] = deck[j], deck[i] + end +end + +function initialize_deck() + draw_pile = {} + discard_pile = {} + + -- Start with first 8 cards for level 1, or use unlocked_cards for higher levels + local cards_to_add = {} + if level == 1 then + unlocked_cards = {} + for i = 1, 8 do + unlocked_cards[i] = true + cards_to_add = {1, 2, 3, 4, 5, 6, 7, 8} + end + end + + -- Add 2 copies of each unlocked card to deck + for i, card in ipairs(cards) do + if unlocked_cards[i] then + table.insert(draw_pile, card) + table.insert(draw_pile, card) + end + end + + shuffle_deck(draw_pile) +end + +function generate_card_choices() + card_choice_options = {} + local available_cards = {} + + -- Find cards not yet unlocked + for i, card in ipairs(cards) do + if not unlocked_cards[i] then + table.insert(available_cards, i) + end + end + + -- If we have available cards, pick 3 random ones + if #available_cards > 0 then + shuffle_deck(available_cards) + for i = 1, math.min(3, #available_cards) do + table.insert(card_choice_options, available_cards[i]) + end + end +end + +function add_card_to_deck(card_index) + unlocked_cards[card_index] = true + local card = cards[card_index] + -- Add 2 copies to discard pile (will be shuffled in next game) + table.insert(discard_pile, card) + table.insert(discard_pile, card) +end + +-- player's starting hand (random subset) +hand = {} + +function shuffle_deck(deck) + for i = #deck, 2, -1 do + local j = math.random(i) + deck[i], deck[j] = deck[j], deck[i] + end +end + +function initialize_deck() + draw_pile = {} + discard_pile = {} + + -- Add 2 copies of each card to deck + for _, card in ipairs(cards) do + table.insert(draw_pile, card) + table.insert(draw_pile, card) + end + + shuffle_deck(draw_pile) +end + +function reshuffle_if_needed() + if #draw_pile < 3 and #discard_pile > 0 then + -- Move discard pile to draw pile and shuffle + for _, card in ipairs(discard_pile) do + table.insert(draw_pile, card) + end + discard_pile = {} + shuffle_deck(draw_pile) + end +end + function draw_hand() hand = {} + reshuffle_if_needed() - -- First, get all cards that are playable with 0 energy (cost 0 or give energy) - local free_cards = {} - for _, card in ipairs(cards) do - if card.energy >= 0 then - table.insert(free_cards, card) + -- If player has no energy, ensure at least one energy-positive card + if player.energy == 0 then + local energy_positive_found = false + local temp_hand = {} + + -- Try to draw 3 cards, checking for energy-positive ones + for i = 1, 3 do + if #draw_pile > 0 then + local card = table.remove(draw_pile, 1) + table.insert(temp_hand, card) + if card.energy >= 0 then + energy_positive_found = true + end + end + end + + -- If no energy-positive card found, replace one with an energy-positive card + if not energy_positive_found and #temp_hand > 0 then + -- Find an energy-positive card in remaining deck or discard + local energy_card = nil + + -- Look in draw pile first + for i, card in ipairs(draw_pile) do + if card.energy >= 0 then + energy_card = table.remove(draw_pile, i) + break + end + end + + -- If not found, look in discard pile + if not energy_card then + for i, card in ipairs(discard_pile) do + if card.energy >= 0 then + energy_card = table.remove(discard_pile, i) + break + end + end + end + + -- Replace first card with energy-positive card + if energy_card then + table.insert(draw_pile, temp_hand[1]) -- Put replaced card back + temp_hand[1] = energy_card + end + end + + hand = temp_hand + else + -- Normal draw when player has energy + for i = 1, 3 do + if #draw_pile > 0 then + table.insert(hand, table.remove(draw_pile, 1)) + end end end - -- Ensure at least one free/energy-giving card is in hand - if #free_cards > 0 then - table.insert(hand, free_cards[math.random(#free_cards)]) - end - - -- Fill the rest with random cards - while #hand < 3 do - table.insert(hand, cards[math.random(#cards)]) + -- Fill remaining slots if deck was too small + while #hand < 3 and (#draw_pile > 0 or #discard_pile > 0) do + reshuffle_if_needed() + if #draw_pile > 0 then + table.insert(hand, table.remove(draw_pile, 1)) + end end end + +-- Initialize deck at start +initialize_deck() draw_hand() -- === CORE TURN LOGIC === @@ -405,8 +572,14 @@ function start_turn(card) current_card = card enemy_card = enemy_cards[math.random(#enemy_cards)] - -- Apply energy cost/gain for player card - player.energy = math.max(0, math.min(5, player.energy + card.energy)) + -- Add 1 energy per turn, then apply card cost/gain + player.energy = math.max(0, math.min(5, player.energy + 1 + card.energy)) + + -- Discard all cards in hand + for _, hand_card in ipairs(hand) do + table.insert(discard_pile, hand_card) + end + hand = {} -- Store effects for proper timing pending_effects.player = {card} @@ -433,6 +606,7 @@ function start_turn(card) end picked = 1 +card_pick_selection = 1 -- === INPUT === function TIC() cls(0) @@ -462,10 +636,11 @@ function TIC() end end - -- camera(dx, dy) -- Draw HUD - print("Level: " .. level, 100, 2, 12) - print("Energy: " .. player.energy .. "/5", 100, 12, 11) + print("Level: " .. level, 140, 2, 12) + print("Energy: " .. player.energy .. "/5", 140, 12, 11) + print("Draw: " .. #draw_pile, 140, 22, 10) + print("Discard: " .. #discard_pile, 140, 32, 6) print("PLAYER HP: " .. player.hp, 4, 2, 12) print("ENEMY HP: " .. enemy.hp, 4, 12, 8) @@ -507,6 +682,58 @@ function TIC() start_turn(hand[picked]) end + elseif phase == "card_reward" then + -- Card selection after level victory + print("Choose a card to add to your deck:", 4, 30, 12) + + if btnp(2) then + card_pick_selection = card_pick_selection - 1 + end + if btnp(3) then + card_pick_selection = card_pick_selection + 1 + end + card_pick_selection = math.min(#card_choice_options, math.max(1, card_pick_selection)) + + -- Show card options + for i, card_index in ipairs(card_choice_options) do + local card = cards[card_index] + local x = 10 + (i - 1) * 64 + local is_selected = i == card_pick_selection + local border_color = is_selected and 11 or 12 + rectb(x, 60, 62, 40, border_color) + local text_color = is_selected and 11 or 10 + print(card.name, x + 3, 70, text_color, false, 1, true) + + -- Show energy cost/gain + local energy_text = card.energy >= 0 and ("+" .. card.energy) or tostring(card.energy) + print(energy_text, x + 50, 62, card.energy >= 0 and 11 or 8, false, 1, true) + end + + -- Show selected card description + if #card_choice_options > 0 then + local selected_card = cards[card_choice_options[card_pick_selection]] + print(selected_card.desc, 4, 110, 15) + end + + if btnp(4) and #card_choice_options > 0 then + add_card_to_deck(card_choice_options[card_pick_selection]) + -- Advance to next level + level = math.min(level + 1, #enemies) + player = { + hp = 10, + roll_mod = 0, + mult = 1, + counter = false, + energy = 0 + } + enemy = get_enemy(level) + initialize_deck() + draw_hand() + phase = "choose" + phase_time = 0 + damage_applied = false + end + elseif phase == "roll" then phase_time = phase_time + 1 @@ -578,6 +805,10 @@ function TIC() local shield_reduction = player.shield or 0 dmg = math.max(0, dmg - shield_reduction) player.hp = player.hp - 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) + end shake = 10 end msgtxt = "Enemy wins! You -" .. dmg @@ -598,24 +829,44 @@ function TIC() player.roll_mod, enemy.roll_mod = 0, 0 player.mult, enemy.mult = 1, 1 player.counter, enemy.counter = false, false - player.shield, enemy.shield = 0, 0 - draw_hand() + -- Don't reset shield - it persists until damage taken + draw_hand() -- Draw new hand from deck phase = (enemy.hp <= 0 or player.hp <= 0) and "game_over" or "choose" phase_time = 0 damage_applied = false end elseif phase == "game_over" then - if enemy.hp < player.hp then - print("You Win", 4, 60, 12) + if enemy.hp <= 0 and player.hp > 0 then + print("You Win! Press Z to choose new card", 4, 60, 12) else - print("You Lose", 4, 60, 14) + print("You Lose! Press X to restart", 4, 60, 14) end - if btnp(5) then - if enemy.hp < player.hp then - level = math.min(level + 1, #enemies) + if btnp(4) and enemy.hp <= 0 and player.hp > 0 then + -- Victory - go to card selection + generate_card_choices() + if #card_choice_options > 0 then + phase = "card_reward" + card_pick_selection = 1 else - level = 1 + -- No more cards to unlock, just advance level + level = math.min(level + 1, #enemies) + player = { + hp = 10, + roll_mod = 0, + mult = 1, + counter = false, + energy = 0 + } + enemy = get_enemy(level) + initialize_deck() + draw_hand() + phase = "choose" end + phase_time = 0 + damage_applied = false + elseif btnp(5) and (enemy.hp > 0 or player.hp <= 0) then + -- Loss - restart from level 1 + level = 1 player = { hp = 10, roll_mod = 0, @@ -623,18 +874,16 @@ function TIC() counter = false, energy = 0 } - enemy = get_enemy(level) msg = "" - - -- State + initialize_deck() + draw_hand() phase = "choose" phase_time = 0 roll_text = "" damage_applied = false end end - -- camera(0,0) end -- @@ -665,4 +914,7 @@ end -- -- 000:1a1c2c5d275db13e53ef7d57ffcd75a7f07038b76425717929366f3b5dc941a6f673eff7f4f4f494b0c2566c86333c57 -- +-- +-- 000:1a1c2c5d275db13e53ef7d57ffcd75a7f07038b76425717929366f3b5dc941a6f673eff7f4f4f494b0c2566c86333c57 +-- -- 2.20.1 From 17857e245b053b1d4929d41eebf4d52dcb47305b Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Tue, 7 Oct 2025 23:25:17 +1300 Subject: [PATCH 03/15] fix: deck mechanics --- lucksmith.lua | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/lucksmith.lua b/lucksmith.lua index 238f836..47fe18c 100644 --- a/lucksmith.lua +++ b/lucksmith.lua @@ -450,19 +450,6 @@ function shuffle_deck(deck) end end -function initialize_deck() - draw_pile = {} - discard_pile = {} - - -- Add 2 copies of each card to deck - for _, card in ipairs(cards) do - table.insert(draw_pile, card) - table.insert(draw_pile, card) - end - - shuffle_deck(draw_pile) -end - function reshuffle_if_needed() if #draw_pile < 3 and #discard_pile > 0 then -- Move discard pile to draw pile and shuffle -- 2.20.1 From f52dc966e260c104f32c928076245b3b1089cd0a Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Wed, 8 Oct 2025 12:50:34 +1300 Subject: [PATCH 04/15] fix: rage and weaken effect --- lucksmith.lua | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/lucksmith.lua b/lucksmith.lua index 47fe18c..b66bf53 100644 --- a/lucksmith.lua +++ b/lucksmith.lua @@ -123,7 +123,7 @@ cards = {{ timing = "pre_roll", energy = 0, -- reduced from -1 use = function(p, e) - e.mult = math.max(0.5, e.mult - 0.5) -- fixed: should affect enemy mult + e.weaken = (e.weaken or 0) + 1 -- enemy is weakened (does less damage) end }, { name = "Rage", @@ -131,7 +131,7 @@ cards = {{ timing = "pre_roll", -- changed from post_result for clarity energy = -1, -- reduced from -1 use = function(p, e) - p.mult = p.mult + 0.5 + p.rage = (p.rage or 0) + 1 -- add rage bonus end }, { name = "Tier", @@ -351,17 +351,15 @@ enemy_cards = {{ timing = "pre_roll", energy = -1, use = function(p, e) - p.mult = math.max(0.5, p.mult - 0.5) + p.weaken = (p.weaken or 0) + 1 -- player is weakened (does less damage) end }, { name = "Rage", desc = "+1 your dmg", - timing = "post_result", + timing = "pre_roll", energy = -1, - use = function(p, e, player_won) - if player_won ~= true then - p.hp = p.hp - 1 - end + use = function(p, e) + e.rage = (e.rage or 0) + 1 -- add rage bonus for enemy end }, { name = "Tier", @@ -779,6 +777,12 @@ function TIC() if player.total > enemy.total then player_won = true local dmg = 2 * player.mult + -- Apply rage bonus to increase damage + local rage_bonus = player.rage or 0 + dmg = dmg + rage_bonus + -- Apply weaken debuff (player is weakened, so their attacks do less damage) + local weaken_reduction = player.weaken or 0 + dmg = math.max(0, dmg - weaken_reduction) if not damage_applied then enemy.hp = enemy.hp - dmg flash = 8 @@ -787,6 +791,12 @@ function TIC() elseif enemy.total > player.total then player_won = false local dmg = 2 * enemy.mult + -- Apply rage bonus to increase damage + local rage_bonus = enemy.rage or 0 + dmg = dmg + rage_bonus + -- Apply weaken debuff (enemy is weakened, so their attacks do less damage) + local weaken_reduction = enemy.weaken or 0 + dmg = math.max(0, dmg - weaken_reduction) if not damage_applied then -- Apply shield reduction local shield_reduction = player.shield or 0 @@ -816,6 +826,8 @@ function TIC() player.roll_mod, enemy.roll_mod = 0, 0 player.mult, enemy.mult = 1, 1 player.counter, enemy.counter = false, false + player.weaken, enemy.weaken = 0, 0 -- reset weaken debuffs + player.rage, enemy.rage = 0, 0 -- reset rage bonuses -- Don't reset shield - it persists until damage taken draw_hand() -- Draw new hand from deck phase = (enemy.hp <= 0 or player.hp <= 0) and "game_over" or "choose" -- 2.20.1 From bb48570f8034c61b690cee18e3493bcf833abfcb Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Wed, 8 Oct 2025 14:05:22 +1300 Subject: [PATCH 05/15] feat: some nicer UI --- lucksmith.lua | 148 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 95 insertions(+), 53 deletions(-) diff --git a/lucksmith.lua b/lucksmith.lua index b66bf53..1b45c87 100644 --- a/lucksmith.lua +++ b/lucksmith.lua @@ -30,6 +30,7 @@ level = 1 function get_enemy(level) return { hp = enemies[level].hp, + max_hp = enemies[level].hp, -- store original max HP roll_mod = enemies[level].roll_mod, mult = enemies[level].mult, counter = enemies[level].counter @@ -43,6 +44,7 @@ phase = "choose" phase_time = 0 roll_text = "" damage_applied = false +current_damage = {player = 0, enemy = 0} -- store damage for display pending_effects = { player = {}, enemy = {} @@ -332,7 +334,7 @@ enemy_cards = {{ timing = "immediate", energy = -1, use = function(p, e) - e.hp = math.min(10, e.hp + 2) + e.hp = math.min(e.max_hp, e.hp + 2) end }, { name = "Counter", @@ -388,7 +390,7 @@ end function initialize_deck() draw_pile = {} discard_pile = {} - + -- Start with first 8 cards for level 1, or use unlocked_cards for higher levels local cards_to_add = {} if level == 1 then @@ -398,7 +400,7 @@ function initialize_deck() cards_to_add = {1, 2, 3, 4, 5, 6, 7, 8} end end - + -- Add 2 copies of each unlocked card to deck for i, card in ipairs(cards) do if unlocked_cards[i] then @@ -406,21 +408,21 @@ function initialize_deck() table.insert(draw_pile, card) end end - + shuffle_deck(draw_pile) end function generate_card_choices() card_choice_options = {} local available_cards = {} - + -- Find cards not yet unlocked for i, card in ipairs(cards) do if not unlocked_cards[i] then table.insert(available_cards, i) end end - + -- If we have available cards, pick 3 random ones if #available_cards > 0 then shuffle_deck(available_cards) @@ -557,8 +559,8 @@ function start_turn(card) current_card = card enemy_card = enemy_cards[math.random(#enemy_cards)] - -- Add 1 energy per turn, then apply card cost/gain - player.energy = math.max(0, math.min(5, player.energy + 1 + card.energy)) + -- Apply card energy cost/gain + player.energy = math.max(0, math.min(5, player.energy + card.energy)) -- Discard all cards in hand for _, hand_card in ipairs(hand) do @@ -622,12 +624,50 @@ function TIC() end -- Draw HUD - print("Level: " .. level, 140, 2, 12) - print("Energy: " .. player.energy .. "/5", 140, 12, 11) - print("Draw: " .. #draw_pile, 140, 22, 10) - print("Discard: " .. #discard_pile, 140, 32, 6) - print("PLAYER HP: " .. player.hp, 4, 2, 12) - print("ENEMY HP: " .. enemy.hp, 4, 12, 8) + print("Level: " .. level, 200, 130, 12, false, 1, true) + -- Draw energy sprites (right-aligned at y=4) + for i = 1, player.energy do + local x = 240 - (8 * i) -- right-aligned, each sprite 8 pixels wide + spr(17, x, 4, 0) + end + print("Draw: " .. #draw_pile, 200, 110, 10, false, 1, true) + print("Discard: " .. #discard_pile, 200, 120, 6, false, 1, true) + -- Draw player health bar (sprite 1 for health, sprite 3 for damage) + for i = 1, 10 do + local x = 4 + (i - 1) * 8 -- 8 pixels apart + if i <= player.hp then + spr(1, x, 2, 0) -- healthy HP + else + spr(3, x, 2, 0) -- damaged HP + end + end + -- Show damage next to player health bar if in result phase + if phase == "result" and current_damage.player > 0 then + print("-" .. current_damage.player, 88, 3, 12, false, 1, true) -- small red text + end + + -- Draw enemy health bar (sprite 2 for health, sprite 3 for damage) + for i = 1, enemy.max_hp do + local x = 4 + (i - 1) * 8 -- 8 pixels apart + if i <= enemy.hp then + spr(2, x, 12, 0) -- healthy HP + else + spr(3, x, 12, 0) -- damaged HP + end + end + -- Show damage next to enemy health bar if in result phase + if phase == "result" and current_damage.enemy > 0 then + local enemy_bar_end = 4 + (enemy.max_hp * 8) + print("-" .. current_damage.enemy, enemy_bar_end + 4, 12, 12, false, 1, true) -- small red text + end + + -- Show shield sprite if player has shield + if player.shield and player.shield > 0 then + spr(16, 220, 14, 0) -- sprite 16 in top right corner + if player.shield > 1 then + print(player.shield, 228, 22, 12) -- show shield count if > 1 + end + end if phase == "choose" then -- Card Picker @@ -645,9 +685,9 @@ function TIC() local x = 10 + (i - 1) * 64 local can_afford = (card.energy >= 0) or (player.energy >= -card.energy) local is_selected = i == picked - local border_color = can_afford and (is_selected and 1 or 12) or 6 + local border_color = can_afford and (is_selected and 1 or 12) or (is_selected and 10 or 9) rectb(x, 80, 62, 24, border_color) - local text_color = can_afford and (is_selected and 11 or 10) or 6 + local text_color = can_afford and (is_selected and 11 or 10) or (is_selected and 10 or 9) print(card.name, x + 3, 90, text_color, false, 1, true) -- Show energy cost/gain @@ -659,7 +699,7 @@ function TIC() local can_afford = (selected_card.energy >= 0) or (player.energy >= -selected_card.energy) print(selected_card.desc, 4, 120, can_afford and 15 or 6) if not can_afford then - print("Not enough energy!", 4, 130, 6) + print("Not enough energy!", 4, 130, 9) end print(msg, 4, 40, 15) @@ -670,7 +710,7 @@ function TIC() elseif phase == "card_reward" then -- Card selection after level victory print("Choose a card to add to your deck:", 4, 30, 12) - + if btnp(2) then card_pick_selection = card_pick_selection - 1 end @@ -678,7 +718,7 @@ function TIC() card_pick_selection = card_pick_selection + 1 end card_pick_selection = math.min(#card_choice_options, math.max(1, card_pick_selection)) - + -- Show card options for i, card_index in ipairs(card_choice_options) do local card = cards[card_index] @@ -688,18 +728,18 @@ function TIC() rectb(x, 60, 62, 40, border_color) local text_color = is_selected and 11 or 10 print(card.name, x + 3, 70, text_color, false, 1, true) - + -- Show energy cost/gain local energy_text = card.energy >= 0 and ("+" .. card.energy) or tostring(card.energy) print(energy_text, x + 50, 62, card.energy >= 0 and 11 or 8, false, 1, true) end - + -- Show selected card description if #card_choice_options > 0 then local selected_card = cards[card_choice_options[card_pick_selection]] print(selected_card.desc, 4, 110, 15) end - + if btnp(4) and #card_choice_options > 0 then add_card_to_deck(card_choice_options[card_pick_selection]) -- Advance to next level @@ -738,40 +778,40 @@ function TIC() card_text = "You played " .. current_card.name enemy_card_text = "Enemy played " .. enemy_card.name - print(card_text, 4, 30, 14) - print(enemy_card_text, 4, 20, 8) + print(card_text, 4, 40, 2) + print(enemy_card_text, 4, 50, 6) -- show rolls roll_text = "You roll " .. player.display_roll .. " / Enemy rolls " .. enemy.display_roll - print(roll_text, 4, 40, 12) + print(roll_text, 4, 60, 12) elseif phase == "mod" then - print(card_text, 4, 30, 14) - print(enemy_card_text, 4, 20, 8) - print(roll_text, 4, 40, 12) + print(card_text, 4, 40, 2) + print(enemy_card_text, 4, 50, 6) + print(roll_text, 4, 60, 14) mod_text = "mods applied: +" .. player.roll_mod .. " / " .. enemy.roll_mod - print(mod_text, 4, 50, 10) + print(mod_text, 4, 70, 12) phase_time = phase_time + 1 if phase_time > 60 then phase = "total" phase_time = 0 end elseif phase == "total" then - print(card_text, 4, 30, 14) - print(enemy_card_text, 4, 20, 8) - print(roll_text, 4, 40, 12) - print(mod_text, 4, 50, 12) - print("Total " .. player.total .. " / " .. enemy.total, 4, 60, 10) + print(card_text, 4, 40, 2) + print(enemy_card_text, 4, 50, 6) + print(roll_text, 4, 60, 14) + print(mod_text, 4, 70, 14) + print("Total " .. player.total .. " / " .. enemy.total, 4, 80, 12) phase_time = phase_time + 1 if phase_time > 120 then phase = "result" phase_time = 0 end elseif phase == "result" then - print(card_text, 4, 30, 14) - print(enemy_card_text, 4, 20, 8) - print(roll_text, 4, 40, 12) - print(mod_text, 4, 50, 12) - print("Total " .. player.total .. " / " .. enemy.total, 4, 60, 10) + print(card_text, 4, 40, 2) + print(enemy_card_text, 4, 50, 6) + print(roll_text, 4, 60, 14) + print(mod_text, 4, 70, 14) + print("Total " .. player.total .. " / " .. enemy.total, 4, 80, 14) local msgtxt = "" local player_won = nil if player.total > enemy.total then @@ -783,11 +823,12 @@ function TIC() -- Apply weaken debuff (player is weakened, so their attacks do less damage) local weaken_reduction = player.weaken or 0 dmg = math.max(0, dmg - weaken_reduction) + current_damage.enemy = dmg -- store for display if not damage_applied then enemy.hp = enemy.hp - dmg flash = 8 end - msgtxt = "You win! Enemy -" .. dmg + msgtxt = "You win!" elseif enemy.total > player.total then player_won = false local dmg = 2 * enemy.mult @@ -797,6 +838,7 @@ function TIC() -- Apply weaken debuff (enemy is weakened, so their attacks do less damage) local weaken_reduction = enemy.weaken or 0 dmg = math.max(0, dmg - weaken_reduction) + current_damage.player = dmg -- store for display if not damage_applied then -- Apply shield reduction local shield_reduction = player.shield or 0 @@ -808,7 +850,7 @@ function TIC() end shake = 10 end - msgtxt = "Enemy wins! You -" .. dmg + msgtxt = "Enemy wins!" else msgtxt = "Tie!" end @@ -819,7 +861,8 @@ function TIC() end damage_applied = true - print(msgtxt, 4, 70, 14) + local color = player_won == true and 2 or (player_won == false and 6 or 9) + print(msgtxt, 4, 90, color) if btnp(4) then -- reset mods & back to choose @@ -829,6 +872,11 @@ function TIC() player.weaken, enemy.weaken = 0, 0 -- reset weaken debuffs player.rage, enemy.rage = 0, 0 -- reset rage bonuses -- Don't reset shield - it persists until damage taken + -- Add 1 energy at end of turn + player.energy = math.min(5, player.energy + 1) + -- Reset damage display + current_damage.player = 0 + current_damage.enemy = 0 draw_hand() -- Draw new hand from deck phase = (enemy.hp <= 0 or player.hp <= 0) and "game_over" or "choose" phase_time = 0 @@ -886,14 +934,11 @@ function TIC() end -- --- 001:eccccccccc888888caaaaaaaca888888cacccccccacc0ccccacc0ccccacc0ccc --- 002:ccccceee8888cceeaaaa0cee888a0ceeccca0ccc0cca0c0c0cca0c0c0cca0c0c --- 003:eccccccccc888888caaaaaaaca888888cacccccccacccccccacc0ccccacc0ccc --- 004:ccccceee8888cceeaaaa0cee888a0ceeccca0cccccca0c0c0cca0c0c0cca0c0c --- 017:cacccccccaaaaaaacaaacaaacaaaaccccaaaaaaac8888888cc000cccecccccec --- 018:ccca00ccaaaa0ccecaaa0ceeaaaa0ceeaaaa0cee8888ccee000cceeecccceeee --- 019:cacccccccaaaaaaacaaacaaacaaaaccccaaaaaaac8888888cc000cccecccccec --- 020:ccca00ccaaaa0ccecaaa0ceeaaaa0ceeaaaa0cee8888ccee000cceeecccceeee +-- 001:0ff00ff0f22ff33ff22f223ff222223f0f2222f000f22f00000ff00000000000 +-- 002:0ff00ff0f66ff55ff66f665ff666665f0f6666f000f66f00000ff00000000000 +-- 003:0ff00ff0feeffddffeefeedffeeeeedf0feeeef000feef00000ff00000000000 +-- 016:0011110001333310133223311333233113323331013323100013310000011000 +-- 017:0066660006555460655544466555545665555556655555560655556000666600 -- -- @@ -913,7 +958,4 @@ end -- -- 000:1a1c2c5d275db13e53ef7d57ffcd75a7f07038b76425717929366f3b5dc941a6f673eff7f4f4f494b0c2566c86333c57 -- --- --- 000:1a1c2c5d275db13e53ef7d57ffcd75a7f07038b76425717929366f3b5dc941a6f673eff7f4f4f494b0c2566c86333c57 --- -- 2.20.1 From bbc5276874bfacdc99ac601eaa842d2c93fcb1e8 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Wed, 8 Oct 2025 19:49:22 +1300 Subject: [PATCH 06/15] feat: show health changes, show correct damage --- lucksmith.lua | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/lucksmith.lua b/lucksmith.lua index 1b45c87..ecf84e4 100644 --- a/lucksmith.lua +++ b/lucksmith.lua @@ -7,24 +7,20 @@ player = { hp = 10, roll_mod = 0, mult = 1, - counter = false, energy = 0 } enemies = {{ hp = 8, roll_mod = 0, - mult = 1, - counter = false + mult = 1 }, { hp = 10, roll_mod = 0, - mult = 1, - counter = false + mult = 1 }, { hp = 12, roll_mod = 0, - mult = 1, - counter = false + mult = 1 }} level = 1 function get_enemy(level) @@ -32,8 +28,7 @@ function get_enemy(level) hp = enemies[level].hp, max_hp = enemies[level].hp, -- store original max HP roll_mod = enemies[level].roll_mod, - mult = enemies[level].mult, - counter = enemies[level].counter + mult = enemies[level].mult } end enemy = get_enemy(level) @@ -108,6 +103,7 @@ cards = {{ energy = -1, -- costs 1 energy use = function(p, e) p.hp = math.min(10, p.hp + 2) + current_damage.player = current_damage.player - 2 -- show damage taken end }, { name = "Counter", @@ -117,6 +113,7 @@ cards = {{ use = function(p, e, player_won) if player_won == false then -- fixed: should trigger when player loses e.hp = e.hp - 1 + current_damage.enemy = current_damage.enemy + 1 -- show damage taken end end }, { @@ -169,8 +166,10 @@ cards = {{ use = function(p, e, player_won) if player_won == true then p.hp = p.hp - 1 -- hurt yourself if you win + current_damage.player = current_damage.player + 1 -- show damage taken elseif player_won == false then e.hp = e.hp - 1 -- hurt enemy if they win + current_damage.enemy = current_damage.enemy + 1 -- show damage taken end -- ties do nothing end @@ -335,6 +334,7 @@ enemy_cards = {{ energy = -1, use = function(p, e) e.hp = math.min(e.max_hp, e.hp + 2) + current_damage.enemy = current_damage.enemy - 2 -- show damage taken end }, { name = "Counter", @@ -345,6 +345,7 @@ enemy_cards = {{ -- player_won is from player's perspective, so enemy perspective is flipped if player_won == true then -- enemy lost (player won) p.hp = p.hp - 1 + current_damage.player = current_damage.player + 1 -- show damage taken end end }, { @@ -642,8 +643,8 @@ function TIC() end end -- Show damage next to player health bar if in result phase - if phase == "result" and current_damage.player > 0 then - print("-" .. current_damage.player, 88, 3, 12, false, 1, true) -- small red text + if current_damage.player ~= 0 then + print( (current_damage.player < 0 and "+" or "") .. -current_damage.player, 88, 3, 12, false, 1, true) -- small red text end -- Draw enemy health bar (sprite 2 for health, sprite 3 for damage) @@ -656,9 +657,9 @@ function TIC() end end -- Show damage next to enemy health bar if in result phase - if phase == "result" and current_damage.enemy > 0 then + if current_damage.enemy > 0 then local enemy_bar_end = 4 + (enemy.max_hp * 8) - print("-" .. current_damage.enemy, enemy_bar_end + 4, 12, 12, false, 1, true) -- small red text + print((current_damage.enemy < 0 and "+" or "") .. -current_damage.enemy, enemy_bar_end + 4, 12, 12, false, 1, true) -- small red text end -- Show shield sprite if player has shield @@ -748,7 +749,6 @@ function TIC() hp = 10, roll_mod = 0, mult = 1, - counter = false, energy = 0 } enemy = get_enemy(level) @@ -796,6 +796,7 @@ function TIC() phase_time = 0 end elseif phase == "total" then + current_damage.player, current_damage.enemy = 0, 0 -- reset damage display print(card_text, 4, 40, 2) print(enemy_card_text, 4, 50, 6) print(roll_text, 4, 60, 14) @@ -823,9 +824,11 @@ function TIC() -- Apply weaken debuff (player is weakened, so their attacks do less damage) local weaken_reduction = player.weaken or 0 dmg = math.max(0, dmg - weaken_reduction) - current_damage.enemy = dmg -- store for display + if not damage_applied then + enemy.hp = enemy.hp - dmg + current_damage.enemy = current_damage.enemy + dmg flash = 8 end msgtxt = "You win!" @@ -838,12 +841,14 @@ function TIC() -- Apply weaken debuff (enemy is weakened, so their attacks do less damage) local weaken_reduction = enemy.weaken or 0 dmg = math.max(0, dmg - weaken_reduction) - current_damage.player = dmg -- store for display + if not damage_applied then + -- Apply shield reduction 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) @@ -868,7 +873,6 @@ function TIC() -- reset mods & back to choose player.roll_mod, enemy.roll_mod = 0, 0 player.mult, enemy.mult = 1, 1 - player.counter, enemy.counter = false, false player.weaken, enemy.weaken = 0, 0 -- reset weaken debuffs player.rage, enemy.rage = 0, 0 -- reset rage bonuses -- Don't reset shield - it persists until damage taken @@ -901,7 +905,6 @@ function TIC() hp = 10, roll_mod = 0, mult = 1, - counter = false, energy = 0 } enemy = get_enemy(level) @@ -918,7 +921,6 @@ function TIC() hp = 10, roll_mod = 0, mult = 1, - counter = false, energy = 0 } enemy = get_enemy(level) -- 2.20.1 From 0b1487c11922c5439d01eaa1f1cde33173836f37 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Wed, 8 Oct 2025 20:44:39 +1300 Subject: [PATCH 07/15] feat: more UI --- lucksmith.lua | 48 ++++++++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/lucksmith.lua b/lucksmith.lua index ecf84e4..8a1e0dc 100644 --- a/lucksmith.lua +++ b/lucksmith.lua @@ -625,14 +625,17 @@ function TIC() end -- Draw HUD - print("Level: " .. level, 200, 130, 12, false, 1, true) + spr(0, 110, 2, 0) + print(level, 115, 2, 7, false, 1, true) -- Draw energy sprites (right-aligned at y=4) for i = 1, player.energy do - local x = 240 - (8 * i) -- right-aligned, each sprite 8 pixels wide - spr(17, x, 4, 0) + local x = -4 + (8 * i) -- right-aligned, each sprite 8 pixels wide + spr(17, x, 12, 0) end - print("Draw: " .. #draw_pile, 200, 110, 10, false, 1, true) - print("Discard: " .. #discard_pile, 200, 120, 6, false, 1, true) + spr(18, 220, 115, 0) + print( #draw_pile, 230, 116, 10, false, 1, true) + spr(19, 220, 125, 0) + print(#discard_pile, 230, 126, 14, false, 1, true) -- Draw player health bar (sprite 1 for health, sprite 3 for damage) for i = 1, 10 do local x = 4 + (i - 1) * 8 -- 8 pixels apart @@ -644,29 +647,29 @@ function TIC() end -- Show damage next to player health bar if in result phase if current_damage.player ~= 0 then - print( (current_damage.player < 0 and "+" or "") .. -current_damage.player, 88, 3, 12, false, 1, true) -- small red text + print( (current_damage.player < 0 and "+" or "") .. -current_damage.player, 88, 3, current_damage.player > 0 and 2 or 6, false, 1, true) -- small red text end - -- Draw enemy health bar (sprite 2 for health, sprite 3 for damage) + -- Draw enemy health bar (sprite 2 for health, sprite 3 for damage) - right aligned at y=2 for i = 1, enemy.max_hp do - local x = 4 + (i - 1) * 8 -- 8 pixels apart - if i <= enemy.hp then - spr(2, x, 12, 0) -- healthy HP + local x = 240 - (enemy.max_hp * 8) + (i - 1) * 8 -- right-aligned, 8 pixels apart + if i <= (enemy.max_hp - enemy.hp) then + spr(3, x, 2, 0) -- damaged HP on the left else - spr(3, x, 12, 0) -- damaged HP + spr(2, x, 2, 0) -- healthy HP on the right end end -- Show damage next to enemy health bar if in result phase - if current_damage.enemy > 0 then - local enemy_bar_end = 4 + (enemy.max_hp * 8) - print((current_damage.enemy < 0 and "+" or "") .. -current_damage.enemy, enemy_bar_end + 4, 12, 12, false, 1, true) -- small red text + if current_damage.enemy > 0 then + local enemy_bar_start = 240 - (enemy.max_hp * 8) - 20 -- position to left of health bar + print((current_damage.enemy < 0 and "+" or "") .. -current_damage.enemy, enemy_bar_start, 3, current_damage.enemy > 0 and 2 or 6, false, 1, true) -- small red text end -- Show shield sprite if player has shield if player.shield and player.shield > 0 then - spr(16, 220, 14, 0) -- sprite 16 in top right corner + spr(16, 20, 22, 0) -- sprite 16 in top right corner if player.shield > 1 then - print(player.shield, 228, 22, 12) -- show shield count if > 1 + print(player.shield, 228, 23, 12, false, 1, true) -- show shield count if > 1 end end @@ -687,13 +690,15 @@ function TIC() local can_afford = (card.energy >= 0) or (player.energy >= -card.energy) local is_selected = i == picked local border_color = can_afford and (is_selected and 1 or 12) or (is_selected and 10 or 9) - rectb(x, 80, 62, 24, border_color) + rectb(x, 40, 52, 64, border_color) + if is_selected then rect(x+1, 41, 50, 62, 14) end local text_color = can_afford and (is_selected and 11 or 10) or (is_selected and 10 or 9) - print(card.name, x + 3, 90, text_color, false, 1, true) + print(card.name, x + 3, 70, text_color, false, 1, true) -- Show energy cost/gain local energy_text = card.energy >= 0 and ("+" .. card.energy) or tostring(card.energy) - print(energy_text, x + 50, 82, card.energy >= 0 and 11 or 8, false, 1, true) + spr(17, x + 30, 42, 0) + print(energy_text, x + 40, 44, card.energy >= 0 and 11 or 8, false, 1, true) end local selected_card = hand[picked] @@ -936,11 +941,14 @@ function TIC() end -- +-- 000:3200000032000000322200003332000033322200333332003333322200000000 -- 001:0ff00ff0f22ff33ff22f223ff222223f0f2222f000f22f00000ff00000000000 -- 002:0ff00ff0f66ff55ff66f665ff666665f0f6666f000f66f00000ff00000000000 -- 003:0ff00ff0feeffddffeefeedffeeeeedf0feeeef000feef00000ff00000000000 -- 016:0011110001333310133223311333233113323331013323100013310000011000 --- 017:0066660006555460655544466555545665555556655555560655556000666600 +-- 017:0000000000333300033443300344c43003444430033443300033330000000000 +-- 018:0aaaaaa00aa99aa00a9999a00a9999a00a9999a00a9999a00aa99aa00aaaaaa0 +-- 019:0eeeeee00eeffee00effffe00effffe00effffe00effffe00eeffee00eeeeee0 -- -- -- 2.20.1 From 02abd67f4eb0ff1aebde5fe37983d480ea49307c Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Wed, 8 Oct 2025 21:25:27 +1300 Subject: [PATCH 08/15] feat: tidier card display --- lucksmith.lua | 184 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 112 insertions(+), 72 deletions(-) diff --git a/lucksmith.lua b/lucksmith.lua index 8a1e0dc..af31c1f 100644 --- a/lucksmith.lua +++ b/lucksmith.lua @@ -10,14 +10,17 @@ player = { energy = 0 } enemies = {{ - hp = 8, + name = "Goblin", + hp = 2, roll_mod = 0, mult = 1 }, { + name = "Orc", hp = 10, roll_mod = 0, mult = 1 }, { + name = "Troll", hp = 12, roll_mod = 0, mult = 1 @@ -25,6 +28,7 @@ enemies = {{ level = 1 function get_enemy(level) return { + name = enemies[level].name, hp = enemies[level].hp, max_hp = enemies[level].hp, -- store original max HP roll_mod = enemies[level].roll_mod, @@ -595,6 +599,84 @@ end picked = 1 card_pick_selection = 1 + +-- === DRAWING FUNCTIONS === +function draw_hud() + -- Draw level + spr(0, 110, 2, 0) + print(level, 115, 2, 7, false, 1, true) + + -- Draw energy sprites + for i = 1, player.energy do + local x = -4 + (8 * i) + spr(17, x, 12, 0) + end + + -- Draw deck info + spr(18, 220, 115, 0) + print(#draw_pile, 230, 116, 10, false, 1, true) + spr(19, 220, 125, 0) + print(#discard_pile, 230, 126, 14, false, 1, true) +end + +function draw_health_bars() + -- Draw player health bar + for i = 1, 10 do + local x = 4 + (i - 1) * 8 + if i <= player.hp then + spr(1, x, 2, 0) -- healthy HP + else + spr(3, x, 2, 0) -- damaged HP + end + end + + -- Show player damage + if current_damage.player ~= 0 then + print((current_damage.player < 0 and "+" or "") .. -math.floor(current_damage.player), 88, 3, current_damage.player > 0 and 2 or 6, false, 1, true) + end + + -- Draw enemy health bar + for i = 1, enemy.max_hp do + local x = 240 - (enemy.max_hp * 8) + (i - 1) * 8 + if i <= (enemy.max_hp - enemy.hp) then + spr(3, x, 2, 0) -- damaged HP on the left + else + spr(2, x, 2, 0) -- healthy HP on the right + end + end + + -- Show enemy damage + if current_damage.enemy > 0 then + local enemy_bar_start = 240 - (enemy.max_hp * 8) - 20 + print((current_damage.enemy < 0 and "+" or "") .. -math.floor(current_damage.enemy), enemy_bar_start, 3, current_damage.enemy > 0 and 2 or 6, false, 1, true) + end + + -- Draw enemy name under health bar + local enemy_name_x = 240 - (enemy.max_hp * 8) + (enemy.max_hp * 4) - (#enemy.name * 3) + print(enemy.name, enemy_name_x, 12, 7, false, 1, true) + + -- Show shield sprite if player has shield + if player.shield and player.shield > 0 then + spr(16, 20, 22, 0) + if player.shield > 1 then + print(player.shield, 228, 23, 12, false, 1, true) + end + end +end + +function draw_card(card, x, is_selected, can_afford) + local border_color = can_afford and (is_selected and 1 or 12) or (is_selected and 10 or 9) + rectb(x, 40, 52, 64, border_color) + if is_selected then rect(x+1, 41, 50, 62, 14) end + local text_color = can_afford and (is_selected and 11 or 10) or (is_selected and 10 or 9) + print(card.name, x + 3, 70, text_color, false, 1, true) + + -- Show energy cost/gain + local energy_text = card.energy >= 0 and ("+" .. card.energy) or tostring(card.energy) + spr(17, x + 30, 42, 0) + print(energy_text, x + 40, 44, card.energy >= 0 and 11 or 8, false, 1, true) +end + -- === INPUT === function TIC() cls(0) @@ -624,54 +706,9 @@ function TIC() end end - -- Draw HUD - spr(0, 110, 2, 0) - print(level, 115, 2, 7, false, 1, true) - -- Draw energy sprites (right-aligned at y=4) - for i = 1, player.energy do - local x = -4 + (8 * i) -- right-aligned, each sprite 8 pixels wide - spr(17, x, 12, 0) - end - spr(18, 220, 115, 0) - print( #draw_pile, 230, 116, 10, false, 1, true) - spr(19, 220, 125, 0) - print(#discard_pile, 230, 126, 14, false, 1, true) - -- Draw player health bar (sprite 1 for health, sprite 3 for damage) - for i = 1, 10 do - local x = 4 + (i - 1) * 8 -- 8 pixels apart - if i <= player.hp then - spr(1, x, 2, 0) -- healthy HP - else - spr(3, x, 2, 0) -- damaged HP - end - end - -- Show damage next to player health bar if in result phase - if current_damage.player ~= 0 then - print( (current_damage.player < 0 and "+" or "") .. -current_damage.player, 88, 3, current_damage.player > 0 and 2 or 6, false, 1, true) -- small red text - end - - -- Draw enemy health bar (sprite 2 for health, sprite 3 for damage) - right aligned at y=2 - for i = 1, enemy.max_hp do - local x = 240 - (enemy.max_hp * 8) + (i - 1) * 8 -- right-aligned, 8 pixels apart - if i <= (enemy.max_hp - enemy.hp) then - spr(3, x, 2, 0) -- damaged HP on the left - else - spr(2, x, 2, 0) -- healthy HP on the right - end - end - -- Show damage next to enemy health bar if in result phase - if current_damage.enemy > 0 then - local enemy_bar_start = 240 - (enemy.max_hp * 8) - 20 -- position to left of health bar - print((current_damage.enemy < 0 and "+" or "") .. -current_damage.enemy, enemy_bar_start, 3, current_damage.enemy > 0 and 2 or 6, false, 1, true) -- small red text - end - - -- Show shield sprite if player has shield - if player.shield and player.shield > 0 then - spr(16, 20, 22, 0) -- sprite 16 in top right corner - if player.shield > 1 then - print(player.shield, 228, 23, 12, false, 1, true) -- show shield count if > 1 - end - end + -- Draw HUD and health bars + draw_hud() + draw_health_bars() if phase == "choose" then -- Card Picker @@ -689,16 +726,7 @@ function TIC() local x = 10 + (i - 1) * 64 local can_afford = (card.energy >= 0) or (player.energy >= -card.energy) local is_selected = i == picked - local border_color = can_afford and (is_selected and 1 or 12) or (is_selected and 10 or 9) - rectb(x, 40, 52, 64, border_color) - if is_selected then rect(x+1, 41, 50, 62, 14) end - local text_color = can_afford and (is_selected and 11 or 10) or (is_selected and 10 or 9) - print(card.name, x + 3, 70, text_color, false, 1, true) - - -- Show energy cost/gain - local energy_text = card.energy >= 0 and ("+" .. card.energy) or tostring(card.energy) - spr(17, x + 30, 42, 0) - print(energy_text, x + 40, 44, card.energy >= 0 and 11 or 8, false, 1, true) + draw_card(card, x, is_selected, can_afford) end local selected_card = hand[picked] @@ -730,14 +758,7 @@ function TIC() local card = cards[card_index] local x = 10 + (i - 1) * 64 local is_selected = i == card_pick_selection - local border_color = is_selected and 11 or 12 - rectb(x, 60, 62, 40, border_color) - local text_color = is_selected and 11 or 10 - print(card.name, x + 3, 70, text_color, false, 1, true) - - -- Show energy cost/gain - local energy_text = card.energy >= 0 and ("+" .. card.energy) or tostring(card.energy) - print(energy_text, x + 50, 62, card.energy >= 0 and 11 or 8, false, 1, true) + draw_card(card, x, is_selected, true) -- always affordable in reward phase end -- Show selected card description @@ -782,11 +803,11 @@ function TIC() end card_text = "You played " .. current_card.name - enemy_card_text = "Enemy played " .. enemy_card.name + enemy_card_text = enemy.name .. " played " .. enemy_card.name print(card_text, 4, 40, 2) print(enemy_card_text, 4, 50, 6) -- show rolls - roll_text = "You roll " .. player.display_roll .. " / Enemy rolls " .. enemy.display_roll + roll_text = "You roll " .. player.display_roll .. " / " .. enemy.name .. " rolls " .. enemy.display_roll print(roll_text, 4, 60, 12) elseif phase == "mod" then @@ -860,7 +881,7 @@ function TIC() end shake = 10 end - msgtxt = "Enemy wins!" + msgtxt = enemy.name .. " wins!" else msgtxt = "Tie!" end @@ -893,9 +914,21 @@ function TIC() end elseif phase == "game_over" then if enemy.hp <= 0 and player.hp > 0 then - print("You Win! Press Z to choose new card", 4, 60, 12) + local victory_text = "You defeated " .. enemy.name .. "!" + local victory_x = 120 - (#victory_text * 3) -- center text (6 pixel font, so 3 pixels per char from center) + print(victory_text, victory_x, 40, 6) + + local continue_text = "Press Z to choose new card" + local continue_x = 120 - (#continue_text * 3) + print(continue_text, continue_x, 80, 9) else - print("You Lose! Press X to restart", 4, 60, 14) + local defeat_text = enemy.name .. " defeated you!" + local defeat_x = 120 - (#defeat_text * 3) + print(defeat_text, defeat_x, 40, 2) + + local restart_text = "Press X to restart" + local restart_x = 120 - (#restart_text * 3) + print(restart_text, restart_x, 60, 14) end if btnp(4) and enemy.hp <= 0 and player.hp > 0 then -- Victory - go to card selection @@ -968,4 +1001,11 @@ end -- -- 000:1a1c2c5d275db13e53ef7d57ffcd75a7f07038b76425717929366f3b5dc941a6f673eff7f4f4f494b0c2566c86333c57 -- +-- +-- 000:100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +-- + +-- +-- 000:1a1c2c5d275db13e53ef7d57ffcd75a7f07038b76425717929366f3b5dc941a6f673eff7f4f4f494b0c2566c86333c57 +-- -- 2.20.1 From 6cce53b37cf46464c85ef0d94982d2bc61169452 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Wed, 8 Oct 2025 21:52:56 +1300 Subject: [PATCH 09/15] feat: 6 enemies, better card colours --- lucksmith.lua | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/lucksmith.lua b/lucksmith.lua index af31c1f..d37e9df 100644 --- a/lucksmith.lua +++ b/lucksmith.lua @@ -11,19 +11,34 @@ player = { } enemies = {{ name = "Goblin", - hp = 2, + hp = 4, roll_mod = 0, mult = 1 }, { name = "Orc", - hp = 10, + hp = 6, roll_mod = 0, mult = 1 }, { name = "Troll", + hp = 8, + roll_mod = 0, + mult = 1 +}, { + name = "Ogre", + hp = 10, + roll_mod = 0, + mult = 1 +}, { + name = "Dragon", hp = 12, roll_mod = 0, mult = 1 +}, { + name = "Demon", + hp = 14, + roll_mod = 0, + mult = 1 }} level = 1 function get_enemy(level) @@ -647,34 +662,33 @@ function draw_health_bars() -- Show enemy damage if current_damage.enemy > 0 then - local enemy_bar_start = 240 - (enemy.max_hp * 8) - 20 + local enemy_bar_start = 240 - (enemy.max_hp * 8) - 8 print((current_damage.enemy < 0 and "+" or "") .. -math.floor(current_damage.enemy), enemy_bar_start, 3, current_damage.enemy > 0 and 2 or 6, false, 1, true) end -- Draw enemy name under health bar - local enemy_name_x = 240 - (enemy.max_hp * 8) + (enemy.max_hp * 4) - (#enemy.name * 3) + local enemy_name_x = 240 - (#enemy.name * 4) print(enemy.name, enemy_name_x, 12, 7, false, 1, true) -- Show shield sprite if player has shield if player.shield and player.shield > 0 then - spr(16, 20, 22, 0) - if player.shield > 1 then - print(player.shield, 228, 23, 12, false, 1, true) + for i = 1, player.shield do + spr(16, 4 + (i - 1) * 8, 22, 0) end end end function draw_card(card, x, is_selected, can_afford) - local border_color = can_afford and (is_selected and 1 or 12) or (is_selected and 10 or 9) + local border_color = can_afford and (is_selected and 11 or 9) or (is_selected and 13 or 14) rectb(x, 40, 52, 64, border_color) - if is_selected then rect(x+1, 41, 50, 62, 14) end - local text_color = can_afford and (is_selected and 11 or 10) or (is_selected and 10 or 9) + if is_selected then rect(x+1, 41, 50, 62, 8) end + local text_color = can_afford and (is_selected and 11 or 9) or (is_selected and 0 or 14) print(card.name, x + 3, 70, text_color, false, 1, true) -- Show energy cost/gain local energy_text = card.energy >= 0 and ("+" .. card.energy) or tostring(card.energy) spr(17, x + 30, 42, 0) - print(energy_text, x + 40, 44, card.energy >= 0 and 11 or 8, false, 1, true) + print(energy_text, x + 40, 44, card.energy >= 0 and 6 or 2, false, 1, true) end -- === INPUT === @@ -731,9 +745,9 @@ function TIC() local selected_card = hand[picked] local can_afford = (selected_card.energy >= 0) or (player.energy >= -selected_card.energy) - print(selected_card.desc, 4, 120, can_afford and 15 or 6) + print(selected_card.desc, 4, 120, can_afford and 6 or 14) if not can_afford then - print("Not enough energy!", 4, 130, 9) + print("Not enough energy!", 4, 130, 3) end print(msg, 4, 40, 15) -- 2.20.1 From e3d731c087469b804abb79adb8a626b9bc43b5fe Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Thu, 9 Oct 2025 20:33:37 +1300 Subject: [PATCH 10/15] feat: card display --- lucksmith.lua | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lucksmith.lua b/lucksmith.lua index d37e9df..b07730b 100644 --- a/lucksmith.lua +++ b/lucksmith.lua @@ -632,6 +632,21 @@ function draw_hud() print(#draw_pile, 230, 116, 10, false, 1, true) spr(19, 220, 125, 0) print(#discard_pile, 230, 126, 14, false, 1, true) + + -- Draw card play boxes at top + -- Player card box (left) + rectb(4, 20, 40, 16, 2) + rectb(45, 20, 40, 16, 2) + if current_card then + print(current_card.name, 47, 25, 2, false, 1, true) + end + + -- Enemy card box (right) + rectb(158, 20, 40, 16, 6) + rectb(199, 20, 40, 16, 6) + if enemy_card then + print(enemy_card.name, 160, 25, 6, false, 1, true) + end end function draw_health_bars() -- 2.20.1 From a2869ba375b1c2d4d11908d05cadbd217cf1b76c Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Thu, 9 Oct 2025 20:40:12 +1300 Subject: [PATCH 11/15] feat: show previous card as well --- lucksmith.lua | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/lucksmith.lua b/lucksmith.lua index b07730b..0bb96a0 100644 --- a/lucksmith.lua +++ b/lucksmith.lua @@ -63,6 +63,9 @@ pending_effects = { player = {}, enemy = {} } +-- Card tracking for two-round strategy +previous_card = nil +previous_enemy_card = nil -- animation + shake player.display_roll = 0 enemy.display_roll = 0 @@ -576,6 +579,10 @@ function apply_effects(timing, player_won) end end function start_turn(card) + -- Store previous cards before setting new ones + previous_card = current_card + previous_enemy_card = enemy_card + current_card = card enemy_card = enemy_cards[math.random(#enemy_cards)] @@ -634,18 +641,26 @@ function draw_hud() print(#discard_pile, 230, 126, 14, false, 1, true) -- Draw card play boxes at top - -- Player card box (left) - rectb(4, 20, 40, 16, 2) - rectb(45, 20, 40, 16, 2) + -- Player card boxes (left side) + rectb(4, 20, 40, 16, 2) -- Current player card if current_card then - print(current_card.name, 47, 25, 2, false, 1, true) + print(current_card.name, 6, 25, 2, false, 1, true) end - -- Enemy card box (right) - rectb(158, 20, 40, 16, 6) - rectb(199, 20, 40, 16, 6) + rectb(45, 20, 40, 16, 8) -- Previous player card + if previous_card then + print(previous_card.name, 47, 25, 8, false, 1, true) + end + + -- Enemy card boxes (right side) + rectb(155, 20, 40, 16, 8) -- Previous enemy card + if previous_enemy_card then + print(previous_enemy_card.name, 157, 25, 8, false, 1, true) + end + + rectb(196, 20, 40, 16, 6) -- Current enemy card if enemy_card then - print(enemy_card.name, 160, 25, 6, false, 1, true) + print(enemy_card.name, 198, 25, 6, false, 1, true) end end @@ -1037,4 +1052,6 @@ end -- -- 000:1a1c2c5d275db13e53ef7d57ffcd75a7f07038b76425717929366f3b5dc941a6f673eff7f4f4f494b0c2566c86333c57 -- +-- 000:1a1c2c5d275db13e53ef7d57ffcd75a7f07038b76425717929366f3b5dc941a6f673eff7f4f4f494b0c2566c86333c57 +-- -- 2.20.1 From e54dcab9dc543b6ca3857fea1f41f0cdc424722c Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Thu, 9 Oct 2025 20:54:43 +1300 Subject: [PATCH 12/15] feat: rename cards --- lucksmith.lua | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/lucksmith.lua b/lucksmith.lua index 0bb96a0..1c3e15d 100644 --- a/lucksmith.lua +++ b/lucksmith.lua @@ -85,7 +85,7 @@ unlocked_cards = {} -- tracks which cards are in your deck -- basic card pool cards = {{ - name = "Strength", + name = "Bless", desc = "+2 to roll", timing = "pre_roll", energy = -1, -- costs 1 energy @@ -101,7 +101,7 @@ cards = {{ e.roll_mod = e.roll_mod - 2 end }, { - name = "Reckless", + name = "Fury", desc = "win/lose double dmg", timing = "pre_roll", energy = -1, -- reduced from -2 @@ -110,7 +110,7 @@ cards = {{ e.mult = e.mult * 2 end }, { - name = "Cautious", + name = "Caution", desc = "win/lose half dmg", timing = "pre_roll", energy = 0, -- reduced from +1 since we get +1 per turn @@ -271,7 +271,7 @@ cards = {{ end end }, { - name = "Fury", + name = "Impulse", desc = "+0.5 dmg per hp missing", timing = "pre_roll", energy = -1, -- reduced from -1 @@ -316,7 +316,7 @@ cards = {{ }} enemy_cards = {{ - name = "Str", + name = "Bless", desc = "+2 to roll", timing = "pre_roll", energy = -1, @@ -332,7 +332,7 @@ enemy_cards = {{ p.roll_mod = p.roll_mod - 2 end }, { - name = "2x", + name = "Fury", desc = "win/lose double dmg", timing = "pre_roll", energy = -2, @@ -341,7 +341,7 @@ enemy_cards = {{ p.mult = p.mult * 2 end }, { - name = "0.5x", + name = "Caution", desc = "win/lose half dmg", timing = "pre_roll", energy = 1, @@ -703,7 +703,7 @@ function draw_health_bars() -- Show shield sprite if player has shield if player.shield and player.shield > 0 then for i = 1, player.shield do - spr(16, 4 + (i - 1) * 8, 22, 0) + spr(16, 44 + (i - 1) * 8, 12, 0) end end end @@ -822,6 +822,11 @@ function TIC() energy = 0 } enemy = get_enemy(level) + -- Clear card displays for new level + current_card = nil + enemy_card = nil + previous_card = nil + previous_enemy_card = nil initialize_deck() draw_hand() phase = "choose" @@ -960,19 +965,19 @@ function TIC() if enemy.hp <= 0 and player.hp > 0 then local victory_text = "You defeated " .. enemy.name .. "!" local victory_x = 120 - (#victory_text * 3) -- center text (6 pixel font, so 3 pixels per char from center) - print(victory_text, victory_x, 40, 6) + print(victory_text, victory_x, 60, 6) local continue_text = "Press Z to choose new card" local continue_x = 120 - (#continue_text * 3) - print(continue_text, continue_x, 80, 9) + print(continue_text, continue_x, 100, 9) else local defeat_text = enemy.name .. " defeated you!" local defeat_x = 120 - (#defeat_text * 3) - print(defeat_text, defeat_x, 40, 2) + print(defeat_text, defeat_x, 60, 2) local restart_text = "Press X to restart" local restart_x = 120 - (#restart_text * 3) - print(restart_text, restart_x, 60, 14) + print(restart_text, restart_x, 100, 14) end if btnp(4) and enemy.hp <= 0 and player.hp > 0 then -- Victory - go to card selection @@ -990,6 +995,11 @@ function TIC() energy = 0 } enemy = get_enemy(level) + -- Clear card displays for new level + current_card = nil + enemy_card = nil + previous_card = nil + previous_enemy_card = nil initialize_deck() draw_hand() phase = "choose" @@ -1006,6 +1016,11 @@ function TIC() energy = 0 } enemy = get_enemy(level) + -- Clear card displays on restart + current_card = nil + enemy_card = nil + previous_card = nil + previous_enemy_card = nil msg = "" initialize_deck() draw_hand() -- 2.20.1 From 442a5786b75dfad48344610ac3169325f8fb70ff Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Thu, 9 Oct 2025 21:22:33 +1300 Subject: [PATCH 13/15] feat: two turn card effects --- lucksmith.lua | 64 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 53 insertions(+), 11 deletions(-) diff --git a/lucksmith.lua b/lucksmith.lua index 1c3e15d..2984296 100644 --- a/lucksmith.lua +++ b/lucksmith.lua @@ -61,7 +61,9 @@ damage_applied = false current_damage = {player = 0, enemy = 0} -- store damage for display pending_effects = { player = {}, - enemy = {} + enemy = {}, + previous_player = {}, + previous_enemy = {} } -- Card tracking for two-round strategy previous_card = nil @@ -559,6 +561,7 @@ draw_hand() -- === CORE TURN LOGIC === function apply_effects(timing, player_won) + -- Apply current card effects for _, effect in ipairs(pending_effects.player) do if effect.timing == timing then if timing == "post_result" then @@ -568,6 +571,19 @@ function apply_effects(timing, player_won) end end end + + -- Apply previous card effects if they exist + for _, effect in ipairs(pending_effects.previous_player) do + if effect.timing == timing then + if timing == "post_result" then + effect.use(player, enemy, player_won) + else + effect.use(player, enemy) + end + end + end + + -- Apply current enemy card effects for _, effect in ipairs(pending_effects.enemy) do if effect.timing == timing then if timing == "post_result" then @@ -577,12 +593,21 @@ function apply_effects(timing, player_won) end end end -end -function start_turn(card) - -- Store previous cards before setting new ones - previous_card = current_card - previous_enemy_card = enemy_card + -- Apply previous enemy card effects if they exist + for _, effect in ipairs(pending_effects.previous_enemy) do + if effect.timing == timing then + if timing == "post_result" then + effect.use(player, enemy, player_won) + else + effect.use(player, enemy) + end + end + end +end + +function start_turn(card) + -- Don't store previous cards here anymore - they're already set when returning to choose phase current_card = card enemy_card = enemy_cards[math.random(#enemy_cards)] @@ -595,9 +620,11 @@ function start_turn(card) end hand = {} - -- Store effects for proper timing + -- Store effects for proper timing - both current and previous cards pending_effects.player = {card} pending_effects.enemy = {enemy_card} + pending_effects.previous_player = previous_card and {previous_card} or {} + pending_effects.previous_enemy = previous_enemy_card and {previous_enemy_card} or {} -- Apply immediate effects apply_effects("immediate") @@ -642,8 +669,10 @@ function draw_hud() -- Draw card play boxes at top -- Player card boxes (left side) - rectb(4, 20, 40, 16, 2) -- Current player card - if current_card then + rectb(4, 20, 40, 16, phase == "choose" and 8 or 2) -- Current player card (or empty slot) + if phase == "choose" then + print("Next", 16, 25, 8, false, 1, true) + elseif current_card then print(current_card.name, 6, 25, 2, false, 1, true) end @@ -658,8 +687,10 @@ function draw_hud() print(previous_enemy_card.name, 157, 25, 8, false, 1, true) end - rectb(196, 20, 40, 16, 6) -- Current enemy card - if enemy_card then + rectb(196, 20, 40, 16, phase == "choose" and 8 or 6) -- Current enemy card (or empty slot) + if phase == "choose" then + print("Next", 208, 25, 8, false, 1, true) + elseif enemy_card then print(enemy_card.name, 198, 25, 6, false, 1, true) end end @@ -956,6 +987,13 @@ function TIC() -- Reset damage display current_damage.player = 0 current_damage.enemy = 0 + + -- Move current cards to previous when returning to choose phase + previous_card = current_card + previous_enemy_card = enemy_card + current_card = nil + enemy_card = nil + draw_hand() -- Draw new hand from deck phase = (enemy.hp <= 0 or player.hp <= 0) and "game_over" or "choose" phase_time = 0 @@ -1069,4 +1107,8 @@ end -- -- 000:1a1c2c5d275db13e53ef7d57ffcd75a7f07038b76425717929366f3b5dc941a6f673eff7f4f4f494b0c2566c86333c57 -- +-- 000:1a1c2c5d275db13e53ef7d57ffcd75a7f07038b76425717929366f3b5dc941a6f673eff7f4f4f494b0c2566c86333c57 +-- +-- 000:1a1c2c5d275db13e53ef7d57ffcd75a7f07038b76425717929366f3b5dc941a6f673eff7f4f4f494b0c2566c86333c57 +-- -- 2.20.1 From 6a7187fb92216d2dccadca808c00232ea96627be Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Thu, 9 Oct 2025 21:26:49 +1300 Subject: [PATCH 14/15] feat: fix some display issues --- lucksmith.lua | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lucksmith.lua b/lucksmith.lua index 2984296..386c799 100644 --- a/lucksmith.lua +++ b/lucksmith.lua @@ -157,13 +157,14 @@ cards = {{ p.rage = (p.rage or 0) + 1 -- add rage bonus end }, { - name = "Tier", - desc = "if tie, you win", + name = "Break", + desc = "if tied, you win", timing = "post_result", energy = -1, -- reduced from -2 use = function(p, e, player_won) if player_won == nil then -- tie occurred e.hp = e.hp - (2 * p.mult) + current_damage.enemy = current_damage.enemy + (2 * p.mult) -- show damage taken end end }, { @@ -181,6 +182,7 @@ cards = {{ energy = 0, -- reduced from -1 use = function(p, e, player_won) e.hp = e.hp - 1 + current_damage.enemy = current_damage.enemy + 1 -- show damage taken end }, { name = "Spike", @@ -258,6 +260,7 @@ cards = {{ use = function(p, e, player_won) if player_won == true then p.hp = math.min(10, p.hp + 1) + current_damage.player = current_damage.player - 1 -- show healing end end }, { @@ -298,6 +301,7 @@ cards = {{ use = function(p, e) p.mult = p.mult * 2 p.hp = p.hp - 1 + current_damage.player = current_damage.player + 1 -- show damage taken end }, { name = "Focus", @@ -313,6 +317,7 @@ cards = {{ timing = "immediate", energy = 1, -- gives 1 energy (net +2 with the +1 per turn) use = function(p, e) + current_damage.player = current_damage.player - 1 -- show healing p.hp = math.min(10, p.hp + 1) end }} @@ -397,6 +402,7 @@ enemy_cards = {{ if player_won == nil then -- tie occurred -- Enemy wins the tie, so player takes damage p.hp = p.hp - (2 * e.mult) + current_damage.player = current_damage.player + (2 * e.mult) -- show damage taken end end }} -- 2.20.1 From 3a96f4d3aac172d16e298b91a20261d91a6af614 Mon Sep 17 00:00:00 2001 From: Nick Koirala Date: Fri, 10 Oct 2025 13:27:35 +1300 Subject: [PATCH 15/15] feat: dice art implements, sword art drawn --- lucksmith.lua | 126 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 94 insertions(+), 32 deletions(-) diff --git a/lucksmith.lua b/lucksmith.lua index 386c799..72b95e4 100644 --- a/lucksmith.lua +++ b/lucksmith.lua @@ -664,13 +664,18 @@ function draw_hud() -- Draw energy sprites for i = 1, player.energy do local x = -4 + (8 * i) - spr(17, x, 12, 0) + spr(17, x, 10, 0) + end + + for i = player.energy + 1, 5 do + local x = -4 + (8 * i) + spr(18, x, 10, 0) end -- Draw deck info - spr(18, 220, 115, 0) + spr(4, 220, 115, 0) print(#draw_pile, 230, 116, 10, false, 1, true) - spr(19, 220, 125, 0) + spr(5, 220, 125, 0) print(#discard_pile, 230, 126, 14, false, 1, true) -- Draw card play boxes at top @@ -888,20 +893,26 @@ function TIC() phase_time = 0 end - card_text = "You played " .. current_card.name - enemy_card_text = enemy.name .. " played " .. enemy_card.name + card_text = ""--"You played " .. current_card.name + enemy_card_text = ""--enemy.name .. " played " .. enemy_card.name print(card_text, 4, 40, 2) print(enemy_card_text, 4, 50, 6) - -- show rolls - roll_text = "You roll " .. player.display_roll .. " / " .. enemy.name .. " rolls " .. enemy.display_roll - print(roll_text, 4, 60, 12) + -- show dice rolls as sprites + local player_dice_sprite = 256 + (player.display_roll - 1) * 2 + local enemy_dice_sprite = 288 + (enemy.display_roll - 1) * 2 + spr(player_dice_sprite, 50, 50, 0, 1, 0, 0, 2, 2) -- player dice on left, 16x16 + spr(enemy_dice_sprite, 150, 50, 0, 1, 0, 0, 2, 2) -- enemy dice on right, 16x16 elseif phase == "mod" then print(card_text, 4, 40, 2) print(enemy_card_text, 4, 50, 6) - print(roll_text, 4, 60, 14) + -- show dice rolls as sprites + local player_dice_sprite = 256 + (player.display_roll - 1) * 2 + local enemy_dice_sprite = 288 + (enemy.display_roll - 1) * 2 + spr(player_dice_sprite, 50, 50, 0, 1, 0, 0, 2, 2) -- player dice on left, 16x16 + spr(enemy_dice_sprite, 150, 50, 0, 1, 0, 0, 2, 2) -- enemy dice on right, 16x16 mod_text = "mods applied: +" .. player.roll_mod .. " / " .. enemy.roll_mod - print(mod_text, 4, 70, 12) + print(mod_text, 4, 80, 12) phase_time = phase_time + 1 if phase_time > 60 then phase = "total" @@ -911,9 +922,13 @@ function TIC() current_damage.player, current_damage.enemy = 0, 0 -- reset damage display print(card_text, 4, 40, 2) print(enemy_card_text, 4, 50, 6) - print(roll_text, 4, 60, 14) - print(mod_text, 4, 70, 14) - print("Total " .. player.total .. " / " .. enemy.total, 4, 80, 12) + -- show dice rolls as sprites + local player_dice_sprite = 256 + (player.display_roll - 1) * 2 + local enemy_dice_sprite = 288 + (enemy.display_roll - 1) * 2 + spr(player_dice_sprite, 50, 50, 0, 1, 0, 0, 2, 2) -- player dice on left, 16x16 + spr(enemy_dice_sprite, 150, 50, 0, 1, 0, 0, 2, 2) -- enemy dice on right, 16x16 + print(mod_text, 4, 80, 14) + print("Total " .. player.total .. " / " .. enemy.total, 4, 90, 12) phase_time = phase_time + 1 if phase_time > 120 then phase = "result" @@ -922,9 +937,13 @@ function TIC() elseif phase == "result" then print(card_text, 4, 40, 2) print(enemy_card_text, 4, 50, 6) - print(roll_text, 4, 60, 14) - print(mod_text, 4, 70, 14) - print("Total " .. player.total .. " / " .. enemy.total, 4, 80, 14) + -- show dice rolls as sprites + local player_dice_sprite = 256 + (player.display_roll - 1) * 2 + local enemy_dice_sprite = 288 + (enemy.display_roll - 1) * 2 + spr(player_dice_sprite, 50, 50, 0, 1, 0, 0, 2, 2) -- player dice on left, 16x16 + spr(enemy_dice_sprite, 150, 50, 0, 1, 0, 0, 2, 2) -- enemy dice on right, 16x16 + print(mod_text, 4, 80, 14) + print("Total " .. player.total .. " / " .. enemy.total, 4, 90, 14) local msgtxt = "" local player_won = nil if player.total > enemy.total then @@ -979,7 +998,7 @@ function TIC() damage_applied = true local color = player_won == true and 2 or (player_won == false and 6 or 9) - print(msgtxt, 4, 90, color) + print(msgtxt, 4, 100, color) if btnp(4) then -- reset mods & back to choose @@ -1081,12 +1100,68 @@ end -- 001:0ff00ff0f22ff33ff22f223ff222223f0f2222f000f22f00000ff00000000000 -- 002:0ff00ff0f66ff55ff66f665ff666665f0f6666f000f66f00000ff00000000000 -- 003:0ff00ff0feeffddffeefeedffeeeeedf0feeeef000feef00000ff00000000000 +-- 004:0aaaaaa00aa99aa00a9999a00a9999a00a9999a00a9999a00aa99aa00aaaaaa0 +-- 005:0eeeeee00eeffee00effffe00effffe00effffe00effffe00eeffee00eeeeee0 -- 016:0011110001333310133223311333233113323331013323100013310000011000 -- 017:0000000000333300033443300344c43003444430033443300033330000000000 --- 018:0aaaaaa00aa99aa00a9999a00a9999a00a9999a00a9999a00aa99aa00aaaaaa0 --- 019:0eeeeee00eeffee00effffe00effffe00effffe00effffe00eeffee00eeeeee0 +-- 018:0000000000eeee000eeddee00eddcde00edddde00eeddee000eeee0000000000 +-- 019:0006600000666600066666600666666000066000000660000006600000066000 +-- 020:0002200000022000000220000002200002222220022222200022220000022000 +-- 021:3300000034300000034300000034300100034110000012100000112100010011 +-- 022:ee000000ede000000ede000000ede00f000edff00000f2f00000ff2f000f00ff -- +-- +-- 000:0000000000022222002222220222222202222222022222220222222f022222ff +-- 001:000000002222200022222200222222202222222022222220f2222220ff222220 +-- 002:000000000002222200222222022f222202fff22202fff222022f222202222222 +-- 003:0000000022222000222222002222222022222220222222202222222022222220 +-- 004:000000000002222200222222022f222202fff22202fff222022f222f022222ff +-- 005:000000002222200022222200222222202222222022222220f2222220ff222220 +-- 006:000000000002222200222222022f222202fff22202fff222022f222202222222 +-- 007:0000000022222000222222002222f220222fff20222fff202222f22022222220 +-- 008:000000000002222200222222022f222202fff22202fff222022f222f022222ff +-- 009:0000000022222000222222002222f220222fff20222fff20f222f220ff222220 +-- 010:000000000002222200222222022f222f02fff2ff02fff2ff022f222202222222 +-- 011:0000000022222000222222002222f220ff2fff20ff2fff20f222f22022222220 +-- 016:022222ff0222222f022222220222222202222222002222220002222200000000 +-- 017:ff222220f2222220222222202222222022222220222222002222200000000000 +-- 018:0222222202222222022222220222222202222222002222220002222200000000 +-- 019:2222222022222220222f222022fff22022fff220222f22002222200000000000 +-- 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 +-- + -- -- 000:00000000ffffffff00000000ffffffff -- 001:0123456789abcdeffedcba9876543210 @@ -1104,17 +1179,4 @@ end -- -- 000:1a1c2c5d275db13e53ef7d57ffcd75a7f07038b76425717929366f3b5dc941a6f673eff7f4f4f494b0c2566c86333c57 -- --- --- 000:100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 --- - --- --- 000:1a1c2c5d275db13e53ef7d57ffcd75a7f07038b76425717929366f3b5dc941a6f673eff7f4f4f494b0c2566c86333c57 --- --- 000:1a1c2c5d275db13e53ef7d57ffcd75a7f07038b76425717929366f3b5dc941a6f673eff7f4f4f494b0c2566c86333c57 --- --- 000:1a1c2c5d275db13e53ef7d57ffcd75a7f07038b76425717929366f3b5dc941a6f673eff7f4f4f494b0c2566c86333c57 --- --- 000:1a1c2c5d275db13e53ef7d57ffcd75a7f07038b76425717929366f3b5dc941a6f673eff7f4f4f494b0c2566c86333c57 --- -- 2.20.1