Семь изменений по итогам игры вживую. НАЧАЛО. Первый этаж встречал одинокого оперативника с ножом тремя тварями, из которых одна быстрая: бюджет 3.0 и бегуны с первого этажа. Стало 2.2 (ровно два бредущих), бегуны с четвёртого. Света прибавлено: обзор начинается с 1.30 вместо 1.0, у этажа появилась своя яркость пройденного (0.42 наверху против 0.13 на дне). Наверху ещё работает освещение, и хоррор первого этажа в том, что игрок один, а не в том, что не видно стен. Темнота это инструмент глубины, и тратить её на первый этаж значит не иметь запаса дальше. СТАВКА. Опыт платится за убийства и сразу: выносить надо ВЕЩИ. Вайп больше не отнимает всё - доезжает около половины добычи, и чем вещь реже, тем охотнее теряется. Прежнее "вайп не возвращает ничего" делало единственным разумным поведением уход наверх при первой царапине. ВЫХОД. Аномалия возврата переехала из точки входа к спуску: развилка "вниз или наверх" теперь там же, где этаж кончился. Обратный путь через растревоженный этаж ничего не решал - это был ещё раз тот же этаж. ЧЕКПОИНТЫ через 50 этажей вместо пяти: забег это долгий спуск, а не перебежка между сохранениями. НАЁМНИКИ. Кнопка "нанять за опыт" убрана, оперативники находятся в капсулах на этажах: в среднем раз в сотню этажей и не чаще раза в двадцать. У каждого свои три прибавки из одного бюджета - разница в характере, а не в ранге. Покупка была скучной ровно в том смысле, в каком скучна любая кнопка "стать сильнее": ничего не рассказывает и никуда не зовёт. ЗАМЕРЫ. Вайп на сотне повторов: доезжает 52% (обычное 69%, реликты 25%). Первая версия проверки считала одну сумку и выдала "обычного доехало 112%" - спасение забирает ещё и надетое. Опыт: банк 558 -> 578 за убийство без эвакуации. Капсула поднимает отряд до двух и даёт наёмнику его числа. Формат профиля 6: строки merc и rescued. Не сделано и обсуждается: ростер сверх пятерых, задания для свободных, пассивные бонусы от сидящих на базе. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
63 lines
4.2 KiB
C++
63 lines
4.2 KiB
C++
#pragma once
|
||
// -----------------------------------------------------------------------------
|
||
// Предмет, лежащий на полу, и его подбор.
|
||
//
|
||
// Зачем отдельная сущность, а не «выдать предмет при убийстве»: в игре про
|
||
// спуск находка — это МЕСТО, до которого надо дойти. Лут, падающий в инвентарь
|
||
// сам, не заставляет никуда идти и превращает «лучше лут глубже» в строку в
|
||
// логе. Лежащий предмет виден в темноте плохо, лежит он там, куда отряд ещё не
|
||
// заходил, и за ним надо разомкнуть строй — это и есть цена находки.
|
||
//
|
||
// Подбор ПАССИВНЫЙ: боец, прошедший по предмету, поднимает его. Отдельной
|
||
// кнопки нет намеренно — игрок и так не нажимает «огонь» (спек 5), и заводить
|
||
// ради лута первое ручное действие в игре значило бы менять её жанр.
|
||
//
|
||
// FloorItem — компонент ECS в своём пуле, как Target и Bullet. Правила боя про
|
||
// него не знают вообще: ни решатель, ни LaneClear, ни клинок его не видят.
|
||
// -----------------------------------------------------------------------------
|
||
#include <vector>
|
||
|
||
#include "engine/math.h"
|
||
#include "ecs/ecs.h"
|
||
#include "sim/events.h"
|
||
#include "sim/items.h"
|
||
|
||
struct Agent;
|
||
|
||
struct FloorItem
|
||
{
|
||
ecs::Entity self = ecs::NO_ENTITY;
|
||
// Лежит на полу ЭКЗЕМПЛЯР со своими аффиксами: он выкатан при сборке
|
||
// этажа и не должен добрасываться заново при подборе (sim/affix.h).
|
||
ItemInstance id;
|
||
Vec2 pos{};
|
||
|
||
// Предмет не удаляется в момент подбора: пул перетасовывается swap-remove,
|
||
// а по нему в этот момент идёт цикл. Помеченные снимаются одним проходом
|
||
// после него.
|
||
bool taken = false;
|
||
|
||
// Сколько секунд предмет НЕ подбирается. Нужно ровно одному случаю: вещь,
|
||
// которую боец только что выбросил, лежит у него под ногами, и пассивный
|
||
// подбор поднял бы её тем же шагом. Выбросить стало бы невозможно.
|
||
float noPickup = 0.0f;
|
||
};
|
||
|
||
// pickupDelay > 0 — предмет полежит, прежде чем его снова можно подобрать.
|
||
void SpawnFloorItem(ecs::World& world, const ItemInstance& id, Vec2 pos,
|
||
float pickupDelay = 0.0f);
|
||
|
||
// Подбор за шаг. Возвращает, сколько предметов поднято.
|
||
//
|
||
// Мёртвый боец ничего не подбирает, полная сумка — тоже: предмет остаётся
|
||
// лежать, и это правильно. «Некуда положить» обязано быть видно как лежащий
|
||
// под ногами предмет, а не как молча пропавшая находка.
|
||
// Подбирают В ОБЩУЮ СУМКУ: кто прошёл по предмету, тот его и поднял, но
|
||
// достанется он всему отряду. carriers — на скольких живых делится ноша.
|
||
// rescued — сюда пишется индекс бойца, наткнувшегося на капсулу, или -1.
|
||
// Саму капсулу подбор не «поднимает»: оперативник встаёт в строй, а это уже
|
||
// дело отряда, и знать про него sim/loot.cpp не обязан.
|
||
int UpdateLootPickup(ecs::World& world, Agent* agents, int agentCount, SquadBag& bag,
|
||
int carriers, float carryBonus, CombatEventLog* events, float dt,
|
||
int* rescued = nullptr);
|