Files
RustNotMC/tools/extract-sounds.py
sasheg dev 27047e8071 База из ремейка: ассеты, предметы, звуки и правки плана
Выгрузили из ремейка 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, деревья - пока блоки мира.
2026-10-21 19:31:51 +03:00

73 lines
2.3 KiB
Python

#!/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())