diff --git a/src/data/cards.js b/src/data/cards.js index 74ee1a7..a725776 100644 --- a/src/data/cards.js +++ b/src/data/cards.js @@ -41,9 +41,9 @@ export const CARDS = { card.cost = 0; card.effect(ctx); card.cost = savedCost; - ctx.log(`Replayed ${card.name} for free!`); + ctx.log(`Macro replays ${card.name} at no cost!`); } else { - ctx.log("No valid card to replay."); + ctx.log("Macro fizzles - no valid card to replay."); } } } @@ -113,7 +113,7 @@ export const CARDS = { const prevHp = ctx.enemy.hp; ctx.deal(ctx.enemy, ctx.scalarFromWeak(5)); if (prevHp > 0 && ctx.enemy.hp <= 0) { - ctx.log("Recursion triggered!"); + ctx.log("Recursion activates and strikes again!"); ctx.enemy.hp = 1; ctx.deal(ctx.enemy, ctx.scalarFromWeak(5)); @@ -139,7 +139,7 @@ export const CARDS = { effect: (ctx) => { ctx.draw(1); - ctx.log("Reviewed code, drew 1 card."); + ctx.log("Code review reveals useful insights. You draw a card."); } }, @@ -154,7 +154,7 @@ export const CARDS = { if (ctx.player.hp <= ctx.player.maxHp * 0.5) { ctx.deal(ctx.enemy, ctx.scalarFromWeak(10)); } else { - ctx.log("Can only hotfix in emergencies!"); + ctx.log("Hotfix can only be deployed when HP is below 50%!"); } } }, @@ -180,7 +180,7 @@ export const CARDS = { effect: (ctx) => { if (ctx.intentIsAttack()) { ctx.player.block += 8; - ctx.log("Tests passed! Gained Block."); + ctx.log("Unit tests pass! You feel more confident and gain block."); } } }, @@ -190,7 +190,7 @@ export const CARDS = { effect: (ctx) => { ctx.deal(ctx.enemy, ctx.scalarFromWeak(25)); ctx.player.hp = Math.max(1, ctx.player.hp - 5); - ctx.log("Deployed to prod... at what cost?"); + ctx.log("Production deployment succeeds, but at what cost to your health?"); } }, @@ -199,7 +199,7 @@ export const CARDS = { id: "sugar_crash", name: "Sugar Crash", cost: 1, type: "curse", text: "Unplayable. -1 Energy when drawn.", effect: (ctx) => { ctx.player.energy = Math.max(0, ctx.player.energy - 1); - ctx.log("Sugar crash! -1 Energy"); + ctx.log("The sugar crash hits hard, draining your energy!"); } }, }; diff --git a/src/data/enemies.js b/src/data/enemies.js index bbcf7c1..7f4a741 100644 --- a/src/data/enemies.js +++ b/src/data/enemies.js @@ -24,7 +24,7 @@ export const ENEMIES = { id: "infinite_loop", name: "Beastco", maxHp: 35, avatar: "assets/avatars/2.png", // Dizzy/confused character background: "assets/backgrounds/throne room.png", - ai: (turn) => ({ type: "attack", value: 4 }), // Always attacks for small damage + ai: (turn) => ({ type: "attack", value: 4 }), }, merge_conflict_enemy: { id: "merge_conflict_enemy", name: "Codegirl", maxHp: 50, @@ -34,7 +34,7 @@ export const ENEMIES = { onDebuff: (ctx) => { ctx.enemy.hp = Math.min(ctx.enemy.maxHp, ctx.enemy.hp + 8); - ctx.log("Merge Conflict splits! Enemy heals 8!"); + ctx.log("Codegirl resolves the merge conflict and heals 8 HP!"); } }, bug_404: { @@ -68,6 +68,6 @@ export const ENEMIES = { if (cyc === 3) return { type: "block", value: 0 }; // Crash β heal return { type: "attack", value: 22 }; // Burst }, - onBlock: (ctx) => { ctx.enemy.hp = Math.min(ctx.enemy.maxHp, ctx.enemy.hp + 8); ctx.log("Bug crashes, heals 8!"); } + onBlock: (ctx) => { ctx.enemy.hp = Math.min(ctx.enemy.maxHp, ctx.enemy.hp + 8); ctx.log("Teej crashes and reboots, healing 8 HP!"); } } }; diff --git a/src/data/relics.js b/src/data/relics.js index 1a49411..d407944 100644 --- a/src/data/relics.js +++ b/src/data/relics.js @@ -17,7 +17,7 @@ export const RELICS = { coffee_thermos: { id: "coffee_thermos", name: "Terminal Coffee Thermos", text: "Start each fight with Coffee Rush.", - hooks: { onBattleStart: (ctx) => { ctx.player.energy += 2; ctx.log("Thermos: +2 energy") } } + hooks: { onBattleStart: (ctx) => { ctx.player.energy += 2; ctx.log("Your coffee thermos provides an energizing boost!") } } }, cpp_compiler: { id: "cpp_compiler", name: "Haskell", @@ -34,7 +34,7 @@ export const RELICS = { hooks: { onBattleStart: (ctx) => { ctx.applyWeak(ctx.enemy, 1); - ctx.log("Worst Streamer Award: Enemy starts Weak!"); + ctx.log("Your Worst Streamer Award intimidates the enemy, making them weak!"); } } }, diff --git a/src/engine/battle.js b/src/engine/battle.js index c1fea92..da98c6a 100644 --- a/src/engine/battle.js +++ b/src/engine/battle.js @@ -13,8 +13,8 @@ export function createBattle(ctx, enemyId) { const relicCtx = { ...ctx, draw: (n) => draw(ctx.player, n), - applyWeak: (who, amt) => { who.weak = (who.weak || 0) + amt; ctx.log(`Weak +${amt}`) }, - applyVulnerable: (who, amt) => { who.vuln = (who.vuln || 0) + amt; ctx.log(`Vulnerable +${amt}`) } + applyWeak: (who, amt) => { who.weak = (who.weak || 0) + amt; ctx.log(`${who === ctx.player ? 'You are' : ctx.enemy.name + ' is'} weakened for ${amt} turn${amt > 1 ? 's' : ''}.`) }, + applyVulnerable: (who, amt) => { who.vuln = (who.vuln || 0) + amt; ctx.log(`${who === ctx.player ? 'You are' : ctx.enemy.name + ' is'} vulnerable for ${amt} turn${amt > 1 ? 's' : ''}.`) } }; for (const r of ctx.relicStates) r.hooks?.onBattleStart?.(relicCtx, r.state); @@ -30,7 +30,7 @@ export function startPlayerTurn(ctx) { const relicCtx = { ...ctx, draw: (n) => draw(ctx.player, n) }; for (const r of ctx.relicStates) r.hooks?.onTurnStart?.(relicCtx, r.state); - ctx.log(`Your turn. Energy ${ctx.player.energy}.`); + ctx.log(`Your turn begins. You have ${ctx.player.energy} energy to spend.`); ctx.render(); } @@ -44,11 +44,11 @@ export function playCard(ctx, handIndex) { if (ctx.flags.nextCardFree) { actualCost = 0; ctx.flags.nextCardFree = false; - ctx.log("Infinite Vim: Card costs 0!"); + ctx.log("Infinite Vim makes your next card free!"); } - if (ctx.player.energy < actualCost) { ctx.log("Not enough energy."); return; } - if (card.oncePerFight && card._used) { ctx.log("That macro already ran."); return; } + if (ctx.player.energy < actualCost) { ctx.log(`You need ${actualCost} energy but only have ${ctx.player.energy}.`); return; } + if (card.oncePerFight && card._used) { ctx.log(`${card.name} can only be used once per fight.`); return; } ctx.player.energy -= actualCost; ctx.lastCard = card.id; @@ -79,7 +79,7 @@ export function playCard(ctx, handIndex) { if (!card.exhaust) { ctx.player.discard.push(used.id); } else { - ctx.log(`${used.name} exhausted.`); + ctx.log(`${used.name} is exhausted and removed from the fight.`); } } @@ -102,10 +102,10 @@ export function enemyTurn(ctx) { } else if (e.intent.type === "block") { ENEMIES[e.id].onBlock?.(ctx, e.intent.value); e.block += e.intent.value; - ctx.log(`${e.name} gains ${e.intent.value} Block.`); + ctx.log(`${e.name} defends and gains ${e.intent.value} block.`); } else if (e.intent.type === "debuff") { ENEMIES[e.id].onDebuff?.(ctx, e.intent.value); - ctx.log(`${e.name} applies a debuff.`); + ctx.log(`${e.name} casts a debuffing spell.`); } @@ -123,7 +123,7 @@ export function enemyTurn(ctx) { function applyDamage(ctx, target, raw, label) { if (target === ctx.enemy && ctx.enemy.id === "bug_404" && ctx.enemy.turn % 3 === 0) { - ctx.log("404 Bug dodges the attack!"); + ctx.log(`${ctx.enemy.name} phases out and dodges your attack completely!`); return; } @@ -136,7 +136,14 @@ function applyDamage(ctx, target, raw, label) { const hpLoss = Math.max(0, dmg - blocked); target.block -= blocked; target.hp = clamp(target.hp - hpLoss, 0, target.maxHp); - ctx.log(`${label}: ${dmg} β Block ${blocked} β HP -${hpLoss}`); + const isPlayer = target === ctx.player; + if (blocked > 0 && hpLoss > 0) { + ctx.log(`${label} for ${dmg} damage. ${blocked} blocked, ${hpLoss} damage taken.`); + } else if (blocked > 0) { + ctx.log(`${label} for ${dmg} damage, but it's completely blocked!`); + } else { + ctx.log(`${label} for ${dmg} damage!`); + } if (hpLoss > 0 && ctx.showDamageNumber) { @@ -154,16 +161,16 @@ export function makeBattleContext(root) { log: (m) => root.log(m), render: () => root.render(), intentIsAttack: () => root.enemy.intent.type === "attack", - deal: (target, amount) => applyDamage(root, target, amount, "You hit"), - applyWeak: (who, amt) => { who.weak = (who.weak || 0) + amt; root.log(`Weak +${amt}`) }, - applyVulnerable: (who, amt) => { who.vuln = (who.vuln || 0) + amt; root.log(`Vulnerable +${amt}`) }, + deal: (target, amount) => applyDamage(root, target, amount, target === root.enemy ? "You attack" : `${root.enemy.name} hits you`), + applyWeak: (who, amt) => { who.weak = (who.weak || 0) + amt; root.log(`${who === root.player ? 'You are' : root.enemy.name + ' is'} weakened for ${amt} turn${amt > 1 ? 's' : ''}.`) }, + applyVulnerable: (who, amt) => { who.vuln = (who.vuln || 0) + amt; root.log(`${who === root.player ? 'You are' : root.enemy.name + ' is'} vulnerable for ${amt} turn${amt > 1 ? 's' : ''}.`) }, forceEndTurn: () => endTurn(root), promptExhaust: async (count) => { // MVP: exhaust first N non-basics while (count-- > 0 && root.player.hand.length > 0) { const idx = root.player.hand.findIndex(c => !["strike", "defend"].includes(c.id)); const drop = idx >= 0 ? idx : 0; const [ex] = root.player.hand.splice(drop, 1); - root.log(`Exhausted ${ex.name}`); + root.log(`${ex.name} is exhausted and removed from the fight.`); } }, scalarFromWeak: (base) => (root.player.weak > 0 ? Math.floor(base * 0.75) : base), diff --git a/src/ui/render.js b/src/ui/render.js index fc042d9..02a7236 100644 --- a/src/ui/render.js +++ b/src/ui/render.js @@ -31,8 +31,8 @@ export function showDamageNumber(damage, target, isPlayer = false) { } export async function renderBattle(root) { - const app = root.app; - const p = root.player, e = root.enemy; + const app = root.app; + const p = root.player, e = root.enemy; const { ENEMIES } = await import("../data/enemies.js"); @@ -40,13 +40,13 @@ export async function renderBattle(root) { const backgroundImage = enemyData?.background || null; - const intentInfo = { + const intentInfo = { attack: { emoji: '', text: `Will attack for ${e.intent.value} damage`, color: 'danger' }, block: { emoji: '', text: `Will gain ${e.intent.value} block`, color: 'info' }, debuff: { emoji: '', text: 'Will apply a debuff', color: 'warning' } }[e.intent.type] || { emoji: '', text: 'Unknown intent', color: 'neutral' }; - app.innerHTML = ` + app.innerHTML = `