mirror of
https://github.com/migatu/vtt_work.git
synced 2026-07-14 21:38:39 +00:00
119 lines
7.6 KiB
Python
119 lines
7.6 KiB
Python
# generate_manifests.py
|
||
# Fortel Trappa — pełne manifesty ładunkowe (HOLD I/II/III) w ZIP
|
||
# Uruchom: python generate_manifests.py -> powstaną dwa pliki ZIP w bieżącym katalogu.
|
||
|
||
import random, zipfile, datetime
|
||
|
||
random.seed(40000) # deterministyczny „smak”
|
||
|
||
WORLDS = ["Ostia","Avachrus","Enoch","Gilead Prime","Nethreus","Ryza","Vostroya","Scintilla","Footfall"]
|
||
INN_NOTES = [
|
||
"Zwykły wyrób, zgodny z normą diecezjalną.",
|
||
"Do użytku cywilnego; dokumentacja pełna.",
|
||
"Na potrzeby konserwacji/edukacji polowej.",
|
||
"Brak zasilania, brak funkcji specjalnych.",
|
||
"Wersja eksportowa; gwinty zgodne z PL-3.",
|
||
"Na morale i porządek; bez cech bojowych.",
|
||
"Próbki kontrolne — wynik negatywny na scrapcode.",
|
||
"Rekwizyty katechetyczne; brak statusu kultowego.",
|
||
"Puste, czyste, opieczętowane.",
|
||
"Zabezpieczone audytem Ministorum.",
|
||
"Składane; bez ostrych krawędzi w papierach.",
|
||
"Zwykła jakość magazynowa; brak niespodzianek.",
|
||
"Brak reakcji psionicznej (pomiar: tło).",
|
||
"Standard przemysłowy; kompatybilność wysoka.",
|
||
"Do ekspozycji; nieotwierane przy inspekcji.",
|
||
"Zestaw muzealny; kojąco nudny.",
|
||
"Oznaczenie ‘cywilne’; instrukcja w komplecie.",
|
||
"Zgodne z przepisem P-77 (ładownie ogólne).",
|
||
"Pieczęć diecezjalna aktualna; datowanie bieżące.",
|
||
"Bezpieczne dla chóru i czytników vox."
|
||
]
|
||
INN_NAMES = [
|
||
"Ziarno kultywacyjne ‘Święty Oset’","Mąka ‘Hostia’","Kasza jęczmienna ‘Pielgrzym’","Groch ‘Kocioł’","Fasola ‘Pilgrim’",
|
||
"Sól żywnościowa","Olej lampowy","Smary maszynowe ‘Stałość’","Farba kadłubowa ‘Mgła’","Pasy mocujące ‘Ordo Cargo’",
|
||
"Złącza heksowe","Zawory nadciśnieniowe","Łożyska baryłkowe ‘Wytrwałość’","Łożyska kulkowe precyzyjne",
|
||
"Taśmy stalowe ‘Krzyżowe’","Plandeki światłochłonne ‘Cień’","Pudła ciszy (obudowy wygłuszające)","Lampiony procesyjne",
|
||
"Witraże polowe (składane)","Zwoje pergaminowe ‘Sztywna Karta’","Maski nabożne ‘Neutral’","Relikwie podręczne (skrzynki)",
|
||
"Szkatuły dewocyjne (stal miękka)","Szkła ochronne ‘Błękit Służbowy’","Barwniki okienne (błękit/purpura)",
|
||
"Kity hermetyczne ‘Głuchy Spaw’","Rury segmentowe PL-7","Kable PL-3 ‘Uniwersalne’","Siatki zabezpieczające ‘Drobne Oczko’",
|
||
"Zasuwy grodziowe PL-10","Zaczepy stalowe ‘Cierpliwość’","Kątowniki ciężkie ‘Prosto’","Nity kadłubowe ‘Amen’",
|
||
"Skrzynki na dźwięk (wygłuszenie)","Szkła różnobarwne (mix)","Amfory gliniane ‘E-Seria’","Szaty ‘Pokora’ (robocze)",
|
||
"Kopułki modlitewne (mini)","Płaszcze przeciwdeszczowe ‘Wachta’","Świece czarne ‘Negocjacje’","Świece woskowe ‘Cisza Nocna’",
|
||
"Zwoje kabli heksowych (ekranowane)","Sprężyny powrotne","Zawiesia wielokrążkowe","Przekaźniki proste ‘Miedź’",
|
||
"Łożyska stożkowe ‘Kierunek’","Szkatuły na krople (apteczne)","Ołtarze polowe (składane)","Figurki pobożne",
|
||
"Piety miniaturowe","Popiół posypny (liturgiczny)","Kleje statkowe ‘Głuchy Spaw’","Klemy zasilające ‘Moc’",
|
||
"Kołnierze izolacyjne PL-5","Beczki puste ‘Gotowość’","Rolki transportowe ‘Gładkie’","Słód jasny ‘Nocny’",
|
||
"Skrzydła drzwiowe ‘Jedność’","Skarbonki parafialne","Księgi wizualne (albumy)","Zegary harmoniczne (niski ton)",
|
||
"Baldachimy małe ‘Krem’","Puchar kapłański (rekwizyt)","Księgi zakładkowe","Pasy transmisyjne ‘Ciągłość’",
|
||
"Pudła akustyczne (puste)","Rękawice robocze ‘Skóra+’",
|
||
]
|
||
XENO_REAL = [
|
||
"fragmenty wraithbone Aeldari (martwe, obrobione ‘na szkło’)",
|
||
"odpryski spirit-stone (pozbawione ładunku)",
|
||
"ukryty vox-scrambler xeno (obudowa cywilna)",
|
||
"mikrofiolki po jadu Lhamaean (dokładnie wyparzone)",
|
||
"moduł holo-emisyjny Aeldari (matryca wycięta, nieaktywny)",
|
||
"kaseta rozliczeń cold trade (podwójne dno)",
|
||
"nekrotech — fragment stele ‘bezcielesnej’ (kamień ‘ozdobny’)",
|
||
"obudowy tłumiące sygnał (technologia nieidentyfikowana)",
|
||
"orb psioniczny — tłumik nastroju (źródło Aeldari)",
|
||
"halo-device: element oprawy (niekompletne, bez rdzenia)",
|
||
"resztki proscribed tomes (okładki, wkład wymieniony na blanki)",
|
||
"zegar-pikietaż dla transakcji cold trade (ukryty znacznik czasu)",
|
||
"ampułki po obscura klasy ceremonialnej (umyte; testy czyste)",
|
||
"fiolki po ‘ichorze’ drukhari (sterylnie czyste)",
|
||
"masker polowy Drukhari — tkanina z włóknem ziggurat (zdezaktywowana)",
|
||
]
|
||
|
||
def inn_note(): return random.choice(INN_NOTES)
|
||
def name(): return random.choice(INN_NAMES)
|
||
def world(): return random.choice(WORLDS)
|
||
def qty(): return random.randint(1, 8)
|
||
|
||
def make_line(idx, suspicious_ratio=0.34):
|
||
q = qty(); nm = name(); ow = world(); note = inn_note()
|
||
if random.random() < suspicious_ratio:
|
||
paren = f"({random.choice(XENO_REAL)})"
|
||
else:
|
||
paren = f"({random.choice(['zwykły ładunek cywilny','materiały szkoleniowe/rekonstrukcja','zestaw konserwatorski','komplet części serwisowych','puste i czyste','standard magazynowy','produkt spożywczy','wyposażenie pomocnicze','materiały dekoracyjne','narzędzia warsztatowe'])})"
|
||
return f"{idx}) {q}× — {nm} — {ow} — [{note}] {paren}", q
|
||
|
||
def make_section_text(hold_label, s_idx, s_cnt):
|
||
header = f"=== FORTEL TRAPPA — MANIFEST ŁADUNKOWY ===\n{hold_label} / SEKCJA {s_idx} z {s_cnt}\n(Format: [Liczba 1–10] × Standardowy Imperialny Kontener — Nazwa — Pochodzenie — [Uwaga kapitańska] (co to naprawdę jest))\n\n"
|
||
total = 0; entries = []
|
||
for i in range(1, 124):
|
||
line, q = make_line(i, suspicious_ratio=0.34)
|
||
entries.append([line, q]); total += q
|
||
if total > 1000:
|
||
excess = total - 1000
|
||
for i in range(len(entries)-1, -1, -1):
|
||
if excess <= 0: break
|
||
q = entries[i][1]
|
||
if q > 1:
|
||
red = min(q-1, excess); entries[i][1] -= red; excess -= red
|
||
prefix, rest = entries[i][0].split("× —", 1)
|
||
idx_str = prefix.split(")")[0] + ")"
|
||
entries[i][0] = f"{idx_str} {entries[i][1]}× —{rest}"
|
||
body = "\n".join(e[0] for e in entries)
|
||
footer = f"\n\n— KONIEC: {hold_label} / SEKCJA {s_idx}/{s_cnt} —"
|
||
return header + body + footer
|
||
|
||
def write_full_zip(path_full, path_hold1):
|
||
with zipfile.ZipFile(path_full, "w", compression=zipfile.ZIP_DEFLATED) as z:
|
||
for s in range(4, 17): # HOLD I 04–16
|
||
z.writestr(f"HOLD_I_SEKCJA_{s:02d}.txt", make_section_text("HOLD I", s, 16))
|
||
for s in range(1, 16): # HOLD II 01–15
|
||
z.writestr(f"HOLD_II_SEKCJA_{s:02d}.txt", make_section_text("HOLD II", s, 15))
|
||
for s in range(1, 16): # HOLD III 01–15
|
||
z.writestr(f"HOLD_III_SEKCJA_{s:02d}.txt", make_section_text("HOLD III", s, 15))
|
||
z.writestr("README.txt", f"FORTEL TRAPPA — MANIFESTY ({datetime.datetime.utcnow().isoformat()}Z)\nHOLD I: 04–16; HOLD II: 01–15; HOLD III: 01–15\n~1/3 pozycji w ( ) ma real-tożsamość (xeno/kontrabanda), [ ] — noty ‘urzędowo niewinne’.\n")
|
||
with zipfile.ZipFile(path_hold1, "w", compression=zipfile.ZIP_DEFLATED) as z:
|
||
for s in range(4, 17):
|
||
z.writestr(f"HOLD_I_SEKCJA_{s:02d}.txt", make_section_text("HOLD I", s, 16))
|
||
z.writestr("README_HOLD_I.txt", f"HOLD I (04–16) — {datetime.datetime.utcnow().isoformat()}Z\n")
|
||
|
||
if __name__ == "__main__":
|
||
write_full_zip("FORTEL_HOLD_I_II_III_MANIFESTS.zip", "FORTEL_HOLD_I_SEKCJE_04-16.zip")
|
||
print("OK: FORTEL_HOLD_I_II_III_MANIFESTS.zip | FORTEL_HOLD_I_SEKCJE_04-16.zip")
|