| |
| import { G } from "./state.js"; |
| import { confettiBurst, heartFloat, moraleWave, revenueRain } from "./particles.js"; |
| import { sfx } from "./audio.js"; |
|
|
| export function dim(on) { G.els.dim.classList.toggle("hidden", !on); } |
|
|
| export function redFlash() { |
| const el = G.els.flash; |
| el.classList.remove("on"); void el.offsetWidth; el.classList.add("on"); |
| } |
|
|
| export function edgePulse(on) { G.els["edge-pulse"].classList.toggle("on", on); } |
|
|
| export function hrStamp() { |
| const el = G.els.stamp; |
| el.classList.remove("hidden"); |
| el.style.animation = "none"; void el.offsetWidth; el.style.animation = ""; |
| sfx.stamp(); |
| setTimeout(() => el.classList.add("hidden"), 950); |
| } |
|
|
| export function wipe(midCallback) { |
| const el = G.els.wipe; |
| el.classList.remove("go"); void el.offsetWidth; el.classList.add("go"); |
| setTimeout(midCallback, 350); |
| setTimeout(() => el.classList.remove("go"), 750); |
| } |
|
|
| export function fadeBlack(midCallback, hold = 1000) { |
| const el = G.els.wipe; |
| el.style.transition = "transform .01s"; |
| el.style.transform = "translateX(0)"; |
| el.style.opacity = 0; |
| el.animate([{ opacity: 0 }, { opacity: 1 }], { duration: 400, fill: "forwards" }); |
| setTimeout(() => { |
| midCallback(); |
| el.animate([{ opacity: 1 }, { opacity: 0 }], |
| { duration: 400, fill: "forwards" }); |
| setTimeout(() => { el.style.transform = "translateX(-100%)"; |
| el.style.opacity = 1; el.style.transition = ""; }, 450); |
| }, 400 + hold); |
| } |
|
|
| |
| const NPC_ANIM_POSE = { |
| npc_happy: "idle", npc_angry: "shake", npc_confused: "idle", |
| npc_devastated: "headdown", npc_celebrating: "idle", npc_hiding: "slump", |
| npc_smug: "lean", npc_suspicious: "lean", npc_crying: "slump", |
| npc_grateful: "idle", |
| }; |
|
|
| export function playOutcome(trigger, npcId, world) { |
| const npc = npcId && world.npcs[npcId]; |
| switch (trigger) { |
| case "disaster_flash": redFlash(); sfx.disaster(); break; |
| case "revenue_rain": revenueRain(); sfx.moneyUp(); break; |
| case "heart_float": |
| if (npc) heartFloat(npc.x, npc.y - 44); sfx.gift(); break; |
| case "bribery_envelope": sfx.click(); break; |
| case "hr_stamp": hrStamp(); break; |
| case "morale_drop_wave": moraleWave(world.npcs); sfx.moneyDown(); break; |
| case "confetti_burst": confettiBurst(); sfx.win(); break; |
| default: |
| if (npc && NPC_ANIM_POSE[trigger]) { |
| npc.setPose(NPC_ANIM_POSE[trigger]); |
| if (trigger === "npc_celebrating" || trigger === "npc_happy") { |
| npc.sprite.animate( |
| [{ transform: "translateY(0)" }, { transform: "translateY(-6px)" }, |
| { transform: "translateY(0)" }], |
| { duration: 320, iterations: 2, easing: "steps(3)" }); |
| } |
| } |
| } |
| } |
|
|