Files
andrey 7f545347b4 Этап 45: локация «Волшебное болото» (id 4, 90 000 🪙) — светящиеся рыбы, лягушки, кувшинки/лилии. (1) Данные: LOCATIONS[4] (тёмно-моховая вода 6 hex, слабая рябь; в массиве ПОСЛЕДНИЙ, по цене — между Озёрами 65536 и Морем 131072); 5 новых видов строго в КОНЕЦ SPECIES (32→37, по одному на редкость r0–r4, у каждого glow:'#hex' — 5 разных цветов): glowfin Светлячок #5ff2ff 8🪙, moonfish Лунная рыбка #b9c8ff 13, emberfin Изумрудный светляк #57ffa8 20, violetlure Фиалковый огонёк #d17bff 38, spiritfin Дух болота #ffe07a 70; SWAMP_IDS/SWAMP_DAY_WEIGHTS/SWAMP_NIGHT_WEIGHTS/SWAMP_SPECIES(_NIGHT) — паттерн LAKE/SEA/OCEAN без пересечений; NIGHT_WEIGHTS — ключи всем 37 id. (2) pickSpecies(): вложенный тернарник → табличный доступ SPECIES_BY_LOCATION(_NIGHT) по save.location + guard (вне 0..4 → Река); роллы 0..3 бит-в-идентичны (lc3/lc4/lc4b/lc4c + речные §9j/M4/M6 не тронуты). (3) Свечение (только ночь): nightMix()>0.35 — тот же порог, что у фонаря; drawGlowAura() (радиальный градиент + 'lighter', save/restore, кэш GLOW_RGBA) — фоновые рыбы болота (AMBIENT_FISH[4] — 7 рыб + palette из 4 цветов, цвет стабильно по индексу), зацепившаяся/вываживаемая (fishGlow — вид с glow), боссовая золотая аура сохранена; карточка — класс glow-card + --glow (только normal-вариант, drop-shadow, не конфликтует с фильтрами вариантов), дневник — drop-shadow на SVG. (4) Декорации: initScenery() ветка i===4 (bank+reed+snag+pine в болотной гамме), ГЛОБАЛЬНЫЕ pads[] (8–14 кувшинок с вырезом, 45% с лилиями — жёлтые/белые/розовые) и frogs[] (3–5, sit→jump по параболе на соседнюю кувшинку, 3–7 с) — очищаются/пересобираются в initScenery() (resize + обе ветки shopClick); updateDecor(dt) — покачивание/прыжки; drawSwampDecor() — ОТДЕЛЬНЫЙ слой после drawWater/drawAmbientFish и до drawBoat (дusk берега не гасит; локальное притухание ночью). (5) Босс: BOSS_BY_LOCATION[4]='spiritfin' (Дух болота, 20–50 кг, ×5 — паттерн Этапа 37). (6) Магазин/i18n/ачивки: тост welcome_swamp (ru/en, тернарник → if/else), ачивки 34→36: swamp_first (bonus:{coinPct:0.02}, locations-based) + swamp_boss (bonus:{}, bosses.spiritfin) → пин achBonus().coinPct 0.16→0.18; species_8 = все 37. (7) Баланс: SWAMP_DAY_WEIGHTS {glowfin:3,moonfish:4,emberfin:28,violetlure:13,spiritfin:4.5}, SWAMP_NIGHT_WEIGHTS {glowfin:2.5,moonfish:2.5,emberfin:20,violetlure:30,spiritfin:4} — Болото 240.3/328.9 🪙 (ночь/день ×1.37), порядок по цене Озёра 194.1/249.0 < Болото < Море 297.3/476.7 в ОБЕ фазы; пины остальных вод не изменились (Река 65.1/125.9 · Озёра 194.1/249.0 · Море 297.3/476.7 · Океан 329.1/552.7). (8) tools/balance.mjs: 8→10 таблиц, +SWAMP_SPECIES(_NIGHT) в return, сводка/пары отношений — сортировка ПО ЦЕНЕ (болото встает между Озёрами и Морем), пины в шапке. (9) Портреты: 5 flat-SVG (каждый — отдельным художником) assets/fish/fish-{glowfin,moonfish,emberfin,violetlure,spiritfin}.svg (viewBox 0 0 160 100, var(--f1..f4,hsl-fallback)); embed-fish.mjs IDS 32→37 (в конец), 37 <symbol> в index.html; fish-preview.html 32→37 карточек. (10) Тесты (тот же коммит): lc1 (37/5 локаций/90000/names/sprites 37/oceanOrder slice(23,32)/swampOrder/swampGlow/swampRar), lc2 (+SWAMP-таблицы, пересечения, nightW 37), lc4d (новый: 3000+3000 роллов болота — все 5 ≥1, чужих нет), lc5 (+location:4 не сбрасывается, location:5→0), lc8w (новый: покупка 90000 + welcome_swamp), lc9 (37), lc10 (mid29), lc11 (новый: glow #rrggbb, 5 цветов различны, веса покрывают id, NIGHT_WEIGHTS — все 37), a22d (36), a36loc (+swamp_first), пин 0.18, §9k2 (+{loc:4, spiritfin, swamp_boss}). 198→204 PASS, exit 0. (11) Скриншоты: gen-screenshots.js +кадры swamp/swamp-night (12→14 × 3 вьюпорта, dayTime 0.3/0.85) — 42 RU + 42 EN PNG (screenshots-wiki/, screenshots-wiki-en/). (12) Доки: AGENTS.md (локации/босс/баланс/баланс-скрипт/награды/портреты/скриншоты), README (5 локаций, 37 видов, 36 ачивок, 204 теста, 14 кадров, mobp-swamp*), KODA.md (SWAMP_*, SPECIES_BY_LOCATION, drawGlowAura/fishGlow/GLOW_RGBA, drawSwampDecor, pads/frogs), DEVLOG (Этап 45), PLAN-SWAMP.md (статус «реализован»). Проверено: 204/204 PASS exit 0, check.mjs OK, balance.mjs — пины без изменений + Болото в цели, emoji-font --check OK (52 глифа, новых emoji нет), ревью @oracle — критичных замечаний нет (.gitignore + .opencode/, fish-preview, осколок комментария species_8 — закрыты в этом же коммите). Миграция сейва не тронута (граница из LOCATIONS.length; location=4 покрыт lc5(f)).
2026-09-21 22:59:15 +03:00

