squad-proto/src/render/view.h

53 lines
2.3 KiB
C
Raw Normal View History

Прототип боевого ядра: отряд, хоррор-слой, ближний бой Тактический отряд с автоматическим огнём в изометрии, собственный софтверный растеризатор (raylib только окно, ввод и финальный блит). Ядро (спек, раздел 6): - LaneClear: проверка линии огня по своим, стенам и дальности; - решатель огневых позиций с гистерезисом и коммитом; - резервирование линий огня и расступание из чужих секторов; - пули-снаряды, дружественный урон физически возможен. Хоррор-слой (render-only): свет и туман войны с памятью карты, светящиеся трассеры, кровь, виньетка, зерно, напряжение. Ближний бой: сектор удара, три фазы, связка из трёх ударов, своя дисциплина «не бить сквозь своего». Проверка: squad_proto.exe --accept прогоняет критерии приёмки раздела 11 плюс блок M7 по ближнему бою — все PASS, FRIENDLY_HITS = 0 за 3 минуты боя. Сборка: cmake -S . -B build && cmake --build build --config Release raylib 6.0 подтягивается через FetchContent. Документация — CLAUDE.md как оглавление, содержание в docs/. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 17:00:49 +07:00
#pragma once
// -----------------------------------------------------------------------------
// Всё render-only состояние живёт здесь и только здесь.
//
// Зачем отдельная структура: правило «эффекты не текут в симуляцию» должно
// проверяться компилятором, а не вниманием. RenderGame принимает Game по
// КОНСТАНТНОЙ ссылке — значит ни свет, ни трассеры, ни тряска камеры физически
// не могут изменить состояние симуляции. Headless-прогоны (--accept, --headless)
// View не создают вообще, поэтому цифры приёмки остаются цифрами симуляции.
// -----------------------------------------------------------------------------
#include "render/atmos.h"
#include "render/blood.h"
#include "render/framebuffer.h"
#include "render/fx.h"
#include "render/iso.h"
#include "render/lighting.h"
#include "render/post.h"
#include "render/scene.h"
struct Game;
struct View
{
iso::Camera cam;
Scene scene;
Lighting lighting;
FxSystem fx;
PostFx post;
Dread dread;
BloodField blood; // вечные декали, запечённые в спрайты пола
Atmosphere atmos; // пепел в воздухе
// Дельты считаются по накопительным счётчикам метрик: за один кадр рендера
// проходит до MAX_STEPS_PER_FRAME шагов, поэтому флаг «выстрелил» не годится.
int prevShots = 0;
int prevKills = 0;
int prevFriendly = 0;
int prevMeleeHits = 0;
bool horrorEnabled = true; // F5 — аварийный возврат к прежнему кадру
bool showSight = false; // F6 — показать диски обзора
// Гамма и усиление меняют САМУ таблицу рампы: без перепечатки ручки молчат.
float rampGamma = -1.0f;
float rampGain = -1.0f;
void Init();
void RefreshRamp();
void Reset(const Game& game);
};
void RenderGame(const Game& game, View& view, Framebuffer& fb, float alpha, float frameDt);