#pragma once // ----------------------------------------------------------------------------- // Предмет, лежащий на полу, и его подбор. // // Зачем отдельная сущность, а не «выдать предмет при убийстве»: в игре про // спуск находка — это МЕСТО, до которого надо дойти. Лут, падающий в инвентарь // сам, не заставляет никуда идти и превращает «лучше лут глубже» в строку в // логе. Лежащий предмет виден в темноте плохо, лежит он там, куда отряд ещё не // заходил, и за ним надо разомкнуть строй — это и есть цена находки. // // Подбор ПАССИВНЫЙ: боец, прошедший по предмету, поднимает его. Отдельной // кнопки нет намеренно — игрок и так не нажимает «огонь» (спек 5), и заводить // ради лута первое ручное действие в игре значило бы менять её жанр. // // FloorItem — компонент ECS в своём пуле, как Target и Bullet. Правила боя про // него не знают вообще: ни решатель, ни LaneClear, ни клинок его не видят. // ----------------------------------------------------------------------------- #include #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);