59 lines
4.4 KiB
XML

<!-- Светлячок (glowfin): мелкая стройная полупрозрачная рыбка болота, тёмно-моховое тело ~4:1, светлое брюшко, мелкий вилочный хвост; вдоль бока — ряд циановых чёрточек свечения, по брюху — фотофоры, плавники усеяны циановыми точками, глаз светится цианом -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 160 100" width="160" height="100">
<!-- свечение хвостового плавника -->
<circle fill="#5ff2ff" cx="19" cy="38" r="1.7"/>
<circle fill="#5ff2ff" cx="19" cy="62" r="1.7"/>
<circle fill="#d6fdff" cx="24.5" cy="50" r="1.4"/>
<!-- хвост: мелкий вилочный -->
<path fill="var(--f3,hsl(150,30%,26%))" d="M35 43 L14 31 L24 48.5 L14 69 L35 57 Z"/>
<!-- тело: мелкое, стройное, заострённая морда -->
<path fill="var(--f1,hsl(150,22%,30%))" d="M146 50 C136 42 114 38 88 38 C62 38 44 42 34 47 L34 53 C44 58 62 62 88 62 C114 62 136 58 146 50 Z"/>
<!-- брюшко: чуть светлее (налёт полупрозрачности) -->
<path fill="var(--f2,hsl(150,18%,46%))" d="M146 50 C136 58 114 62 88 62 C62 62 44 58 34 53 C44 56 62 59 88 59 C114 59 136 56 146 50 Z"/>
<!-- просвет тела: тонкая светлая жилка-полупрозрачность -->
<path fill="var(--f2,hsl(150,18%,46%))" d="M134 47.5 C122 43.5 106 41.8 88 41.8 C70 41.8 56 43.5 46 47 C56 45 70 44 88 44 C106 44 122 45.5 134 47.5 Z"/>
<!-- спинная кромка: тонкая тёмная полоса -->
<path fill="var(--f4,hsl(150,25%,17%))" d="M146 50 C136 42 114 38 88 38 C62 38 44 42 34 47 C44 44 62 41.8 88 41.8 C114 41.8 136 44 146 50 Z"/>
<!-- спинной плавник: низкий, со свечением -->
<path fill="var(--f3,hsl(150,30%,26%))" d="M70 39.5 Q82 24 96 39 Z"/>
<circle fill="#5ff2ff" cx="79" cy="33" r="1.4"/>
<circle fill="#5ff2ff" cx="89" cy="35" r="1.4"/>
<!-- грудной плавник -->
<path fill="var(--f3,hsl(150,30%,26%))" d="M116 53 C112 56.5 111.5 60.5 115 63.5 C118 60 118.5 56.5 117.5 53.5 Z"/>
<circle fill="#5ff2ff" cx="115.5" cy="58" r="1.2"/>
<!-- брюшной плавник -->
<path fill="var(--f3,hsl(150,30%,26%))" d="M86 62 L82 68.5 L94 62.5 Z"/>
<!-- анальный плавник -->
<path fill="var(--f3,hsl(150,30%,26%))" d="M62 61.5 L57 68 L68 62.2 Z"/>
<circle fill="#5ff2ff" cx="63" cy="64" r="1.2"/>
<!-- рот: маленькая тёмная щель на конце морды (внутри силуэта) -->
<path fill="var(--f4,hsl(150,25%,17%))" d="M143 49.6 C145.5 49.9 147 50.6 147.8 51.6 C146.2 52.8 144.6 52.4 143.2 51.2 Z"/>
<!-- свечение вдоль бока: ряд циановых чёрточек -->
<ellipse fill="#5ff2ff" cx="50" cy="50.2" rx="2.3" ry="1.4"/>
<ellipse fill="#5ff2ff" cx="60" cy="50" rx="2.3" ry="1.4"/>
<ellipse fill="#5ff2ff" cx="70" cy="49.6" rx="2.3" ry="1.4"/>
<ellipse fill="#5ff2ff" cx="80" cy="49.2" rx="2.3" ry="1.4"/>
<ellipse fill="#5ff2ff" cx="90" cy="48.8" rx="2.3" ry="1.4"/>
<ellipse fill="#5ff2ff" cx="100" cy="48.4" rx="2.3" ry="1.4"/>
<ellipse fill="#5ff2ff" cx="110" cy="48" rx="2.3" ry="1.4"/>
<!-- яркие ядрышки свечения -->
<ellipse fill="#e8feff" cx="50" cy="49.6" rx="0.9" ry="0.6"/>
<ellipse fill="#e8feff" cx="70" cy="49" rx="0.9" ry="0.6"/>
<ellipse fill="#e8feff" cx="90" cy="48.2" rx="0.9" ry="0.6"/>
<ellipse fill="#e8feff" cx="110" cy="47.4" rx="0.9" ry="0.6"/>
<!-- фотофоры: точки свечения вдоль брюха -->
<circle fill="#5ff2ff" cx="49" cy="55.6" r="1.05"/>
<circle fill="#5ff2ff" cx="60" cy="57.6" r="1.05"/>
<circle fill="#5ff2ff" cx="71" cy="58.9" r="1.05"/>
<circle fill="#5ff2ff" cx="83" cy="59.4" r="1.05"/>
<circle fill="#5ff2ff" cx="95" cy="58.8" r="1.05"/>
<circle fill="#5ff2ff" cx="107" cy="57.6" r="1.05"/>
<circle fill="#5ff2ff" cx="117" cy="55.8" r="1.05"/>
<circle fill="#5ff2ff" cx="126" cy="53.2" r="1.05"/>
<!-- глаз: светится цианом -->
<circle fill="var(--f4,hsl(150,25%,17%))" cx="126.5" cy="47.5" r="4.1"/>
<circle fill="#5ff2ff" cx="126.5" cy="47.5" r="3.2"/>
<circle fill="#bdfbff" cx="126.5" cy="47.5" r="1.7"/>
<circle fill="#f2ffff" cx="126.5" cy="47" r="0.85"/>
</svg>