{"id":"fxkvpi","deleted":false,"future_paste":false,"expired":false,"language":"html","created_at":"2026-09-05 18:32:00","expires_at":null,"content":"<!DOCTYPE html>\r\n<html lang=\"de\">\r\n<head>\r\n<meta charset=\"UTF-8\">\r\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no\">\r\n<title>HYPERSTITION: SHENZHEN<\/title>\r\n<style>\r\n  * { \r\n    box-sizing: border-box; \r\n    touch-action: manipulation;\r\n  }\r\n  html, body {\r\n    width: 100%;\r\n    height: 100%;\r\n    overflow: hidden;\r\n    background: #020206;\r\n    color: #00ffcc;\r\n    font-family: 'Courier New', 'PingFang SC', 'Microsoft YaHei', monospace;\r\n    margin: 0;\r\n    padding: 6px;\r\n    display: flex;\r\n    justify-content: center;\r\n    align-items: flex-start;\r\n    user-select: none;\r\n    -webkit-user-select: none;\r\n  }\r\n  \r\n  #game-wrapper {\r\n    position: relative;\r\n    width: 100%;\r\n    max-width: 380px;\r\n    display: flex;\r\n    flex-direction: column;\r\n    gap: 5px;\r\n    justify-content: flex-start;\r\n  }\r\n\r\n  \/* CYBERPUNK CHINESE TITLE SCREEN *\/\r\n  #title-screen {\r\n    position: absolute;\r\n    top: 0; left: 0; right: 0; bottom: 0;\r\n    background: radial-gradient(circle at center, #0e051c 0%, #020208 100%);\r\n    border: 2px solid #ff0055;\r\n    box-shadow: inset 0 0 30px rgba(255, 0, 85, 0.5), 0 0 20px rgba(0, 255, 204, 0.3);\r\n    display: flex;\r\n    flex-direction: column;\r\n    justify-content: center;\r\n    align-items: center;\r\n    z-index: 500;\r\n    padding: 15px;\r\n    text-align: center;\r\n    overflow: hidden;\r\n  }\r\n\r\n  \/* CRT Scanline Overlay Effect *\/\r\n  #title-screen::before {\r\n    content: \" \";\r\n    display: block;\r\n    position: absolute;\r\n    top: 0; left: 0; bottom: 0; right: 0;\r\n    background: linear-gradient(rgba(18, 16, 16, 0) 50%, rgba(0, 0, 0, 0.35) 50%), linear-gradient(90deg, rgba(255, 0, 0, 0.05), rgba(0, 255, 0, 0.02), rgba(0, 0, 255, 0.05));\r\n    z-index: 2;\r\n    background-size: 100% 3px, 6px 100%;\r\n    pointer-events: none;\r\n  }\r\n\r\n  \/* Watermark Chinese Characters in Background *\/\r\n  .title-bg-kanji {\r\n    position: absolute;\r\n    font-size: 110px;\r\n    color: rgba(255, 0, 85, 0.05);\r\n    font-weight: 900;\r\n    z-index: 1;\r\n    pointer-events: none;\r\n    line-height: 0.9;\r\n    letter-spacing: -5px;\r\n  }\r\n\r\n  .title-main-box {\r\n    z-index: 3;\r\n    border-top: 1.5px solid #00ffcc;\r\n    border-bottom: 1.5px solid #00ffcc;\r\n    padding: 12px 10px;\r\n    width: 100%;\r\n    background: rgba(8, 3, 18, 0.75);\r\n    box-shadow: 0 0 15px rgba(0, 255, 204, 0.15);\r\n  }\r\n\r\n  .title-kanji-top {\r\n    font-size: 13px;\r\n    color: #ffcc00;\r\n    letter-spacing: 5px;\r\n    text-shadow: 0 0 8px #ffcc00;\r\n    margin-bottom: 4px;\r\n    font-weight: bold;\r\n  }\r\n\r\n  .title-glitch {\r\n    font-size: 21px;\r\n    font-weight: 900;\r\n    color: #ff0055;\r\n    text-shadow: 3px 0 #00ffcc, -2px 0 #ffcc00;\r\n    letter-spacing: 2px;\r\n    line-height: 1.1;\r\n    animation: glitch 1.6s infinite alternate;\r\n  }\r\n\r\n  .title-sub {\r\n    font-size: 11px;\r\n    color: #00ffcc;\r\n    margin-top: 6px;\r\n    letter-spacing: 2px;\r\n    text-shadow: 0 0 8px #00ffcc;\r\n    font-weight: bold;\r\n  }\r\n\r\n  .title-tags {\r\n    display: flex;\r\n    gap: 6px;\r\n    margin: 12px 0 6px 0;\r\n    z-index: 3;\r\n  }\r\n\r\n  .tag-badge {\r\n    font-size: 8px;\r\n    background: #160829;\r\n    border: 1px solid #ff0055;\r\n    color: #ff0055;\r\n    padding: 2px 6px;\r\n    border-radius: 2px;\r\n    letter-spacing: 1px;\r\n  }\r\n\r\n  .title-info {\r\n    z-index: 3;\r\n    font-size: 8px;\r\n    color: #8899a6;\r\n    margin: 10px 0 18px 0;\r\n    line-height: 1.5;\r\n    border-left: 2px solid #00ffcc;\r\n    padding-left: 8px;\r\n    text-align: left;\r\n    background: rgba(0, 0, 0, 0.4);\r\n    width: 100%;\r\n  }\r\n\r\n  .start-btn {\r\n    z-index: 3;\r\n    background: #ff0055;\r\n    border: 1.5px solid #00ffcc;\r\n    color: #020208;\r\n    font-family: inherit;\r\n    font-weight: 900;\r\n    font-size: 11px;\r\n    padding: 10px 22px;\r\n    cursor: pointer;\r\n    box-shadow: 0 0 15px rgba(255, 0, 85, 0.8);\r\n    letter-spacing: 1.5px;\r\n    animation: pulse 1.2s infinite alternate;\r\n  }\r\n  .start-btn:active {\r\n    background: #00ffcc;\r\n    color: #000;\r\n    box-shadow: 0 0 20px #00ffcc;\r\n  }\r\n\r\n  \/* GAME UI *\/\r\n  #ui-stats {\r\n    width: 100%;\r\n    display: grid;\r\n    grid-template-columns: repeat(4, 1fr);\r\n    gap: 2px;\r\n    font-weight: bold;\r\n    color: #ff0055;\r\n    font-size: 9px;\r\n    background: #08030f;\r\n    padding: 4px;\r\n    border: 1px solid #ff0055;\r\n    box-shadow: 0 0 6px rgba(255, 0, 85, 0.3);\r\n  }\r\n  #ui-stats div { text-align: center; white-space: nowrap; }\r\n  \r\n  #game-container {\r\n    position: relative;\r\n    width: 100%;\r\n  }\r\n\r\n  #map {\r\n    background: #000;\r\n    border: 1.5px solid #ff0055;\r\n    box-shadow: 0 0 8px rgba(255, 0, 85, 0.25);\r\n    padding: 2px;\r\n    width: 100%;\r\n    height: 250px;\r\n    display: grid;\r\n    grid-template-columns: repeat(22, 1fr);\r\n    grid-template-rows: repeat(14, 1fr);\r\n    align-items: center;\r\n    justify-items: center;\r\n  }\r\n\r\n  .t {\r\n    width: 100%;\r\n    height: 100%;\r\n    display: flex;\r\n    align-items: center;\r\n    justify-content: center;\r\n    font-size: 11px;\r\n    font-weight: bold;\r\n    line-height: 1;\r\n  }\r\n\r\n  \/* AIMING SKILL-CHECK MODAL *\/\r\n  #aim-modal {\r\n    display: none;\r\n    position: absolute;\r\n    top: 50%; left: 50%;\r\n    transform: translate(-50%, -50%);\r\n    width: 88%;\r\n    background: rgba(6, 2, 14, 0.95);\r\n    border: 2px solid #00ffcc;\r\n    box-shadow: 0 0 20px rgba(0, 255, 204, 0.6);\r\n    padding: 10px;\r\n    flex-direction: column;\r\n    align-items: center;\r\n    gap: 8px;\r\n    z-index: 200;\r\n    cursor: pointer;\r\n  }\r\n  #aim-title {\r\n    color: #ff0055;\r\n    font-size: 10px;\r\n    font-weight: bold;\r\n    letter-spacing: 1px;\r\n  }\r\n  #aim-bar-container {\r\n    width: 100%;\r\n    height: 22px;\r\n    background: #000;\r\n    border: 1px solid #00ffcc;\r\n    position: relative;\r\n    overflow: hidden;\r\n  }\r\n  #aim-target-zone {\r\n    position: absolute;\r\n    top: 0; bottom: 0;\r\n    background: rgba(0, 255, 204, 0.35);\r\n    border-left: 2px solid #00ffcc;\r\n    border-right: 2px solid #00ffcc;\r\n  }\r\n  #aim-cursor {\r\n    position: absolute;\r\n    top: 0; bottom: 0;\r\n    width: 4px;\r\n    background: #ff0055;\r\n    box-shadow: 0 0 8px #ff0055, 0 0 12px #ff0055;\r\n  }\r\n  #aim-instruction {\r\n    font-size: 9px;\r\n    color: #ffcc00;\r\n    font-weight: bold;\r\n    letter-spacing: 1px;\r\n  }\r\n\r\n  #shop-modal {\r\n    display: none;\r\n    position: absolute;\r\n    top: 4px; left: 4px; right: 4px; bottom: 4px;\r\n    background: rgba(4, 2, 10, 0.98);\r\n    border: 1.5px solid #ffcc00;\r\n    box-shadow: 0 0 15px rgba(255, 204, 0, 0.4);\r\n    padding: 6px;\r\n    flex-direction: column;\r\n    z-index: 100;\r\n  }\r\n  #shop-title {\r\n    color: #ffcc00;\r\n    font-size: 10px;\r\n    font-weight: bold;\r\n    text-align: center;\r\n    border-bottom: 1px dashed #ffcc00;\r\n    padding-bottom: 2px;\r\n    margin-bottom: 4px;\r\n  }\r\n  .shop-items {\r\n    display: flex;\r\n    flex-direction: column;\r\n    gap: 4px;\r\n    overflow-y: auto;\r\n    flex: 1;\r\n  }\r\n  .shop-btn {\r\n    background: #0a0a1a;\r\n    border: 1px solid #00ffcc;\r\n    color: #00ffcc;\r\n    padding: 4px 6px;\r\n    font-size: 9px;\r\n    font-family: inherit;\r\n    cursor: pointer;\r\n    text-align: left;\r\n    display: flex;\r\n    justify-content: space-between;\r\n  }\r\n  .shop-btn:active { background: #00ffcc; color: #000; }\r\n  .close-shop {\r\n    margin-top: 4px;\r\n    background: #ff0055;\r\n    color: #fff;\r\n    border: none;\r\n    padding: 5px;\r\n    font-weight: bold;\r\n    cursor: pointer;\r\n    text-align: center;\r\n    font-size: 10px;\r\n  }\r\n\r\n  #action-panel, #inventory-panel {\r\n    width: 100%;\r\n    display: flex;\r\n    gap: 3px;\r\n  }\r\n  .action-btn, .inv-slot {\r\n    flex: 1;\r\n    background: #0f0a1c;\r\n    border: 1px solid #00ffcc;\r\n    color: #ffcc00;\r\n    font-size: 9px;\r\n    padding: 5px 1px;\r\n    text-align: center;\r\n    cursor: pointer;\r\n    border-radius: 2px;\r\n    white-space: nowrap;\r\n    overflow: hidden;\r\n    text-overflow: ellipsis;\r\n    font-weight: bold;\r\n  }\r\n  .action-btn { background: #240a18; border-color: #ff0055; color: #ff0055; }\r\n  .action-btn:active, .inv-slot:active { background: #00ffcc; color: #000; }\r\n  \r\n  #log {\r\n    width: 100%;\r\n    height: 42px;\r\n    background: #05020c;\r\n    border: 1px solid #222;\r\n    color: #ffcc00;\r\n    font-size: 9px;\r\n    padding: 3px 5px;\r\n    overflow-y: auto;\r\n    line-height: 1.2;\r\n  }\r\n\r\n  .controls-wrapper {\r\n    display: flex;\r\n    justify-content: center;\r\n    margin-top: 2px;\r\n  }\r\n\r\n  .controls {\r\n    display: grid;\r\n    grid-template-columns: repeat(3, 1fr);\r\n    gap: 4px;\r\n    width: 170px;\r\n  }\r\n  .btn {\r\n    background: #0f0f24;\r\n    color: #00ffcc;\r\n    border: 1px solid #00ffcc;\r\n    padding: 7px 0;\r\n    font-size: 12px;\r\n    font-weight: bold;\r\n    text-align: center;\r\n    border-radius: 3px;\r\n    cursor: pointer;\r\n  }\r\n  .btn:active { background: #00ffcc; color: #000; }\r\n  \r\n  .p-player { color: #00ffcc; }\r\n  .p-psychotic { color: #ff0055; animation: blink 0.4s infinite; }\r\n  .e-triad { color: #ff3333; }\r\n  .e-ministry { color: #ffcc00; }\r\n  .e-drone { color: #ff00ff; }\r\n  .i-vendor { color: #ffcc00; text-shadow: 0 0 5px #ffcc00; }\r\n  .i-item { color: #00ff66; }\r\n  .i-exit { color: #00ffcc; text-shadow: 0 0 6px #00ffcc; font-size: 12px; }\r\n  .tile-wall { color: #3d1c3d; }\r\n  .tile-floor { color: #160f24; }\r\n  .fog-hidden { color: #000000; }\r\n  .fog-explored { color: #12081c; }\r\n  .stunned { color: #777777 !important; }\r\n\r\n  @keyframes glitch {\r\n    0% { transform: skew(0deg); }\r\n    80% { transform: skew(0deg); }\r\n    85% { transform: skew(3deg); }\r\n    90% { transform: skew(-3deg); }\r\n    100% { transform: skew(0deg); }\r\n  }\r\n\r\n  @keyframes pulse {\r\n    0% { transform: scale(1); box-shadow: 0 0 10px rgba(255, 0, 85, 0.6); }\r\n    100% { transform: scale(1.04); box-shadow: 0 0 20px rgba(255, 0, 85, 0.9); }\r\n  }\r\n\r\n  @keyframes blink { 0% { opacity: 1; } 50% { opacity: 0.2; } 100% { opacity: 1; } }\r\n<\/style>\r\n<\/head>\r\n<body>\r\n\r\n<div id=\"game-wrapper\">\r\n\r\n  <!-- CHINESE CYBERPUNK TITLE SCREEN -->\r\n  <div id=\"title-screen\">\r\n    <div class=\"title-bg-kanji\">\u8d85\u8ff7\u4fe1<br>\u6df1\u5733<\/div>\r\n    \r\n    <div class=\"title-main-box\">\r\n      <div class=\"title-kanji-top\">\u3010 \u8d85 \u8ff7 \u4fe1 \u3011<\/div>\r\n      <div class=\"title-glitch\">HYPERSTITION<\/div>\r\n      <div class=\"title-sub\">SHENZHEN \/\/ \u6df1\u5733<\/div>\r\n    <\/div>\r\n\r\n    <div class=\"title-tags\">\r\n      <span class=\"tag-badge\">\u52a0\u901f\u4e3b\u4e49<\/span>\r\n      <span class=\"tag-badge\">\u8d5b\u535a\u670b\u514b<\/span>\r\n      <span class=\"tag-badge\">\u7279\u533a S-01<\/span>\r\n    <\/div>\r\n\r\n    <div class=\"title-info\">\r\n      > SYSTEM: NEURAL INTERFACE ONLINE<br>\r\n      > LOCATION: SHENZHEN SEZ [\u6df1\u5733\u7279\u533a]<br>\r\n      > WARNING: \u4eba\u6027\u6d41\u5931 (HUMANITY DEPLETION)\r\n    <\/div>\r\n\r\n    <button class=\"start-btn\" onclick=\"startGame()\">[ \u7f51\u7edc\u63a5\u5165 \/\/ ACCESS ]<\/button>\r\n  <\/div>\r\n\r\n  <!-- GAME INTERFACE -->\r\n  <div id=\"ui-stats\">\r\n    <div id=\"stat-level\">ZONE: S-01<\/div>\r\n    <div id=\"stat-hp\">INT: 35<\/div>\r\n    <div id=\"stat-ram\">RAM: 4\/4<\/div>\r\n    <div id=\"stat-psyche\">HUM: 100%<\/div>\r\n    <div id=\"stat-food\">CAL: 100%<\/div>\r\n    <div id=\"stat-ammo\">AMMO: 8<\/div>\r\n    <div id=\"stat-atk\">GUN: 4<\/div>\r\n    <div id=\"stat-cred\">\u00a550<\/div>\r\n  <\/div>\r\n\r\n  <div id=\"game-container\">\r\n    <div id=\"map\"><\/div>\r\n    \r\n    <!-- AIMING SKILL CHECK OVERLAY -->\r\n    <div id=\"aim-modal\" onclick=\"resolveShot()\">\r\n      <div id=\"aim-title\">=== ZIELERFASSUNG \/\/ LOCK-ON ===<\/div>\r\n      <div id=\"aim-bar-container\">\r\n        <div id=\"aim-target-zone\"><\/div>\r\n        <div id=\"aim-cursor\"><\/div>\r\n      <\/div>\r\n      <div id=\"aim-instruction\">[F] \/ [SPACE] \/ TIPPE ZUM FEUERN<\/div>\r\n    <\/div>\r\n\r\n    <div id=\"shop-modal\">\r\n      <div id=\"shop-title\">=== SHENZHEN TAOBAO-LOOM [\u00a5] ===<\/div>\r\n      <div class=\"shop-items\">\r\n        <button class=\"shop-btn\" onclick=\"buyShopItem('Sheng-Stim', 35, 0)\"><span>[1] Sheng-Stim (+20 Int)<\/span><span>\u00a535<\/span><\/button>\r\n        <button class=\"shop-btn\" onclick=\"buyShopItem('Synth-Baozi', 15, 0)\"><span>[2] Synth-Baozi (+50% Cal)<\/span><span>\u00a515<\/span><\/button>\r\n        <button class=\"shop-btn\" onclick=\"buyShopItem('Mag-Rounds', 25, 0)\"><span>[3] Kinetic-Mag (+6 Ammo)<\/span><span>\u00a525<\/span><\/button>\r\n        <button class=\"shop-btn\" onclick=\"buyShopItem('Xeno-Blade', 110, 25)\"><span>[4] Xeno-Blade (+3 ATK)<\/span><span>\u00a5110 (-25% H)<\/span><\/button>\r\n        <button class=\"shop-btn\" onclick=\"buyShopItem('Subdermal-Weave', 110, 25)\"><span>[5] Subdermal (+15 HP)<\/span><span>\u00a5110 (-25% H)<\/span><\/button>\r\n        <button class=\"shop-btn\" onclick=\"buyShopItem('Teleoplex-Chip', 110, 25)\"><span>[6] Teleoplex (+2 RAM)<\/span><span>\u00a5110 (-25% H)<\/span><\/button>\r\n      <\/div>\r\n      <div class=\"close-shop\" onclick=\"closeShop()\">TRENNEN [\u00d8]<\/div>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <div id=\"action-panel\">\r\n    <div class=\"action-btn\" onclick=\"shootNearest()\">[F] KINETIK-SCHUSS<\/div>\r\n    <div class=\"action-btn\" onclick=\"hackEnemy()\">[H] OVERLOAD<\/div>\r\n  <\/div>\r\n\r\n  <div id=\"inventory-panel\">\r\n    <div class=\"inv-slot\" onclick=\"useItem(0)\" id=\"inv-0\">[1] -<\/div>\r\n    <div class=\"inv-slot\" onclick=\"useItem(1)\" id=\"inv-1\">[2] -<\/div>\r\n    <div class=\"inv-slot\" onclick=\"useItem(2)\" id=\"inv-2\">[3] -<\/div>\r\n    <div class=\"inv-slot\" onclick=\"useItem(3)\" id=\"inv-3\">[4] -<\/div>\r\n  <\/div>\r\n\r\n  <div id=\"log\"><\/div>\r\n\r\n  <div class=\"controls-wrapper\">\r\n    <div class=\"controls\">\r\n      <div><\/div>\r\n      <div class=\"btn\" onclick=\"handleInput(0, -1)\">\u25b2<\/div>\r\n      <div><\/div>\r\n      <div class=\"btn\" onclick=\"handleInput(-1, 0)\">\u25c4<\/div>\r\n      <div class=\"btn\" onclick=\"handleInput(0, 0)\">Wait<\/div>\r\n      <div class=\"btn\" onclick=\"handleInput(1, 0)\">\u25ba<\/div>\r\n      <div><\/div>\r\n      <div class=\"btn\" onclick=\"handleInput(0, 1)\">\u25bc<\/div>\r\n      <div><\/div>\r\n    <\/div>\r\n  <\/div>\r\n<\/div>\r\n\r\n<script>\r\nconst WIDTH = 22;\r\nconst HEIGHT = 14;\r\nconst MAX_INV = 4;\r\nconst VISIBILITY_RADIUS = 6;\r\n\r\nlet audioCtx = null;\r\n\r\nfunction initAudio() {\r\n  if (!audioCtx) {\r\n    audioCtx = new (window.AudioContext || window.webkitAudioContext)();\r\n  }\r\n  if (audioCtx.state === 'suspended') {\r\n    audioCtx.resume();\r\n  }\r\n}\r\n\r\nfunction startGame() {\r\n  initAudio();\r\n  playSfx('exit');\r\n  document.getElementById('title-screen').style.display = 'none';\r\n}\r\n\r\nfunction playSfx(type) {\r\n  initAudio();\r\n  if (!audioCtx) return;\r\n\r\n  const now = audioCtx.currentTime;\r\n  const osc = audioCtx.createOscillator();\r\n  const gain = audioCtx.createGain();\r\n  osc.connect(gain);\r\n  gain.connect(audioCtx.destination);\r\n\r\n  if (type === 'move') {\r\n    osc.type = 'triangle';\r\n    osc.frequency.setValueAtTime(110, now);\r\n    osc.frequency.exponentialRampToValueAtTime(40, now + 0.04);\r\n    gain.gain.setValueAtTime(0.04, now);\r\n    gain.gain.exponentialRampToValueAtTime(0.001, now + 0.04);\r\n    osc.start(now);\r\n    osc.stop(now + 0.04);\r\n  } else if (type === 'shoot') {\r\n    osc.type = 'sawtooth';\r\n    osc.frequency.setValueAtTime(700, now);\r\n    osc.frequency.exponentialRampToValueAtTime(60, now + 0.12);\r\n    gain.gain.setValueAtTime(0.12, now);\r\n    gain.gain.exponentialRampToValueAtTime(0.001, now + 0.12);\r\n    osc.start(now);\r\n    osc.stop(now + 0.12);\r\n  } else if (type === 'hit') {\r\n    osc.type = 'square';\r\n    osc.frequency.setValueAtTime(140, now);\r\n    osc.frequency.exponentialRampToValueAtTime(30, now + 0.18);\r\n    gain.gain.setValueAtTime(0.15, now);\r\n    gain.gain.exponentialRampToValueAtTime(0.001, now + 0.18);\r\n    osc.start(now);\r\n    osc.stop(now + 0.18);\r\n  } else if (type === 'item') {\r\n    osc.type = 'square';\r\n    osc.frequency.setValueAtTime(440, now);\r\n    osc.frequency.setValueAtTime(880, now + 0.06);\r\n    gain.gain.setValueAtTime(0.08, now);\r\n    gain.gain.exponentialRampToValueAtTime(0.001, now + 0.18);\r\n    osc.start(now);\r\n    osc.stop(now + 0.18);\r\n  } else if (type === 'buy') {\r\n    osc.type = 'square';\r\n    osc.frequency.setValueAtTime(523, now);\r\n    osc.frequency.setValueAtTime(659, now + 0.06);\r\n    osc.frequency.setValueAtTime(783, now + 0.12);\r\n    gain.gain.setValueAtTime(0.08, now);\r\n    gain.gain.exponentialRampToValueAtTime(0.001, now + 0.22);\r\n    osc.start(now);\r\n    osc.stop(now + 0.22);\r\n  } else if (type === 'hack') {\r\n    osc.type = 'sawtooth';\r\n    osc.frequency.setValueAtTime(220, now);\r\n    osc.frequency.linearRampToValueAtTime(880, now + 0.08);\r\n    osc.frequency.linearRampToValueAtTime(330, now + 0.16);\r\n    gain.gain.setValueAtTime(0.1, now);\r\n    gain.gain.exponentialRampToValueAtTime(0.001, now + 0.18);\r\n    osc.start(now);\r\n    osc.stop(now + 0.18);\r\n  } else if (type === 'exit') {\r\n    \/\/ 8-Bit Chiptune Warp \/ Level Clear Sound\r\n    osc.type = 'square';\r\n    const notes = [261.63, 329.63, 392.00, 523.25, 659.25, 783.99, 1046.50];\r\n    const step = 0.035;\r\n    notes.forEach((freq, i) => {\r\n      osc.frequency.setValueAtTime(freq, now + i * step);\r\n    });\r\n    gain.gain.setValueAtTime(0.1, now);\r\n    gain.gain.exponentialRampToValueAtTime(0.001, now + notes.length * step);\r\n    osc.start(now);\r\n    osc.stop(now + notes.length * step);\r\n  } else if (type === 'gameover') {\r\n    osc.type = 'sawtooth';\r\n    osc.frequency.setValueAtTime(300, now);\r\n    osc.frequency.exponentialRampToValueAtTime(30, now + 0.5);\r\n    gain.gain.setValueAtTime(0.2, now);\r\n    gain.gain.exponentialRampToValueAtTime(0.001, now + 0.5);\r\n    osc.start(now);\r\n    osc.stop(now + 0.5);\r\n  }\r\n}\r\n\r\nlet player = {\r\n  x: 0, y: 0,\r\n  hp: 35, maxHp: 35,\r\n  ram: 4, maxRam: 4,\r\n  humanity: 100,\r\n  hunger: 100,\r\n  ammo: 8,\r\n  atk: 4,\r\n  creds: 50,\r\n  level: 1,\r\n  noise: 0,\r\n  inventory: ['Sheng-Stim', 'Synth-Baozi']\r\n};\r\n\r\nlet map = [];\r\nlet visibleMap = [];\r\nlet exploredMap = [];\r\nlet enemies = [];\r\nlet items = [];\r\nlet vendors = [];\r\nlet exitGate = { x: 0, y: 0 };\r\nlet turnCounter = 0;\r\nlet inShop = false;\r\n\r\n\/\/ AIMING SKILL CHECK VARIABLES\r\nlet isAiming = false;\r\nlet aimPos = 0;\r\nlet aimDir = 1;\r\nlet aimSpeed = 2.5;\r\nlet aimAnimFrame = null;\r\nlet currentAimTargetIdx = -1;\r\n\r\nfunction log(msg) {\r\n  const logBox = document.getElementById('log');\r\n  if (logBox) {\r\n    logBox.innerHTML += `> ${msg}<br>`;\r\n    logBox.scrollTop = logBox.scrollHeight;\r\n  }\r\n}\r\n\r\nfunction initGame() {\r\n  log(\"SONDERWIRTSCHAFTSZONE L\u00c4DT... NETZWERK GENERIERT.\");\r\n  generateCitySector();\r\n  updateVision();\r\n  render();\r\n\r\n  document.addEventListener('keydown', e => {\r\n    initAudio();\r\n\r\n    if (isAiming) {\r\n      if (e.key === 'f' || e.key === 'F' || e.key === ' ' || e.key === 'Enter') {\r\n        resolveShot();\r\n      }\r\n      return;\r\n    }\r\n\r\n    if (inShop) {\r\n      if (e.key === 'Escape') closeShop();\r\n      return;\r\n    }\r\n\r\n    if (e.key === 'ArrowUp' || e.key === 'w') handleInput(0, -1);\r\n    if (e.key === 'ArrowDown' || e.key === 's') handleInput(0, 1);\r\n    if (e.key === 'ArrowLeft' || e.key === 'a') handleInput(-1, 0);\r\n    if (e.key === 'ArrowRight' || e.key === 'd') handleInput(1, 0);\r\n    if (e.key === ' ') handleInput(0, 0);\r\n    if (e.key === 'f' || e.key === 'F') shootNearest();\r\n    if (e.key === 'h' || e.key === 'H') hackEnemy();\r\n    if (e.key >= '1' && e.key <= '4') useItem(parseInt(e.key) - 1);\r\n  });\r\n}\r\n\r\nfunction generateCitySector() {\r\n  map = Array(HEIGHT).fill(null).map(() => Array(WIDTH).fill('\u2593'));\r\n  exploredMap = Array(HEIGHT).fill(null).map(() => Array(WIDTH).fill(false));\r\n  visibleMap = Array(HEIGHT).fill(null).map(() => Array(WIDTH).fill(false));\r\n  enemies = [];\r\n  items = [];\r\n  vendors = [];\r\n\r\n  let blocks = [];\r\n  let attempts = 0;\r\n  \r\n  while (blocks.length < 7 && attempts < 120) {\r\n    attempts++;\r\n    let w = Math.floor(Math.random() * 3) + 3;\r\n    let h = Math.floor(Math.random() * 3) + 3;\r\n    let x = Math.floor(Math.random() * (WIDTH - w - 2)) + 1;\r\n    let y = Math.floor(Math.random() * (HEIGHT - h - 2)) + 1;\r\n\r\n    let overlap = blocks.some(b => !(x + w + 1 < b.x || x > b.x + b.w + 1 || y + h + 1 < b.y || y > b.y + b.h + 1));\r\n    if (!overlap) {\r\n      blocks.push({ x, y, w, h, center: { x: Math.floor(x + w\/2), y: Math.floor(y + h\/2) } });\r\n      for (let rx = x; rx < x + w; rx++) {\r\n        for (let ry = y; ry < y + h; ry++) map[ry][rx] = '\u00b7';\r\n      }\r\n    }\r\n  }\r\n\r\n  for (let i = 0; i < blocks.length; i++) {\r\n    let distances = blocks\r\n      .map((b, idx) => ({ idx, dist: Math.hypot(b.center.x - blocks[i].center.x, b.center.y - blocks[i].center.y) }))\r\n      .filter(d => d.idx !== i)\r\n      .sort((a, b) => a.dist - b.dist);\r\n\r\n    let neighbors = distances.slice(0, 2);\r\n    neighbors.forEach(n => {\r\n      let c1 = blocks[i].center;\r\n      let c2 = blocks[n.idx].center;\r\n      let currX = c1.x, currY = c1.y;\r\n      \r\n      if (Math.random() < 0.5) {\r\n        while (currX !== c2.x) { map[currY][currX] = '\u00b7'; currX += currX < c2.x ? 1 : -1; }\r\n        while (currY !== c2.y) { map[currY][currX] = '\u00b7'; currY += currY < c2.y ? 1 : -1; }\r\n      } else {\r\n        while (currY !== c2.y) { map[currY][currX] = '\u00b7'; currY += currY < c2.y ? 1 : -1; }\r\n        while (currX !== c2.x) { map[currY][currX] = '\u00b7'; currX += currX < c2.x ? 1 : -1; }\r\n      }\r\n    });\r\n  }\r\n\r\n  for (let k = 0; k < 3; k++) {\r\n    let rx = Math.floor(Math.random() * (WIDTH - 6)) + 3;\r\n    let ry = Math.floor(Math.random() * (HEIGHT - 6)) + 3;\r\n    if (Math.random() < 0.5) {\r\n      for (let len = 0; len < 5; len++) { if (rx + len < WIDTH - 1) map[ry][rx + len] = '\u00b7'; }\r\n    } else {\r\n      for (let len = 0; len < 5; len++) { if (ry + len < HEIGHT - 1) map[ry + len][rx] = '\u00b7'; }\r\n    }\r\n  }\r\n\r\n  player.x = blocks[0].center.x;\r\n  player.y = blocks[0].center.y;\r\n\r\n  let sortedByDist = blocks.slice().sort((a, b) => {\r\n    let dA = Math.hypot(a.center.x - player.x, a.center.y - player.y);\r\n    let dB = Math.hypot(b.center.x - player.x, b.center.y - player.y);\r\n    return dB - dA;\r\n  });\r\n  let furthestBlock = sortedByDist[0];\r\n  exitGate = { x: furthestBlock.center.x, y: furthestBlock.center.y };\r\n\r\n  let vendorCandidates = blocks.filter(b => b !== blocks[0] && b !== furthestBlock);\r\n  if (vendorCandidates.length > 0) {\r\n    let vBlock = vendorCandidates[0];\r\n    vendors.push({ x: vBlock.center.x, y: vBlock.center.y, char: '\u00a5' });\r\n  } else if (blocks.length > 1) {\r\n    vendors.push({ x: blocks[1].x + 1, y: blocks[1].y + 1, char: '\u00a5' });\r\n  }\r\n\r\n  blocks.forEach((b) => {\r\n    let rand = Math.random();\r\n    \r\n    let isReserved = (x, y) => (x === player.x && y === player.y) || \r\n                              (x === exitGate.x && y === exitGate.y) || \r\n                              vendors.some(v => v.x === x && v.y === y);\r\n\r\n    let enemyX = b.x + 1;\r\n    let enemyY = b.y + 1;\r\n    if (!isReserved(enemyX, enemyY) && rand > 0.3) {\r\n      let enemyType = rand < 0.6 ? 'triad' : (rand < 0.85 ? 'ministry' : 'drone');\r\n      enemies.push({\r\n        x: enemyX, y: enemyY,\r\n        type: enemyType,\r\n        char: enemyType === 'triad' ? '\u5e2e' : (enemyType === 'ministry' ? '\u5b98' : '\u2206'),\r\n        hp: enemyType === 'triad' ? 10 : (enemyType === 'ministry' ? 16 : 8),\r\n        atk: enemyType === 'triad' ? 4 : (enemyType === 'ministry' ? 7 : 8),\r\n        range: enemyType === 'triad' ? 1.5 : (enemyType === 'ministry' ? 4 : 6),\r\n        bounty: enemyType === 'triad' ? 25 : (enemyType === 'ministry' ? 45 : 60),\r\n        stunned: 0\r\n      });\r\n    }\r\n\r\n    let itemX = b.x + b.w - 2;\r\n    let itemY = b.y + b.h - 2;\r\n    if (!isReserved(itemX, itemY) && Math.random() > 0.35) {\r\n      let itemRand = Math.random();\r\n      let type = itemRand < 0.4 ? 'Sheng-Stim' : (itemRand < 0.7 ? 'Synth-Baozi' : 'Mag-Rounds');\r\n      let char = type === 'Sheng-Stim' ? '\u751f' : (type === 'Synth-Baozi' ? '\u5305' : '\u2316');\r\n      items.push({ x: itemX, y: itemY, type, char });\r\n    }\r\n  });\r\n}\r\n\r\nfunction updateVision() {\r\n  for (let y = 0; y < HEIGHT; y++) {\r\n    for (let x = 0; x < WIDTH; x++) visibleMap[y][x] = false;\r\n  }\r\n\r\n  for (let angle = 0; angle < 360; angle += 5) {\r\n    let rad = angle * (Math.PI \/ 180);\r\n    let dx = Math.cos(rad);\r\n    let dy = Math.sin(rad);\r\n    let cx = player.x + 0.5;\r\n    let cy = player.y + 0.5;\r\n\r\n    for (let d = 0; d < VISIBILITY_RADIUS; d++) {\r\n      let tileX = Math.floor(cx);\r\n      let tileY = Math.floor(cy);\r\n\r\n      if (tileX >= 0 && tileX < WIDTH && tileY >= 0 && tileY < HEIGHT) {\r\n        visibleMap[tileY][tileX] = true;\r\n        exploredMap[tileY][tileX] = true;\r\n        if (map[tileY][tileX] === '\u2593') break;\r\n      }\r\n      cx += dx;\r\n      cy += dy;\r\n    }\r\n  }\r\n}\r\n\r\nfunction handleInput(dx, dy) {\r\n  initAudio();\r\n  if (player.hp <= 0 || inShop || isAiming) return;\r\n\r\n  let newX = player.x + dx;\r\n  let newY = player.y + dy;\r\n\r\n  if (map[newY][newX] !== '\u2593') {\r\n    let enemyIdx = enemies.findIndex(e => e.x === newX && e.y === newY);\r\n    let vendorIdx = vendors.findIndex(v => v.x === newX && v.y === newY);\r\n\r\n    if (enemyIdx !== -1) {\r\n      attackEnemyMelee(enemyIdx);\r\n    } else if (vendorIdx !== -1) {\r\n      openShop();\r\n      return;\r\n    } else {\r\n      player.x = newX;\r\n      player.y = newY;\r\n      playSfx('move');\r\n      checkItems();\r\n      checkExit();\r\n    }\r\n    endTurn();\r\n  }\r\n}\r\n\r\nfunction openShop() {\r\n  inShop = true;\r\n  playSfx('buy');\r\n  document.getElementById('shop-modal').style.display = 'flex';\r\n  log(`<span style=\"color:#ffcc00\">Verbindung mit Automat [\u00a5] hergestellt.<\/span>`);\r\n}\r\n\r\nfunction closeShop() {\r\n  inShop = false;\r\n  document.getElementById('shop-modal').style.display = 'none';\r\n  render();\r\n}\r\n\r\nfunction buyShopItem(itemType, cost, humanityCost) {\r\n  initAudio();\r\n  if (player.creds < cost) {\r\n    log(`<span style=\"color:#ff3333\">FEHLER: Zu wenig Yuan! (\u00a5${cost})<\/span>`);\r\n    return;\r\n  }\r\n\r\n  playSfx('buy');\r\n\r\n  if (humanityCost > 0) {\r\n    player.creds -= cost;\r\n    player.humanity = Math.max(0, player.humanity - humanityCost);\r\n\r\n    if (itemType === 'Xeno-Blade') player.atk += 3;\r\n    if (itemType === 'Subdermal-Weave') { player.maxHp += 15; player.hp += 15; }\r\n    if (itemType === 'Teleoplex-Chip') { player.maxRam += 2; player.ram += 2; }\r\n\r\n    log(`<span style=\"color:#ff00ff\">CYBERWARE: ${itemType}. Menschlichkeit: ${player.humanity}%.<\/span>`);\r\n    \r\n    if (player.humanity <= 30) {\r\n      log(`<span style=\"color:#ff0055; font-weight:bold;\">HYPERSTITION: Cyber-D\u00e4mon [\u9b54]!<\/span>`);\r\n    }\r\n  } else {\r\n    if (itemType === 'Mag-Rounds') {\r\n      player.creds -= cost;\r\n      player.ammo += 6;\r\n      log(`Magazin [\u2316] erworben (+6 Ammo).`);\r\n    } else {\r\n      if (player.inventory.length < MAX_INV) {\r\n        player.creds -= cost;\r\n        player.inventory.push(itemType);\r\n        log(`${itemType} verstaut.`);\r\n      } else {\r\n        log(`<span style=\"color:#ff3333\">KAUF ABGEBROCHEN: Inventar voll!<\/span>`);\r\n      }\r\n    }\r\n  }\r\n  render();\r\n}\r\n\r\nfunction shootNearest() {\r\n  initAudio();\r\n  if (player.hp <= 0 || inShop || isAiming) return;\r\n  if (player.ammo <= 0) {\r\n    log(`<span style=\"color:#ff3333\">MAGAZIN LEER!<\/span>`);\r\n    return;\r\n  }\r\n\r\n  let targetIdx = -1;\r\n  let minDistance = 999;\r\n\r\n  enemies.forEach((e, idx) => {\r\n    if (visibleMap[e.y][e.x]) {\r\n      let dist = Math.hypot(e.x - player.x, e.y - player.y);\r\n      if (dist < minDistance) {\r\n        minDistance = dist;\r\n        targetIdx = idx;\r\n      }\r\n    }\r\n  });\r\n\r\n  if (targetIdx !== -1) {\r\n    currentAimTargetIdx = targetIdx;\r\n    startAimMiniGame();\r\n  } else {\r\n    log(`Kein Ziel sichtbar.`);\r\n  }\r\n}\r\n\r\nfunction startAimMiniGame() {\r\n  isAiming = true;\r\n  aimPos = 0;\r\n  aimDir = 1;\r\n  aimSpeed = 2.4 + Math.random() * 1.6;\r\n\r\n  let zoneLeft = 30 + Math.floor(Math.random() * 25);\r\n  let zoneWidth = 20;\r\n\r\n  let targetZoneElem = document.getElementById('aim-target-zone');\r\n  targetZoneElem.style.left = zoneLeft + '%';\r\n  targetZoneElem.style.width = zoneWidth + '%';\r\n  targetZoneElem.dataset.min = zoneLeft;\r\n  targetZoneElem.dataset.max = zoneLeft + zoneWidth;\r\n\r\n  document.getElementById('aim-modal').style.display = 'flex';\r\n  updateAimLoop();\r\n}\r\n\r\nfunction updateAimLoop() {\r\n  if (!isAiming) return;\r\n\r\n  aimPos += aimSpeed * aimDir;\r\n  if (aimPos >= 100) {\r\n    aimPos = 100;\r\n    aimDir = -1;\r\n  } else if (aimPos <= 0) {\r\n    aimPos = 0;\r\n    aimDir = 1;\r\n  }\r\n\r\n  document.getElementById('aim-cursor').style.left = aimPos + '%';\r\n  aimAnimFrame = requestAnimationFrame(updateAimLoop);\r\n}\r\n\r\nfunction resolveShot() {\r\n  if (!isAiming) return;\r\n  cancelAnimationFrame(aimAnimFrame);\r\n  isAiming = false;\r\n  document.getElementById('aim-modal').style.display = 'none';\r\n\r\n  player.ammo--;\r\n  player.noise += 3;\r\n\r\n  let targetZoneElem = document.getElementById('aim-target-zone');\r\n  let min = parseFloat(targetZoneElem.dataset.min);\r\n  let max = parseFloat(targetZoneElem.dataset.max);\r\n  let center = min + (max - min) \/ 2;\r\n\r\n  let e = enemies[currentAimTargetIdx];\r\n\r\n  if (!e) {\r\n    endTurn();\r\n    return;\r\n  }\r\n\r\n  if (aimPos >= min && aimPos <= max) {\r\n    let isCrit = Math.abs(aimPos - center) <= 3.5;\r\n    let bonusAtk = player.humanity <= 30 ? 6 : 0;\r\n    let dmg = player.atk + bonusAtk + Math.floor(Math.random() * 4);\r\n    if (isCrit) dmg = Math.floor(dmg * 1.6) + 4;\r\n\r\n    playSfx('shoot');\r\n    if (isCrit) {\r\n      log(`<span style=\"color:#ffcc00; font-weight:bold;\">CRITICAL LOCK! [${e.char}] kritisch getroffen f\u00fcr ${dmg} DMG!<\/span>`);\r\n    } else {\r\n      log(`<span style=\"color:#00ffcc\">TREFFER! Schuss auf [${e.char}] f\u00fcr ${dmg} DMG!<\/span>`);\r\n    }\r\n\r\n    e.hp -= dmg;\r\n    if (e.hp <= 0) {\r\n      player.creds += e.bounty;\r\n      log(`<span style=\"color:#00ffcc\">[${e.char}] eliminiert! +\u00a5${e.bounty}.<\/span>`);\r\n      enemies.splice(currentAimTargetIdx, 1);\r\n    }\r\n  } else {\r\n    playSfx('hit');\r\n    log(`<span style=\"color:#ff0055\">FEHLSCHUSS! Zielverfehlung (${Math.round(aimPos)}%).<\/span>`);\r\n  }\r\n\r\n  endTurn();\r\n}\r\n\r\nfunction hackEnemy() {\r\n  initAudio();\r\n  if (player.ram < 2 || inShop || isAiming) {\r\n    log(`<span style=\"color:#ff3333\">RAM ZU NIEDRIG! (2 K-RAM n\u00f6tig)<\/span>`);\r\n    return;\r\n  }\r\n\r\n  let targetIdx = -1;\r\n  let minDistance = 999;\r\n\r\n  enemies.forEach((e, idx) => {\r\n    if (visibleMap[e.y][e.x] && e.stunned === 0) {\r\n      let dist = Math.hypot(e.x - player.x, e.y - player.y);\r\n      if (dist < minDistance) {\r\n        minDistance = dist;\r\n        targetIdx = idx;\r\n      }\r\n    }\r\n  });\r\n\r\n  if (targetIdx !== -1) {\r\n    playSfx('hack');\r\n    player.ram -= 2;\r\n    let e = enemies[targetIdx];\r\n    e.stunned = 3;\r\n    log(`<span style=\"color:#ff00ff\">OVERCLOCK auf [${e.char}]! 3 Z\u00fcge gel\u00e4hmt.<\/span>`);\r\n    endTurn();\r\n  } else {\r\n    log(`Kein erfassbares Ziel.`);\r\n  }\r\n}\r\n\r\nfunction attackEnemyMelee(idx) {\r\n  playSfx('hit');\r\n  let e = enemies[idx];\r\n  let bonusAtk = player.humanity <= 30 ? 5 : 0;\r\n  let dmg = Math.floor(player.atk * 0.7) + bonusAtk;\r\n  e.hp -= dmg;\r\n  log(`Nahkampf auf [${e.char}] f\u00fcr ${dmg} DMG.`);\r\n  if (e.hp <= 0) {\r\n    player.creds += e.bounty;\r\n    log(`<span style=\"color:#00ffcc\">[${e.char}] eliminiert! +\u00a5${e.bounty}.<\/span>`);\r\n    enemies.splice(idx, 1);\r\n  }\r\n}\r\n\r\nfunction useItem(slot) {\r\n  initAudio();\r\n  if (player.hp <= 0 || slot >= player.inventory.length || inShop || isAiming) return;\r\n\r\n  playSfx('item');\r\n  let item = player.inventory[slot];\r\n  if (item === 'Sheng-Stim') {\r\n    player.hp = Math.min(player.maxHp, player.hp + 20);\r\n    log(`<span style=\"color:#00ffcc\">Sheng-Stim [\u751f] (+20 HP).<\/span>`);\r\n  } else if (item === 'Synth-Baozi') {\r\n    player.hunger = Math.min(100, player.hunger + 50);\r\n    player.hp = Math.min(player.maxHp, player.hp + 5);\r\n    log(`<span style=\"color:#00ffcc\">Synth-Baozi [\u5305] (+50% Cal).<\/span>`);\r\n  }\r\n\r\n  player.inventory.splice(slot, 1);\r\n  endTurn();\r\n}\r\n\r\nfunction checkItems() {\r\n  let idx = items.findIndex(i => i.x === player.x && i.y === player.y);\r\n  if (idx !== -1) {\r\n    let item = items[idx];\r\n    playSfx('item');\r\n    if (item.type === 'Mag-Rounds') {\r\n      player.ammo += 5;\r\n      log(`Magazin [\u2316] aufgesammelt (+5).`);\r\n      items.splice(idx, 1);\r\n    } else {\r\n      if (player.inventory.length < MAX_INV) {\r\n        player.inventory.push(item.type);\r\n        log(`${item.type} [${item.char}] aufgesammelt.`);\r\n        items.splice(idx, 1);\r\n      } else {\r\n        log(`<span style=\"color:#ff0055\">Inventar voll f\u00fcr ${item.type}.<\/span>`);\r\n      }\r\n    }\r\n  }\r\n}\r\n\r\nfunction checkExit() {\r\n  if (player.x === exitGate.x && player.y === exitGate.y) {\r\n    playSfx('exit');\r\n    player.level++;\r\n    log(`<span style=\"color:#00ffcc\">ACCELERATING... Betrete Zone S-0${player.level} [\u95e8].<\/span>`);\r\n    generateCitySector();\r\n  }\r\n}\r\n\r\nfunction endTurn() {\r\n  turnCounter++;\r\n  updateVision();\r\n\r\n  if (turnCounter % 3 === 0 && player.ram < player.maxRam) player.ram++;\r\n\r\n  if (player.humanity <= 30 && Math.random() < 0.25) {\r\n    let psychosisEffect = Math.random();\r\n    if (psychosisEffect < 0.5) {\r\n      player.hp -= 2;\r\n      playSfx('hit');\r\n      log(`<span style=\"color:#ff0055; font-weight:bold;\">HYPERSTITION! (-2 HP).<\/span>`);\r\n    } else {\r\n      player.noise += 5;\r\n      log(`<span style=\"color:#ff0055; font-weight:bold;\">TIME-LOOP-PULSE!<\/span>`);\r\n    }\r\n  }\r\n\r\n  if (player.noise > 0) player.noise--;\r\n\r\n  if (turnCounter % 5 === 0 && player.hunger > 0) player.hunger--;\r\n  if (player.hunger <= 0) {\r\n    player.hp--;\r\n    playSfx('hit');\r\n    log(`<span style=\"color:#ff0055\">METABOLISCHER KOLLAPS! -1 HP.<\/span>`);\r\n  }\r\n\r\n  enemies.forEach(e => {\r\n    if (e.stunned > 0) {\r\n      e.stunned--;\r\n      return;\r\n    }\r\n\r\n    let isVisible = visibleMap[e.y][e.x];\r\n    let dist = Math.hypot(e.x - player.x, e.y - player.y);\r\n\r\n    if (isVisible || dist < player.noise) {\r\n      if (dist <= e.range) {\r\n        let dmg = Math.max(1, e.atk - Math.floor(Math.random() * 2));\r\n        player.hp -= dmg;\r\n        playSfx('hit');\r\n        log(`<span style=\"color:#ff0055\">[${e.char}] trifft dich f\u00fcr ${dmg} DMG!<\/span>`);\r\n      } else {\r\n        let dx = Math.sign(player.x - e.x);\r\n        let dy = Math.sign(player.y - e.y);\r\n        if (map[e.y + dy][e.x + dx] !== '\u2593' && !enemies.some(o => o.x === e.x + dx && o.y === e.y + dy)) {\r\n          e.x += dx;\r\n          e.y += dy;\r\n        }\r\n      }\r\n    }\r\n  });\r\n\r\n  if (player.hp <= 0) {\r\n    playSfx('gameover');\r\n    log(`<span style=\"color:#ff0000; font-weight:bold;\">FLATLINE: Vom Kapital vollst\u00e4ndig reabsorbiert. Game Over.<\/span>`);\r\n  }\r\n\r\n  render();\r\n}\r\n\r\nfunction render() {\r\n  document.getElementById('stat-level').innerText = `ZONE: S-0${player.level}`;\r\n  document.getElementById('stat-hp').innerText = `INT: ${player.hp}\/${player.maxHp}`;\r\n  document.getElementById('stat-ram').innerText = `RAM: ${player.ram}\/${player.maxRam}`;\r\n  document.getElementById('stat-psyche').innerText = `HUM: ${player.humanity}%`;\r\n  document.getElementById('stat-food').innerText = `CAL: ${player.hunger}%`;\r\n  document.getElementById('stat-ammo').innerText = `AMMO: ${player.ammo}`;\r\n  document.getElementById('stat-atk').innerText = `GUN: ${player.atk}`;\r\n  document.getElementById('stat-cred').innerText = `\u00a5${player.creds}`;\r\n\r\n  for (let i = 0; i < MAX_INV; i++) {\r\n    let slot = document.getElementById(`inv-${i}`);\r\n    let name = player.inventory[i] || 'Leer';\r\n    let icon = name === 'Sheng-Stim' ? '[\u751f]' : (name === 'Synth-Baozi' ? '[\u5305]' : (name === 'Mag-Rounds' ? '[\u2316]' : ''));\r\n    slot.innerText = `[${i+1}] ${name} ${icon}`;\r\n  }\r\n\r\n  let htmlMap = '';\r\n  for (let y = 0; y < HEIGHT; y++) {\r\n    for (let x = 0; x < WIDTH; x++) {\r\n      let isVisible = visibleMap[y][x];\r\n      let isExplored = exploredMap[y][x];\r\n\r\n      if (!isExplored) {\r\n        htmlMap += '<div class=\"t fog-hidden\"><\/div>';\r\n        continue;\r\n      }\r\n\r\n      if (x === player.x && y === player.y) {\r\n        let pClass = player.humanity <= 30 ? 'p-psychotic' : 'p-player';\r\n        let pChar = player.humanity <= 30 ? '\u9b54' : '@';\r\n        htmlMap += `<div class=\"t ${pClass}\">${pChar}<\/div>`;\r\n      } else if (x === exitGate.x && y === exitGate.y) {\r\n        htmlMap += '<div class=\"t i-exit\">\u95e8<\/div>';\r\n      } else {\r\n        let enemy = enemies.find(e => e.x === x && e.y === y);\r\n        let item = items.find(i => i.x === x && i.y === y);\r\n        let vendor = vendors.find(v => v.x === x && v.y === y);\r\n\r\n        if (isVisible && enemy) {\r\n          let cssClass = enemy.type === 'triad' ? 'e-triad' : (enemy.type === 'ministry' ? 'e-ministry' : 'e-drone');\r\n          if (enemy.stunned > 0) cssClass += ' stunned';\r\n          htmlMap += `<div class=\"t ${cssClass}\">${enemy.char}<\/div>`;\r\n        } else if (isVisible && vendor) {\r\n          htmlMap += `<div class=\"t i-vendor\">${vendor.char}<\/div>`;\r\n        } else if (isVisible && item) {\r\n          htmlMap += `<div class=\"t i-item\">${item.char}<\/div>`;\r\n        } else {\r\n          let char = map[y][x];\r\n          let cssClass = isVisible ? (char === '\u2593' ? 'tile-wall' : 'tile-floor') : 'fog-explored';\r\n          htmlMap += `<div class=\"t ${cssClass}\">${char}<\/div>`;\r\n        }\r\n      }\r\n    }\r\n  }\r\n  document.getElementById('map').innerHTML = htmlMap;\r\n}\r\n\r\ninitGame();\r\n<\/script>\r\n<\/body>\r\n<\/html>\r\n"}