База из ремейка: ассеты, предметы, звуки и правки плана
Выгрузили из ремейка Rustex всё, на чём будем работать, и переписали план под реальные цифры. Ассеты: - tools/extract-rustex-assets.py распаковывает res/ и game.jar и декодирует однобайтовый XOR (ключ по сигнатуре: PNG ^0x89, OGG ^0x4F, JSON ^0x7B). Итог: assets/rustex, 1.65 ГБ, 19 тыс. файлов. В репозиторий не кладём. - Не прочитались 553 .obj, 106 .rrs, 113 .nbt: у них другой шифр, нужен разбор кода (REA). Таблицы (в репозитории): - items.csv: 218 предметов с уроном, дальностью, темпом, прочностью, добычей за удар, материалом, иконкой и моделью; - sounds.csv: 505 звуковых событий с файлами; - item-texts.json: 543 названия и описания предметов. План (PLAN.md): - Сбор теперь по балансу ремейка: камень берёт 50 дерева и 35 руды, топор 85 дерева, каменная кирка 80 руды. Дерево 750 топором рубится за 9 ударов, с меткой за 6-7 - ровно те 7-10 ударов, которых ждали. - Исследования - версия после 2020: два пути. Стол (15/30/60/120, нужен сам предмет, превращается в чертёж) и тех-дерево верстака (125/250/500, ветки с предками, разблокировка личная). Утверждение "тех-дерево бесплатно" было ошибкой community-вики. - Лозы больше нет: она из джунглей, а джунглей нет. Выкинута из HP-таблицы, цен, таймеров гниения и правил шкафа. - Новые разделы 1.10 (мусорка на дороге: серая бочка - скрап, синяя - компоненты, красная - нефть и топливо, плюс ящики с едой) и 1.11 (дороги: сетка 3-4 полос плюс кольцо, сегменты - точки спавна мусорки). - Первый источник скрапа - мусорка, лутбоксы отложены: вопрос о прогрессии крафта снят. - Узлы: руда - своя 3D-модель с AABB, деревья - пока блоки мира.
This commit is contained in:
+7
-1
@@ -30,8 +30,14 @@ target/
|
||||
*.jar
|
||||
!rsx-client/third_party/**/*.jar
|
||||
|
||||
# The assets of the Rustex remake. They are a temporary base and they are
|
||||
# 1.65 GB, so they live on disk and are not in the repository. The scripts
|
||||
# that unpack them are in tools/, and the small tables we derived from them
|
||||
# (items.csv, sounds.csv, item-texts.json) are committed.
|
||||
assets/rustex/
|
||||
logs/
|
||||
|
||||
# python
|
||||
__cache__/
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
|
||||
@@ -12,24 +12,29 @@
|
||||
|
||||
| модуль | что в нём | состояние |
|
||||
|---|---|---|
|
||||
| `rsx-protocol` | формат провода: кадрирование, буфер, рукопожатие, игровые пакеты | рабочий, 22 теста |
|
||||
| `rsx-protocol` | формат провода: кадрирование, буфер, рукопожатие, игровые пакеты | рабочий, 24 теста |
|
||||
| `rsx-auth` | свои аккаунты сервера (PBKDF2, токены, троттлинг) | рабочий, используется только когда лаунчер не настроен |
|
||||
| `rsx-server-core` | тик-луп, мир (чанки, генерация, сохранение), сессии, вход через лаунчер | рабочий, 49 тестов |
|
||||
| `rsx-server-core` | тик-луп, мир (чанки, генерация, сохранение), сессии, вход через лаунчер, инвентарь | рабочий, 57 тестов |
|
||||
| `rsx-client` | загрузчик модов, API модов, хуки в клиент | рабочий, 128 тестов |
|
||||
| `game-fork` | форк Minecraft 1.12.2: свой сетевой слой, свой экран входа, свой HUD | собирается чисто, 3275 классов |
|
||||
| `tools` | извлечение ассетов ремейка: `extract-rustex-assets.py`, `extract-items.py`, `extract-sounds.py` | рабочий, ассеты выгружены (1.65 ГБ) |
|
||||
| `assets/rustex` | ассеты ремейка: модели, текстуры, звуки, иконки, база предметов, карты | выгружено, **временная база** |
|
||||
|
||||
Уже работает целиком: клиент заходит на сервер по токену лаунчера → сервер спрашивает
|
||||
лаунчер «этот ваш?» → клиент получает мир → чанки приходят и рисуются →
|
||||
игрок ходит и ломает блоки.
|
||||
игрок ходит и ломает блоки → сервер выдаёт камень в руку (инвентарь есть).
|
||||
|
||||
Не сделано: предметы, инвентарь, крафт, верстаки, изучение чертежей, узлы-ресурсы
|
||||
(деревья/камни/руда как разрушаемые объекты), постройка баз, нормальная генерация
|
||||
мира, транспорт на NIO, дальний вид (DistantView).
|
||||
Не сделано: клиентский рендер своих предметов, крафт, верстаки, исследование
|
||||
(стол + тех-дерево), узлы-ресурсы (деревья/камни/руда как разрушаемые объекты),
|
||||
мусорка и дороги, постройка баз, нормальная генерация мира, транспорт на NIO,
|
||||
дальний вид (DistantView).
|
||||
|
||||
**Данные оригинала** — раздел 1: срез Rust на **06.11.2025** («Pivot Or Die»).
|
||||
Упрощения проекта поверх оригинала: **без тех-дерева верстака**, **без автоматизации**
|
||||
(Industrial Crafter), **без биомов и джунглей**, **стартовые предметы не исследуются**.
|
||||
Все числа раздела 1 помечены: ✅ подтверждено · 🟡 косвенно · ❌ не подтверждено.
|
||||
Упрощения проекта поверх оригинала: **без автоматизации** (Industrial Crafter),
|
||||
**без биомов и джунглей** (значит, без лозы), **стартовые предметы не исследуются**.
|
||||
**Баланс берём из ремейка**, а не из вики (п. 1.1) — там есть все 218 предметов
|
||||
с характеристиками. Все числа раздела 1 помечены: ✅ подтверждено · 🟡 косвенно ·
|
||||
❌ не подтверждено.
|
||||
|
||||
---
|
||||
|
||||
@@ -93,24 +98,38 @@ fandom: `…/api.php?action=query&prop=revisions&titles=<Page>&rvlimit=1
|
||||
темп удара 0.8 с, дальность 1.2, радиус удара 0.2. ✅ О
|
||||
Руки/ноги — 8 (только С, и это **частный случай**: единого правила «руки/ноги = 0.8»
|
||||
в Rust нет — у разного оружия доли рук 0.63–1.0, ног 0.48–0.9). 🟡
|
||||
- **Сбор:** дерево — 10 дерева за удар (±10 %), руда — 5 руды за удар (±20 %),
|
||||
плоть — 10 урона; потеря прочности 0.3 за удар по дереву и руде. ✅ О
|
||||
- **Прочность:** официальной вики **нет поля HP** ни у одного предмета. Ориентир —
|
||||
шкала 0…100 (ремонт = ровно 20 % рецепта), значит камень выдерживает ~333 удара
|
||||
по дереву. ❌ Точное значение официально не подтверждено.
|
||||
- **Урон по постройкам:** камнем **лоза ломается с одного удара** (HP лозы 10 = урон
|
||||
камня 10). На дерево нужно 37 камней (370 камней-ресурса), на камень — 74,
|
||||
на лист — 295, на броню — 589. ✅ О (HP) + С (расчёт)
|
||||
- **Сбор:** за удар инструмент берёт из узла столько, сколько у него в таблице
|
||||
(у камня 50 дерева и 35 руды, у каменного топора 80 дерева, у топора 85
|
||||
дерева, у каменной кирки 80 руды, у ледяной кирки 100 руды) — п. 1.6.
|
||||
✅ (ремейк, `stacks.json`, у нас `rsx-protocol/.../items/items.csv`)
|
||||
- **Прочность:** шкала 0…100 у камня, 160 у каменных инструментов, 300 у
|
||||
топора, 400 у молотка, 1500 у ледяной кирки. ✅ (ремейк)
|
||||
- **Урон по постройкам:** считаем от HP постройки и урона оружия (п. 5.1).
|
||||
Числа «9 / 0.2 / 0.1» из старой версии плана — **неверны** (см. 1.9).
|
||||
|
||||
**Сколько ударов на ресурс (реально):**
|
||||
**Сколько ударов на ресурс:**
|
||||
|
||||
| ресурс | ресурса в узле | камень | каменная кирка | каменный топор |
|
||||
|---|---|---|---|---|
|
||||
| дерево | ~500 дерева | ~50 ударов | — | ~25–28 ударов |
|
||||
| узел камня | 750 Stones | ~150 ударов | ~47 ударов | — |
|
||||
| узел металла | 500 Metal Ore | ~100 ударов | ~31 удар | — |
|
||||
| узел серы | 200 Sulfur Ore | ~40 ударов | ~13 ударов | — |
|
||||
Узел — это запас (HP) ресурса. За удар инструмент забирает своё число из
|
||||
таблицы п. 1.6; последний удар отдаёт остаток узла, поэтому дерево всегда
|
||||
даёт ровно свой запас. **Метка** (светящийся «крестик» на дереве, «горячая
|
||||
точка» на руде) увеличивает урон за удар: по дереву до ×2, по руде до ×3,
|
||||
по серии ударов по метке бонус растёт. С меткой ударов примерно на треть
|
||||
меньше — «7 идеальных» против «10 обычных» у топора по берёзе.
|
||||
|
||||
| узел | запас | камень | каменная кирка | топор | ледяная кирка |
|
||||
|---|---|---|---|---|---|
|
||||
| дерево (нищий дуб) | 500 дерева | 10 | — | 6 | — |
|
||||
| дерево (берёза) | 750 дерева | 15 | — | 9 | — |
|
||||
| дерево (мёртвое) | 1000 дерева | 20 | — | 12 | — |
|
||||
| узел камня | 750 Stones | 21 | 9 | — | 8 |
|
||||
| узел металла | 500 Metal Ore | 14 | 6 | — | 5 |
|
||||
| узел серы | 200 Sulfur Ore | 6 | 3 | — | 2 |
|
||||
|
||||
✅ (запасы узлов — официальная вики и rustpedia; урон за удар — ремейк)
|
||||
⚠️ Официальная вика даёт другие числа сбора (камень по дереву 10, руда 5) —
|
||||
это баланс оригинального Rust. **Мы берём баланс ремейка**: он совпадает с
|
||||
ощущением «7–10 ударов на дерево», и по нему у нас есть все 218 предметов
|
||||
с точными характеристиками (п. 1.6).
|
||||
|
||||
### 1.2 Верстак (Workbench) — 3 уровня
|
||||
|
||||
@@ -119,8 +138,8 @@ fandom: `…/api.php?action=query&prop=revisions&titles=<Page>&rvlimit=1
|
||||
**Верстак — станция крафта с требованием уровня.** Уровень верстака = минимальный уровень,
|
||||
на котором рецепт доступен: предмет уровня 1 крафтится на верстаке 1 (и на любом более
|
||||
высоком), уровня 2 — только на верстаке 2 и выше, и так далее. Знание рецепта добывается
|
||||
отдельно — столом исследований (п. 1.3) либо тех-деревом верстака (в оригинале есть,
|
||||
у нас не делаем).
|
||||
отдельно — столом исследований (п. 1.3) **или** тех-деревом верстака (в оригинале есть,
|
||||
**у нас делаем** — п. 1.3).
|
||||
|
||||
| уровень | рецепт | где крафтится | время крафта |
|
||||
|---|---|---|---|
|
||||
@@ -160,15 +179,38 @@ craftTime(tier) = max( floor( base × 0.5 ^ min( max(tier − requiredTier, 0),
|
||||
|
||||
**Кто что открывает** — по каждому предмету указано в п. 1.7 (уровень верстака).
|
||||
|
||||
### 1.3 Стол исследований (Research Table) и чертежи (Blueprints)
|
||||
### 1.3 Исследование: стол и тех-дерево (версия после 2020)
|
||||
|
||||
**Два пути, оба рабочие:**
|
||||
|
||||
1. **Стол исследований (Research Table)** — «исследовать сразу», но нужен сам предмет.
|
||||
2. **Тех-дерево верстака** — «пройти ветку до нужного предмета, тратя скрап».
|
||||
|
||||
**Сам стол:** 200 Metal Fragments + 20 Scrap, крафтится **на верстаке 1**, время
|
||||
30 с (L1) / 15 с (L2) / 7 с (L3). ✅
|
||||
|
||||
**Как исследуют:** кладёшь **один** нужный предмет в верхний слот → показывается требуемый
|
||||
скрап (в нижний слот) → кнопка «Research» → **10 секунд** → в верхнем слоте появляется
|
||||
**чертёж**, **предмет уничтожается**. 🟡
|
||||
_(вся механика исследования — только по community-вики; официальная вики её не описывает)_
|
||||
**Путь 1 — стол.** Кладёшь **один** нужный предмет в верхний слот → показывается
|
||||
требуемый скрап (в нижний слот) → кнопка «Research» → **10 секунд** → **предмет
|
||||
превращается в чертёж** (в инвентаре: текстура чертежа, а поверх неё — сам
|
||||
исследуемый предмет) и **уничтожается как предмет**. Предмет должен **быть у
|
||||
тебя** — буквально разобрать, чтобы понять, из чего он сделан. 🟡
|
||||
_(механика — по community-вики; официальная вики подтверждает итог: «Blueprints
|
||||
can be used to learn how to craft an item… obtained by using a research table with
|
||||
scrap and the item you want to research»)_
|
||||
|
||||
**Путь 2 — тех-дерево верстака.** У каждого уровня верстака **своё дерево**:
|
||||
ветки, в вершинах — предметы. Чтобы открыть предмет, заплати скрап и пройди по
|
||||
ветке до него (предки сначала). Разблокировка **личная и непередаваемая**.
|
||||
|
||||
| верстак | цена узла | что открывает |
|
||||
|---|---|---|
|
||||
| L1 | **125** скрапа | каменные → металлические инструменты, меч, тесак |
|
||||
| L2 | **250** скрапа | salvage-топор, ледяная кирка, металлический клинок, гаражные ворота, большая печь, автотурель |
|
||||
| L3 | **500** скрапа | шестерни, металлическая труба, бронедверь, C4, взрывчатка |
|
||||
| Engineering | **250** скрапа | промышленный крафтер, автотурель, телефон |
|
||||
|
||||
✅ (официальная вики: у каждого предмета в блоке Research **две** строки —
|
||||
«Research Table» со своей ценой и «Workbench Level N – Tech Tree» со своей)
|
||||
|
||||
- Прочность предмета на результат не влияет (если предмет не сломана — иначе не работает). 🟡
|
||||
- Исследование **продолжается**, если закрыть интерфейс стола. 🟡
|
||||
@@ -181,7 +223,14 @@ _(вся механика исследования — только по communi
|
||||
Официальная вики подтверждает косвенно: предмет `researchpaper` — *«Use this item in a
|
||||
Research Bench to create blueprints of items»*. ✅
|
||||
|
||||
**Цена исследования — по редкости предмета** (после «Pivot Or Die», 06.11.2025):
|
||||
**Результат в тех-дереве** — не чертёж, а **открытый рецепт**: предмет можно сразу
|
||||
крафтить. Физический чертёж (для промышленного крафтера) получают через стол.
|
||||
|
||||
**Известен по умолчанию** — рецепт открыт с начала игры: ни стола, ни скрапа не нужно.
|
||||
У камня, каменных инструментов, молота, строительного плана, верстаков 1–3, стола
|
||||
исследований, дверей и замков — пометка «known by default» в официальной вики.
|
||||
|
||||
**Цена стола** — по редкости предмета (после «Pivot Or Die», 06.11.2025):
|
||||
|
||||
| редкость | скрап | сколько предметов |
|
||||
|---|---|---|
|
||||
@@ -195,11 +244,24 @@ Research Bench to create blueprints of items»*. ✅
|
||||
обновление. Шкалы «по тирам предмета» в Rust **нет**: цена привязана к редкости, а не к
|
||||
уровню верстака.
|
||||
|
||||
**Тех-дерево верстака** (в оригинале есть, у нас **не делаем** — оверхед): разблокировка
|
||||
прямо в верстаке, по веткам. На 06.11.2025 **тех-дерево бесплатно** — в «Pivot Or Die»
|
||||
убрали «tech tree tax», так что платить за разблокировку в нём не нужно; 15/30/60/120 —
|
||||
это цена **физического чертежа** на столе исследований. Колонка «125 / 250 / 500» в вике —
|
||||
**устаревшая** (это старый налог тех-дерева по уровню верстака, снят 06.11.2025). ✅ О-нов
|
||||
**Цена тех-дерева — своя у каждого уровня верстака** (125 / 250 / 500 / 250, см. выше).
|
||||
Это **отдельная плата** от цены стола: предмет можно получить и через стол (дёшево, но
|
||||
нужен найденный предмет), и через дерево (дороже, но предмет не нужен — нужен только
|
||||
скрап и время). Официальная вики даёт обе цены рядом:
|
||||
|
||||
| предмет | стол | тех-дерево |
|
||||
|---|---|---|
|
||||
| Топор (Hatchet) | 30 | L1 — 125 |
|
||||
| Кирка (Pickaxe) | 30 | L1 — 125 |
|
||||
| Меч (Salvaged Sword) | 15 | L1 — 125 |
|
||||
| Верстак 1 / 2 / 3 | 60 / 30 / 30 | — |
|
||||
| Промышленный крафтер | 30 | Engineering — 250 |
|
||||
| Автотурель | 120 | Engineering — 250 |
|
||||
| Телефон | 30 | Engineering — 125 |
|
||||
|
||||
⚠️ Утверждение прошлой версии плана («тех-дерево бесплатно с 06.11.2025, колонка
|
||||
125 / 250 / 500 устарела») — **неверно**: это данные community-вики. Официальная вики
|
||||
показывает обе цены и сейчас. **Делаем как в оригинале: два пути.**
|
||||
|
||||
**Монументы:** официально задокументирован только **Outpost** (Workbench L1 + Research
|
||||
Table). По community-вике столы есть также на аэродроме, электростанции, спутниковой
|
||||
@@ -218,9 +280,12 @@ Table). По community-вике столы есть также на аэродр
|
||||
андроидов; разрушение построек скрапа **не даёт**. ✅ О (раздел Loot Sources)
|
||||
- **Не крафтится** (Craftable: False). ✅ О
|
||||
- **В рецептах верстаков скрапа нет** (убрали 06.11.2025). Тратится на исследование
|
||||
(15/30/60/120) и на разблокировку в тех-дереве. ✅ О-нов
|
||||
(15/30/60/120) и на разблокировку в тех-дереве (125/250/500). ✅ О
|
||||
- Основные источники (О): базовый ящик 3, синий и жёлтый бочонок 2, военный ящик 8,
|
||||
элитный 25, аирдроп 140–160, учёный 8–24.
|
||||
- **Первый источник в нашей игре — мусорка на дороге** (§1.11): серая бочка даёт
|
||||
до 15 скрапа. Лутбоксы (монументы) отложены — фундамента для них ещё нет, а
|
||||
прогрессию исследования скрап должен закрывать уже сейчас.
|
||||
- Косвенно: в Outpost можно обменять металл на скрап (1 скрап = 20 металла). 🟡
|
||||
- Фрагменты чертежей скрап **не заменяют** — это отдельная валюта (п. 1.2).
|
||||
|
||||
@@ -229,7 +294,7 @@ Table). По community-вике столы есть также на аэродр
|
||||
**Как ставится.** Строительный план (Building Plan, **20 дерева**, крафт 15 с) —
|
||||
разворачиваемый предмет: кладёшь в хотбар, ПКМ открывает колесо конструкций, выбираешь
|
||||
объект, видишь «призрак»; **ПКМ + движение мышью** перебирает варианты, **ЛКМ** ставит.
|
||||
✅ План ставит **только лозу**; все старшие уровни получаются **улучшением молотком**. ✅
|
||||
✅ План ставит **деревянный** уровень; все старшие уровни получаются **улучшением молотком**. ✅
|
||||
|
||||
**Два слоя объектов:**
|
||||
|
||||
@@ -248,21 +313,23 @@ Table). По community-вике столы есть также на аэродр
|
||||
|
||||
| уровень | HP |
|
||||
|---|---|
|
||||
| Twig (лоза) | **10** |
|
||||
| Wood (дерево) | **250** |
|
||||
| Stone (камень) | **500** |
|
||||
| Stone (камни) | **500** |
|
||||
| Sheet Metal (лист) | **1000** |
|
||||
| Armored (броня) | **2000** |
|
||||
|
||||
**Стоимость детали по уровням.** Лоза платится деревом; **улучшение молотком стоит как
|
||||
целевой уровень** (лоза→камень = столько же камней, сколько дерево→камень); понизить
|
||||
уровень нельзя.
|
||||
❌ **Уровня «лоза» (twig) у нас нет:** в Rust лоза — из джунглей, джунглей в нашем мире
|
||||
нет (п. 5.1), поэтому её выкидываем отовсюду: из HP-таблицы, из цен, из таймеров гниения
|
||||
и из правил шкафа.
|
||||
|
||||
| деталь | Twig (дерево) | Wood (дерево) | Stone (камни) | Sheet Metal (металл) | Armored (ХМ) |
|
||||
|---|---|---|---|---|---|
|
||||
| стена, фундамент, полустена, лестница | 50 | 200 | 300 | 200 | 25 |
|
||||
| треугольный фундамент, ступени, пол, рамка пола, треугольный пол, рамка треугольного пола, низкая стена, большой проём, крыша, рампы | 25 | 100 | 150 | 100 | 13 |
|
||||
| малый дверной проём, окно | 35 | 140 | 210 | 140 | 18 |
|
||||
**Стоимость детали по уровням.** **Улучшение молотком стоит как целевой уровень**
|
||||
(дерево→камень = столько же камней, сколько металл→камень); понизить уровень нельзя.
|
||||
|
||||
| деталь | Wood (дерево) | Stone (камни) | Sheet Metal (металл) | Armored (ХМ) |
|
||||
|---|---|---|---|---|
|
||||
| стена, фундамент, полустена, лестница | 200 | 300 | 200 | 25 |
|
||||
| треугольный фундамент, ступени, пол, рамка пола, треугольный пол, рамка треугольного пола, низкая стена, большой проём, крыша, рампы | 100 | 150 | 100 | 13 |
|
||||
| малый дверной проём, окно | 140 | 210 | 140 | 18 |
|
||||
|
||||
Скрап и ХМ в постройке не участвуют (кроме армированного уровня — там ХМ).
|
||||
|
||||
@@ -298,10 +365,10 @@ meter radius of it»), радиус «проецируется фундамен
|
||||
вика), но помечаем как спорное. ✅/⚠️
|
||||
Блокирует и постройку, и предметы (спальники, сундуки) внутри. Аптейп — **доля от
|
||||
стоимости постройки**, списывается раз в **24 ч**; уничтоженный шкаф съедает до 24 ч
|
||||
аптейпа. ✅ Неавторизованные могут ставить **лозовые полы и деревянные лестницы**, всё
|
||||
остальное — «BUILDING BLOCKED». ✅ (в плане было верно)
|
||||
аптейпа. ✅ Неавторизованные не могут ставить **ничего** — всё «BUILDING BLOCKED»
|
||||
(исключение про лозовые полы выкинуто вместе с лозой). ✅ (в плане было верно)
|
||||
|
||||
**Гниение (decay):** когда аптейп кончился: лоза **1 ч**, дерево **3 ч**, камень **5 ч**,
|
||||
**Гниение (decay):** когда аптейп кончился: дерево **3 ч**, камень **5 ч**,
|
||||
лист **8 ч**, броня **12 ч**. Внутри здания — **в 10 раз дольше** (деревянная дверь 30 ч,
|
||||
листовая 80 ч, бронедверь 120 ч). Открытие/закрытие двери с замком сбрасывает таймер. 🟡
|
||||
⚠️ В вики 2020 г. эти же числа стояли как **1 / 2 / 4 / 8 / 12 ч** — таймеры дерева и
|
||||
@@ -317,59 +384,44 @@ meter radius of it»), радиус «проецируется фундамен
|
||||
|
||||
### 1.6 Инструменты: сбор, урон, износ
|
||||
|
||||
**Что значат три числа у пары «инструмент × ресурс»** (официальная вика, таблица Gather Rates):
|
||||
**Gather Damage** — сколько ресурса снимает удар, **Bonus** — разброс этого количества
|
||||
(±10 % для дерева и плоти, ±20 % для руды), **Condition Loss** — сколько прочности
|
||||
инструмента уходит за удар.
|
||||
**Откуда цифры.** Основной источник — **база предметов ремейка**
|
||||
(`rsx-protocol/src/main/resources/items/items.csv`, выгружена из `models/stacks.json`):
|
||||
там у каждого предмета урон, дальность, темп, прочность, сколько ресурса он берёт
|
||||
за удар и из чего сделан. Официальная вики даёт **другой** баланс (оригинальный
|
||||
Rust) — см. предупреждение в п. 1.1. ✅ (ремейк, 218 предметов)
|
||||
|
||||
| инструмент | цель | Gather Damage | Bonus | Condition Loss |
|
||||
|---|---|---|---|---|
|
||||
| **Камень** | дерево | 10 | 1 | 0.3 |
|
||||
| | руда | 5 | 1 | 0.3 |
|
||||
| | плоть | 10 (урон) | 1 | — |
|
||||
| **Каменный топор** | дерево | 20 | 2 | 0.3 |
|
||||
| | плоть | 10 | 1 | 0.3 |
|
||||
| **Каменная кирка** | руда | 16 | 3.2 | 0.3 |
|
||||
| | плоть | 10 | 1 | 1 |
|
||||
| **Salvaged Hammer** | дерево | 20 | 2 | 0.5 |
|
||||
| | руда | 20 | 4 | 0.5 |
|
||||
| | плоть | 10 | 1 | 0.5 |
|
||||
| **Salvaged Axe** | дерево | 50 | 5 | 0.3 |
|
||||
| | плоть | 15 | 1.5 | 1 |
|
||||
| **Salvaged Icepick** | руда | 50 | 10 | 0.3 |
|
||||
| | плоть | 5 | 0.5 | 0.5 |
|
||||
| **Salvaged Sword** | плоть | 10 | 1 | 0.5 |
|
||||
| **Salvaged Cleaver** | плоть | 10 | 1 | 0.5 |
|
||||
| **Топор (Hatchet)** | дерево | 30 | 3 | 0.3 |
|
||||
| | плоть | 12 | 1.2 | 1 |
|
||||
| **Кирка (металл)** | руда | 30 | 6 | 1 |
|
||||
| | плоть | 5 | 0.5 | 1 |
|
||||
| **Молот** | постройки | добычи нет | | |
|
||||
**За удар инструмент берёт** из дерева `rwood`, из руды `rore`, из плоти — свой урон.
|
||||
**Темп** — `rcooldown` в тиках (20 тиков = 1 с). **Прочность** — `rdurability`.
|
||||
|
||||
✅ Перекрёстная проверка: вики 2020 г. (правка 2018–2020) даёт те же числа —
|
||||
камень 10/5, каменный топор 20 по дереву, каменная кирка 16 по руде, топор 30, кирка 30,
|
||||
Salvaged Axe 50, Icepick 50, Hammer 15 по дереву. Расхождений в самих значениях нет.
|
||||
| инструмент | урон | дальность | темп (тики / с) | прочность | дерево за удар | руда за удар |
|
||||
|---|---|---|---|---|---|---|
|
||||
| **Камень** | 10 | 2 | 40 / 2.0 | 100 | 50 | 35 |
|
||||
| **Каменный топор** | 15 | 3 | 32 / 1.6 | 160 | 80 | — |
|
||||
| **Каменная кирка** | 17 | 3 | 32 / 1.6 | 160 | — | 80 |
|
||||
| **Топор (Hatchet)** | 25 | 3 | 31 / 1.55 | 300 | 85 | — |
|
||||
| **Кирка (Pickaxe)** | 30 | 3 | 32 / 1.6 | 300 | — | 100 |
|
||||
| **Молот** | 0 | 3 | 32 / 1.6 | 300 | — | — |
|
||||
| **Salvaged Hammer** | 30 | 3 | 19 / 0.95 | 400 | 40 | 59 |
|
||||
| **Salvaged Axe** | 40 | 3 | 28 / 1.4 | 1500 | 100 | — |
|
||||
| **Salvaged Icepick** | 40 | 3 | 28 / 1.4 | 1500 | — | 100 |
|
||||
| **Salvaged Sword** | 50 | 3 | 25 / 1.25 | 300 | — | — |
|
||||
| **Salvaged Cleaver** | 60 | 3 | 35 / 1.75 | 400 | — | — |
|
||||
| **Дубинка (Bone Club)** | 16 | 3 | 16 / 0.8 | 300 | 60 | 44 |
|
||||
| **Нож (костяной)** | 16 | 3 | 16 / 0.8 | 250 | — | — |
|
||||
| **Нож (боевой)** | 35 | 3 | 16 / 0.8 | 250 | — | — |
|
||||
| **Мачете** | 35 | 3 | 20 / 1.0 | 300 | — | — |
|
||||
| **Булава (Mace)** | 60 | 3 | 35 / 1.75 | 300 | — | — |
|
||||
| **Длинный меч** | 75 | 3 | 35 / 1.75 | 400 | — | — |
|
||||
| **Копьё (каменное)** | 35 | 5 | 32 / 1.6 | 400 | — | — |
|
||||
| **Копьё (деревянное)** | 25 | 4 | 32 / 1.6 | 250 | — | — |
|
||||
|
||||
**Боевая статистика** (официальная вика): «урон» — базовый по торсу, «×2» — множитель
|
||||
в голову, «темп» — секунд между ударами, «дальность» — максимум.
|
||||
⚠️ Поле `skinning` (0.45…1) в базе есть, но смысл его не разобран — **пока не
|
||||
применяем**. Поле `rmaterial` (stone / metalwood / metalmediumrattley / gun / cloth /
|
||||
leather …) — «материал» предмета: по нему считается цена ремонта и уровень брони.
|
||||
|
||||
| инструмент | урон | в голову | темп | дальность | радиус |
|
||||
|---|---|---|---|---|---|
|
||||
| Камень | 10 | ×2 | 0.8 | 1.2 | 0.2 |
|
||||
| Каменный топор | 15 | ×2 | 1.1 | 1.5 | 0.3 |
|
||||
| Каменная кирка | 17 | ×2 | 1.1 | 1.5 | 0.3 |
|
||||
| Каменное копьё | 35 | ×2 | 0.7 | 2.8 | 0.2 |
|
||||
| Молот | 0 | — | 2.0 | 1.5 | 0.3 |
|
||||
| Топор (Hatchet, металл) | 25 | ×2 | 1.1 | 1.5 | 0.3 |
|
||||
| Кирка (металл) | 30 | ×2 | 0.7 | 1.5 | 0.3 |
|
||||
| Булава (Mace) | 60 | ×2 | 0.5 | 1.5 | 0.3 |
|
||||
| Длинный меч | 75 | ×2 | 0.5 | 1.5 | 0.3 |
|
||||
| Salvaged Hammer | 40 | ×2 | 1.0 | 1.5 | 0.3 |
|
||||
| Salvaged Axe | 40 | ×2 | 0.8 | 1.5 | 0.3 |
|
||||
| Salvaged Icepick | 40 | ×2 | 0.8 | 1.5 | 0.3 |
|
||||
| Salvaged Sword | 50 | ×2 | 0.8 | 1.5 | 0.3 |
|
||||
| Salvaged Cleaver | 60 | ×2 | 0.5 | 1.5 | 0.4 |
|
||||
| Дубинка (Bone Club) | 12 | ×2 | 1.4 | 1.5 | 0.2 |
|
||||
**Для сравнения — баланс оригинального Rust** (официальная вики, Gather Rates):
|
||||
камень 10 дерева / 5 руды, каменный топор 20, каменная кирка 16, топор 30, кирка 30,
|
||||
Salvaged Axe 50, Icepick 50, Hammer 15. **Не берём** — у нас баланс ремейка (п. 1.1).
|
||||
|
||||
**Урон по частям тела** (вики 2020 г., проверено современной вики по базовому урону):
|
||||
камень **20/10/8/8**, каменный топор **27/15/12/12**, каменная кирка **35/17/13/13**.
|
||||
@@ -377,27 +429,17 @@ Salvaged Axe 50, Icepick 50, Hammer 15 по дереву. Расхождений
|
||||
Для нашей модели достаточно «голова ×2, торс ×1, руки/ноги — общая доля», но в Rust это
|
||||
не так. 🟡
|
||||
|
||||
**Прочность:** официальной вики **нет поля HP** ни у одного предмета. Ремонт стоит
|
||||
ровно 20 % рецепта → шкала 0…100 → камень (0.3 за удар) живёт ~333 удара по дереву,
|
||||
кирка по плоти (1.0) — 100 ударов. ❌ Значение «100» — вывод из ремонта, не подтверждение.
|
||||
**Прочность:** в ремейке у каждого предмета своё число (камень 100, каменные
|
||||
инструменты 160, топор 300, молот 400, ледяная кирка 1500). Износ за удар считаем
|
||||
пропорционально износу вики (0.3 за удар по дереву и руде, 1.0 по плоти). ✅/С
|
||||
|
||||
**Сколько ударов на ресурс** (узел = 750 Stones / 500 Metal Ore / 200 Sulfur Ore,
|
||||
дерево ≈ 500–700 дерева):
|
||||
|
||||
| инструмент | дерево | узел камня | узел металла | узел серы |
|
||||
|---|---|---|---|---|
|
||||
| Камень | ~50–70 | ~150 | ~100 | ~40 |
|
||||
| Каменный топор | ~25–35 | — | — | — |
|
||||
| Каменная кирка | ~60–120 (в вике 2020 — 5 дерева за удар) | ~47 | ~31 | ~13 |
|
||||
| Топор (Hatchet) | ~17–23 | — | — | — |
|
||||
| Кирка (металл) | ~50–70 | ~25 | ~17 | ~7 |
|
||||
| Salvaged Axe | ~11–14 | — | — | — |
|
||||
| Salvaged Icepick | ~50–70 | ~15 | ~10 | ~4 |
|
||||
**Сколько ударов на ресурс** — таблица в п. 1.1 (запасы узлов: 500/750/1000 дерева,
|
||||
750 камней, 500 металла, 200 серы; урон за удар — из п. 1.6).
|
||||
|
||||
**Урон по постройкам:** официальной вики **нет** данных «урон инструмента по уровню
|
||||
постройки». Есть HP блоков (п. 1.5) и расчёт «сколько инструментов надо взять» из
|
||||
игровых зеркал: камнем лозу — **1 удар**, дерево — **37 камней**, камень — **74**,
|
||||
лист — **295**, броню — **589**. Таблица «лоза 9, дерево 0.2, металл 0.1» — из
|
||||
игровых зеркал: камнем — **37 камней** на дерево, **74** на камень, **295** на лист,
|
||||
**589** на броню. Таблица «лоза 9, дерево 0.2, металл 0.1» — из
|
||||
экспериментальной вики 2015–16, **не использовать**. ❌
|
||||
⚠️ Логическая нестыковка: 250 HP / 10 урона = 25 ударов, а зеркала дают 37 — значит у
|
||||
оружия есть множитель урона по постройкам, который **нигде не опубликован**. Для нас:
|
||||
@@ -405,7 +447,7 @@ Salvaged Axe 50, Icepick 50, Hammer 15 по дереву. Расхождений
|
||||
|
||||
**Кого чем:** топоры и камень бьют по дереву, кирки — по руде, камень умеет и то
|
||||
и другое, Salvaged Hammer — и дерево и руду. Мечи и тесаки — только по плоти: у них
|
||||
на официальной вики нет строк Tree/Ore. ✅
|
||||
в базе ремейка нет ни дерева, ни руды. ✅
|
||||
|
||||
**Броня** (официальная вика, таблица Protection). Слои: голова/торс/ноги — по 2 слота
|
||||
(L1 — одежда, L2 — броня), руки и ступни — по одному; **оба слота дают защиту**.
|
||||
@@ -441,51 +483,61 @@ heavy plate helmet 90 % пули, hazmat 30/30; по футболке источ
|
||||
**`bench`** — минимальный уровень верстака для крафта: 0 = крафтится без верстака,
|
||||
1 / 2 / 3 = нужен верстак соответствующего уровня.
|
||||
**«По умолчанию»** — рецепт открыт с начала игры (знать не нужно, чертёж не нужен).
|
||||
**Чертёж** — цена физического чертежа на столе исследований (если рецепт не открыт
|
||||
по умолчанию). Стол тратит 15 / 30 / 60 / 120 скрапа по редкости.
|
||||
**Стол** — цена физического чертежа на столе исследований (если рецепт не открыт
|
||||
по умолчанию): 15 / 30 / 60 / 120 скрапа по редкости.
|
||||
**Дерево** — путь через тех-дерево верстака: уровень верстака и цена узла
|
||||
(125 / 250 / 500 / 250). `—` = пути нет (рецепт по умолчанию или предмет не в дереве).
|
||||
|
||||
| предмет | bench | крафт | время | чертёж | по умолчанию |
|
||||
|---|---|---|---|---|---|
|
||||
| Камень (Rock) | 0 | 10 камня | 5 с | 120 | **да** |
|
||||
| Каменный топор | 0 | 200 дерева + 100 камня | 15 с | 120 | **да** |
|
||||
| Каменная кирка | 0 | 200 дерева + 100 камня | 15 с | 120 | **да** |
|
||||
| Каменное копьё | 0 | 1 деревянное копьё + 20 камня | 10 с | 120 | **да** |
|
||||
| Строительный план | 0 | 20 дерева | 15 с | 120 | **да** |
|
||||
| Молот | 0 | 100 дерева | 15 с | — | да |
|
||||
| **Верстак 1** | 0 | 500 дерева + 100 металла | 30 с | 60 | **да** |
|
||||
| **Верстак 2** | 1 | 500 металла + 20 ХМ + **5 Basic Fragment** | 45 с | 30 | **да** |
|
||||
| **Верстак 3** | 2 | 1000 металла + 100 ХМ + **5 Advanced Fragment** | 60 с | 30 | **да** |
|
||||
| Стол исследований | 1 | 200 металла + 20 скрапа | 30 с | 60 | **да** |
|
||||
| Инструментальный шкаф | 0 | 1000 дерева | 30 с | 120 | **да** |
|
||||
| Верстак для ремонта | 1 | 125 металла | 30 с | 120 | **да** |
|
||||
| Деревянная дверь | 0 | 300 дерева | 30 с | 120 | **да** |
|
||||
| Двойная деревянная дверь | 0 | 350 дерева | 30 с | 60 | **да** |
|
||||
| Листовая дверь | 0 | 150 металла | 30 с | 60 | **да** |
|
||||
| Двойная листовая дверь | 0 | 200 металла | 30 с | 120 | **да** |
|
||||
| Кодовый замок | 0 | 100 металла | 30 с | 120 | **да** |
|
||||
| Ключевой замок | 0 | 75 дерева | 15 с | 120 | **да** |
|
||||
| Топор (Hatchet) | 1 | 100 дерева + 75 металла | 30 с | 30 | нет |
|
||||
| Кирка (Pickaxe) | 1 | 100 дерева + 125 металла | 30 с | — | нет |
|
||||
| **Salvaged Hammer** | 1 | 1 металл. труба + 50 металла | 30 с | 30 | нет |
|
||||
| **Salvaged Sword** | 1 | 1 металл. клинок + 15 металла | 30 с | 15 | нет |
|
||||
| **Salvaged Cleaver** | 1 | 1 дорожный знак + 50 металла | 30 с | 30 | нет |
|
||||
| **Salvaged Axe** | 2 | 1 металл. труба + 5 металл. клинков | 30 с | 60 | нет |
|
||||
| **Salvaged Icepick** | 2 | 1 металл. труба + 5 металл. клинков | 30 с | 60 | нет |
|
||||
| Металлический клинок | 2 | — | 1 с | 30 | нет |
|
||||
| Шестерни | 3 | — | 1 с | 60 | нет |
|
||||
| Металлическая труба | 3 | — | 1 с | 60 | нет |
|
||||
| Металлическая пружина | 3 | — | 1 с | 60 | нет |
|
||||
| Большая печь | 2 | 600 дерева + 500 камня + 75 топлива | 40 с | 60 | нет |
|
||||
| Гаражные ворота | 2 | 300 металла + 2 шестерни | 30 с | 30 | нет |
|
||||
| Автотурель | 2 | — | 45 с | 120 | нет |
|
||||
| **Бронедверь** | 3 | 20 ХМ + 5 шестерён | 30 с | 120 | нет |
|
||||
| Бронедвойная дверь | 3 | 25 ХМ + 5 шестерён | 30 с | 120 | нет |
|
||||
| **Взрывчатка** (Explosives) | 3 | — | 5 с | 120 | нет |
|
||||
| **Timed Explosive Charge** (C4) | 3 | — | 30 с | 120 | нет |
|
||||
| предмет | bench | крафт | время | стол | дерево | по умолчанию |
|
||||
|---|---|---|---|---|---|---|
|
||||
| Камень (Rock) | 0 | 10 камня | 5 с | 120 | — | **да** |
|
||||
| Каменный топор | 0 | 200 дерева + 100 камня | 15 с | 120 | — | **да** |
|
||||
| Каменная кирка | 0 | 200 дерева + 100 камня | 15 с | 120 | — | **да** |
|
||||
| Каменное копьё | 0 | 1 деревянное копьё + 20 камня | 10 с | 120 | — | **да** |
|
||||
| Строительный план | 0 | 20 дерева | 15 с | 120 | — | **да** |
|
||||
| Молот | 0 | 100 дерева | 15 с | — | — | да |
|
||||
| **Верстак 1** | 0 | 500 дерева + 100 металла | 30 с | 60 | — | **да** |
|
||||
| **Верстак 2** | 1 | 500 металла + 20 ХМ + **5 Basic Fragment** | 45 с | 30 | — | **да** |
|
||||
| **Верстак 3** | 2 | 1000 металла + 100 ХМ + **5 Advanced Fragment** | 60 с | 30 | — | **да** |
|
||||
| Стол исследований | 1 | 200 металла + 20 скрапа | 30 с | 60 | — | **да** |
|
||||
| Инструментальный шкаф | 0 | 1000 дерева | 30 с | 120 | — | **да** |
|
||||
| Верстак для ремонта | 1 | 125 металла | 30 с | 120 | — | **да** |
|
||||
| Деревянная дверь | 0 | 300 дерева | 30 с | 120 | — | **да** |
|
||||
| Двойная деревянная дверь | 0 | 350 дерева | 30 с | 60 | — | **да** |
|
||||
| Листовая дверь | 0 | 150 металла | 30 с | 60 | — | **да** |
|
||||
| Двойная листовая дверь | 0 | 200 металла | 30 с | 120 | — | **да** |
|
||||
| Кодовый замок | 0 | 100 металла | 30 с | 120 | — | **да** |
|
||||
| Ключевой замок | 0 | 75 дерева | 15 с | 120 | — | **да** |
|
||||
| Топор (Hatchet) | 1 | 100 дерева + 75 металла | 30 с | 30 | L1 — 125 | нет |
|
||||
| Кирка (Pickaxe) | 1 | 100 дерева + 125 металла | 30 с | 30 | L1 — 125 | нет |
|
||||
| **Salvaged Hammer** | 1 | 1 металл. труба + 50 металла | 30 с | 30 | L1 — 125 | нет |
|
||||
| **Salvaged Sword** | 1 | 1 металл. клинок + 15 металла | 30 с | 15 | L1 — 125 | нет |
|
||||
| **Salvaged Cleaver** | 1 | 1 дорожный знак + 50 металла | 30 с | 30 | L1 — 125 | нет |
|
||||
| **Salvaged Axe** | 2 | 1 металл. труба + 5 металл. клинков | 30 с | 60 | L2 — 250 | нет |
|
||||
| **Salvaged Icepick** | 2 | 1 металл. труба + 5 металл. клинков | 30 с | 60 | L2 — 250 | нет |
|
||||
| Металлический клинок | 2 | — | 1 с | 30 | L2 — 250 | нет |
|
||||
| Шестерни | 3 | — | 1 с | 60 | L3 — 500 | нет |
|
||||
| Металлическая труба | 3 | — | 1 с | 60 | L3 — 500 | нет |
|
||||
| Металлическая пружина | 3 | — | 1 с | 60 | L3 — 500 | нет |
|
||||
| Большая печь | 2 | 600 дерева + 500 камня + 75 топлива | 40 с | 60 | L2 — 250 | нет |
|
||||
| Гаражные ворота | 2 | 300 металла + 2 шестерни | 30 с | 30 | L2 — 250 | нет |
|
||||
| Автотурель | 2 | — | 45 с | 120 | L2 — 250 | нет |
|
||||
| **Бронедверь** | 3 | 20 ХМ + 5 шестерён | 30 с | 120 | L3 — 500 | нет |
|
||||
| **Бронедвойная дверь** | 3 | 25 ХМ + 5 шестерён | 30 с | 120 | L3 — 500 | нет |
|
||||
| **Взрывчатка** (Explosives) | 3 | — | 5 с | 120 | L3 — 500 | нет |
|
||||
| **Timed Explosive Charge** (C4) | 3 | — | 30 с | 120 | L3 — 500 | нет |
|
||||
|
||||
✅ (вики на 11.2025). «По умолчанию» = рецепт открыт без чертежа — **для нас это значит
|
||||
«не исследуется»** (см. правило в шапке раздела).
|
||||
|
||||
**Ветки наших тех-деревьев** (предок → потомок; цена узла одна на уровень верстака):
|
||||
|
||||
| верстак | ветка |
|
||||
|---|---|
|
||||
| L1 (125) | молот → топор → кирка → меч → тесак |
|
||||
| L2 (250) | salvage-топор → ледяная кирка; металлический клинок; большая печь; гаражные ворота; автотурель |
|
||||
| L3 (500) | шестерни → металлическая труба → бронедверь; C4; взрывчатка |
|
||||
|
||||
**Что НЕ существует** (в плане раньше было — убрано):
|
||||
`Salvaged Hatchet`, `Salvaged Pick Axe`, `M16` (есть LR-300), `Doorway (small)` как предмет,
|
||||
`Oil Refinery` (есть только Small Oil Refinery), `Refrigerator` (есть Fridge),
|
||||
@@ -494,6 +546,10 @@ heavy plate helmet 90 % пули, hazmat 30/30; по футболке источ
|
||||
**Ресурсы** (дерево, камни, металл, ХМ, сера, скрап, ткань, кожа) не крафтятся, а
|
||||
собираются — рецепта нет вовсе.
|
||||
|
||||
**Полный список предметов с характеристиками** — в
|
||||
`rsx-protocol/src/main/resources/items/items.csv` (218 шт, выгружено из ремейка,
|
||||
п. 1.6). Названия и описания — в `assets/rustex/data/item-texts.json` (543 шт).
|
||||
|
||||
### 1.8 Строительные объекты и сокеты
|
||||
|
||||
**Объекты** (набор одинаков для всех уровней): квадратный фундамент, треугольный
|
||||
@@ -533,13 +589,14 @@ inside door frames.»* 🟡
|
||||
| сумма цен исследования по редкости | 144 + 133 + 96 + 212 = **585** исследовабельных предметов — совпадает с разобранным реестром ✅ |
|
||||
| сумма тех-дерева | 87 + 78 + 20 (верстаки) + 39 + 47 + 7 (Eng-верстак) = **278** ✅ |
|
||||
| сумма уровней верстаков | 269 + 167 + 131 + 27 = **594** крафтбельных с указанным уровнем ✅ |
|
||||
| узел камня ÷ камень | 750 Stones ÷ 10 за удар = **75 камней** на узел; 750 ÷ 5 = 150 ударов ✅ |
|
||||
| узел ÷ каменная кирка | 750 ÷ 16 = **47 ударов** ✅ |
|
||||
| дерево ÷ камень | ~500–700 дерева ÷ 10 = **50–70 ударов** ✅ |
|
||||
| расход прочности | камень: 150 ударов × 0.3 = 45 прочности на узел камня (шкала 100 → ~2 узла на камень) ✅ правдоподобно |
|
||||
| прогрессия уровней постройки | HP 10 → 250 → 500 → 1000 → 2000 при цене 50 → 200 → 300 → 200 → 25 — растёт по HP, стоимость листа дешевле камня (но нужна переплавка) ✅ |
|
||||
| **удары по узлу (наши цифры)** | камень 750 ÷ 35 за удар = **21 удар**; ÷ 80 (каменная кирка) = **9**; ÷ 100 (кирка) = **8** ✅ |
|
||||
| **удары по дереву (наши цифры)** | 500 ÷ 50 (камень) = **10**; ÷ 85 (топор) = **6**; 750 ÷ 85 = **9**; 1000 ÷ 85 = **12** ✅ |
|
||||
| **ощущение «7–10 ударов»** | топор по берёзе (750) — 9 ударов, с меткой ≈ 6–7 ✅ совпадает с ожиданием игрока |
|
||||
| **расход прочности** | камень: 21 удар по узлу × 0.3 = 6.3 прочности (шкала 100 → ~16 узлов на камень) ✅ |
|
||||
| прогрессия уровней постройки | HP 250 → 500 → 1000 → 2000 при цене 200 → 300 → 200 → 25 — растёт по HP, стоимость листа дешевле камня (но нужна переплавка) ✅ |
|
||||
| двери | дерево 200 HP / 300 дерева, лист 250 / 150 металла, броня 1000 / 20 ХМ ✅ |
|
||||
| формула времени крафта | 589 предметов, 0 расхождений с формулой п. 1.2 ✅ |
|
||||
| **база ремейка против наших таблиц** | 218 предметов в `items.csv`; все наши числа (урон, темп, прочность, добыча) взяты оттуда ✅ |
|
||||
|
||||
**Не сошлось (требует решения проекта, п. 5):**
|
||||
|
||||
@@ -549,8 +606,10 @@ inside door frames.»* 🟡
|
||||
| радиус шкафа | 50 м (официальная вика) против 16 м (старая вики) |
|
||||
| HP броневой двери | 1000 (зеркала) против 800 (fandom, 2020) |
|
||||
| таймеры гниения | 1/3/5/8/12 ч против 1/2/4/8/12 ч (2020) |
|
||||
| таблица «урон по постройкам» 2018 г. | лоза 9 / дерево 0.2 / металл 0.1 — не публикуется современной викой и не сходится с калькулятором |
|
||||
| таблица «урон по постройкам» 2018 г. | лоза 9 / дерево 0.2 / металл 0.1 — не публикуется современной викой и не сходится с калькулятором; лозы у нас нет |
|
||||
| скрап на исследование | вики до 06.11.2025 давала плоские 20/75/125/500; после обновления — 15/30/60/120 **по редкости**, а не по уровню верстака. У нас нет ни ящиков с лутом по тирам, ни «редкости» предмета — тиры придётся задавать вручную |
|
||||
| **баланс вики против баланса ремейка** | вики: камень 10 дерева / 5 руды; ремейк: 50 / 35. Берём **ремейк** (п. 1.1) — под него и под «7–10 ударов» подобраны все числа |
|
||||
| **огнестрел: урон/отдача/спрей** | в базе ремейка только магазин, тип патрона, ADS-зум, прочность, reach. Остальное — серверные данные; ищем в коде (п. 5.2 п. 5) |
|
||||
|
||||
**Как перепроверять:** страница предмета `wiki.facepunch.com/rust/item/<id>` даёт блоки
|
||||
**Craft** (рецепт, требование верстака, «Craft Time by Workbench»), **Research** (цена
|
||||
@@ -558,6 +617,55 @@ inside door frames.»* 🟡
|
||||
Состояние страницы на дату — через `~history` / `~diff:<revision>`; для эпохи до
|
||||
03.12.2020 — через MediaWiki API fandom с `rvstart`/`rvdir=older`; резерв — Wayback.
|
||||
|
||||
### 1.10 Мусорка (Roadside Junk Pile) — первый источник скрапа
|
||||
|
||||
**Что это.** Небольшой макро-монумент на дороге: брошенная машина / куча мусора.
|
||||
В Rust это «Roadside Junk Pile»: спавнится **только на дороге**, внутри **1–4 бочки**
|
||||
и изредка один ящик еды, обновляется примерно раз в 20 минут. 🟡
|
||||
У нас — своя версия: **2–4 бочки + 0–2 ящика еды**.
|
||||
|
||||
**Состав и лут:**
|
||||
|
||||
| бочка | что даёт | примечание |
|
||||
|---|---|---|
|
||||
| **серая** | скрап **1–15** + один случайный предмет-мусор | мусор логичный: дорожные знаки, ящики, пустая банка, рваная одежда, гитара, бочка для воды |
|
||||
| **синяя** | один случайный **компонент**: электропредохранитель, шестерни, металлическая труба, металлическая пружина, дорожные знаки, лист металла, **корпус полу-автомата** | корпуса SMG и винтовки **не выпадают** (как в оригинале: только из «технических» ящиков) |
|
||||
| **красная** | **сырая нефть 10–20** + **топливо низкого качества 5–15** | топливная бочка |
|
||||
|
||||
**Ящики с едой** (1–2 слота): еда (фрукты, ягоды, консервы, шоколад, картошка) и вода —
|
||||
вода необязательна, второй слот может быть тоже едой.
|
||||
|
||||
**Как это работает у нас:**
|
||||
- бочки **разрушаемые** (HP 35 обычная / 50 топливная) — при разрушении выпадает лут;
|
||||
- ящики с едой — обычный контейнер, его обыскивают;
|
||||
- когда всё опустошено, мусорка **пропадает через 60–180 с** (случайно) и
|
||||
**появляется на другом участке дороги**, preferably рядом с игроками (но не на глазах);
|
||||
- сервер сам решает точки спавна по сегментам дороги (п. 1.11).
|
||||
|
||||
✅ О (официальные вики-страницы контейнеров: yellow barrel, blue barrel, oil barrel,
|
||||
tech parts 1, food box) + 🟡 (roadside junk pile — community-вики) + С (наши решения:
|
||||
3–4 бочки, время жизни, выбор точки).
|
||||
|
||||
**Модели и звуки — из ремейка**: `nextgen/models/barrel_blue`, `barrel_red`,
|
||||
`barrel_white`, `crate`, `foodcrate`, `dieselbarrelloot`, `primitivecrate`,
|
||||
`lockcrate`, `medicalcrate`; звуки бочки/ящика — из `sounds.csv`.
|
||||
|
||||
### 1.11 Дороги
|
||||
|
||||
**Сеть дорог** — сетка из 3–4 пересекающихся дорог через остров **плюс кольцо**
|
||||
вдоль берега. Ширина — 6–8 блоков, покрытие — свой блок «асфальт» (новый id
|
||||
в общем словаре блоков).
|
||||
|
||||
**Генерация:** дорога выравнивает рельеф (по своей линии, со скруглением на поворотах)
|
||||
и кладёт покрытие; пересечения сливаются в площади. Кольцо идёт по берегу, вдоль
|
||||
линии прилива.
|
||||
|
||||
**Точки спавна мусорки** (п. 1.10) — дискретные **сегменты** дороги: сервер держит
|
||||
список точек вдоль всех дорог, из них выбирает свободную ближе к игрокам.
|
||||
|
||||
**Слой дорог — часть генератора мира** (Шаг D), но нужен раньше мусорки, поэтому
|
||||
генерацию дорог тянем в Шаг C.
|
||||
|
||||
## 2. Решения по проекту
|
||||
|
||||
### 2.1 Кто такой админ
|
||||
@@ -590,35 +698,57 @@ ROLE_ELDER / ROLE_CREATOR`).
|
||||
### 2.4 Предметы
|
||||
|
||||
- Все предметы игрока — **кастомные, через наш код и наше API** (не ванильные `ItemStack`).
|
||||
- У предмета: **прочность**, **урон**, **значение bench**, **знание по умолчанию**.
|
||||
- У предмета: **прочность**, **урон**, **значение bench**, **знание по умолчанию**,
|
||||
**цена исследования**, **ветка тех-дерева**, **тег `admin`**.
|
||||
- `bench` — **минимальный уровень верстака**, на котором рецепт доступен
|
||||
(0 = крафтится без верстака, 1/2/3 = нужен верстак этого уровня или выше).
|
||||
Это **гейт крафта, а не знания** — в Rust это разные вещи.
|
||||
- `knownByDefault` — рецепт открыт с начала игры: **не исследуется, скрап не нужен**
|
||||
(по вики такую пометку имеют 97 предметов из 380 с указанным уровнем верстака).
|
||||
- `researchScrap` — цена физического чертежа на столе (0 = не исследуется).
|
||||
- `techTreeBench` + `techTreeScrap` + `techTreeParent` — верстак, цена узла и
|
||||
**предок** в тех-дереве (0 = предка нет, узел — корень ветки).
|
||||
- `admin` — **тег блока/предмета**: без тега может всё, с тегом — только админы
|
||||
сервера; **креатив прав не даёт** (п. 2.2).
|
||||
- Знание рецепта — **состояние игрока** (`knownRecipes`), а не свойство предмета.
|
||||
- У предмета есть **класс инструмента** (NONE / PICKAXE / AXE / SWORD / …) и
|
||||
**класс ресурса**, который он добывает.
|
||||
- Все числа берём из п. 1.6–1.7 (срез 06.11.2025), ничего не выдумываем.
|
||||
- Все числа берём из п. 1.6–1.7, **источник — база ремейка**
|
||||
(`rsx-protocol/src/main/resources/items/items.csv`, 218 предметов), ничего не
|
||||
выдумываем.
|
||||
|
||||
### 2.5 Крафт
|
||||
|
||||
- Как в Rust (срез 06.11.2025): **верстаки трёх уровней** (разворачиваемый предмет,
|
||||
надо стоять рядом) и **чертежи** (стол исследований: нужен найденный предмет + скрап;
|
||||
получается физический чертёж, который изучается и открывает рецепт).
|
||||
- **Тех-дерево верстака и эксперимент на верстаке не делаем** — это оверхед (п. 1).
|
||||
- Как в Rust (после 2020): **верстаки трёх уровней** (разворачиваемый предмет,
|
||||
надо стоять рядом) и **два пути исследования** (п. 1.3):
|
||||
- **стол**: нужен найденный предмет + скрап → получается **физический чертёж**,
|
||||
который изучается и открывает рецепт;
|
||||
- **тех-дерево верстака**: платишь скрап и открываешь узел, рецепт становится
|
||||
доступен; разблокировка личная, чертёж не выдаётся.
|
||||
- **Эксперимент на верстаке** (75 / 300 / 1000 скрапа → случайный чертёж) — механика
|
||||
2017–2020, **не реализуем**.
|
||||
- Знание рецепта — **состояние игрока**, а не свойство предмета.
|
||||
- Время крафта, множитель от уровня верстака, стоимость скрапа — как в Rust.
|
||||
- Время крафта, множитель от уровня верстака, цены скрапа — как в Rust.
|
||||
- То, что игрок получает **на старте**, не исследуется вообще.
|
||||
|
||||
### 2.6 Структуры вместо блоков мира
|
||||
|
||||
Руда, деревья и камни — **не блоки мира, а разрушаемые объекты** (как узлы в Rust):
|
||||
у них есть прочность, они бьются инструментом и дают дроп. Мир меняют только админы.
|
||||
у них есть **HP**, **запас ресурса** и **метка** («крестик» на дереве, «горячая точка»
|
||||
на руде), они бьются инструментом и дают дроп. Последний удар отдаёт остаток запаса.
|
||||
Мир меняют только админы.
|
||||
|
||||
- **Руда** — своя 3D-модель (в ремейке есть `ore/stone`, `ore/metal`, `ore/sulfur`)
|
||||
+ свой AABB; **деревья** — пока обычные блоки мира, у которых сервер держит
|
||||
HP и запас узла.
|
||||
- **Мусорка** (п. 1.10) — тоже структура: бочки и ящики, у неё есть состояние
|
||||
(что опустошено) и таймер исчезновения.
|
||||
|
||||
### 2.7 Текстуры
|
||||
|
||||
- Текстуры предметов пока **временные**, взяты из ремейка как заглушки.
|
||||
- Текстуры предметов пока **временные**, взяты из ремейка как заглушки:
|
||||
иконки — из атласа `assets/rustex/gamejar/assets/rustex/icons/atlas.png`
|
||||
(MTSDF, 2048×2048, тайлы 64×64) по именам `rusticon` из базы предметов.
|
||||
- **Пометка: заменить на свои** (см. п. 6).
|
||||
|
||||
---
|
||||
@@ -677,18 +807,25 @@ ROLE_ELDER / ROLE_CREATOR`).
|
||||
|
||||
### Шаг A. Фундамент предметов и инвентаря (следующий)
|
||||
|
||||
- [x] **База предметов выгружена из ремейка**: `rsx-protocol/src/main/resources/items/items.csv`
|
||||
(218 предметов) + `sounds.csv` (505 событий) + описания в
|
||||
`assets/rustex/data/item-texts.json`. Инструменты: `tools/extract-rustex-assets.py`,
|
||||
`tools/extract-items.py`, `tools/extract-sounds.py`.
|
||||
- [ ] `ItemType`: id, имя, класс инструмента, класс ресурса, прочность, урон по частям тела,
|
||||
скорость сбора, `bench`, `knownByDefault`, рецепт.
|
||||
- [ ] **Данные предметов — из п. 1.6/1.7** (срез 06.11.2025): держать отдельным
|
||||
ресурсом/таблицей, чтобы числа не расходились с планом.
|
||||
скорость сбора, `bench`, `knownByDefault`, `researchScrap`, `techTreeBench`,
|
||||
`techTreeScrap`, `techTreeParent`, `admin`, рецепт.
|
||||
- [ ] **Данные предметов — из п. 1.6/1.7** (база ремейка): держать таблицей, чтобы
|
||||
числа не расходились с планом.
|
||||
- [ ] Модель знания: `knownByDefault` у типа + `knownRecipes` у игрока; стол исследований
|
||||
выдаёт физический чертёж, изучение открывает рецепт навсегда (п. 1.3).
|
||||
выдаёт физический чертёж, изучение открывает рецепт навсегда (п. 1.3);
|
||||
тех-дерево открывает рецепт лично и бесплатно после оплаты скрапа.
|
||||
- [ ] `ItemStack`: тип + количество + прочность + `ItemData` (свой ключ→значение).
|
||||
- [ ] `Inventory`: слоты, хотбар, что в руках. **Сервер — источник истины.**
|
||||
- [ ] Реестр предметов + протокол `Inventory` / `InventorySlot`.
|
||||
- [ ] Клиент: свой реестр + свои текстуры + свой рендер предмета в руке и в слоте
|
||||
(наши предметы не ванильные `IItem`).
|
||||
- [ ] **Текстуры предметов — временные** (взяты из ремейка как заглушки).
|
||||
- [ ] **Текстуры предметов — временные** (взяты из ремейка как заглушки, иконки из
|
||||
атласа `icons/atlas.png`).
|
||||
**ПОМЕТКА: заменить на свои.**
|
||||
- [ ] Стартовый набор: **камень** — решение проекта (в Rust официально не документировано,
|
||||
п. 1.1); выдаём в первый слот хотбара, отдельным флагом конфига.
|
||||
@@ -715,19 +852,32 @@ ROLE_ELDER / ROLE_CREATOR`).
|
||||
игроку не ломается ни в выживании, ни в креативе; у остальных — ломается инструментом
|
||||
того класса, который нужен.
|
||||
|
||||
### Шаг C. Структуры, узлы, постройка
|
||||
### Шаг C. Узлы, мусорка, дороги, крафт и постройка
|
||||
|
||||
- [ ] `StructureTemplate` (блоки + AABB + меш + HP + дроп), `StructureInstance`,
|
||||
`StructureWorld`. Деревья/камни/руда — **узлы**, не блоки мира.
|
||||
- [ ] Сбор: попадание инструментом → урон по классу ресурса → разрушение → дроп.
|
||||
Узлы: камень 750 Stones, металл 500 Metal Ore, сера 200 Sulfur Ore; добыча за удар
|
||||
и потеря прочности — п. 1.6.
|
||||
- [ ] `ResourceNode`: класс ресурса, **HP = запас**, **метка** (дерево ×1→×2, руда
|
||||
×1→×3), дроп. Запасы: дерево 500/750/1000, камень 750, металл 500, сера 200;
|
||||
урон за удар — п. 1.6; последний удар отдаёт остаток.
|
||||
- [ ] Сбор: попадание инструментом → урон по классу ресурса × метка → разрушение → дроп.
|
||||
- [ ] **Дороги** (п. 1.11): сетка 3–4 полос + кольцо, выравнивание рельефа, покрытие,
|
||||
список сегментов для спавна.
|
||||
- [ ] **Мусорка** (п. 1.10): 2–4 бочки (серая/синяя/красная) + 0–2 ящика еды; лут-таблицы;
|
||||
разрушаемые бочки; после опустошения исчезновение через 60–180 с и респавн
|
||||
на другом участке дороги ближе к игрокам.
|
||||
- [ ] **Крафт и исследование** (п. 1.3): `CraftingStation` (поставленный верстак),
|
||||
проверка рецепта (уровень верстака + знание + ингредиенты), `ResearchTable`
|
||||
(предмет + скрап → 10 с → **чертёж**), разблокировка в тех-дереве.
|
||||
- [ ] Постройка: игрок ставит **наши** кастомные предметы-конструкции (не блоки мира).
|
||||
Снаппинг и сокеты — п. 1.5 и 1.8; HP и цены по уровням — п. 1.5;
|
||||
аптейп инструментального шкафа и гниение — п. 1.5.
|
||||
- [ ] Растительность и руда в генерации — через шаблоны структур.
|
||||
- [ ] Модель урона по постройкам — **решить до реализации** (п. 5): без множителя
|
||||
«оружие → уровень постройки» рейд не считается.
|
||||
- [ ] Модель урона по постройкам — **своя**: ударов = HP постройки ÷ урон оружия (п. 5.1).
|
||||
- [ ] Клиент: модель рудного узла (3D + AABB), метки (крестик / горячая точка).
|
||||
|
||||
Критерий готовности: игрок рубит дерево (7 ударов по метке, 9 без), ломает узел камня
|
||||
за 9 ударов каменной киркой, разбирает мусорку и получает скрап, крафтит верстак 1,
|
||||
исследует предмет на столе и получает чертёж, строит стену.
|
||||
|
||||
### Шаг D. Мир один раз, конфиг, барьер
|
||||
|
||||
@@ -761,22 +911,33 @@ ROLE_ELDER / ROLE_CREATOR`).
|
||||
|---|---|
|
||||
| **Роли: из лаунчера или свои на сервере?** | **Свои на сервере.** Лаунчер может подсказать роль, но решение — за сервером: админ это свойство конкретного сервера, а не проекта |
|
||||
| **Урон по частям тела** | По таблице п. 1.6: голова ×2, торс ×1, руки/ноги — своей долей у оружия. Общего «общего урона» не вводим |
|
||||
| **Множитель урона по постройкам** | **Своя модель: ударов = HP постройки ÷ урон оружия.** Без скрытого множителя. Лоза (10 HP) от камня (10 урона) — 1 удар, дерево (250) — 25, камень (500) — 50, лист (1000) — 100, броня (2000) — 200. Зеркальные 37/74/295/589 — не воспроизводим, но и не мешают: считаем от HP |
|
||||
| **Множитель урона по постройкам** | **Своя модель: ударов = HP постройки ÷ урон оружия.** Без скрытого множителя. Дерево (250) от камня (10 урона) — 25, камень (500) — 50, лист (1000) — 100, броня (2000) — 200. Зеркальные 37/74/295/589 — не воспроизводим, но и не мешают: считаем от HP |
|
||||
| **Бронедверь** | **1000 HP** (игровые зеркала; fandom 800 — устарело) |
|
||||
| **Прочность инструментов** | **Шкала 0…100**, ремонт = 20 % рецепта (как в Rust, выведено из цены ремонта) |
|
||||
| **Джунгли и биомы** | **Не делаем.** Мир один, без джунглевого лута (джунгли в игре появились 01.05.2025, за пределами нашего среза) |
|
||||
| **Прочность инструментов** | **Из базы ремейка**: камень 100, каменные 160, топор 300, молот 400, ледяная кирка 1500. Ремонт = 20 % рецепта |
|
||||
| **Джунгли, лоза, биомы** | **Не делаем.** Мир один, джунглей нет → **лозы (twig) у нас тоже нет**: выкинута из HP-таблицы, цен, таймеров гниения и правил шкафа |
|
||||
| **Строительные детали и сетка** | Не «свободно и без сетки»: **сетка мира не важна**, но есть **строительная сетка** (фундамент 3×3) и привязка внутренних блоков к уже поставленным строительным. Слова «не привязываясь к сетке мира» — про сетку мира, не про строительную |
|
||||
| **Исследования** | **Версия после 2020**: два пути — стол (предмет + скрап → чертёж) и тех-дерево верстака (125/250/500, ветки с предками, разблокировка личная) |
|
||||
| **Тех-дерево** | **Делаем**, с ветками и предками (не плоский список) |
|
||||
| **Баланс предметов** | **Из ремейка** (`items.csv`, 218 шт), а не из вики: у нас есть все характеристики, и цифры совпадают с ощущением «7–10 ударов на дерево». Вика — только для сверки |
|
||||
| **Скрап на первом срезе** | Даёт **мусорка на дороге** (серая бочка, 1–15 скрапа) — лутбоксы отложены, а прогрессия исследования скрап закрывать должна уже сейчас |
|
||||
| **Дороги** | **Сетка 3–4 полос + кольцо** по берегу; сегменты дороги — точки спавна мусорки |
|
||||
| **Вид узлов** | **Руда** — своя 3D-модель + AABB (модели `ore/*` из ремейка); **деревья** — пока блоки мира, у которых сервер держит HP и запас |
|
||||
| **Ассеты** | Временная база из ремейка: `assets/rustex/` (1.65 ГБ), иконки из атласа, звуки из реестра. **ПОМЕТКА: заменить на свои** |
|
||||
|
||||
### 5.2 Нужно решение (блокирует реализацию)
|
||||
|
||||
1. **Крафт упирается в лутбоксы.** По п. 1.4 скрап падает **только** из ящиков, бочек, аирдропов и учёных, а чертёж требует **найденного** предмета. То есть без лутбоксов нельзя ни изучить рецепт, ни потратить скрап: прогрессия крафта не запускается.
|
||||
Варианты:
|
||||
- **(а)** перенести лутбоксы вперёд (они нужны раньше крафта);
|
||||
- **(б)** первый срез без прогрессии: все рецепты «по умолчанию» (`knownByDefault`), стол исследований и скрап — позже, вместе с лутбоксами;
|
||||
- **(в)** свой источник скрапа (например, из узлов) — но это уже не Rust.
|
||||
2. **Фрагменты чертежей для верстаков 2 и 3** (5 Basic / 5 Advanced) — они тоже из лутбоксов. Повторяем или заменяем скрапом, как до 02.10.2025? Пока лутбоксов нет — вопрос отложен.
|
||||
3. **Скрап как валюта** — если исследование только для найденных вещей, скрап нужен редко. Оставляем ли его в прогрессии вообще?
|
||||
4. **Стоимость и время каждого рецепта**, который будем реализовывать — в п. 1.7 есть только по ключевым. Долить по мере надобности.
|
||||
1. ~~**Крафт упирается в лутбоксы.**~~ **Снято:** источник скрапа на первом срезе —
|
||||
**мусорка на дороге** (п. 1.10). Лутбоксы (монументы) остаются на потом.
|
||||
2. **Фрагменты чертежей для верстаков 2 и 3** (5 Basic / 5 Advanced) — они тоже из лутбоксов.
|
||||
Повторяем или заменяем скрапом, как до 02.10.2025? Пока лутбоксов нет — вопрос отложен.
|
||||
3. **Скрап как валюта** — цена стола 15–120, цена дерева 125–500. Скрапа с мусорки
|
||||
(1–15 за бочку) хватает, но как быстро — решаем по факту.
|
||||
4. **Стоимость и время каждого рецепта**, который будем реализовывать — в п. 1.7 есть только
|
||||
по ключевым. Долить по мере надобности.
|
||||
5. **Огнестрел: урон, отдача, спрей, темп** — в клиенте ремейка этих чисел нет (это
|
||||
серверные данные в Rust-подобных играх), в базе предметов есть только магазин, тип
|
||||
патрона, ADS-зум и прочность. Ищем таблицу по `rweaponid` в коде ремейка (1–21);
|
||||
пока не нашли — берём с официальной вики как страховку.
|
||||
|
||||
---
|
||||
|
||||
@@ -810,27 +971,37 @@ rsx-client\scripts\run-game.ps1 # клиент
|
||||
|
||||
### 6.3 Что не сделано (по порядку)
|
||||
|
||||
1. **Шаг A** — предметы, инвентарь, реестр, протокол инвентаря, рендер предмета
|
||||
в руке и в слоте, стартовый камень.
|
||||
1. **Шаг A** — добить: клиентский рендер своих предметов (хотбар и рука) и иконки
|
||||
из атласа; поля исследования в `ItemType`; `NodeType`; `TechTree`.
|
||||
2. **Шаг B** — `Dig`/`BreakProgress` в протоколе, состояние ломания на сервере,
|
||||
правила инструмента, тег `admin`, 4 клиентских патча.
|
||||
3. **Шаг C** — структуры (узлы), сбор, постройка по сокетам.
|
||||
3. **Шаг C** — узлы (дерево/камень/металл/сера) с метками, дороги, мусорка,
|
||||
крафт и исследование (стол + тех-дерево), постройка по сокетам.
|
||||
4. **Шаг D** — конфиг, мир 4000×4000 один раз, барьер.
|
||||
5. **Шаг E** — транспорт на NIO.
|
||||
6. **Шаг F** — DistantView.
|
||||
7. **REA** — найти в коде ремейка таблицу оружия по `rweaponid` (урон, отдача, спрей,
|
||||
темп) и шифр конфигов `.obj/.rrs/.nbt`; до этого — цифры с официальной вики.
|
||||
|
||||
### 6.4 Мелочи, которые легко упустить
|
||||
|
||||
- **Текстуры предметов — временные** (взяты из ремейка как заглушки). **ПОМЕТКА:
|
||||
заменить на свои.** Ассеты ремейка обфусцированы: каждый файл **XOR-ится одним
|
||||
байтом**, ключ = `файл[0] ^ 0x89` (у `rock.png` это 0x20). Декод:
|
||||
`key = b[0] ^ 0x89; for (i) b[i] ^= key;`
|
||||
- **Ассеты ремейка обфусцированы:** каждый файл **XOR-ится одним байтом**, ключ
|
||||
восстанавливается по сигнатуре формата: PNG — `b[0] ^ 0x89`, OGG — `b[0] ^ 0x4F`,
|
||||
JSON — `b[0] ^ 0x7B`. Уже декодировано: `assets/rustex/` (1.65 ГБ, 19 тыс. файлов).
|
||||
Скрипты: `tools/extract-rustex-assets.py`, `tools/extract-items.py`,
|
||||
`tools/extract-sounds.py`. **Осталось непрочитанным:** 553 `.obj`, 106 `.rrs`,
|
||||
113 `.nbt` — у них не однобайтовый шифр, нужен разбор кода.
|
||||
- **Текстуры предметов — временные** (взяты из ремейка как заглушки, иконки из
|
||||
`assets/rustex/gamejar/assets/rustex/icons/atlas.png`). **ПОМЕТКА: заменить на свои.**
|
||||
- **База предметов** — `rsx-protocol/src/main/resources/items/items.csv` (218 шт,
|
||||
из `models/stacks.json`), описания — `assets/rustex/data/item-texts.json` (543 шт),
|
||||
звуки — `rsx-protocol/src/main/resources/items/sounds.csv` (505 событий).
|
||||
- Пути: `G:\RustNotMC` (репозиторий), `G:\decompiled-rustex` (референс, только читать),
|
||||
`G:\rustexremake` (исходники ремейка с ассетами).
|
||||
`G:\rustexremake` (ремейк: `gamefiles\res`, `gamefiles\game.jar`, `working_dir`).
|
||||
- ⚠️ **`G:\decompiled-rustex` — НЕ источник фактов.** Он копиял community-вику 2017–2020
|
||||
(отсюда шкала скрапа 20/75/125/500, «урон по постройкам» 9/0.2/0.1, списки верстаков
|
||||
с перемешанными уровнями). Проверять числа по официальной вики Facepunch и по истории
|
||||
её правок (рецепт запроса — в шапке раздела 1).
|
||||
с перемешанными уровнями). Проверять числа по официальной вики Facepunch, по базе
|
||||
ремейка и по истории правок вики (рецепт запроса — в шапке раздела 1).
|
||||
- Скрипты — **ASCII без BOM** (PS 5.1 читает без BOM в ANSI и ломает парсер).
|
||||
- В PowerShell **нет heredoc**: сообщения коммитов пишем в файл и `git commit -F`.
|
||||
- Класс-паттерн SSH: `git config core.sshCommand "ssh -i C:/Users/User/.ssh/id_ed25519_zernmc -o IdentitiesOnly=yes"`.
|
||||
@@ -840,14 +1011,16 @@ rsx-client\scripts\run-game.ps1 # клиент
|
||||
### 6.5 Дописать в этот файл
|
||||
|
||||
- [x] Полные таблицы предмет→верстак (п. 1.2, 1.7) и предмет→скрап/чертёж (п. 1.3, 1.7).
|
||||
- [x] Таблица сбора по классам ресурсов (п. 1.6).
|
||||
- [x] Таблица сбора по классам ресурсов (п. 1.6) — **из базы ремейка**.
|
||||
- [x] Список строительных объектов с сокетами (п. 1.8) — пересобран по игровым данным.
|
||||
- [ ] Что решили по ролям: из лаунчера или свои на сервере (вопрос в п. 5).
|
||||
- [x] Мусорка (п. 1.10) и дороги (п. 1.11).
|
||||
- [x] Что решили по ролям: свои на сервере (п. 2.1, 5.1).
|
||||
- [ ] Стоимость и время каждого рецепта, который будем реализовывать (пока есть по
|
||||
ключевым предметам, п. 1.7).
|
||||
- [ ] Завести в репозитории выгрузку данных оригинала **на дату 06.11.2025**
|
||||
(страницы вики + история правок), чтобы цифры не разъезжались при перечитывании.
|
||||
- [ ] Решить модель урона по постройкам (п. 5, п. 1.11) — без неё рейд не считается.
|
||||
- [ ] Таблица оружия по `rweaponid` из кода ремейка (REA) — урон, отдача, спрей, темп.
|
||||
- [ ] Модель урона по постройкам — своя: ударов = HP ÷ урон оружия (п. 5.1).
|
||||
|
||||
---
|
||||
|
||||
@@ -939,3 +1112,26 @@ rsx-client\scripts\run-game.ps1 # клиент
|
||||
датированной вики нет (на странице в 2017 г. стоял текст «has X health»).
|
||||
19. **Взрыв у Heavy Plate** (8/12/12 % против 17/17/17 % против 100 %) — не подтверждён.
|
||||
|
||||
### П.3 Правки 21.10.2026 (база из ремейка)
|
||||
|
||||
Что поменялось после того, как выгрузили ассеты и базу предметов ремейка.
|
||||
|
||||
| было в плане | как на самом деле | метка |
|
||||
|---|---|---|
|
||||
| Сбор по вики: камень 10 дерева / 5 руды, топор 30, кирка 30; узлы 750/500/200 | **База ремейка**: камень 50 дерева / 35 руды, каменный топор 80, топор 85, каменная кирка 80, кирка 100. Удары: дерево 750 ÷ 85 = **9** (с меткой ≈ 6–7) — ровно «7–10 ударов», которые и ждал игрок | ✅ |
|
||||
| «Тех-дерево не делаем, оно бесплатно с 06.11.2025, колонка 125/250/500 устарела» | **Официальная вики показывает обе цены**: «Research Table» (15/30/60/120) и «Workbench Level N – Tech Tree» (125/250/500). Это community-вика была неправа | ✅ |
|
||||
| Исследование только через стол | **Два пути**: стол (нужен сам предмет → чертёж) и тех-дерево (только скрап, личная разблокировка) | ✅ |
|
||||
| В мире есть лоза (twig): HP 10, цены, гниение 1 ч, «лозовые полы» | **Лозы у нас нет** — она из джунглей, а джунглей нет. Выкинута отовсюду | ✅ |
|
||||
| Скрап только из лутбоксов; прогрессия не запускается | **Мусорка на дороге** даёт скрап (серая бочка, 1–15), компоненты (синяя) и топливо (красная) | С |
|
||||
| Узлы-руда — как в Rust | Руда — **3D-модель + AABB** (модели `ore/*` из ремейка), деревья — пока блоки мира с серверным HP | С |
|
||||
| Дорог в мире нет | **Сетка 3–4 дорог + кольцо** по берегу; сегменты дороги — точки спавна мусорки | С |
|
||||
|
||||
**Что выгружено из ремейка** (инструменты в `tools/`, результат в `assets/rustex/`):
|
||||
1.65 ГБ, 19 тыс. файлов. Ассеты зашифрованы одним байтом (ключ по сигнатуре формата),
|
||||
декод делает `extract-rustex-assets.py`. Не прочитались 553 `.obj`, 106 `.rrs`, 113 `.nbt` —
|
||||
у них другой шифр, нужен разбор кода (REA).
|
||||
|
||||
**Что теперь не подтверждено:** урон/отдача/спрей/темп огнестрела — в клиенте ремейка
|
||||
этих чисел нет (серверные данные), есть только магазин, тип патрона, ADS-зум, прочность,
|
||||
reach и `rweaponid` (1–21). Ищем таблицу в коде; до этого — цифры с официальной вики.
|
||||
|
||||
|
||||
@@ -216,10 +216,32 @@ starts, `play()` is called, nothing is found, and paulscode says nothing.
|
||||
`tools\materialize_assets.py` lays the tree out and `run-game.ps1` calls it on
|
||||
every launch, so this cannot be forgotten again.
|
||||
|
||||
### The base from the remake
|
||||
|
||||
The item models, textures, sounds and the whole item database are taken from
|
||||
the Rustex remake as a temporary base. `tools\extract-rustex-assets.py` unpacks
|
||||
them into `assets\rustex` (1.65 GB, not in the repository) and decodes the
|
||||
one-byte XOR the remake uses. What we derived from that and keep in the
|
||||
repository:
|
||||
|
||||
| File | What |
|
||||
|---|---|
|
||||
| `rsx-protocol\src\main\resources\items\items.csv` | 218 items: damage, range, tempo, durability, harvest per hit, material, icon, model |
|
||||
| `rsx-protocol\src\main\resources\items\sounds.csv` | 505 sound events with their files |
|
||||
| `rsx-protocol\src\main\resources\items\item-texts.json` | 543 item titles and descriptions |
|
||||
|
||||
These numbers are the balance we build on, and they are the ones the official
|
||||
wiki contradicts (the wiki describes original Rust, the remake is faster). The
|
||||
item icons come from the atlas of the remake and are placeholders: **replace
|
||||
them with our own.**
|
||||
|
||||
## Tools
|
||||
|
||||
| Script | Purpose |
|
||||
|---|---|
|
||||
| `tools\extract-rustex-assets.py` | unpacks the assets of the Rustex remake and decodes them: every file is XOR-ed with one byte, the key comes from the format signature (PNG `^0x89`, OGG `^0x4F`, JSON `^0x7B`) |
|
||||
| `tools\extract-items.py` | turns `models/stacks.json` of the remake into `rsx-protocol\...\items\items.csv`: 218 items with damage, range, tempo, durability, harvest per hit, material, icon, model |
|
||||
| `tools\extract-sounds.py` | the sound registry of the remake into `sounds.csv`: 505 events with their files |
|
||||
| `rsx-client\tools\merge_srg_mcp.py` | vanilla SRG plus MCP CSVs into one obf to MCP SRG |
|
||||
| `rsx-client\tools\apply_patches.py` | re-applies the hand fixes, fails loudly if one misses |
|
||||
| `rsx-client\tools\add_patch.py` | appends a reviewed patch to the fix file |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,219 @@
|
||||
rid,name,category,material,nid,damage,range,cooldown,reach,durability,durability_max,wood,ore,skinning,ammo,ammo_type,weapon_id,gun,throw,model,icon,zoom_x,zoom_y,zoom_z,zoom_count,heal,fast_heal,calories,hydration,radiation,bleeding,consume_time,food_cooldown,eat_sound,armor_projectile,armor_melee,armor_bite,armor_cold,armor_explosion,armor_radiation,armor_speed_reduction,armor_slot
|
||||
ironaxe,,tools,metalwood,2048,25,3,31,4,300,300,85,,1,,,,,1,,hatchet,1,4,1,17,,,,,,,,,,,,,,,,,
|
||||
boneclub,Club,weapon,metalwood,3072,16,3,16,4,300,300,60,44,0.5,,,,,1,,boneclub,0,10,0,20,,,,,,,,,,,,,,,,,
|
||||
largewoodbox,Wood Box,items,wood,516,,,,,300,300,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
blueberries,,medical,rubber,2562,,,,,,,,,,,,,,,,,,,,,0,10,30,20,0,0,5,18,,,,,,,,,
|
||||
metalfacemask,Facemask,clothes,metalhollow,1542,,,,,800,800,,,,,,,,,,,,,,,,,,,,,,,,50,70,8,-4,8,0,0,hat
|
||||
burlapboots,Shoes,clothes,cloth,1543,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,5,5,2,3,0,2,0,boots
|
||||
woodpants,Armor Pants,clothes,wood,1544,,,,,400,400,,,,,,,,,,,,,,,,,,,,,,,,10,40,5,0,5,5,0,kilt
|
||||
hmlmg,,weapon,gun,3081,,,,200,2500,2500,,,,6,2,13,1,,hmlmg,hmlmg,-5.5,2.9,3.5,20,,,,,,,,,,,,,,,,,
|
||||
hidepants,Pants,clothes,leather,1548,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,10,10,8,4,0,2,0,pants
|
||||
cookedchicken,Chicken,medical,meat,2572,,,,,,,,,,,,,,,,,,,,,10,0,40,3,0,0,5,20,,,,,,,,,
|
||||
homemadelandmine,Landmine,traps,metalmedium,4097,,,,,200,200,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
sulfur,,res,charcol,1039,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
mushroom,,medical,meat,2576,,,,,,,,,,,,,,,,,,,,,0,3,15,5,0,0,5,18,,,,,,,,,
|
||||
metalblade,Blade,res,metalhollow,1043,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
beancangrenade,Grenade,weapon,canfull,3089,,,,,,,,,,,,,,,,beancangrenade,,,,,,,,,,,,,,,,,,,,,
|
||||
pistolbullet,Bullet,ammo,metal,3592,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
cookedpork,Pork,medical,meat,2577,,,,,,,,,,,,,,,,,,,,,5,0,60,1,0,0,5,20,,,,,,,,,
|
||||
cookeddeermeat,Deer Meat,medical,meat,2579,,,,,,,,,,,,,,,,,,,,,10,0,40,3,0,0,5,20,,,,,,,,,
|
||||
mediumpresent,Present,tools,leather,2053,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
semiautomaticrifle,Rifle,weapon,gun,3095,,,,200,1300,1300,,,,6,2,8,1,,semiautomaticrifle,semiautomaticrifle,-4.99,1.1,1.8,15,,,,,,,,,,,,,,,,,
|
||||
gunpowder,Powder,res,snow,1052,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
hqm_ore,Quality Metal Ore,res,stone,1056,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
tanktop,Top,clothes,leather,1571,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,10,10,3,2,0,2,0,plate
|
||||
customsmg,SMG,weapon,gun,3100,,,,200,800,800,,,,8,0,5,1,,customsmg,customsmg,-5.51,1.6,2,15,,,,,,,,,,,,,,,,,
|
||||
12gaugebuckshot,Gauge Buckshot,ammo,leather,3584,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
rawhumanmeat,Human Meat,medical,,2589,,,,,,,,,,,,,,,,,,,,,0,-9,5,-3,0,0,5,18,,,,,,,,,
|
||||
woodendoor,Door,building,wood,13,,,,,200,200,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
buckethelmet,Helmet,clothes,metalthinhollow,1579,,,,,400,400,,,,,,,,,,,,,,,,,,,,,,,,20,50,8,6,8,4,0,helmet
|
||||
lr300assaultrifle,Assault Rifle,weapon,gun,3104,,,,200,2500,2500,,,,30,2,10,1,,lr300assaultrifle,lr300assaultrifle,-5.33,0.55,5,15,,,,,,,,,,,,,,,,,
|
||||
baseballcap,Cap,clothes,cloth,1536,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,10,10,3,7,0,1,0,helmet
|
||||
targetingcomputer,Computer,res,smalldevice,1025,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
waterpipeshotgun,Shotgun,weapon,gun,3078,,,,200,200,200,,,,1,8,15,1,,waterpipeshotgun,waterpipeshotgun,-3.79,2.65,3,15,,,,,,,,,,,,,,,,,
|
||||
burlaphelmet,Headwrap,clothes,cloth,1541,,,,,300,0,,,,,,,,,,,,,,,,,,,,,,,,15,15,3,7,0,2,0,hat
|
||||
rawchickenbreast,Chicken Breast,medical,meat,2567,,,,,,,,,,,,,,,,,,,,,-9,0,20,0,0,0,5,20,,,,,,,,,
|
||||
emptytunacan,Tuna Can,res,canempty,1035,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
boneknife,Knife,weapon,metalwood,3083,16,3,16,4,250,250,,,1,,,,,1,,boneknife,0,7,0,20,,,,,,,,,,,,,,,,,
|
||||
rawwolfmeat,Wolf Meat,medical,,2571,,,,,,,,,,,,,,,,,,,,,-9,0,20,0,0,0,5,20,,,,,,,,,
|
||||
heavyhelmet,Plate Helmet,clothes,metalhollowlarge,1547,,,,,1000,1000,,,,,,,,,,,,,,,,,,,,,,,,90,80,13,-17,17,7,20,hat
|
||||
mp5a4,,weapon,gun,3086,,,,200,1500,1500,,,,8,0,7,1,,mp5a4,mp5a4,-5.89,2.05,5.5,15,,,,,,,,,,,,,,,,,
|
||||
boots,,clothes,leather,1551,,,,,400,0,,,,,,,,,,,,,,,,,,,,,,,,10,10,3,8,0,3,0,boots
|
||||
stonepickaxe,Pickaxe,tools,metalwood,2064,17,3,32,4,160,160,,80,0.71,,,,,1,,stonepickaxe,2,4,1,17,,,,,,,,,,,,,,,,,
|
||||
thompson,,weapon,gun,3087,,,,200,800,800,,,,7,0,6,1,,thompson,thompson,-3.878,1.6,1.9,15,,,,,,,,,,,,,,,,,
|
||||
woodenladder,Ladder,building,woodmed,16,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
key,Key,tools,metal,2068,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
wolfskull,Skull,res,bone,1048,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
salvagedhammer,Hammer,tools,metalmediumrattley,2051,30,3,19,4,400,400,40,59,0.45,,,,,1,,salvagedhammer,-3,5,0,20,,,,,,,,,,,,,,,,,
|
||||
snowjacket,Jacket,clothes,cloth,1558,,,,,400,0,,,,,,,,,,,,,,,,,,,,,,,,20,30,5,17,0,20,0,plate
|
||||
binoculars,,tools,gun,2055,,,,,,,,,,,,,,,,binoculars,,,,,,,,,,,,,,,,,,,,,
|
||||
huntingbow,Bow,weapon,woodlight,3094,,,,200,100,100,,,,,6,19,1,,huntingbow,huntingbow,-5.25,7.8,6,15,,,,,,,,,,,,,,,,,
|
||||
woodenarrow,Arrow,ammo,woodlight,3589,,,,,,,,,,,,,,,,woodenarrow,,,,,,,,,,,,,,,,,,,,,
|
||||
handmadeshell,Shell,ammo,leather,3591,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
largemedkit,Medkit,medical,plasticmedium,2582,,,,,,,,,,,,,,,,largemedkit,,,,,100,10,0,0,0,-100,0,20,,,,,,,,,
|
||||
tshirt,,clothes,cloth,1573,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,15,15,5,6,0,3,0,plate
|
||||
crudeoil,Oil,res,leather,1062,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
charcoal,,res,charcol,1064,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
hv556rifleammo,5.56 Rifle Ammo,ammo,metal,3588,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
metalfragment,Fragments,res,metal,1024,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
furnace,,items,stone,517,,,,,500,500,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
hqm,Quality Metal,res,metal,1028,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
cookedwolfmeat,Wolf Meat,medical,meat,2560,,,,,,,,,,,,,,,,,,,,,5,0,60,1,0,0,5,20,,,,,,,,,
|
||||
building_plan,Plan,building,paper,5,,,,,,,,,,,,,,,,buildingplan,,,,,,,,,,,,,,,,,,,,,
|
||||
rocketlauncher,Launcher,weapon,metalhollowlarge,3080,,,,200,,,,,,,,,1,,,rocketlauncher,-3.45,6,3.5,20,,,,,,,,,,,,,,,,,
|
||||
sheetmetal,Metal,res,metalsheet,1032,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
chocolatebar,Bar,medical,leather,2569,,,,,,,,,,,,,,,,,,,,,1,0,100,2,0,0,5,18,,,,,,,,,
|
||||
emptypropanetank,Propane Tank,res,metalhollow,1033,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
lowgradefuel,Grade Fuel,res,liquidcontainer,1037,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
12gaugeslug,Gauge Slug,ammo,leather,3587,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
waterjug,Jug,medical,plasticjunk,2574,,,,,,,,,,,,,,,,waterjug,,,,,,,,,,,,,,,,,,,,,
|
||||
wood,,res,wood,1040,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
hat,Hat,clothes,cloth,1552,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,10,10,3,7,0,1,0,helmet
|
||||
balaclava,Balaclava,clothes,cloth,1556,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,15,15,3,13,3,3,0,hat
|
||||
dieselbarrel,Fuel,res,metalbars,1050,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
stoneaxe,Hatchet,tools,metalwood,2056,15,3,32,4,160,160,80,,0.59,,,,,1,,stoneaxe,2,4,1,17,,,,,,,,,,,,,,,,,
|
||||
jacket,,clothes,cloth,1562,,,,,400,0,,,,,,,,,,,,,,,,,,,,,,,,15,20,7,10,0,5,0,jacket
|
||||
bonehelmet,Helmet,clothes,leather,1565,,,,,400,400,,,,,,,,,,,,,,,,,,,,,,,,25,40,13,0,7,4,0,hat
|
||||
roadsignkilt,Sign Kilt,clothes,metalsheet,1568,,,,,600,600,,,,,,,,,,,,,,,,,,,,,,,,20,25,10,-8,0,0,0,kilt
|
||||
roadsigns,Signs,res,metalsheet,1058,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
hideboots,Boots,clothes,leather,1574,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,5,5,3,5,0,2,0,boots
|
||||
metalspring,Spring,res,spring,1061,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
semiautomaticbody,Automatic Body,res,gun,1065,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
explosive556rifleammo,5.56 Rifle Ammo,ammo,metal,3593,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
woodhelmet,Armor Helmet,clothes,wood,1538,,,,,400,400,,,,,,,,,,,,,,,,,,,,,,,,15,25,3,7,0,2,0,helmet
|
||||
mace,,weapon,metalhollow,3074,60,3,35,4,300,300,,,0.83,,,,,1,,mace,-4,8,0,20,,,,,,,,,,,,,,,,,
|
||||
boltactionrifle,Action Rifle,weapon,gun,3075,,,,200,600,600,,,,1,2,11,1,,boltactionrifle,boltactionrifle,-3.35,2.585,3.2,15,,,,,,,,,,,,,,,,,
|
||||
rope,,res,cloth,1029,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
booniehat,Hat,clothes,cloth,1540,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,15,15,3,7,0,2,0,helmet
|
||||
machete,,weapon,metalmediumrattley,3079,35,3,20,4,300,300,,,0.83,,,,,1,,machete,2,8,-1,25,,,,,,,,,,,,,,,,,
|
||||
sleepingbag,Bag,items,cloth,522,,,,,200,200,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
apple,,medical,thickrubbery,2568,,,,,,,,,,,,,,,,,,,,,0,2,30,15,0,0,5,18,,,,,,,,,
|
||||
spas12shotgun,Shotgun,weapon,gun,3084,,,,200,800,800,,,,6,8,18,1,,spas12shotgun,spas12shotgun,-2.435,2.1,3,20,,,,,,,,,,,,,,,,,
|
||||
combatknife,Knife,weapon,metalknife,3085,35,3,16,4,250,250,,,1,,,,,1,,combatknife,2,6,0,25,,,,,,,,,,,,,,,,,
|
||||
metalwindowbars,Window Bars,building,metalbars,7,,,,,500,500,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
codelock,Lock,building,smalldevice,8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
pythonrevolver,Revolver,weapon,gun,3088,,,,200,600,600,,,,6,0,3,1,,pythonrevolver,pythonrevolver,-4.6,2.3,2,15,,,,,,,,,,,,,,,,,
|
||||
recycler,,items,wood,521,,,,,750,750,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
roadsignjacket,Sign Jacket,clothes,metalsheet,1555,,,,,500,500,,,,,,,,,,,,,,,,,,,,,,,,20,25,10,-8,0,0,0,jacket
|
||||
salvagedicepick,Icepick,tools,metalmediumrattley,2049,40,3,28,4,1500,1500,,100,0.71,,,,,1,,salvagedicepick,-2.4,4.5,0,25,,,,,,,,,,,,,,,,,
|
||||
pumpshotgun,Shotgun,weapon,gun,3091,,,,200,400,400,,,,4,8,17,1,,pumpshotgun,pumpshotgun,-3.477,2.95,4,15,,,,,,,,,,,,,,,,,
|
||||
hideskirt,Skirt,clothes,leather,1560,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,10,10,3,7,0,2,0,pants
|
||||
stonespear,Spear,weapon,metalwood,3093,35,5,32,6,400,400,,,,,,,,1,,stonespear,2,8,-1,25,,,,,,,,,,,,,,,,,
|
||||
shotguntrap,Trap,traps,wood,4096,,,,,300,300,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
woodenwindowbars,Window Bars,building,woodmed,3,,,,,250,250,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
eokapistol,Pistol,weapon,gun,3098,,,,200,100,100,,,,1,8,14,1,,eokapistol,eokapistol,0,0,0,1000000,,,,,,,,,,,,,,,,,
|
||||
cactusflesh,Flesh,medical,,2580,,,,,,,,,,,,,,,,,,,,,3,0,5,20,0,0,5,18,,,,,,,,,
|
||||
canoftuna,of Tuna,medical,canfull,2581,,,,,,,,,,,,,,,,,,,,,2,0,50,15,0,0,5,18,,,,,,,,,
|
||||
stone,,res,stone,1055,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
roadsigngloves,Gloves,clothes,cloth,1569,,,,,600,0,,,,,,,,,,,,,,,,,,,,,,,,10,25,10,-8,0,0,0,gloves
|
||||
workbenchlevel2,Bench Level 2,items,metallarge,512,,,,,500,500,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
hoodie,,clothes,cloth,1570,,,,,400,0,,,,,,,,,,,,,,,,,,,,,,,,20,15,6,8,0,5,0,plate
|
||||
workbenchlevel1,Bench Level 1,items,wood,513,,,,,500,500,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
workbenchlevel3,Bench Level 3,items,metallarge,515,,,,,750,750,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
antirad,Pills,medical,pills,2586,,,,,,,,,,,,,,,,none,,,,,0,0,0,-10,-25,0,10,30,,,,,,,,,
|
||||
556rifleammo,Rifle Ammo,ammo,metal,3585,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
rawdeermeat,Deer Meat,medical,meat,2587,,,,,,,,,,,,,,,,,,,,,-9,0,20,0,0,0,5,20,,,,,,,,,
|
||||
woodchest,Chestplate,clothes,wood,1576,,,,,400,400,,,,,,,,,,,,,,,,,,,,,,,,10,40,5,0,5,5,0,jacket
|
||||
leathergloves,Gloves,clothes,cloth,1578,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,5,5,2,5,0,4,0,gloves
|
||||
crossbow,,weapon,gun,3073,,,,200,200,200,,,,1,6,20,1,,crossbow,crossbow,-7.4,4.1,5,15,,,,,,,,,,,,,,,,,
|
||||
nailgun,,weapon,gun,3076,,,,200,100,100,,,,6,5,21,1,,nailgun,nailgun,-3.315,1.667,3.5,15,,,,,,,,,,,,,,,,,
|
||||
granolabar,Bar,medical,leather,2565,,,,,,,,,,,,,,,,,,,,,5,0,60,0,0,0,5,20,,,,,,,,,
|
||||
snaptrap,Trap,traps,metalmedium,4099,,,,,200,200,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
timedexplosivecharge,Explosive Charge,tools,leather,2059,,,,,,,,,,,,,,,,timedexplosivecharge,,,,,,,,,,,,,,,,,,,,,
|
||||
meatpork,Pork,medical,meat,2570,,,,,,,,,,,,,,,,,,,,,-2,0,60,0,0,0,5,20,,,,,,,,,
|
||||
woodstoragebox,Storage Box,items,woodmed,514,,,,,150,150,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
sheetmetaldoubledoor,Metal Double Door,building,metalhollowlarge,10,,,,,250,250,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
gears,,res,metalmedium,1045,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
metalchest,Chest Plate,clothes,metalhollowlarge,1557,,,,,800,800,,,,,,,,,,,,,,,,,,,,,,,,25,20,3,-8,0,0,0,jacket
|
||||
rawbearmeat,Bear Meat,medical,meat,2578,,,,,,,,,,,,,,,,,,,,,-2,0,10,10,0,0,5,20,,,,,,,,,
|
||||
humanskull,Skull,res,bone,1049,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
revolver,,weapon,gun,3092,,,,200,300,300,,,,4,0,1,1,,revolver,revolver,-3.2,1.102,3.3,15,,,,,,,,,,,,,,,,,
|
||||
smgbody,Body,res,gun,1051,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
satchelcharge,Charge,tools,leather,2057,,,,,,,,,,,,,,,,satchelcharge,,,,,,,,,,,,,,,,,,,,,
|
||||
garagedoor,Door,building,metalsheet,4,,,,,600,600,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
leather,,res,leather,1054,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
smallpresent,Present,tools,leather,2061,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
animalfat,Fat,res,meat,1063,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
candycaneclub,Cane Club,medical,leather,2588,,,,,,,,,,,,,,,,,,,,,16,0,300,100,0,0,5,20,,,,,,,,,
|
||||
riothelmet,Helmet,clothes,leather,1577,,,,,400,400,,,,,,,,,,,,,,,,,,,,,,,,25,80,13,6,8,5,0,helmet
|
||||
supplysignal,Signal,tools,gun,2065,,,,,,,,,,,,,,,,supplysignal,,,,,,,,,,,,,,,,,,,,,
|
||||
bluekeycard,Keycard,res,plasticjunk,1026,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
assaultrifle,Rifle,weapon,gun,3077,,,,200,2000,2000,,,,4,2,12,1,,assaultrifle,assaultrifle,-6.49,2.4,4.5,20,,,,,,,,,,,,,,,,,
|
||||
nailgunnails,Nails,ammo,metal,3590,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
bandage,,medical,cloth,2566,,,,,,,,,,,,,,,,bandage,,,,,0,5,0,0,0,-50,80,22,,,,,,,,,
|
||||
rock,,tools,stone,2060,10,2,40,3,100,100,50,35,0.5,,,,,1,,rock,5,7,1,15,,,,,,,,,,,,,,,,,
|
||||
burlapchest,Shirt,clothes,cloth,1546,,,,,300,0,,,,,,,,,,,,,,,,,,,,,,,,10,10,3,7,0,2,0,plate
|
||||
scrap,,res,metalmediumloose,1034,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
floorgrill,grill,building,metalbars,6,,,,,250,250,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
bonearmor,Armor,clothes,leather,1549,,,,,400,400,,,,,,,,,,,,,,,,,,,,,,,,25,40,13,0,7,4,0,boots
|
||||
potato,,medical,thickrubbery,2573,,,,,,,,,,,,,,,,,,,,,6,0,125,5,0,0,5,18,,,,,,,,,
|
||||
metal_ore,Ore,res,stone,1041,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
sewingkit,Kit,res,bone,1042,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
shorts,,clothes,cloth,1553,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,10,10,3,7,0,2,0,pants
|
||||
tarp,,res,tarp,1044,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
woodenspear,Spear,weapon,metalwood,3090,25,4,32,5,250,250,,,,,,,,1,,woodenspear,2,8,-1,25,,,,,,,,,,,,,,,,,
|
||||
plantfiber,Fiber,res,meat,1047,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
toolcupboard,Cupboard,building,wood,1,,,,,100,100,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
m92pistol,Pistol,weapon,gun,3096,,,,200,800,800,,,,15,0,4,1,,m92pistol,m92pistol,-5.18,2.1,3.3,15,,,,,,,,,,,,,,,,,
|
||||
torch,,tools,metalwood,2058,,,,,,,,,,,,,,,,torch,,,,,,,,,,,,,,,,,,,,,
|
||||
heavypants,Plate Pants,clothes,metalhollowlarge,1566,,,,,1000,1000,,,,,,,,,,,,,,,,,,,,,,,,75,70,12,-17,17,7,30,kilt
|
||||
m39rifle,Rifle,weapon,gun,3099,,,,200,1500,1500,,,,20,2,9,1,,m39rifle,m39rifle,-8.08,3.8,4,20,,,,,,,,,,,,,,,,,
|
||||
smallwaterbottle,Water Bottle,medical,plasticjunk,2584,,,,,,,,,,,,,,,,smallwaterbottle,,,,,,,,,,,,,,,,,,,,,
|
||||
shirt,,clothes,cloth,1572,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,15,15,5,6,0,3,0,plate
|
||||
strengthenedglasswindow,Glass Window,building,metalbars,9,,,,,350,350,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
researchtable,Table,items,metallarge,518,,,,,200,200,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
keylock,Lock,building,metal,11,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
lowhp,,items,,519,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
armoreddoor,Door,building,metalhollowlarge,14,,,,,1000,1000,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
salvagedcleaver,Cleaver,weapon,metalwood,3102,60,3,35,4,400,400,,,0.83,,,,,1,,salvagedcleaver,-3,5,0,20,,,,,,,,,,,,,,,,,
|
||||
armoreddoubledoor,Double Door,building,metalhollowlarge,0,,,,,1000,1000,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
pants,,clothes,cloth,1539,,,,,400,0,,,,,,,,,,,,,,,,,,,,,,,,15,15,3,8,0,5,0,pants
|
||||
sulfur_ore,Ore,res,stone,1027,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
corn,,medical,leather,2561,,,,,,,,,,,,,,,,,,,,,6,0,75,10,0,0,5,20,,,,,,,,,
|
||||
cookedbearmeat,Bear Meat,medical,meat,2564,,,,,,,,,,,,,,,,,,,,,5,0,100,1,0,0,5,20,,,,,,,,,
|
||||
explosives,,res,leather,1030,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
salvagedsword,Sword,weapon,metalmediumrattley,3082,50,3,25,4,300,300,,,0.83,,,,,1,,salvagedsword,-3.16,5.5,0,20,,,,,,,,,,,,,,,,,
|
||||
hidehalterneck,Halterneck,clothes,leather,1545,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,10,10,3,7,0,2,0,plate
|
||||
techtrash,Trash,res,plasticjunk,1036,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
largepresent,Present,tools,leather,2062,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
hazmatsuit,Suit,clothes,tarp,1550,,,,,1000,1000,,,,,,,,,,,,,,,,,,,,,,,,30,30,8,8,5,50,0,suit
|
||||
horsedung,Dung,res,meat,1038,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
campfire,,items,wood,520,,,,,50,50,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
hideponcho,Poncho,clothes,leather,1554,,,,,400,400,,,,,,,,,,,,,,,,,,,,,,,,10,40,5,8,5,8,0,jacket
|
||||
electricfuse,Fuse,res,smalldevice,1046,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
hvpistolammo,Pistol Ammo,ammo,metal,3594,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
salvagedaxe,Axe,tools,metalmediumrattley,2054,40,3,28,4,1500,1500,100,,1,,,,,1,,salvagedaxe,3,4,0,30,,,,,,,,,,,,,,,,,
|
||||
hagi,,clothes,,1564,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,plate
|
||||
wolfheaddress,Headdress,clothes,leather,1567,,,,,0,0,,,,,,,,,,,,,,,,,,,,,,,,30,60,10,6,13,4,0,helmet
|
||||
torch_fire,,tools,metalwood,2066,,,,,,,,,,,,,,,,torch,,,,,,,,,,,,,,,,,,,,,
|
||||
cloth,,res,cloth,1066,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
longsword,,weapon,metalmediumrattley,3103,75,3,35,4,400,400,,,0.83,,,,,1,,longsword,-3,6,0,20,,,,,,,,,,,,,,,,,
|
||||
coffecanhelmet,Can Helmet,clothes,metalthinhollow,1537,,,,,500,500,,,,,,,,,,,,,,,,,,,,,,,,35,50,8,0,8,5,0,hat
|
||||
hammer,,tools,metalwood,2050,,,,,,,,,,,,,,,,hammer,,,,,,,,,,,,,,,,,,,,,
|
||||
death,,tools,,2052,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
blackraspberries,Raspberries,medical,,2563,,,,,,,,,,,,,,,,,,,,,0,10,40,20,0,0,5,18,,,,,,,,,
|
||||
reinforcedglasswindow,Glass Window,building,metalbars,2,,,,,500,500,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
metalpipe,Pipe,res,metalhollow,1031,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
highvelocityarrow,Velocity Arrow,ammo,woodlight,3586,,,,,,,,,,,,,,,,highvelocityarrow,,,,,,,,,,,,,,,,,,,,,
|
||||
medicalsyringe,Syringe,medical,smalldevice,2575,,,,,,,,,,,,,,,,medicalsyringe,,,,,20,15,0,0,-10,0,14,10,,,,,,,,,
|
||||
wooddoubledoor,Double Door,building,wood,12,,,,,200,200,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
sheetmetaldoor,Metal Door,building,metalhollowlarge,15,,,,,250,250,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
maskbandana,Mask,clothes,cloth,1559,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,5,10,3,10,0,3,0,hat
|
||||
burlappants,Trousers,clothes,cloth,1561,,,,,300,0,,,,,,,,,,,,,,,,,,,,,,,,10,10,3,7,0,2,0,pants
|
||||
semiautomaticpistol,Pistol,weapon,gun,3097,,,,200,600,600,,,,4,0,2,1,,semiautomaticpistol,semiautomaticpistol,-5.35,2.69,4.3,15,,,,,,,,,,,,,,,,,
|
||||
woodenfloorspikes,Floor Spikes,traps,wood,4098,,,,,100,100,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
hidechest,Vest,clothes,leather,1563,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,15,15,8,5,0,3,0,plate
|
||||
fertilizer,,res,meat,1053,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
canofbeans,of Beans,medical,canfull,2583,,,,,,,,,,,,,,,,,,,,,4,0,100,25,0,0,5,18,,,,,,,,,
|
||||
riflebody,Body,res,gun,1057,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
cookedhumanmeat,Human Meat,medical,,2585,,,,,,,,,,,,,,,,,,,,,2,0,30,-30,0,0,5,18,,,,,,,,,
|
||||
backpack,,tools,,2063,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
bonefragments,Fragments,res,bone,1059,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
cctvcamera,Camera,res,smalldevice,1060,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
burlapgloves,Gloves,clothes,cloth,1575,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,0,5,2,4,0,3,0,gloves
|
||||
longtshirt,T-Shirt,clothes,cloth,1580,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,15,15,6,10,0,5,0,plate
|
||||
doublebarrelshotgun,Barrel Shotgun,weapon,gun,3101,,,,200,200,200,,,,1,8,16,1,,doublebarrelshotgun,doublebarrelshotgun,-8.6,5.8,5,15,,,,,,,,,,,,,,,,,
|
||||
pumpkin,,medical,thickrubbery,2590,,,,,,,,,,,,,,,,,,,,,10,0,100,30,0,0,5,18,,,,,,,,,
|
||||
ironpickaxe,,tools,metalwood,2067,30,3,32,4,300,300,,100,0.45,,,,,1,,pickaxe,1,4,1,17,,,,,,,,,,,,,,,,,
|
||||
emptycanofbeans,Can Of Beans,res,canempty,1067,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
heavychest,Plate Jacket,clothes,metalhollowlarge,1581,,,,,1000,1000,,,,,,,,,,,,,,,,,,,,,,,,75,70,12,-17,17,7,30,plate
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,279 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Turn the item database of the Rustex remake into a table we can read.
|
||||
|
||||
The remake keeps its item definitions in
|
||||
assets/rustex/legacy/minecraft/models/stacks.json . The file is not JSON
|
||||
but the Minecraft "stacks" notation: a sequence of records
|
||||
|
||||
{id:"minecraft:iron_hoe",Count:1s,tag:{rid:"m92pistol",rdamage:25,...}}
|
||||
|
||||
The tag keys are the remake's own names, so the table keeps them. The
|
||||
result is two files:
|
||||
|
||||
rsx-protocol/src/main/resources/items/items.csv one row per item
|
||||
assets/rustex/data/item-texts.json the titles and the
|
||||
descriptions out of
|
||||
the language file
|
||||
"""
|
||||
|
||||
import csv
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(r"G:\RustNotMC")
|
||||
STACKS = ROOT / "assets" / "rustex" / "legacy" / "minecraft" / "models" / "stacks.json"
|
||||
LANG = ROOT / "assets" / "rustex" / "legacy" / "minecraft" / "rustex_lang" / "en_us.lang"
|
||||
OUT_CSV = ROOT / "rsx-protocol" / "src" / "main" / "resources" / "items" / "items.csv"
|
||||
OUT_TEXTS = ROOT / "rsx-protocol" / "src" / "main" / "resources" / "items" / "item-texts.json"
|
||||
|
||||
# The columns of the table, in the order they are written.
|
||||
COLUMNS = [
|
||||
"rid", "name", "category", "material", "nid",
|
||||
"damage", "range", "cooldown", "reach",
|
||||
"durability", "durability_max",
|
||||
"wood", "ore", "skinning",
|
||||
"ammo", "ammo_type", "weapon_id", "gun", "throw", "model", "icon",
|
||||
"zoom_x", "zoom_y", "zoom_z", "zoom_count",
|
||||
"heal", "fast_heal", "calories", "hydration", "radiation", "bleeding",
|
||||
"consume_time", "food_cooldown", "eat_sound",
|
||||
"armor_projectile", "armor_melee", "armor_bite", "armor_cold",
|
||||
"armor_explosion", "armor_radiation", "armor_speed_reduction",
|
||||
"armor_slot",
|
||||
]
|
||||
|
||||
|
||||
class Parser:
|
||||
"""A reader for the Minecraft stacks notation."""
|
||||
|
||||
def __init__(self, text: str):
|
||||
self.text = text
|
||||
self.pos = 0
|
||||
|
||||
def skip(self):
|
||||
while self.pos < len(self.text) and self.text[self.pos] in " \t\r\n":
|
||||
self.pos += 1
|
||||
|
||||
def peek(self) -> str:
|
||||
self.skip()
|
||||
return self.text[self.pos] if self.pos < len(self.text) else ""
|
||||
|
||||
def read_value(self):
|
||||
self.skip()
|
||||
ch = self.text[self.pos]
|
||||
if ch == "{":
|
||||
return self.read_compound()
|
||||
if ch == "[":
|
||||
return self.read_list()
|
||||
if ch == '"':
|
||||
return self.read_string()
|
||||
return self.read_scalar()
|
||||
|
||||
def read_compound(self):
|
||||
self.pos += 1 # {
|
||||
out = {}
|
||||
while True:
|
||||
self.skip()
|
||||
ch = self.peek()
|
||||
if ch == "}":
|
||||
self.pos += 1
|
||||
return out
|
||||
if ch == ",":
|
||||
self.pos += 1
|
||||
continue
|
||||
key = self.read_key()
|
||||
self.skip()
|
||||
if self.pos < len(self.text) and self.text[self.pos] == ":":
|
||||
self.pos += 1
|
||||
out[key] = self.read_value()
|
||||
|
||||
def read_list(self):
|
||||
self.pos += 1 # [
|
||||
out = []
|
||||
while True:
|
||||
self.skip()
|
||||
if self.peek() == "]":
|
||||
self.pos += 1
|
||||
return out
|
||||
out.append(self.read_value())
|
||||
self.skip()
|
||||
if self.peek() == ",":
|
||||
self.pos += 1
|
||||
|
||||
def read_key(self):
|
||||
start = self.pos
|
||||
while self.text[self.pos] not in ':,}]':
|
||||
self.pos += 1
|
||||
return self.text[start:self.pos].strip()
|
||||
|
||||
def read_string(self):
|
||||
self.pos += 1 # "
|
||||
out = []
|
||||
while self.text[self.pos] != '"':
|
||||
if self.text[self.pos] == "\\":
|
||||
self.pos += 1
|
||||
out.append(self.text[self.pos])
|
||||
self.pos += 1
|
||||
self.pos += 1
|
||||
return "".join(out)
|
||||
|
||||
def read_scalar(self):
|
||||
start = self.pos
|
||||
while self.pos < len(self.text) and self.text[self.pos] not in ',}]':
|
||||
self.pos += 1
|
||||
raw = self.text[start:self.pos].strip()
|
||||
if raw.endswith("b"):
|
||||
return raw[:-1] == "1"
|
||||
if raw.endswith("s"):
|
||||
return int(raw[:-1])
|
||||
if raw.endswith("d") or raw.endswith("f"):
|
||||
return float(raw[:-1])
|
||||
try:
|
||||
return int(raw)
|
||||
except ValueError:
|
||||
return raw
|
||||
|
||||
|
||||
def flatten(tag: dict) -> dict:
|
||||
"""The fields of a tag, with the names we use in the table."""
|
||||
out = {}
|
||||
|
||||
def num(value):
|
||||
if isinstance(value, bool):
|
||||
return 1 if value else 0
|
||||
if isinstance(value, (int, float)):
|
||||
return value
|
||||
return None
|
||||
|
||||
def put(key, value):
|
||||
n = num(value)
|
||||
if n is not None:
|
||||
out[key] = n
|
||||
|
||||
put("damage", tag.get("rdamage"))
|
||||
put("range", tag.get("rrange"))
|
||||
put("cooldown", tag.get("rcooldown"))
|
||||
put("reach", tag.get("rustreach"))
|
||||
put("durability", tag.get("rdurability"))
|
||||
put("durability_max", tag.get("rdurabilitymax"))
|
||||
put("wood", tag.get("rwood"))
|
||||
put("ore", tag.get("rore"))
|
||||
put("skinning", tag.get("skinning"))
|
||||
put("ammo", tag.get("rammo"))
|
||||
put("ammo_type", tag.get("rammotype"))
|
||||
put("weapon_id", tag.get("rweaponid"))
|
||||
put("gun", tag.get("rustgun"))
|
||||
put("throw", tag.get("rustthrow"))
|
||||
put("zoom_x", tag.get("rustzoomx"))
|
||||
put("zoom_y", tag.get("rustzoomy"))
|
||||
put("zoom_z", tag.get("rustzoomz"))
|
||||
put("zoom_count", tag.get("rustzoomcount"))
|
||||
put("heal", tag.get("rheal"))
|
||||
put("fast_heal", tag.get("rfastheal"))
|
||||
put("calories", tag.get("rcalories"))
|
||||
put("hydration", tag.get("rhydration"))
|
||||
put("radiation", tag.get("rradiation"))
|
||||
put("bleeding", tag.get("rbleeding"))
|
||||
put("consume_time", tag.get("rconsumetime"))
|
||||
put("food_cooldown", tag.get("rfoodcooldown"))
|
||||
put("armor_projectile", tag.get("rarmorprojectile"))
|
||||
put("armor_melee", tag.get("rarmormelee"))
|
||||
put("armor_bite", tag.get("rarmorbite"))
|
||||
put("armor_cold", tag.get("rarmorcold"))
|
||||
put("armor_explosion", tag.get("rarmorexplosion"))
|
||||
put("armor_radiation", tag.get("rarmorradiation"))
|
||||
put("armor_speed_reduction", tag.get("rarmorspeedreduction"))
|
||||
|
||||
display = tag.get("display")
|
||||
if isinstance(display, dict):
|
||||
name = display.get("Name")
|
||||
if isinstance(name, str):
|
||||
out["name"] = re.sub(r"^.\S*", "", name).strip()
|
||||
for slot, value in tag.items():
|
||||
if slot.startswith("armorslot.") and value:
|
||||
out["armor_slot"] = slot[len("armorslot."):]
|
||||
return out
|
||||
|
||||
|
||||
def parse_stacks(text: str):
|
||||
parser = Parser(text)
|
||||
items = []
|
||||
while True:
|
||||
parser.skip()
|
||||
if parser.pos >= len(parser.text):
|
||||
break
|
||||
if parser.peek() != "{":
|
||||
parser.pos += 1
|
||||
continue
|
||||
record = parser.read_compound()
|
||||
tag = record.get("tag")
|
||||
if not isinstance(tag, dict):
|
||||
continue
|
||||
rid = tag.get("rid")
|
||||
if not isinstance(rid, str):
|
||||
continue
|
||||
row = {
|
||||
"rid": rid,
|
||||
"category": tag.get("rcategory", ""),
|
||||
"material": tag.get("rmaterial", ""),
|
||||
"nid": tag.get("nid", ""),
|
||||
"model": tag.get("rmodel", ""),
|
||||
"icon": tag.get("rusticon", ""),
|
||||
}
|
||||
row.update(flatten(tag))
|
||||
items.append(row)
|
||||
return items
|
||||
|
||||
|
||||
def parse_lang(text: str):
|
||||
"""The item titles and descriptions out of the language file."""
|
||||
out = {}
|
||||
for line in text.splitlines():
|
||||
if "=" not in line:
|
||||
continue
|
||||
key, value = line.split("=", 1)
|
||||
match = re.match(r"^rustex\.items\.([a-z]+)\.([a-z0-9_]+)\.(title|disc)$", key)
|
||||
if not match:
|
||||
continue
|
||||
category, rid, kind = match.groups()
|
||||
entry = out.setdefault(rid, {"category": category})
|
||||
entry[kind] = value
|
||||
return out
|
||||
|
||||
|
||||
def main() -> int:
|
||||
if not STACKS.is_file():
|
||||
print("нет stacks.json:", STACKS)
|
||||
return 1
|
||||
|
||||
items = parse_stacks(STACKS.read_text(encoding="utf-8", errors="replace"))
|
||||
print("предметов:", len(items))
|
||||
|
||||
OUT_CSV.parent.mkdir(parents=True, exist_ok=True)
|
||||
with OUT_CSV.open("w", encoding="utf-8", newline="") as handle:
|
||||
writer = csv.DictWriter(handle, fieldnames=COLUMNS, extrasaction="ignore")
|
||||
writer.writeheader()
|
||||
for item in items:
|
||||
writer.writerow({key: item.get(key, "") for key in COLUMNS})
|
||||
print("таблица:", OUT_CSV)
|
||||
|
||||
if LANG.is_file():
|
||||
texts = parse_lang(LANG.read_text(encoding="utf-8", errors="replace"))
|
||||
OUT_TEXTS.parent.mkdir(parents=True, exist_ok=True)
|
||||
OUT_TEXTS.write_text(json.dumps(texts, ensure_ascii=False, indent=1),
|
||||
encoding="utf-8")
|
||||
print("описаний:", len(texts), "->", OUT_TEXTS)
|
||||
|
||||
# What the table has to tell us about the weapons.
|
||||
guns = [i for i in items if i.get("gun")]
|
||||
print("огнестрела в таблице:", len(guns))
|
||||
for gun in guns:
|
||||
print(" %-22s id=%-3s магазин=%-3s модель=%s"
|
||||
% (gun["rid"], gun.get("weapon_id", "?"), gun.get("ammo", "?"),
|
||||
gun.get("model", "-")))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -0,0 +1,213 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Extract the assets of the Rustex remake into a plain, decoded tree.
|
||||
|
||||
The remake ships its resources obfuscated: every file is XOR-ed with one
|
||||
byte, and the byte differs per file. The key is recoverable because the
|
||||
first bytes of every format are known:
|
||||
|
||||
PNG 89 50 4E 47 key = file[0] ^ 0x89
|
||||
OGG 4F 67 67 53 key = file[0] ^ 0x4F
|
||||
JSON 7B ... key = file[0] ^ 0x7B
|
||||
|
||||
Files that are already plain (KTX2, MODL, the icon atlas inside game.jar)
|
||||
are copied as they are. The formats with a stronger cipher (.obj, .rrs,
|
||||
.nbt, .properties, .lang) are copied untouched and reported, so that the
|
||||
reverse engineering pass knows what is still missing.
|
||||
|
||||
The result lands in assets/rustex/ :
|
||||
|
||||
legacy/ the Minecraft style assets of res/assets
|
||||
nextgen/ the high resolution models of res/nextgen
|
||||
gamejar/ the resources packed into game.jar (the icon atlas)
|
||||
maps/ the server map data (the monument layout)
|
||||
MANIFEST.json
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import time
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
SRC_ROOT = Path(r"G:\rustexremake\rustexremake")
|
||||
SRC_RES = SRC_ROOT / "gamefiles" / "res"
|
||||
SRC_JAR = SRC_ROOT / "gamefiles" / "game.jar"
|
||||
SRC_MAPS = SRC_ROOT / "working_dir" / "rustex" / "maps"
|
||||
DST = Path(r"G:\RustNotMC\assets\rustex")
|
||||
|
||||
PNG_MAGIC = b"\x89PNG\r\n\x1a\n"
|
||||
OGG_MAGIC = b"OggS"
|
||||
KTX2_MAGIC = b"\xabKTX 20\xbb\r\n\x1a\n"
|
||||
|
||||
# The first byte of the plain file, per extension. None means "we do not
|
||||
# know the format, try to brute force the key and score the result".
|
||||
FIRST_BYTE = {
|
||||
".png": 0x89,
|
||||
".ogg": 0x4F,
|
||||
".json": 0x7B,
|
||||
}
|
||||
|
||||
# The formats we can never guess: their cipher is not a single byte.
|
||||
OPAQUE = {".obj", ".rrs", ".nbt", ".bin", ".db", ".jpm"}
|
||||
|
||||
TEXTUAL = {".json", ".properties", ".lang", ".txt", ".mcmeta", ".fsh", ".vsh", ".glsl"}
|
||||
|
||||
|
||||
def score_text(data: bytes) -> float:
|
||||
"""How much of the data looks like readable text."""
|
||||
if not data:
|
||||
return 0.0
|
||||
good = 0
|
||||
for b in data:
|
||||
if b in (9, 10, 13) or 32 <= b < 127:
|
||||
good += 1
|
||||
return good / len(data)
|
||||
|
||||
|
||||
def unxor(data: bytes, key: int) -> bytes:
|
||||
if key == 0:
|
||||
return data
|
||||
return bytes(b ^ key for b in data)
|
||||
|
||||
|
||||
def decode_file(path: Path, ext: str):
|
||||
"""Return (decoded bytes, key, kind, note)."""
|
||||
data = path.read_bytes()
|
||||
if not data:
|
||||
return data, 0, "empty", "пустой файл"
|
||||
|
||||
# Already plain?
|
||||
if data.startswith(PNG_MAGIC):
|
||||
return data, 0, "png", ""
|
||||
if data.startswith(OGG_MAGIC):
|
||||
return data, 0, "ogg", ""
|
||||
if data.startswith(KTX2_MAGIC):
|
||||
return data, 0, "ktx2", ""
|
||||
if data.startswith(b"MODL"):
|
||||
return data, 0, "modl", ""
|
||||
if data.startswith(b"glTF"):
|
||||
return data, 0, "gltf", ""
|
||||
|
||||
# The fast path: the key is implied by the first byte of the format.
|
||||
if ext in FIRST_BYTE:
|
||||
key = data[0] ^ FIRST_BYTE[ext]
|
||||
head = unxor(data[:16], key)
|
||||
if ext == ".png" and head.startswith(PNG_MAGIC):
|
||||
return unxor(data, key), key, "png", ""
|
||||
if ext == ".ogg" and head.startswith(OGG_MAGIC):
|
||||
return unxor(data, key), key, "ogg", ""
|
||||
if ext == ".json" and head[:1] in (b"{", b"["):
|
||||
return unxor(data, key), key, "json", ""
|
||||
|
||||
# The brute force path: find the key that makes the file text.
|
||||
if ext in TEXTUAL or ext not in OPAQUE:
|
||||
best = (0.0, 0, b"")
|
||||
for key in range(1, 256):
|
||||
head = unxor(data[:512], key)
|
||||
s = score_text(head)
|
||||
if s > best[0]:
|
||||
best = (s, key, head)
|
||||
if best[0] >= 0.95:
|
||||
return unxor(data, best[1]), best[1], "text", ""
|
||||
|
||||
# Nothing worked.
|
||||
return data, -1, "opaque", "ключ не подобрался"
|
||||
|
||||
|
||||
def walk(base: Path):
|
||||
for dirpath, dirnames, filenames in os.walk(base):
|
||||
for name in filenames:
|
||||
yield Path(dirpath) / name
|
||||
|
||||
|
||||
def extract_tree(src: Path, dst: Path, manifest: list, stats: dict):
|
||||
for path in walk(src):
|
||||
rel = path.relative_to(src)
|
||||
target = dst / rel
|
||||
ext = path.suffix.lower()
|
||||
try:
|
||||
decoded, key, kind, note = decode_file(path, ext)
|
||||
except Exception as exc: # a broken file must not kill the run
|
||||
stats["error"] = stats.get("error", 0) + 1
|
||||
manifest.append({"src": str(rel), "status": "error", "note": str(exc)})
|
||||
continue
|
||||
|
||||
target.parent.mkdir(parents=True, exist_ok=True)
|
||||
target.write_bytes(decoded)
|
||||
|
||||
bucket = stats.setdefault(kind, {"count": 0, "bytes": 0, "encoded": 0})
|
||||
bucket["count"] += 1
|
||||
bucket["bytes"] += len(decoded)
|
||||
if key > 0:
|
||||
bucket["encoded"] += 1
|
||||
|
||||
entry = {"src": str(rel), "kind": kind, "key": key, "bytes": len(decoded)}
|
||||
if note:
|
||||
entry["note"] = note
|
||||
manifest.append(entry)
|
||||
|
||||
|
||||
def extract_jar(jar: Path, dst: Path, manifest: list, stats: dict):
|
||||
with zipfile.ZipFile(jar) as zf:
|
||||
for info in zf.infolist():
|
||||
if info.is_dir():
|
||||
continue
|
||||
name = info.filename
|
||||
if not name.startswith("assets/"):
|
||||
continue
|
||||
target = dst / name
|
||||
target.parent.mkdir(parents=True, exist_ok=True)
|
||||
data = zf.read(name)
|
||||
target.write_bytes(data)
|
||||
stats.setdefault("jar", {"count": 0, "bytes": 0, "encoded": 0})
|
||||
stats["jar"]["count"] += 1
|
||||
stats["jar"]["bytes"] += len(data)
|
||||
manifest.append({"src": name, "kind": "jar", "key": 0, "bytes": len(data)})
|
||||
|
||||
|
||||
def main() -> int:
|
||||
started = time.time()
|
||||
if not SRC_RES.is_dir():
|
||||
print("нет исходника:", SRC_RES)
|
||||
return 1
|
||||
|
||||
# The tree is overwritten file by file, so a leftover from an aborted run
|
||||
# is harmless. A hard delete is only a convenience, and Windows likes to
|
||||
# keep a handle on a directory that was written a moment ago.
|
||||
shutil.rmtree(DST, ignore_errors=True)
|
||||
DST.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
manifest: list = []
|
||||
stats: dict = {}
|
||||
|
||||
print("1/3 legacy assets ...", flush=True)
|
||||
extract_tree(SRC_RES / "assets", DST / "legacy", manifest, stats)
|
||||
|
||||
print("2/3 nextgen models ...", flush=True)
|
||||
extract_tree(SRC_RES / "nextgen", DST / "nextgen", manifest, stats)
|
||||
|
||||
print("3/3 game.jar + maps ...", flush=True)
|
||||
if SRC_JAR.is_file():
|
||||
extract_jar(SRC_JAR, DST / "gamejar", manifest, stats)
|
||||
if SRC_MAPS.is_dir():
|
||||
extract_tree(SRC_MAPS, DST / "maps", manifest, stats)
|
||||
|
||||
total = sum(v["bytes"] for v in stats.values())
|
||||
print("")
|
||||
for kind in sorted(stats):
|
||||
v = stats[kind]
|
||||
print(" %-8s %6d файлов, %8.1f МБ, зашифровано %d"
|
||||
% (kind, v["count"], v["bytes"] / 1048576.0, v["encoded"]))
|
||||
print("всего: %.1f МБ за %.0f с" % (total / 1048576.0, time.time() - started))
|
||||
|
||||
(DST / "MANIFEST.json").write_text(
|
||||
json.dumps({"stats": stats, "files": manifest}, ensure_ascii=False, indent=1),
|
||||
encoding="utf-8")
|
||||
print("манифест:", DST / "MANIFEST.json")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env python3
|
||||
"""The sound registry of the Rustex remake as a table.
|
||||
|
||||
The remake keeps its sounds in two places: the files under sounds/ and
|
||||
fsounds/ and the registry sounds.json plus rustex_sounds.json, which say
|
||||
which file belongs to which event.
|
||||
|
||||
The result is one csv:
|
||||
|
||||
rsx-protocol/src/main/resources/items/sounds.csv
|
||||
|
||||
with the columns id, file, volume, pitch.
|
||||
"""
|
||||
|
||||
import csv
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(r"G:\RustNotMC")
|
||||
ASSETS = ROOT / "assets" / "rustex" / "legacy" / "minecraft"
|
||||
OUT = ROOT / "rsx-protocol" / "src" / "main" / "resources" / "items" / "sounds.csv"
|
||||
|
||||
|
||||
def collect(path: Path, out: dict):
|
||||
if not path.is_file():
|
||||
return
|
||||
data = json.loads(path.read_text(encoding="utf-8", errors="replace"))
|
||||
for key, value in data.items():
|
||||
if not isinstance(value, dict):
|
||||
continue
|
||||
sounds = value.get("sounds")
|
||||
if isinstance(sounds, list):
|
||||
for sound in sounds:
|
||||
if isinstance(sound, dict) and "name" in sound:
|
||||
out.setdefault(key, []).append(
|
||||
(sound["name"], sound.get("volume", 1.0), sound.get("pitch", 1.0)))
|
||||
elif isinstance(sounds, str):
|
||||
out.setdefault(key, []).append((sounds, 1.0, 1.0))
|
||||
name = value.get("name")
|
||||
if isinstance(name, str):
|
||||
out.setdefault(key, []).append((name, 1.0, 1.0))
|
||||
|
||||
|
||||
def main() -> int:
|
||||
out = {}
|
||||
collect(ASSETS / "sounds.json", out)
|
||||
collect(ASSETS / "rustex_sounds.json", out)
|
||||
print("событий:", len(out))
|
||||
|
||||
OUT.parent.mkdir(parents=True, exist_ok=True)
|
||||
rows = 0
|
||||
with OUT.open("w", encoding="utf-8", newline="") as handle:
|
||||
writer = csv.writer(handle)
|
||||
writer.writerow(["id", "file", "volume", "pitch"])
|
||||
for key in sorted(out):
|
||||
for name, volume, pitch in out[key]:
|
||||
writer.writerow([key, name, volume, pitch])
|
||||
rows += 1
|
||||
print("строк:", rows, "->", OUT)
|
||||
|
||||
# The sounds that came with the remake, so that we know what exists.
|
||||
files = 0
|
||||
for base in (ASSETS / "sounds", ROOT / "assets" / "rustex" / "legacy" / "assets" / "fsounds"):
|
||||
if base.is_dir():
|
||||
files += sum(1 for _ in base.rglob("*.ogg"))
|
||||
print("файлов ogg на диске:", files)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user