ItemRackMod
Adds slotted item racks to the walls inside the starting truck, similar to the item shelf in Phasmophobia's van.ItemRackMod
Добавляет систему хранения предметов внутрь начального грузовика:
- Две настенные стойки (левая/правая) — сетка ячеек, куда предметы вешаются на стену.
- Три горизонтальные платформы —
GrenadePlatform,DronePlatform,MinePlatform— для предметов, которые логичнее класть, чем вешать (гранаты, мины, дроны). У ячеек платформ нет физического коллайдера, только триггер.
Конкретные предметы (оружие, инструменты, гранаты, дроны и т.д.) закрепляются за конкретными ячейками через конфиг и расставляются туда автоматически при заходе в грузовик — не нужно руками разносить вещи по полкам каждый забег.
Сборка (Rider)
- Установи через Thunderstore Mod Manager BepInExPack для R.E.P.O. и запусти игру раз в modded-режиме — это создаст
BepInEx/core/BepInEx.dllи0Harmony.dllв папке игры. - Скопируй 8 нужных
.dll(список и точные пути — вBUILD.md) в папкуsrc/libs/. - Открой
src/ItemRackMod.csprojв Rider → Build → Build Solution. - Скопируй
src/bin/Debug/net48/ItemRackMod.dllв<игра>/BepInEx/plugins/ItemRackMod/ItemRackMod.dll.
Как это устроено
Файлы
Patches.cs— Harmony-патч наTruckSafetySpawnPoint.Awake(): как только этот синглтон появляется внутри грузовика, на него вешаетсяItemRackController.ItemRackController.cs— строит обе стены и все три платформы как сетки дочернихTransform+SphereCollider(isTrigger)на каждой ячейке. Держит справочникSlotKey → ItemRackSlot(Wall:Row:Col, напримерLeft:2:4) и создаётDefaultItemPlacement.ItemRackSlot.cs— логика одной ячейки: удержание предмета (PhysGrabObject.OverrideKinematic+ периодическийTeleport), освобождение при захвате игроком, и 5-секундное "окно приоритета" после старта/сброса сцены (см. ниже).DefaultItemPlacement.cs— активный сканер: первые 90 секунд после появления грузовика каждые 0.2 сек проходит по всемPhysGrabObjectна сцене (FindObjectsOfType) и расставляет их по назначенным ячейкам — не дожидаясь, пока предмет случайно подплывёт к полке. Платформы обрабатываются в фиксированном порядке (мины → дроны → гранаты) — это специально, чтобы одинаковые предметы (например три мины) не "перескакивали" между ячейками при одновременном спавне.DefaultItemNameResolver.cs— определяет имя/тип предмета через рефлексию (в т.ч.private/internalполя вродеItemAttributes.itemName) плюс таблицу алиасов на реальные C#-классы игры ("sledge hammer" → ItemMelee) — нужно для предметов, у которых нет надёжного текстового имени или оно совпадает с другим предметом.ModConfig.cs— все настройки + парсингSlotAssignments/ItemOrientationsиз строк конфига.Plugin.cs— точка входа; подписывается наSceneManager.sceneLoaded, чтобы при каждом переходе труба↔уровень↔магазин заново армировать стартовые привязки ячеек (ItemRackController.ResetForNewScene()).
"Окно приоритета" (5 секунд)
Ячейка с назначенным предметом (через SlotAssignments) первые 5 секунд после старта/сброса сцены принимает только этот предмет. По истечении 5 секунд фильтр снимается и ячейка становится универсальной — в неё можно вручную положить что угодно. Это защищает именные ячейки от постороннего предмета в момент, пока автоматическая расстановка ещё не успела всё разложить, но не блокирует их навсегда.
Настройка (BepInEx/config/ItemRackMod.cfg)
Основные секции: [Rack] (общие: Rows, Columns, SpacingHorizontal/Vertical, SlotRadius, MaxSnapSpeed, ShowVisualMarkers), [Rack.LeftWall]/[Rack.RightWall] (смещение и разворот стены), [Rack.GrenadePlatform]/[Rack.DronePlatform]/[Rack.MinePlatform] (смещение, разворот, шаг сетки, размер маркера — своя копия настроек на каждую платформу), и [Rack.ItemAssignments] с двумя ключевыми строками:
SlotAssignments—Wall:Row:Col=ИмяПредметачерез запятую.Wall—Left/Right(стены) илиGrenadePlatform/DronePlatform/MinePlatform. Row/Col — с 1, от угла сетки.ItemOrientations—ИмяПредмета=X,Y,Z(доп. поворот в градусах) через;. Применяется поверх обычного поворота ячейки — так пистолеты/дробовик/инструменты кладутся плашмя к стене, а карт-пушки/посохи остаются торчать перпендикулярно (для них просто нет записи в этом списке).
Текущий config/ItemRackMod.cfg в архиве — уже настроенный рабочий конфиг с реальной раскладкой (см. список предметов там).
Известные ограничения
- Сеть/мультиплеер: авторитетность отдаётся мастер-клиенту через
SemiFunc.IsMasterClientOrSingleplayer(), владение (PhotonView.Ownership) перед телепортом запрашивается штатнымRequestOwnership(). Поведение в реальной мультиплеерной сессии стоит перепроверить на своей группе. - Визуальные маркеры используют дефолтный материал
GameObject.CreatePrimitive— в билде игры может выглядеть иначе, чем в редакторе (в худшем случае — просто белый/розовый куб; создание маркера обёрнуто вtry/catch, на сам мод это не влияет). ItemOrientations— углы поворота подобраны вручную по факту (не теоретически), но если добавишь новый предмет вSlotAssignments, для него может понадобиться свой угол.
